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