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