]> git.pond.sub.org Git - empserver/blob - src/lib/subs/takeover.c
84411a3f93125eb38a648baf3c1b9178e5016203
[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;
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, (caddr_t)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, (caddr_t)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 = get_che_value(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     che = 0;
128     if (n > 0 && sp->sct_own == sp->sct_oldown) {
129         che_count = (civ * n / 3000) + 5;
130         if (che_count * 2 > civ)
131             che_count = civ / 2;
132         che_count /= hap_fact(getnatp(newown), getnatp(sp->sct_own));
133         if (che_count + oldche > CHE_MAX)
134             che_count = CHE_MAX - oldche;
135         if (che_count > 0) {
136             civ -= che_count;
137             che_count += oldche;
138         } else
139             che_count = oldche;
140     } else
141         che_count = oldche;
142     set_che_value(che, che_count);
143     if (newown != sp->sct_oldown)
144         set_che_cnum(che, newown);
145     sp->sct_che = che;
146     sp->sct_item[I_CIVIL] = civ;
147     if (sp->sct_oldown == newown || civ == 0) {
148         /*
149          * taking over one of your old sectors
150          */
151         sp->sct_loyal = 0;
152         sp->sct_oldown = newown;
153     } else {
154         /*
155          * taking over someone else's sector
156          */
157         sp->sct_loyal = 50;
158     }
159     makelost(EF_SECTOR, sp->sct_own, 0, sp->sct_x, sp->sct_y);
160     makenotlost(EF_SECTOR, newown, 0, sp->sct_x, sp->sct_y);
161     sp->sct_own = newown;
162     if (opt_MOB_ACCESS) {
163         time(&sp->sct_access);
164         sp->sct_mobil = -(etu_per_update / sect_mob_neg_factor);
165     } else {
166         sp->sct_mobil = 0;
167     }
168 }
169
170 void
171 takeover_plane(register struct plnstr *pp, natid newown)
172 {
173     int n;
174
175     if ((pp->pln_own == newown) || (pp->pln_own == 0))
176         return;
177     if (pp->pln_flags & PLN_LAUNCHED)
178         return;
179     if (pp->pln_ship >= 0 || pp->pln_land >= 0)
180         return;
181     /*
182      * XXX If this was done right, planes could escape,
183      * flying to a nearby friendly airport.
184      */
185     n = pp->pln_effic - (30 + (random() % 100));
186     if (n < 0)
187         n = 0;
188     pp->pln_effic = n;
189     if (pp->pln_effic < PLANE_MINEFF || pp->pln_harden > (s_char)0) {
190         pp->pln_effic = 0;
191         mpr(newown, "%s blown up by the crew!\n", prplane(pp));
192         wu(0, pp->pln_own,
193            "%s blown up by the crew to avoid capture by %s at %s!\n",
194            prplane(pp),
195            cname(newown), xyas(pp->pln_x, pp->pln_y, pp->pln_own));
196     } else {
197         mpr(newown, "We have captured %s!\n", prplane(pp));
198         wu(0, pp->pln_own,
199            "%s captured by %s at %s!\n",
200            prplane(pp),
201            cname(newown), xyas(pp->pln_x, pp->pln_y, pp->pln_own));
202     }
203     if (opt_MARKET)
204         trdswitchown(EF_PLANE, (int *)pp, newown);
205     if (pp->pln_mobil > (s_char)0)
206         pp->pln_mobil = 0;
207     makelost(EF_PLANE, pp->pln_own, pp->pln_uid, pp->pln_x, pp->pln_y);
208     pp->pln_own = newown;
209     makenotlost(EF_PLANE, pp->pln_own, pp->pln_uid, pp->pln_x, pp->pln_y);
210     pp->pln_mission = 0;
211     putplane(pp->pln_uid, pp);
212 }
213
214 void
215 takeover_ship(register struct shpstr *sp, natid newown, int hostile)
216 {
217     register struct plnstr *pp;
218     register struct lndstr *lp;
219     struct nstr_item ni;
220     struct plnstr p;
221     struct lndstr llp;
222
223     if (opt_MARKET)
224         trdswitchown(EF_SHIP, (int *)sp, newown);
225     makelost(EF_SHIP, sp->shp_own, sp->shp_uid, sp->shp_x, sp->shp_y);
226     sp->shp_own = newown;
227     makenotlost(EF_SHIP, sp->shp_own, sp->shp_uid, sp->shp_x, sp->shp_y);
228     sp->shp_mission = 0;
229     sp->shp_fleet = ' ';
230     sp->shp_rflags = 0;
231     /* Keep track of when this was taken over */
232     time(&sp->shp_access);
233     memset(sp->shp_rpath, 0, sizeof(sp->shp_rpath));
234     pp = &p;
235     lp = &llp;
236     /* Take over planes */
237     snxtitem_all(&ni, EF_PLANE);
238     while (nxtitem(&ni, (caddr_t)pp)) {
239         if (pp->pln_ship != sp->shp_uid)
240             continue;
241         if (pp->pln_own == 0)
242             continue;
243         if (hostile) {
244             if (pp->pln_effic > PLANE_MINEFF)
245                 pp->pln_effic = PLANE_MINEFF;
246         }
247         pp->pln_mobil = 0;
248         /* Keep track of when this was taken over */
249         time(&pp->pln_access);
250         if (opt_MARKET)
251             trdswitchown(EF_PLANE, (int *)pp, newown);
252         pp->pln_mission = 0;
253         makelost(EF_PLANE, pp->pln_own, pp->pln_uid, pp->pln_x, pp->pln_y);
254         pp->pln_own = newown;
255         makenotlost(EF_PLANE, pp->pln_own, pp->pln_uid, pp->pln_x,
256                     pp->pln_y);
257         putplane(pp->pln_uid, pp);
258     }
259     /* Take over land units */
260     snxtitem_all(&ni, EF_LAND);
261     while (nxtitem(&ni, (caddr_t)lp)) {
262         if (lp->lnd_ship != sp->shp_uid)
263             continue;
264         if (lp->lnd_own == 0)
265             continue;
266         takeover_land(lp, newown, hostile);
267     }
268     putship(sp->shp_uid, sp);
269 }
270
271 void
272 takeover_land(register struct lndstr *landp, natid newown, int hostile)
273 {
274     register struct plnstr *pp;
275     register struct lndstr *lp;
276     struct nstr_item ni;
277     struct plnstr p;
278     struct lndstr llp;
279
280     if (landp->lnd_effic < LAND_MINEFF) {
281         putland(landp->lnd_uid, landp);
282         return;
283     }
284     landp->lnd_army = ' ';
285     landp->lnd_mobil = 0;
286     landp->lnd_harden = 0;
287     /* Keep track of when this was taken over */
288     time(&landp->lnd_access);
289     if (opt_MARKET)
290         trdswitchown(EF_LAND, (int *)landp, newown);
291     landp->lnd_mission = 0;
292     makelost(EF_LAND, landp->lnd_own, landp->lnd_uid, landp->lnd_x,
293              landp->lnd_y);
294     landp->lnd_own = newown;
295     makenotlost(EF_LAND, landp->lnd_own, landp->lnd_uid, landp->lnd_x,
296                 landp->lnd_y);
297     pp = &p;
298     lp = &llp;
299     /* Take over planes */
300     snxtitem_all(&ni, EF_PLANE);
301     while (nxtitem(&ni, (caddr_t)pp)) {
302         if (pp->pln_land != landp->lnd_uid)
303             continue;
304         if (pp->pln_own == 0)
305             continue;
306         if (hostile) {
307             if (pp->pln_effic > PLANE_MINEFF)
308                 pp->pln_effic = PLANE_MINEFF;
309         }
310         pp->pln_mobil = 0;
311         /* Keep track of when this was taken over */
312         time(&pp->pln_access);
313         if (opt_MARKET)
314             trdswitchown(EF_PLANE, (int *)pp, newown);
315         pp->pln_mission = 0;
316         makelost(EF_PLANE, pp->pln_own, pp->pln_uid, pp->pln_x, pp->pln_y);
317         pp->pln_own = newown;
318         makenotlost(EF_PLANE, pp->pln_own, pp->pln_uid, pp->pln_x,
319                     pp->pln_y);
320         putplane(pp->pln_uid, pp);
321     }
322     /* Take over land units */
323     snxtitem_all(&ni, EF_LAND);
324     while (nxtitem(&ni, (caddr_t)lp)) {
325         if (lp->lnd_land != landp->lnd_uid)
326             continue;
327         if (lp->lnd_own == 0)
328             continue;
329         takeover_land(lp, newown, hostile);
330     }
331     putland(landp->lnd_uid, landp);
332 }