]> git.pond.sub.org Git - empserver/blob - src/lib/subs/snxtsct.c
New macro ARRAY_SIZE()
[empserver] / src / lib / subs / snxtsct.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2020, 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
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
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
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
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
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
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 }