]> git.pond.sub.org Git - empserver/blob - src/lib/subs/takeover.c
Change encoding of `not in any group' from space to 0, because that's
[empserver] / src / lib / subs / takeover.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2006, 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 files README, COPYING and CREDITS in the root of the source
23  *  tree for related information and legal notices.  It is expected
24  *  that future 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, 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     pp->pln_wing = 0;
210     putplane(pp->pln_uid, pp);
211 }
212
213 void
214 takeover_ship(struct shpstr *sp, natid newown, int hostile)
215 {
216     struct plnstr *pp;
217     struct lndstr *lp;
218     struct nstr_item ni;
219     struct plnstr p;
220     struct lndstr llp;
221
222     if (opt_MARKET)
223         trdswitchown(EF_SHIP, sp, newown);
224     makelost(EF_SHIP, sp->shp_own, sp->shp_uid, sp->shp_x, sp->shp_y);
225     sp->shp_own = newown;
226     makenotlost(EF_SHIP, sp->shp_own, sp->shp_uid, sp->shp_x, sp->shp_y);
227     sp->shp_mission = 0;
228     sp->shp_fleet = 0;
229     sp->shp_rflags = 0;
230     /* Keep track of when this was taken over */
231     time(&sp->shp_access);
232     memset(sp->shp_rpath, 0, sizeof(sp->shp_rpath));
233     pp = &p;
234     lp = &llp;
235     /* Take over planes */
236     snxtitem_all(&ni, EF_PLANE);
237     while (nxtitem(&ni, pp)) {
238         if (pp->pln_ship != sp->shp_uid)
239             continue;
240         if (pp->pln_own == 0)
241             continue;
242         if (hostile) {
243             if (pp->pln_effic > PLANE_MINEFF)
244                 pp->pln_effic = PLANE_MINEFF;
245         }
246         pp->pln_mobil = 0;
247         /* Keep track of when this was taken over */
248         time(&pp->pln_access);
249         if (opt_MARKET)
250             trdswitchown(EF_PLANE, pp, newown);
251         pp->pln_mission = 0;
252         makelost(EF_PLANE, pp->pln_own, pp->pln_uid, pp->pln_x, pp->pln_y);
253         pp->pln_own = newown;
254         makenotlost(EF_PLANE, pp->pln_own, pp->pln_uid,
255                     pp->pln_x, pp->pln_y);
256         putplane(pp->pln_uid, pp);
257     }
258     /* Take over land units */
259     snxtitem_all(&ni, EF_LAND);
260     while (nxtitem(&ni, lp)) {
261         if (lp->lnd_ship != sp->shp_uid)
262             continue;
263         if (lp->lnd_own == 0)
264             continue;
265         takeover_land(lp, newown, hostile);
266     }
267     putship(sp->shp_uid, sp);
268 }
269
270 void
271 takeover_land(struct lndstr *landp, natid newown, int hostile)
272 {
273     struct plnstr *pp;
274     struct lndstr *lp;
275     struct nstr_item ni;
276     struct plnstr p;
277     struct lndstr llp;
278
279     if (landp->lnd_effic < LAND_MINEFF) {
280         putland(landp->lnd_uid, landp);
281         return;
282     }
283     landp->lnd_army = 0;
284     landp->lnd_mobil = 0;
285     landp->lnd_harden = 0;
286     /* Keep track of when this was taken over */
287     time(&landp->lnd_access);
288     if (opt_MARKET)
289         trdswitchown(EF_LAND, landp, newown);
290     landp->lnd_mission = 0;
291     makelost(EF_LAND, landp->lnd_own, landp->lnd_uid,
292              landp->lnd_x, landp->lnd_y);
293     landp->lnd_own = newown;
294     makenotlost(EF_LAND, landp->lnd_own, landp->lnd_uid,
295                 landp->lnd_x, landp->lnd_y);
296     pp = &p;
297     lp = &llp;
298     /* Take over planes */
299     snxtitem_all(&ni, EF_PLANE);
300     while (nxtitem(&ni, pp)) {
301         if (pp->pln_land != landp->lnd_uid)
302             continue;
303         if (pp->pln_own == 0)
304             continue;
305         if (hostile) {
306             if (pp->pln_effic > PLANE_MINEFF)
307                 pp->pln_effic = PLANE_MINEFF;
308         }
309         pp->pln_mobil = 0;
310         /* Keep track of when this was taken over */
311         time(&pp->pln_access);
312         if (opt_MARKET)
313             trdswitchown(EF_PLANE, pp, newown);
314         pp->pln_mission = 0;
315         makelost(EF_PLANE, pp->pln_own, pp->pln_uid, pp->pln_x, pp->pln_y);
316         pp->pln_own = newown;
317         makenotlost(EF_PLANE, pp->pln_own, pp->pln_uid,
318                     pp->pln_x, pp->pln_y);
319         putplane(pp->pln_uid, pp);
320     }
321     /* Take over land units */
322     snxtitem_all(&ni, EF_LAND);
323     while (nxtitem(&ni, lp)) {
324         if (lp->lnd_land != landp->lnd_uid)
325             continue;
326         if (lp->lnd_own == 0)
327             continue;
328         takeover_land(lp, newown, hostile);
329     }
330     putland(landp->lnd_uid, landp);
331 }