]> git.pond.sub.org Git - empserver/blob - src/lib/update/mobility.c
Cleanup #includes of (mostly a long time) unused header files.
[empserver] / src / lib / update / mobility.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2004, 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  *  mobility.c: Add mobility to each of the items which accumulate mobility.
29  * 
30  *  Known contributors to this file:
31  *     Dave Pare, 1986
32  *     Steve McClure, 1998-1999
33  */
34
35 #include "misc.h"
36 #include "sect.h"
37 #include "ship.h"
38 #include "land.h"
39 #include "plane.h"
40 #include "nat.h"
41 #include "file.h"
42 #include "optlist.h"
43 #include "update.h"
44 #include "gen.h"
45 #include "subs.h"
46 #include "optlist.h"
47 #include "server.h"
48
49
50 int updating_mob = 1;
51
52 static int timestamp_fixing;
53 static int do_upd_checking = 0;
54
55 static void do_mob_land(struct lndstr *, int);
56 static void do_mob_plane(struct plnstr *, int);
57 static void do_mob_sect(struct sctstr *sp, int etus);
58 static void do_mob_ship(struct shpstr *, int);
59
60 static int
61 increase_mob(time_t * counter, float mult)
62 {
63     time_t secs;
64     time_t now;
65     time_t left;
66     int newetus;
67     float newmob;
68     int inewmob;
69
70     time(&now);
71
72     secs = now - *counter;
73     if (secs < 1 || secs < s_p_etu)
74         return 0;
75     newetus = (int)(secs / s_p_etu);
76     if (newetus < 1)
77         return 0;
78     left = (secs % s_p_etu);
79     do {
80         newmob = (float)(newetus * mult);
81         inewmob = (int)(newetus * mult);
82         if (newmob == inewmob || newetus > 7)
83             break;
84         newetus--;
85         left += s_p_etu;
86     } while (newetus > 0);
87     if (newetus <= 0)
88         return 0;
89
90     time(counter);
91     *counter = *counter - left;
92
93     if (updating_mob)
94         return (newetus);
95     return 0;
96 }
97
98 void
99 update_timestamps(time_t lastsavedtime)
100 {
101     struct shpstr *shipp;
102     struct sctstr *sectp;
103     struct lndstr *landp;
104     struct plnstr *planep;
105     int n;
106     time_t now;
107     time_t delta;
108
109     timestamp_fixing = 1;
110     time(&now);
111     delta = now - lastsavedtime;
112     for (n = 0; (shipp = getshipp(n)); n++)
113         shipp->shp_access += delta;
114     for (n = 0; (sectp = getsectid(n)); n++)
115         sectp->sct_access += delta;
116     for (n = 0; (landp = getlandp(n)); n++)
117         landp->lnd_access += delta;
118     for (n = 0; (planep = getplanep(n)); n++)
119         planep->pln_access += delta;
120     timestamp_fixing = 0;
121 }
122
123 void
124 update_all_mob(void)
125 {
126     struct shpstr *shipp;
127     struct sctstr *sectp;
128     struct lndstr *landp;
129     struct plnstr *planep;
130     int n;
131
132     n = 0;
133     while (1) {
134         do_upd_checking = 1;
135         shipp = getshipp(n);
136         sectp = getsectid(n);
137         landp = getlandp(n);
138         planep = getplanep(n);
139         do_upd_checking = 0;
140         if (shipp)
141             shp_do_upd_mob(shipp);
142         if (sectp)
143             sct_do_upd_mob(sectp);
144         if (landp)
145             lnd_do_upd_mob(landp);
146         if (planep)
147             pln_do_upd_mob(planep);
148         if (!shipp && !sectp && !landp && !planep)
149             break;
150         n++;
151     }
152     do_upd_checking = 0;
153 }
154
155 void
156 sct_do_upd_mob(struct sctstr *sp)
157 {
158     int etus;
159
160     if (do_upd_checking || timestamp_fixing || update_pending)
161         return;
162     if (sp->sct_own == 0)
163         return;
164     if (sp->sct_type == SCT_SANCT)
165         return;
166     if ((etus = increase_mob(&sp->sct_access, sect_mob_scale)) == 0)
167         return;
168     do_upd_checking = 1;
169     do_mob_sect(sp, etus);
170 /*    putsect(sp);*/
171     do_upd_checking = 0;
172 }
173
174 void
175 shp_do_upd_mob(struct shpstr *sp)
176 {
177     int etus;
178
179     if (do_upd_checking || timestamp_fixing || update_pending)
180         return;
181     if (sp->shp_own == 0)
182         return;
183     if ((etus = increase_mob(&sp->shp_access, ship_mob_scale)) == 0)
184         return;
185     do_upd_checking = 1;
186     do_mob_ship(sp, etus);
187     do_upd_checking = 0;
188 }
189
190 void
191 lnd_do_upd_mob(struct lndstr *lp)
192 {
193     int etus;
194
195     if (do_upd_checking || timestamp_fixing || update_pending)
196         return;
197     if (lp->lnd_own == 0)
198         return;
199     if ((etus = increase_mob(&lp->lnd_access, land_mob_scale)) == 0)
200         return;
201
202     do_upd_checking = 1;
203     do_mob_land(lp, etus);
204     do_upd_checking = 0;
205 }
206
207 void
208 pln_do_upd_mob(struct plnstr *pp)
209 {
210     int etus;
211
212     if (do_upd_checking || timestamp_fixing || update_pending)
213         return;
214     if (pp->pln_own == 0)
215         return;
216     if ((etus = increase_mob(&pp->pln_access, plane_mob_scale)) == 0)
217         return;
218
219     do_upd_checking = 1;
220     do_mob_plane(pp, etus);
221     do_upd_checking = 0;
222 }
223
224 void
225 mob_sect(int etus)
226 {
227     struct sctstr *sp;
228     int n;
229     time_t now;
230
231     time(&now);
232     for (n = 0; NULL != (sp = getsectid(n)); n++) {
233         sp->sct_timestamp = now;
234         if (opt_MOB_ACCESS)
235             sct_do_upd_mob(sp);
236         else
237             do_mob_sect(sp, etus);
238     }
239 }
240
241 static void
242 do_mob_sect(struct sctstr *sp, int etus)
243 {
244     int value;
245
246     if (sp->sct_own == 0)
247         return;
248     if (sp->sct_type == SCT_SANCT)
249         return;
250     /* Do we have to even bother? */
251     if (sp->sct_mobil >= sect_mob_max) {
252         /* No, so set just in case and then return */
253         sp->sct_mobil = sect_mob_max;
254         return;
255     }
256     value = sp->sct_mobil + ((float)etus * sect_mob_scale);
257     if (value > sect_mob_max)
258         value = sect_mob_max;
259     sp->sct_mobil = value;
260 }
261
262 void
263 mob_ship(int etus)
264 {
265     struct shpstr *sp;
266     int n;
267     time_t now;
268
269     time(&now);
270     for (n = 0; NULL != (sp = getshipp(n)); n++) {
271         sp->shp_timestamp = now;
272         if (opt_MOB_ACCESS)
273             shp_do_upd_mob(sp);
274         else
275             do_mob_ship(sp, etus);
276     }
277 }
278
279 static void
280 do_mob_ship(struct shpstr *sp, int etus)
281 {
282     int newfuel = 0;
283     int value;
284     int can_add, have_fuel_for, total_add;
285     double d;
286
287     if (sp->shp_own == 0)
288         return;
289
290     /* Do we even have to bother updating this mobility? */
291     if (sp->shp_mobil >= ship_mob_max) {
292         /* No, so don't.  Just set it to max (just in case) and
293            return. */
294         sp->shp_mobil = ship_mob_max;
295         return;
296     }
297
298     if (opt_FUEL == 0) {        /* only a bit to do ... */
299         value = sp->shp_mobil + ((float)etus * ship_mob_scale);
300         if (value > ship_mob_max)
301             value = ship_mob_max;
302         sp->shp_mobil = value;
303         return;                 /* so we ship the FUEL stuff */
304     }
305
306     /* opt_FUEL in force */
307     if (mchr[(int)sp->shp_type].m_fuelu == 0) {
308         value = sp->shp_mobil + ((float)etus * ship_mob_scale);
309         if (value > ship_mob_max)
310             value = ship_mob_max;
311         sp->shp_mobil = (s_char)value;
312     } else {
313         can_add = ship_mob_max - sp->shp_mobil;
314         if (can_add > ((float)etus * ship_mob_scale))
315             can_add = ((float)etus * ship_mob_scale);
316         have_fuel_for = ldround((((double)sp->shp_fuel /
317                                   (double)mchr[(int)sp->shp_type].
318                                   m_fuelu) * (double)fuel_mult), 1);
319
320         if (can_add > have_fuel_for) {
321             int need;
322             need = can_add - have_fuel_for;
323             d = (double)need;
324             d *= (double)mchr[(int)sp->shp_type].m_fuelu;
325             d /= (double)fuel_mult;
326             d /= 5.0;
327             if ((d - (int)d) > 0.0)
328                 d++;
329             need = (int)d;
330             newfuel = supply_commod(sp->shp_own, sp->shp_x,
331                                     sp->shp_y, I_PETROL, need);
332             sp->shp_fuel += (u_char)(newfuel * 5);
333         }
334
335         have_fuel_for = ldround((((double)sp->shp_fuel /
336                                   (double)mchr[(int)sp->shp_type].
337                                   m_fuelu) * (double)fuel_mult), 1);
338
339         if (can_add > have_fuel_for) {
340             int need;
341             need = can_add - have_fuel_for;
342             d = (double)need;
343             d *= (double)mchr[(int)sp->shp_type].m_fuelu;
344             d /= (double)fuel_mult;
345             d /= 50.0;
346             if ((d - (int)d) > 0.0)
347                 d++;
348             need = (int)d;
349             newfuel = supply_commod(sp->shp_own, sp->shp_x,
350                                     sp->shp_y, I_OIL, need);
351             sp->shp_fuel += (u_char)(newfuel * 50);
352         }
353
354         have_fuel_for = ldround((((double)sp->shp_fuel /
355                                   (double)mchr[(int)sp->shp_type].
356                                   m_fuelu) * (double)fuel_mult), 1);
357
358         if (can_add > have_fuel_for)
359             total_add = have_fuel_for;
360         else
361             total_add = can_add;
362         d = (double)total_add;
363         d *= (double)mchr[(int)sp->shp_type].m_fuelu;
364         d /= (double)fuel_mult;
365         sp->shp_fuel -= (u_char)ldround(d, 1);
366         sp->shp_fuel = (u_char)min(sp->shp_fuel,
367                                    mchr[(int)sp->shp_type].m_fuelc);
368         sp->shp_mobil += (s_char)total_add;
369     }
370 }
371
372 void
373 mob_land(int etus)
374 {
375     struct lndstr *lp;
376     int n;
377     time_t now;
378
379     time(&now);
380     for (n = 0; NULL != (lp = getlandp(n)); n++) {
381         lp->lnd_timestamp = now;
382         if (opt_MOB_ACCESS)
383             lnd_do_upd_mob(lp);
384         else
385             do_mob_land(lp, etus);
386     }
387 }
388
389 static void
390 do_mob_land(struct lndstr *lp, int etus)
391 {
392     int newfuel = 0;
393     int value;
394     int can_add, have_fuel_for, total_add;
395     double d;
396
397     if (lp->lnd_own == 0)
398         return;
399
400     if (lp->lnd_mobil >= land_mob_max) {
401         lp->lnd_mobil = land_mob_max;
402         if (lp->lnd_harden >= land_mob_max) {
403             lp->lnd_harden = land_mob_max;
404             return;
405         }
406     }
407
408     if (opt_FUEL == 0) {        /* just some bits and pieces */
409         value = lp->lnd_mobil + ((float)etus * land_mob_scale);
410         if (value > land_mob_max) {
411             lnd_fortify(lp, value - land_mob_max);
412             value = land_mob_max;
413         }
414         lp->lnd_mobil = value;
415
416         return;                 /* Done! */
417     }
418
419     /* opt_FUEL in force ... */
420     if (lp->lnd_fuelu == 0) {
421         value = lp->lnd_mobil + ((float)etus * land_mob_scale);
422         if (value > land_mob_max) {
423             lnd_fortify(lp, value - land_mob_max);
424             value = land_mob_max;
425         }
426         lp->lnd_mobil = value;
427
428     } else {
429
430         can_add = land_mob_max - lp->lnd_mobil;
431
432         if (can_add > ((float)etus * land_mob_scale))
433             can_add = ((float)etus * land_mob_scale);
434
435         have_fuel_for = (lp->lnd_fuel / lp->lnd_fuelu) * fuel_mult;
436
437         if (can_add > have_fuel_for) {
438             int need;
439             need = can_add - have_fuel_for;
440             d = (double)need;
441             d *= (double)lp->lnd_fuelu;
442             d /= (double)fuel_mult;
443             d /= 5.0;
444             if ((d - (int)d) > 0.0)
445                 d++;
446             need = (int)d;
447             newfuel = supply_commod(lp->lnd_own, lp->lnd_x,
448                                     lp->lnd_y, I_PETROL, need);
449             lp->lnd_fuel += (u_char)(newfuel * 5);
450         }
451
452         have_fuel_for = (lp->lnd_fuel / lp->lnd_fuelu) * fuel_mult;
453
454         if (can_add > have_fuel_for) {
455             int need;
456             need = can_add - have_fuel_for;
457             d = (double)need;
458             d *= (double)lp->lnd_fuelu;
459             d /= (double)fuel_mult;
460             d /= 50.0;
461             if ((d - (int)d) > 0.0)
462                 d++;
463             need = (int)d;
464             newfuel = supply_commod(lp->lnd_own, lp->lnd_x,
465                                     lp->lnd_y, I_OIL, need);
466             lp->lnd_fuel += (u_char)(newfuel * 50);
467         }
468
469         have_fuel_for = (lp->lnd_fuel / lp->lnd_fuelu) * fuel_mult;
470
471         if (can_add > have_fuel_for) {
472             total_add = have_fuel_for;
473         } else
474             total_add = can_add;
475         d = (double)total_add;
476         d *= (double)lp->lnd_fuelu;
477         d /= (double)fuel_mult;
478         lp->lnd_fuel -= (u_char)ldround(d, 1);
479         lp->lnd_fuel = (u_char)min(lp->lnd_fuel, lp->lnd_fuelc);
480         if (total_add + lp->lnd_mobil > land_mob_max) {
481             total_add = land_mob_max - lp->lnd_mobil;
482         }
483         /* no automatic fortification here, as it would cost fuel */
484
485         lp->lnd_mobil += (s_char)total_add;
486     }
487 }
488
489 void
490 mob_plane(int etus)
491 {
492     struct plnstr *pp;
493     int n;
494     time_t now;
495
496     time(&now);
497     for (n = 0; NULL != (pp = getplanep(n)); n++) {
498         pp->pln_timestamp = now;
499         if (opt_MOB_ACCESS)
500             pln_do_upd_mob(pp);
501         else
502             do_mob_plane(pp, etus);
503     }
504 }
505
506 static void
507 do_mob_plane(struct plnstr *pp, int etus)
508 {
509     int value;
510
511     if (pp->pln_own == 0)
512         return;
513     if (pp->pln_mobil >= plane_mob_max) {
514         pp->pln_mobil = plane_mob_max;
515         return;
516     }
517
518     value = pp->pln_mobil + ((float)etus * plane_mob_scale);
519     if (value > plane_mob_max)
520         value = plane_mob_max;
521     pp->pln_mobil = value;
522 }