1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2021, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                Ken Stevens, Steve McClure, Markus Armbruster
5  *
6  *  Empire is free software: you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation, either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  *  ---
20  *
21  *  See files README, COPYING and CREDITS in the root of the source
22  *  tree for related information and legal notices.  It is expected
23  *  that future projects/authors will amend these files as needed.
24  *
25  *  ---
26  *
27  *  snxtsct.c: Arrange sector selection using either distance or area
28  *
29  *  Known contributors to this file:
30  *     Dave Pare, 1989
31  *     Markus Armbruster, 2006-2020
32  */
33 
34 #include <config.h>
35 
36 #include "misc.h"
37 #include "nat.h"
38 #include "nsc.h"
39 #include "optlist.h"
40 #include "player.h"
41 #include "prototypes.h"
42 #include "xy.h"
43 
44 /*
45  * setup the nstr_sect structure for sector selection.
46  * can select on either NS_ALL, NS_AREA, or NS_DIST
47  * iterate thru the "condarg" string looking
48  * for arguments to compile into the nstr.
49  * Using this function for anything but command arguments is usually
50  * incorrect, because it respects conditionals.  Use the snxtsct_FOO()
51  * instead.
52  */
53 int
snxtsct(struct nstr_sect * np,char * str)54 snxtsct(struct nstr_sect *np, char *str)
55 {
56     struct range range;
57     struct natstr *natp;
58     coord cx, cy;
59     int dist;
60     char buf[1024];
61 
62     if (!str || !*str) {
63 	if (!(str = getstring("(sects)? ", buf)))
64 	    return 0;
65     } else
66 	make_stale_if_command_arg(str);
67     switch (sarg_type(str)) {
68     case NS_AREA:
69 	if (!sarg_area(str, &range))
70 	    return 0;
71 	snxtsct_area(np, &range);
72 	break;
73     case NS_DIST:
74 	if (!sarg_range(str, &cx, &cy, &dist))
75 	    return 0;
76 	snxtsct_dist(np, cx, cy, dist);
77 	break;
78     case NS_ALL:
79 	/*
80 	 * Can't use snxtsct_all(), as it would disclose the real
81 	 * origin.  Use a world-sized area instead.
82 	 */
83 	natp = getnatp(player->cnum);
84 	range.lx = xabs(natp, -WORLD_X / 2);
85 	range.ly = yabs(natp, -WORLD_Y / 2);
86 	range.hx = xnorm(range.lx + WORLD_X - 1);
87 	range.hy = ynorm(range.ly + WORLD_Y - 1);
88 	xysize_range(&range);
89 	snxtsct_area(np, &range);
90 	break;
91     default:
92 	return 0;
93     }
94     return snxtsct_use_condarg(np);
95 }
96 
97 void
snxtsct_all(struct nstr_sect * np)98 snxtsct_all(struct nstr_sect *np)
99 {
100     struct range worldrange;
101 
102     worldrange.lx = 0;
103     worldrange.ly = 0;
104     worldrange.hx = WORLD_X - 1;
105     worldrange.hy = WORLD_Y - 1;
106     xysize_range(&worldrange);
107     snxtsct_area(np, &worldrange);
108 }
109 
110 void
snxtsct_area(struct nstr_sect * np,struct range * range)111 snxtsct_area(struct nstr_sect *np, struct range *range)
112 {
113     memset(np, 0, sizeof(*np));
114     np->range = *range;
115     np->ncond = 0;
116     np->type = NS_AREA;
117     np->x = np->range.lx - 1;
118     np->y = np->range.ly;
119     np->dx = -1;
120     np->dy = 0;
121 }
122 
123 int
snxtsct_use_condarg(struct nstr_sect * np)124 snxtsct_use_condarg(struct nstr_sect *np)
125 {
126     int n;
127 
128     if (!player->condarg)
129 	return 1;
130     n = nstr_comp(np->cond, ARRAY_SIZE(np->cond),
131 		  EF_SECTOR, player->condarg);
132     if (n < 0)
133 	return 0;
134     np->ncond = n;
135     return 1;
136 }
137 
138 void
snxtsct_rewind(struct nstr_sect * np)139 snxtsct_rewind(struct nstr_sect *np)
140 {
141     np->x = np->range.lx - 1;
142     np->y = np->range.ly;
143     np->dx = -1;
144     np->dy = 0;
145     np->id = -1;
146 }
147 
148 void
snxtsct_dist(struct nstr_sect * np,coord cx,coord cy,int dist)149 snxtsct_dist(struct nstr_sect *np, coord cx, coord cy, int dist)
150 {
151     memset(np, 0, sizeof(*np));
152     xydist_range(cx, cy, dist, &np->range);
153     np->cx = cx;
154     np->cy = cy;
155     np->ncond = 0;
156     np->dist = dist;
157     np->type = NS_DIST;
158     np->x = np->range.lx - 1;
159     np->y = np->range.ly;
160     np->dx = -1;
161     np->dy = 0;
162 }
163