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:
44 static int freeslot(u_char *vec, register u_char *end);
47 vl_find(register int vtype, u_char *typevec, u_short *amtvec, int nelem)
51 register u_char *endp;
53 if (vtype < 0 || vtype > V_MAX)
58 for (; vp < endp; vp++, ap++) {
66 vl_set(register int vtype, u_int amt, u_char *typevec, u_short *amtvec,
70 register u_char *endp;
74 if (vtype < 0 || vtype > V_MAX)
77 logerror("vl_set: bad amt %d (%x), vtype %d\n", (int)amt, amt,
84 for (; vp < endp; vp++, ap++) {
90 /* deleting, but not present */
94 if (isdel(vtype) || isdist(vtype))
96 /* replace any del or dst entries */
97 if ((n = freeslot(typevec, endp)) < 0)
109 /* altering; just change value */
115 /* if not last element, copy last to current */
124 vl_damage(register int pct, register u_char *typevec,
125 register u_short *amtvec, register int nelem)
129 extern double people_damage;
135 for (i = 0; i < nelem; i++) {
136 if (!isitem(typevec[i]))
138 if (opt_SUPER_BARS && typevec[i] == V_BAR)
140 lose = roundavg((double)amtvec[i] * pct * 0.01);
141 if (typevec[i] == V_CIVIL ||
142 typevec[i] == V_MILIT || typevec[i] == V_UW)
143 lose = ldround(people_damage * lose, 1);
144 if ((amtvec[i] -= lose) + 1 == 0) {
148 typevec[i] = typevec[nelem];
149 amtvec[i] = amtvec[nelem];
157 * extract all "mask" items from the variable list
158 * caller must pass a pointer to an aray of I_MAX+1,
159 * or else bad things will happen.
162 vl_getvec(register u_char *src_type, register u_short *src_amt,
163 register int src_nv, register int class, register int *dst_amt)
169 for (n = 0; n < I_MAX + 1; n++)
171 for (count = 0, n = 0; n < src_nv; n++) {
172 if ((src_type[n] & VT_TYPE) != class)
174 item = src_type[n] & ~VT_TYPE;
176 logerror("vl_getvec: bad I-type %d (vtype %d)\n",
180 dst_amt[item] = src_amt[n];
187 * Copy the vec into the variable list. All items zero in
188 * the vec will be deleted from the vlist, and all items
189 * present in the vec will be added to the vlist.
192 vl_setvec(register u_char *type, register u_short *amt, u_char *nvp,
193 int max, register int class, register int *vec)
203 if ((type[n] & VT_TYPE) != class) {
207 /* find non-zero vec entry to overwrite current slot */
208 for (; vec_n <= I_MAX; vec_n++)
212 /* no more elements left; delete */
215 /* copy last entry over current entry */
220 /* use new (unused) entry */
221 type[n] = vec_n | class;
228 if (n >= nv && vec_n > I_MAX)
230 /* free slots at end; copy rest of vec into the vlist */
231 for (; vec_n <= I_MAX && nv < max; vec_n++) {
234 type[nv] = vec_n | class;
235 amt[nv] = vec[vec_n];
239 if (vec_n <= I_MAX && (class == VT_ITEM || class == VT_COND)) {
241 * still stuff left; make free slots out of deliveries
242 * and distributes and stuff 'em in (only for item or cond)
244 for (; vec_n <= I_MAX; vec_n++) {
247 if ((n = freeslot(type, &type[max])) < 0) {
248 logerror("vl_setvec: no free slots left\n");
251 logerror("vl_setvec: replacing type %d amt %d\n",
253 type[n] = vec_n | class;
258 /* checking for overflow */
259 while (vec_n <= I_MAX) {
263 if (vec_n <= I_MAX) {
264 logerror("vl_setvec: no space for i-type #%d (%d)\n",
273 * make a free slot; deliveries and distributions
274 * are fair game for us.
278 freeslot(u_char *vec, register u_char *end)
282 for (vp = vec; vp < end; vp++) {
283 if (isdel(*vp) || isdist(*vp))