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