]> git.pond.sub.org Git - empserver/blob - src/lib/update/mobility.c
production: Use update code instead of duplicating it
[empserver] / src / lib / update / mobility.c
1 /*
2  *  Empire - A multi-player, client/server Internet based war game.
3  *  Copyright (C) 1986-2016, Dave Pare, Jeff Bailey, Thomas Ruschak,
4  *                Ken Stevens, Steve McClure, Markus Armbruster
5  *
6  *  Empire 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 3 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, see <http://www.gnu.org/licenses/>.
18  *
19  *  ---
20  *
21  *  See files README, COPYING and CREDITS in the root of the source
22  *  tree for related information and legal notices.  It is expected
23  *  that future projects/authors will amend these files as needed.
24  *
25  *  ---
26  *
27  *  mobility.c: Add mobility to each of the items which accumulate mobility.
28  *
29  *  Known contributors to this file:
30  *     Dave Pare, 1986
31  *     Steve McClure, 1998-1999
32  *     Markus Armbruster, 2004-2008
33  */
34
35 #include <config.h>
36
37 #include "file.h"
38 #include "game.h"
39 #include "land.h"
40 #include "optlist.h"
41 #include "plane.h"
42 #include "sect.h"
43 #include "server.h"
44 #include "ship.h"
45 #include "update.h"
46
47 static int do_upd_checking;
48
49 static void do_mob_land(struct lndstr *, int);
50 static void do_mob_plane(struct plnstr *, int);
51 static void do_mob_sect(struct sctstr *sp, int etus);
52 static void do_mob_ship(struct shpstr *, int);
53
54 void
55 sct_do_upd_mob(struct sctstr *sp)
56 {
57     int etus;
58
59     if (do_upd_checking || update_running)
60         return;
61     if (sp->sct_own == 0)
62         return;
63     if (sp->sct_type == SCT_SANCT)
64         return;
65     etus = game_tick_to_now(&sp->sct_access);
66     if (etus == 0)
67         return;
68
69     do_upd_checking = 1;        /* avoid recursion */
70     do_mob_sect(sp, etus);
71     do_upd_checking = 0;
72 }
73
74 void
75 shp_do_upd_mob(struct shpstr *sp)
76 {
77     int etus;
78
79     if (do_upd_checking || update_running)
80         return;
81     if (sp->shp_own == 0)
82         return;
83     etus = game_tick_to_now(&sp->shp_access);
84     if (etus == 0)
85         return;
86
87     do_upd_checking = 1;        /* avoid recursion */
88     do_mob_ship(sp, etus);
89     do_upd_checking = 0;
90 }
91
92 void
93 lnd_do_upd_mob(struct lndstr *lp)
94 {
95     int etus;
96
97     if (do_upd_checking || update_running)
98         return;
99     if (lp->lnd_own == 0)
100         return;
101     etus = game_tick_to_now(&lp->lnd_access);
102     if (etus == 0)
103         return;
104
105     do_upd_checking = 1;        /* avoid recursion */
106     do_mob_land(lp, etus);
107     do_upd_checking = 0;
108 }
109
110 void
111 pln_do_upd_mob(struct plnstr *pp)
112 {
113     int etus;
114
115     if (do_upd_checking || update_running)
116         return;
117     if (pp->pln_own == 0)
118         return;
119     etus = game_tick_to_now(&pp->pln_access);
120     if (etus == 0)
121         return;
122
123     do_upd_checking = 1;        /* avoid recursion */
124     do_mob_plane(pp, etus);
125     do_upd_checking = 0;
126 }
127
128 void
129 mob_sect(void)
130 {
131     struct sctstr *sp;
132     int n, etus;
133     time_t now;
134
135     time(&now);
136     for (n = 0; NULL != (sp = getsectid(n)); n++) {
137         sp->sct_timestamp = now;
138         if (opt_MOB_ACCESS)
139             etus = game_reset_tick(&sp->sct_access);
140         else
141             etus = etu_per_update;
142         do_mob_sect(sp, etus);
143     }
144 }
145
146 static void
147 do_mob_sect(struct sctstr *sp, int etus)
148 {
149     int value;
150
151     if (CANT_HAPPEN(etus < 0))
152         etus = 0;
153
154     if (sp->sct_own == 0)
155         return;
156     if (sp->sct_type == SCT_SANCT)
157         return;
158
159     value = sp->sct_mobil + ((float)etus * sect_mob_scale);
160     if (value > sect_mob_max)
161         value = sect_mob_max;
162     sp->sct_mobil = value;
163 }
164
165 void
166 mob_ship(void)
167 {
168     struct shpstr *sp;
169     int n, etus;
170     time_t now;
171
172     time(&now);
173     for (n = 0; NULL != (sp = getshipp(n)); n++) {
174         sp->shp_timestamp = now;
175         if (opt_MOB_ACCESS)
176             etus = game_reset_tick(&sp->shp_access);
177         else
178             etus = etu_per_update;
179         do_mob_ship(sp, etus);
180     }
181 }
182
183 static void
184 do_mob_ship(struct shpstr *sp, int etus)
185 {
186     int value;
187
188     if (CANT_HAPPEN(etus < 0))
189         etus = 0;
190
191     if (sp->shp_own == 0)
192         return;
193
194     value = sp->shp_mobil + (float)etus * ship_mob_scale;
195     if (value > ship_mob_max)
196         value = ship_mob_max;
197     sp->shp_mobil = (signed char)value;
198 }
199
200 void
201 mob_land(void)
202 {
203     struct lndstr *lp;
204     int n, etus;
205     time_t now;
206
207     time(&now);
208     for (n = 0; NULL != (lp = getlandp(n)); n++) {
209         lp->lnd_timestamp = now;
210         if (opt_MOB_ACCESS)
211             etus = game_reset_tick(&lp->lnd_access);
212         else
213             etus = etu_per_update;
214         do_mob_land(lp, etus);
215     }
216 }
217
218 static void
219 do_mob_land(struct lndstr *lp, int etus)
220 {
221     int value;
222
223     if (CANT_HAPPEN(etus < 0))
224         etus = 0;
225
226     if (lp->lnd_own == 0)
227         return;
228
229     value = lp->lnd_mobil + ((float)etus * land_mob_scale);
230     if (value > land_mob_max) {
231         if (lp->lnd_harden < land_mob_max && !opt_MOB_ACCESS) {
232             /*
233              * Automatic fortification on excess mobility.
234              * Disabled for MOB_ACCESS, because it leads to
235              * excessively deep recursion and thus miserable
236              * performance as the number of land units grows.
237              *
238              * Provide mobility to be used in lnd_fortify()
239              * without overflowing lnd_mobil.
240              */
241             lp->lnd_mobil = land_mob_max;
242             lnd_fortify(lp, value - land_mob_max);
243         }
244         value = land_mob_max;
245     }
246     lp->lnd_mobil = value;
247 }
248
249 void
250 mob_plane(void)
251 {
252     struct plnstr *pp;
253     int n, etus;
254     time_t now;
255
256     time(&now);
257     for (n = 0; NULL != (pp = getplanep(n)); n++) {
258         pp->pln_timestamp = now;
259         if (opt_MOB_ACCESS)
260             etus = game_reset_tick(&pp->pln_access);
261         else
262             etus = etu_per_update;
263         do_mob_plane(pp, etus);
264     }
265 }
266
267 static void
268 do_mob_plane(struct plnstr *pp, int etus)
269 {
270     int value;
271
272     if (CANT_HAPPEN(etus < 0))
273         etus = 0;
274
275     if (pp->pln_own == 0)
276         return;
277
278     value = pp->pln_mobil + ((float)etus * plane_mob_scale);
279     if (value > plane_mob_max)
280         value = plane_mob_max;
281     pp->pln_mobil = value;
282 }