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