]> git.pond.sub.org Git - empserver/blob - src/lib/subs/takeover.c
Supply prototypes where possible. This uncovered type errors with
[empserver] / src / lib / subs / takeover.c
1 /*
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
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 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.
25  *
26  *  ---
27  *
28  *  takeover.c: Take over from another country
29  * 
30  *  Known contributors to this file:
31  *     Dave Pare, 1986
32  *     Steve McClure, 1996-2000
33  */
34
35 #include "misc.h"
36 #include "var.h"
37 #include "sect.h"
38 #include "xy.h"
39 #include "nsc.h"
40 #include "nat.h"
41 #include "plane.h"
42 #include "land.h"
43 #include "ship.h"
44 #include "file.h"
45 #include "prototypes.h"
46 #include "optlist.h"
47
48 #define CHE_MAX                 255
49
50 void takeover_land(register struct lndstr *landp, natid newown,
51                    int hostile);
52 void takeover_plane(register struct plnstr *pp, natid newown);
53
54 void
55 takeover(register struct sctstr *sp, natid newown)
56 {
57     struct plnstr *pp;
58     struct lndstr *lp;
59     int civ;
60     int che;
61     int che_count;
62     int oldche;
63     int n, vec[I_MAX + 1];
64     struct nstr_item ni;
65     struct plnstr p;
66     struct lndstr land;
67     extern int etu_per_update;
68     extern int sect_mob_neg_factor;
69
70     /* Wipe all the distribution info */
71     memset(vec, 0, sizeof(vec));
72     putvec(VT_DIST, vec, (s_char *)sp, EF_SECTOR);
73     putvec(VT_DEL, vec, (s_char *)sp, EF_SECTOR);
74     if (sp->sct_own == 0)
75         sp->sct_off = 0;
76     else
77         sp->sct_off = 1;
78     sp->sct_dist_x = sp->sct_x;
79     sp->sct_dist_y = sp->sct_y;
80
81     pp = &p;
82     /* Take over planes */
83     snxtitem_dist(&ni, EF_PLANE, sp->sct_x, sp->sct_y, 0);
84     while (nxtitem(&ni, (caddr_t)pp)) {
85         if (pp->pln_own != sp->sct_own)
86             continue;
87         takeover_plane(pp, newown);
88     }
89
90     /* Take over land units */
91     lp = &land;
92     snxtitem_dist(&ni, EF_LAND, sp->sct_x, sp->sct_y, 0);
93     while (nxtitem(&ni, (caddr_t)lp)) {
94         if ((lp->lnd_own == newown) || (lp->lnd_own == 0))
95             continue;
96         if (lp->lnd_own != sp->sct_own)
97             continue;
98         if (lp->lnd_ship >= 0 || lp->lnd_land >= 0)
99             continue;
100         /* Spies get a chance to hide */
101         if (lchr[(int)lp->lnd_type].l_flags & L_SPY) {
102             if (!(chance(LND_SPY_DETECT_CHANCE(lp->lnd_effic))))
103                 continue;
104         }
105         n = lp->lnd_effic - (30 + (random() % 100));
106         if (n < 0)
107             n = 0;
108         lp->lnd_effic = n;
109         if (lp->lnd_effic < LAND_MINEFF) {
110             lp->lnd_effic = 0;
111             mpr(newown, "%s blown up by the crew!\n", prland(lp));
112             wu(0, lp->lnd_own,
113                "%s blown up by the crew when %s took %s!\n",
114                prland(lp),
115                cname(newown), xyas(lp->lnd_x, lp->lnd_y, lp->lnd_own));
116         } else {
117             mpr(newown, "We have captured %s!\n", prland(lp));
118             wu(0, lp->lnd_own,
119                "%s captured when %s took %s!\n",
120                prland(lp),
121                cname(newown), xyas(lp->lnd_x, lp->lnd_y, lp->lnd_own));
122         }
123         takeover_land(lp, newown, 1);
124     }
125
126     sp->sct_avail = 0;
127     civ = getvar(V_CIVIL, (s_char *)sp, EF_SECTOR);
128     oldche = get_che_value(getvar(V_CHE, (s_char *)sp, EF_SECTOR));
129     /*
130      * create guerrillas from civilians
131      * how spunky are these guys?
132      * n: random number from -25:75 + (50 - loyalty)
133      */
134     n = (50 - sp->sct_loyal) + ((random() % 100) - 25);
135     che_count = 0;
136     che = 0;
137     if (n > 0 && sp->sct_own == sp->sct_oldown) {
138         che_count = (civ * n / 3000) + 5;
139         if (che_count * 2 > civ)
140             che_count = civ / 2;
141         che_count /= hap_fact(getnatp(newown), getnatp(sp->sct_own));
142         if (che_count + oldche > CHE_MAX)
143             che_count = CHE_MAX - oldche;
144         if (che_count > 0) {
145             civ -= che_count;
146             che_count += oldche;
147         } else
148             che_count = oldche;
149     } else
150         che_count = oldche;
151     set_che_value(che, che_count);
152     if (newown != sp->sct_oldown)
153         set_che_cnum(che, newown);
154     (void)putvar(V_CHE, che, (s_char *)sp, EF_SECTOR);
155     (void)putvar(V_CIVIL, civ, (s_char *)sp, EF_SECTOR);
156     if (sp->sct_oldown == newown || civ == 0) {
157         /*
158          * taking over one of your old sectors
159          */
160         sp->sct_loyal = 0;
161         sp->sct_oldown = newown;
162     } else {
163         /*
164          * taking over someone else's sector
165          */
166         sp->sct_loyal = 50;
167     }
168     makelost(EF_SECTOR, sp->sct_own, 0, sp->sct_x, sp->sct_y);
169     makenotlost(EF_SECTOR, newown, 0, sp->sct_x, sp->sct_y);
170     sp->sct_own = newown;
171     if (opt_MOB_ACCESS) {
172         time(&sp->sct_access);
173         sp->sct_mobil = -(etu_per_update / sect_mob_neg_factor);
174     } else {
175         sp->sct_mobil = 0;
176     }
177 }
178
179 void
180 takeover_plane(register struct plnstr *pp, natid newown)
181 {
182     int n;
183
184     if ((pp->pln_own == newown) || (pp->pln_own == 0))
185         return;
186     if (pp->pln_flags & PLN_LAUNCHED)
187         return;
188     if (pp->pln_ship >= 0 || pp->pln_land >= 0)
189         return;
190     /*
191      * XXX If this was done right, planes could escape,
192      * flying to a nearby friendly airport.
193      */
194     n = pp->pln_effic - (30 + (random() % 100));
195     if (n < 0)
196         n = 0;
197     pp->pln_effic = n;
198     if (pp->pln_effic < PLANE_MINEFF || pp->pln_harden > (s_char)0) {
199         pp->pln_effic = 0;
200         mpr(newown, "%s blown up by the crew!\n", prplane(pp));
201         wu(0, pp->pln_own,
202            "%s blown up by the crew to avoid capture by %s at %s!\n",
203            prplane(pp),
204            cname(newown), xyas(pp->pln_x, pp->pln_y, pp->pln_own));
205     } else {
206         mpr(newown, "We have captured %s!\n", prplane(pp));
207         wu(0, pp->pln_own,
208            "%s captured by %s at %s!\n",
209            prplane(pp),
210            cname(newown), xyas(pp->pln_x, pp->pln_y, pp->pln_own));
211     }
212     if (opt_MARKET)
213         trdswitchown(EF_PLANE, (int *)pp, newown);
214     if (pp->pln_mobil > (s_char)0)
215         pp->pln_mobil = 0;
216     makelost(EF_PLANE, pp->pln_own, pp->pln_uid, pp->pln_x, pp->pln_y);
217     pp->pln_own = newown;
218     makenotlost(EF_PLANE, pp->pln_own, pp->pln_uid, pp->pln_x, pp->pln_y);
219     pp->pln_mission = 0;
220     putplane(pp->pln_uid, pp);
221 }
222
223 void
224 takeover_ship(register struct shpstr *sp, natid newown, int hostile)
225 {
226     register struct plnstr *pp;
227     register struct lndstr *lp;
228     struct nstr_item ni;
229     struct plnstr p;
230     struct lndstr llp;
231
232     if (opt_MARKET)
233         trdswitchown(EF_SHIP, (int *)sp, newown);
234     makelost(EF_SHIP, sp->shp_own, sp->shp_uid, sp->shp_x, sp->shp_y);
235     sp->shp_own = newown;
236     makenotlost(EF_SHIP, sp->shp_own, sp->shp_uid, sp->shp_x, sp->shp_y);
237     sp->shp_mission = 0;
238     sp->shp_fleet = ' ';
239     sp->shp_rflags = 0;
240     /* Keep track of when this was taken over */
241     time(&sp->shp_access);
242     memset(sp->shp_rpath, 0, sizeof(sp->shp_rpath));
243     pp = &p;
244     lp = &llp;
245     /* Take over planes */
246     snxtitem_all(&ni, EF_PLANE);
247     while (nxtitem(&ni, (caddr_t)pp)) {
248         if (pp->pln_ship != sp->shp_uid)
249             continue;
250         if (pp->pln_own == 0)
251             continue;
252         if (hostile) {
253             if (pp->pln_effic > PLANE_MINEFF)
254                 pp->pln_effic = PLANE_MINEFF;
255         }
256         pp->pln_mobil = 0;
257         /* Keep track of when this was taken over */
258         time(&pp->pln_access);
259         if (opt_MARKET)
260             trdswitchown(EF_PLANE, (int *)pp, newown);
261         pp->pln_mission = 0;
262         makelost(EF_PLANE, pp->pln_own, pp->pln_uid, pp->pln_x, pp->pln_y);
263         pp->pln_own = newown;
264         makenotlost(EF_PLANE, pp->pln_own, pp->pln_uid, pp->pln_x,
265                     pp->pln_y);
266         putplane(pp->pln_uid, pp);
267     }
268     /* Take over land units */
269     snxtitem_all(&ni, EF_LAND);
270     while (nxtitem(&ni, (caddr_t)lp)) {
271         if (lp->lnd_ship != sp->shp_uid)
272             continue;
273         if (lp->lnd_own == 0)
274             continue;
275         takeover_land(lp, newown, hostile);
276     }
277     putship(sp->shp_uid, sp);
278 }
279
280 void
281 takeover_land(register struct lndstr *landp, natid newown, int hostile)
282 {
283     register struct plnstr *pp;
284     register struct lndstr *lp;
285     struct nstr_item ni;
286     struct plnstr p;
287     struct lndstr llp;
288
289     if (landp->lnd_effic < LAND_MINEFF) {
290         putland(landp->lnd_uid, landp);
291         return;
292     }
293     landp->lnd_army = ' ';
294     landp->lnd_mobil = 0;
295     landp->lnd_harden = 0;
296     /* Keep track of when this was taken over */
297     time(&landp->lnd_access);
298     if (opt_MARKET)
299         trdswitchown(EF_LAND, (int *)landp, newown);
300     landp->lnd_mission = 0;
301     makelost(EF_LAND, landp->lnd_own, landp->lnd_uid, landp->lnd_x,
302              landp->lnd_y);
303     landp->lnd_own = newown;
304     makenotlost(EF_LAND, landp->lnd_own, landp->lnd_uid, landp->lnd_x,
305                 landp->lnd_y);
306     pp = &p;
307     lp = &llp;
308     /* Take over planes */
309     snxtitem_all(&ni, EF_PLANE);
310     while (nxtitem(&ni, (caddr_t)pp)) {
311         if (pp->pln_land != landp->lnd_uid)
312             continue;
313         if (pp->pln_own == 0)
314             continue;
315         if (hostile) {
316             if (pp->pln_effic > PLANE_MINEFF)
317                 pp->pln_effic = PLANE_MINEFF;
318         }
319         pp->pln_mobil = 0;
320         /* Keep track of when this was taken over */
321         time(&pp->pln_access);
322         if (opt_MARKET)
323             trdswitchown(EF_PLANE, (int *)pp, newown);
324         pp->pln_mission = 0;
325         makelost(EF_PLANE, pp->pln_own, pp->pln_uid, pp->pln_x, pp->pln_y);
326         pp->pln_own = newown;
327         makenotlost(EF_PLANE, pp->pln_own, pp->pln_uid, pp->pln_x,
328                     pp->pln_y);
329         putplane(pp->pln_uid, pp);
330     }
331     /* Take over land units */
332     snxtitem_all(&ni, EF_LAND);
333     while (nxtitem(&ni, (caddr_t)lp)) {
334         if (lp->lnd_land != landp->lnd_uid)
335             continue;
336         if (lp->lnd_own == 0)
337             continue;
338         takeover_land(lp, newown, hostile);
339     }
340     putland(landp->lnd_uid, landp);
341 }