2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak,
4 * Ken Stevens, Steve McClure
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.
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.
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
22 * See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
23 * related information and legal notices. It is expected that any future
24 * projects/authors will amend these files as needed.
28 * vlist.c: manage variable lists
30 * Known contributors to this file:
45 static int freeslot(u_char *vec, register u_char *end);
49 vl_find(register int vtype, u_char *typevec, u_short *amtvec, int nelem)
53 register u_char *endp;
55 if (vtype < 0 || vtype > V_MAX)
60 for (; vp < endp; vp++, ap++) {
69 vl_set(register int vtype, u_int amt, u_char *typevec, u_short *amtvec,
73 register u_char *endp;
77 if (vtype < 0 || vtype > V_MAX)
80 logerror("vl_set: bad amt %d (%x), vtype %d\n", (int)amt, amt,
87 for (; vp < endp; vp++, ap++) {
93 /* deleting, but not present */
97 if (isdel(vtype) || isdist(vtype))
99 /* replace any del or dst entries */
100 if ((n = freeslot(typevec, endp)) < 0)
112 /* altering; just change value */
118 /* if not last element, copy last to current */
127 vl_damage(register int pct, register u_char *typevec,
128 register u_short *amtvec, register int nelem)
137 for (i = 0; i < nelem; i++) {
138 if (!isitem(typevec[i]))
140 if (opt_SUPER_BARS && typevec[i] == V_BAR)
142 lose = roundavg((double)amtvec[i] * pct * 0.01);
143 if (typevec[i] == V_CIVIL ||
144 typevec[i] == V_MILIT || typevec[i] == V_UW)
145 lose = ldround(people_damage * lose, 1);
146 if ((amtvec[i] -= lose) + 1 == 0) {
150 typevec[i] = typevec[nelem];
151 amtvec[i] = amtvec[nelem];
159 * extract all "mask" items from the variable list
160 * caller must pass a pointer to an aray of I_MAX+1,
161 * or else bad things will happen.
164 vl_getvec(register u_char *src_type, register u_short *src_amt,
165 register int src_nv, register int class, register int *dst_amt)
171 for (n = 0; n < I_MAX + 1; n++)
173 for (count = 0, n = 0; n < src_nv; n++) {
174 if ((src_type[n] & VT_TYPE) != class)
176 item = src_type[n] & ~VT_TYPE;
178 logerror("vl_getvec: bad I-type %d (vtype %d)\n",
182 dst_amt[item] = src_amt[n];
189 * Copy the vec into the variable list. All items zero in
190 * the vec will be deleted from the vlist, and all items
191 * present in the vec will be added to the vlist.
194 vl_setvec(register u_char *type, register u_short *amt, u_char *nvp,
195 int max, register int class, register int *vec)
205 if ((type[n] & VT_TYPE) != class) {
209 /* find non-zero vec entry to overwrite current slot */
210 for (; vec_n <= I_MAX; vec_n++)
214 /* no more elements left; delete */
217 /* copy last entry over current entry */
222 /* use new (unused) entry */
223 type[n] = vec_n | class;
230 if (n >= nv && vec_n > I_MAX)
232 /* free slots at end; copy rest of vec into the vlist */
233 for (; vec_n <= I_MAX && nv < max; vec_n++) {
236 type[nv] = vec_n | class;
237 amt[nv] = vec[vec_n];
241 if (vec_n <= I_MAX && (class == VT_ITEM || class == VT_COND)) {
243 * still stuff left; make free slots out of deliveries
244 * and distributes and stuff 'em in (only for item or cond)
246 for (; vec_n <= I_MAX; vec_n++) {
249 if ((n = freeslot(type, &type[max])) < 0) {
250 logerror("vl_setvec: no free slots left\n");
253 logerror("vl_setvec: replacing type %d amt %d\n",
255 type[n] = vec_n | class;
260 /* checking for overflow */
261 while (vec_n <= I_MAX) {
265 if (vec_n <= I_MAX) {
266 logerror("vl_setvec: no space for i-type #%d (%d)\n",
275 * make a free slot; deliveries and distributions
276 * are fair game for us.
279 freeslot(u_char *vec, register u_char *end)
283 for (vp = vec; vp < end; vp++) {
284 if (isdel(*vp) || isdist(*vp))