]> git.pond.sub.org Git - empserver/blob - src/lib/subs/takeover.c
(LND_SPY_DETECT_CHANCE): New.
[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,
51                    int hostile);
52 void takeover_plane(register struct plnstr *pp, natid newown);
53
54 void
55 takeover(register struct sctstr *sp, natid newown)
56 {
57     struct plnstr *pp;
58     struct lndstr *lp;
59     int civ;
60     int che;
61     int che_count;
62     int oldche;
63     int n, vec[I_MAX + 1];
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             if (!(chance(LND_SPY_DETECT_CHANCE(lp->lnd_effic))))
104                 continue;
105         }
106         n = lp->lnd_effic - (30 + (random() % 100));
107         if (n < 0)
108             n = 0;
109         lp->lnd_effic = n;
110         if (lp->lnd_effic < LAND_MINEFF) {
111             lp->lnd_effic = 0;
112             mpr(newown, "%s blown up by the crew!\n", prland(lp));
113             wu(0, lp->lnd_own,
114                "%s blown up by the crew when %s took %s!\n",
115                prland(lp),
116                cname(newown), xyas(lp->lnd_x, lp->lnd_y, lp->lnd_own));
117         } else {
118             mpr(newown, "We have captured %s!\n", prland(lp));
119             wu(0, lp->lnd_own,
120                "%s captured when %s took %s!\n",
121                prland(lp),
122                cname(newown), xyas(lp->lnd_x, lp->lnd_y, lp->lnd_own));
123         }
124         takeover_land(lp, newown, 1);
125     }
126
127     sp->sct_avail = 0;
128     civ = getvar(V_CIVIL, (s_char *)sp, EF_SECTOR);
129     oldche = get_che_value(getvar(V_CHE, (s_char *)sp, EF_SECTOR));
130     /*
131      * create guerrillas from civilians
132      * how spunky are these guys?
133      * n: random number from -25:75 + (50 - loyalty)
134      */
135     n = (50 - sp->sct_loyal) + ((random() % 100) - 25);
136     che_count = 0;
137     che = 0;
138     if (n > 0 && sp->sct_own == sp->sct_oldown) {
139         che_count = (civ * n / 3000) + 5;
140         if (che_count * 2 > civ)
141             che_count = civ / 2;
142         che_count /= hap_fact(getnatp(newown), getnatp(sp->sct_own));
143         if (che_count + oldche > CHE_MAX)
144             che_count = CHE_MAX - oldche;
145         if (che_count > 0) {
146             civ -= che_count;
147             che_count += oldche;
148         } else
149             che_count = oldche;
150     } else
151         che_count = oldche;
152     set_che_value(che, che_count);
153     if (newown != sp->sct_oldown)
154         set_che_cnum(che, newown);
155     (void)putvar(V_CHE, che, (s_char *)sp, EF_SECTOR);
156     (void)putvar(V_CIVIL, civ, (s_char *)sp, EF_SECTOR);
157     if (sp->sct_oldown == newown || civ == 0) {
158         /*
159          * taking over one of your old sectors
160          */
161         sp->sct_loyal = 0;
162         sp->sct_oldown = newown;
163     } else {
164         /*
165          * taking over someone else's sector
166          */
167         sp->sct_loyal = 50;
168     }
169     makelost(EF_SECTOR, sp->sct_own, 0, sp->sct_x, sp->sct_y);
170     makenotlost(EF_SECTOR, newown, 0, sp->sct_x, sp->sct_y);
171     sp->sct_own = newown;
172     if (opt_MOB_ACCESS) {
173         time(&sp->sct_access);
174         sp->sct_mobil = -(etu_per_update / sect_mob_neg_factor);
175     } else {
176         sp->sct_mobil = 0;
177     }
178 }
179
180 void
181 takeover_plane(register struct plnstr *pp, natid newown)
182 {
183     int n;
184
185     if ((pp->pln_own == newown) || (pp->pln_own == 0))
186         return;
187     if (pp->pln_flags & PLN_LAUNCHED)
188         return;
189     if (pp->pln_ship >= 0 || pp->pln_land >= 0)
190         return;
191     /*
192      * XXX If this was done right, planes could escape,
193      * flying to a nearby friendly airport.
194      */
195     n = pp->pln_effic - (30 + (random() % 100));
196     if (n < 0)
197         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,
266                     pp->pln_y);
267         putplane(pp->pln_uid, pp);
268     }
269     /* Take over land units */
270     snxtitem_all(&ni, EF_LAND);
271     while (nxtitem(&ni, (caddr_t)lp)) {
272         if (lp->lnd_ship != sp->shp_uid)
273             continue;
274         if (lp->lnd_own == 0)
275             continue;
276         takeover_land(lp, newown, hostile);
277     }
278     putship(sp->shp_uid, sp);
279 }
280
281 void
282 takeover_land(register struct lndstr *landp, natid newown, int hostile)
283 {
284     register struct plnstr *pp;
285     register struct lndstr *lp;
286     struct nstr_item ni;
287     struct plnstr p;
288     struct lndstr llp;
289
290     if (landp->lnd_effic < LAND_MINEFF) {
291         putland(landp->lnd_uid, landp);
292         return;
293     }
294     landp->lnd_army = ' ';
295     landp->lnd_mobil = 0;
296     landp->lnd_harden = 0;
297     /* Keep track of when this was taken over */
298     time(&landp->lnd_access);
299     if (opt_MARKET)
300         trdswitchown(EF_LAND, (int *)landp, newown);
301     landp->lnd_mission = 0;
302     makelost(EF_LAND, landp->lnd_own, landp->lnd_uid, landp->lnd_x,
303              landp->lnd_y);
304     landp->lnd_own = newown;
305     makenotlost(EF_LAND, landp->lnd_own, landp->lnd_uid, landp->lnd_x,
306                 landp->lnd_y);
307     pp = &p;
308     lp = &llp;
309     /* Take over planes */
310     snxtitem_all(&ni, EF_PLANE);
311     while (nxtitem(&ni, (caddr_t)pp)) {
312         if (pp->pln_land != landp->lnd_uid)
313             continue;
314         if (pp->pln_own == 0)
315             continue;
316         if (hostile) {
317             if (pp->pln_effic > PLANE_MINEFF)
318                 pp->pln_effic = PLANE_MINEFF;
319         }
320         pp->pln_mobil = 0;
321         /* Keep track of when this was taken over */
322         time(&pp->pln_access);
323         if (opt_MARKET)
324             trdswitchown(EF_PLANE, (int *)pp, newown);
325         pp->pln_mission = 0;
326         makelost(EF_PLANE, pp->pln_own, pp->pln_uid, pp->pln_x, pp->pln_y);
327         pp->pln_own = newown;
328         makenotlost(EF_PLANE, pp->pln_own, pp->pln_uid, pp->pln_x,
329                     pp->pln_y);
330         putplane(pp->pln_uid, pp);
331     }
332     /* Take over land units */
333     snxtitem_all(&ni, EF_LAND);
334     while (nxtitem(&ni, (caddr_t)lp)) {
335         if (lp->lnd_land != landp->lnd_uid)
336             continue;
337         if (lp->lnd_own == 0)
338             continue;
339         takeover_land(lp, newown, hostile);
340     }
341     putland(landp->lnd_uid, landp);
342 }