]> git.pond.sub.org Git - empserver/blob - src/lib/subs/snxtitem.c
Change encoding of `not in any group' from space to 0, because that's
[empserver] / src / lib / subs / snxtitem.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2006, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                           Ken Stevens, Steve McClure
5  *
6  *  This program 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 2 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, write to the Free Software
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  *  ---
21  *
22  *  See files README, COPYING and CREDITS in the root of the source
23  *  tree for related information and legal notices.  It is expected
24  *  that future projects/authors will amend these files as needed.
25  *
26  *  ---
27  *
28  *  snxtitem.c: Arrange item selection using one of many criteria.
29  * 
30  *  Known contributors to this file:
31  *     Dave Pare, 1989
32  */
33
34 #include <config.h>
35
36 #include "misc.h"
37 #include "player.h"
38 #include "xy.h"
39 #include "nsc.h"
40 #include "file.h"
41 #include "prototypes.h"
42
43 /*
44  * setup the nstr structure for sector selection.
45  * can select on NS_ALL, NS_AREA, NS_DIST, and NS_LIST.
46  * iterate thru the "condarg" string looking
47  * for arguments to compile into the nstr.
48  * Using this function for anything but command arguments is usually
49  * incorrect, because it respects conditionals.  Use the snxtitem_FOO()
50  * instead.
51  */
52 int
53 snxtitem(struct nstr_item *np, int type, char *str)
54 {
55     struct range range;
56     int list[NS_LSIZE];
57     int n;
58     coord cx, cy;
59     int dist;
60     int flags;
61     char natnumber[16];
62     char prompt[128];
63     char buf[1024];
64
65     np->type = EF_BAD;
66     np->sel = NS_UNDEF;
67     if (str == 0) {
68         sprintf(prompt, "%s(s)? ", ef_nameof(type));
69         str = getstring(prompt, buf);
70         if (str == 0)
71             return 0;
72     }
73     if (*str == 0) {
74         /* empty string passed by player */
75         return 0;
76     }
77     if (type == EF_NATION && isalpha(*str)) {
78         sprintf(natnumber, "%d", natarg(str, NULL));
79         str = natnumber;
80     }
81     flags = ef_flags(type);
82     switch (sarg_type(str)) {
83     case NS_AREA:
84         if (!(flags & EFF_XY))
85             return 0;
86         if (!sarg_area(str, &range))
87             return 0;
88         snxtitem_area(np, type, &range);
89         break;
90     case NS_DIST:
91         if (!(flags & EFF_XY))
92             return 0;
93         if (!sarg_range(str, &cx, &cy, &dist))
94             return 0;
95         snxtitem_dist(np, type, cx, cy, dist);
96         break;
97     case NS_ALL:
98         snxtitem_all(np, type);
99         break;
100     case NS_LIST:
101         if ((n = sarg_list(str, list, NS_LSIZE)) == 0)
102             return 0;
103         if (!snxtitem_list(np, type, list, n))
104             return 0;
105         break;
106     case NS_XY:
107         if (!(flags & EFF_XY))
108             return 0;
109         if (!sarg_xy(str, &cx, &cy))
110             return 0;
111         snxtitem_xy(np, type, cx, cy);
112         break;
113     case NS_GROUP:
114         if (!(flags & EFF_GROUP))
115             return 0;
116         snxtitem_group(np, type, *str);
117         break;
118     default:
119         return 0;
120     }
121     np->flags = flags;
122     if (player->condarg == 0)
123         return 1;
124     n = nstr_comp(np->cond, sizeof(np->cond) / sizeof(*np->cond), type,
125                   player->condarg);
126     np->ncond = n >= 0 ? n : 0;
127     return n >= 0;
128 }
129
130 void
131 snxtitem_area(struct nstr_item *np, int type, struct range *range)
132 {
133     memset(np, 0, sizeof(*np));
134     np->cur = -1;
135     np->type = type;
136     np->sel = NS_AREA;
137     np->index = -1;
138     np->range = *range;
139     np->read = ef_read;
140     np->flags = ef_flags(type);
141     xysize_range(&np->range);
142 }
143
144 void
145 snxtitem_dist(struct nstr_item *np, int type, int cx, int cy,
146               int dist)
147 {
148     struct range range;
149
150     memset(np, 0, sizeof(*np));
151     xydist_range(cx, cy, dist, &range);
152     np->cur = -1;
153     np->type = type;
154     np->sel = NS_DIST;
155     np->cx = cx;
156     np->cy = cy;
157     np->index = -1;
158     np->range = range;
159     np->dist = dist;
160     np->read = ef_read;
161     np->flags = ef_flags(type);
162 #if 0
163     /* This is no longer proper. */
164     /* It did the wrong thing for small, hitech worlds. */
165     xysize_range(&np->range);
166 #endif
167 }
168
169 void
170 snxtitem_xy(struct nstr_item *np, int type, coord x, coord y)
171 {
172     memset(np, 0, sizeof(*np));
173     np->cur = -1;
174     np->type = type;
175     np->sel = NS_XY;
176     np->cx = xnorm(x);
177     np->cy = ynorm(y);
178     np->index = -1;
179     np->dist = 0;
180     np->read = ef_read;
181     np->flags = ef_flags(type);
182 }
183
184 void
185 snxtitem_all(struct nstr_item *np, int type)
186 {
187     memset(np, 0, sizeof(*np));
188     np->cur = -1;
189     np->sel = NS_ALL;
190     np->type = type;
191     np->index = -1;
192     np->read = ef_read;
193     np->flags = ef_flags(type);
194     xysize_range(&np->range);
195 }
196
197 void
198 snxtitem_group(struct nstr_item *np, int type, char group)
199 {
200     if (group == '~')
201         group = 0;
202     memset(np, 0, sizeof(*np));
203     np->cur = -1;
204     np->sel = NS_GROUP;
205     np->group = group;
206     np->type = type;
207     np->index = -1;
208     np->read = ef_read;
209     np->flags = ef_flags(type);
210     xysize_range(&np->range);
211 }
212
213 void
214 snxtitem_rewind(struct nstr_item *np)
215 {
216     np->cur = -1;
217     np->index = -1;
218 }
219
220 int
221 snxtitem_list(struct nstr_item *np, int type, int *list, int len)
222 {
223     int i;
224
225     memset(np, 0, sizeof(*np));
226     np->cur = -1;
227     np->type = type;
228     np->sel = NS_LIST;
229     np->index = -1;
230     np->read = ef_read;
231     np->flags = ef_flags(type);
232     if (len <= 0 || len > NS_LSIZE)
233         return 0;
234     for (i = 0; i < len; i++)
235         np->list[i] = list[i];
236     np->size = len;
237     return 1;
238 }