]> git.pond.sub.org Git - empserver/blob - src/lib/update/mobility.c
subs: Simplify MOB_ACCESS mobility update
[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-2016
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 "ship.h"
44 #include "update.h"
45
46 /* Increase mobility of everything for @etus ETUs, update timestamps */
47 void
48 mob_inc_all(int etus)
49 {
50     struct sctstr *sectp;
51     struct shpstr *sp;
52     struct plnstr *pp;
53     struct lndstr *lp;
54     int i;
55     time_t now;
56
57     time(&now);
58
59     for (i = 0; (sectp = getsectid(i)); i++) {
60         sectp->sct_timestamp = now;
61         if (!opt_MOB_ACCESS)
62             mob_inc_sect(sectp, etus);
63     }
64
65     for (i = 0; (sp = getshipp(i)); i++) {
66         sp->shp_timestamp = now;
67         if (!opt_MOB_ACCESS)
68             mob_inc_ship(sp, etus);
69     }
70
71     for (i = 0; (pp = getplanep(i)); i++) {
72         pp->pln_timestamp = now;
73         if (!opt_MOB_ACCESS)
74             mob_inc_plane(pp, etus);
75     }
76
77     for (i = 0; (lp = getlandp(i)); i++) {
78         lp->lnd_timestamp = now;
79         if (!opt_MOB_ACCESS)
80             mob_inc_land(lp, etus);
81     }
82 }
83
84 /* Increase @sp's mobility for @etus ETUs */
85 void
86 mob_inc_sect(struct sctstr *sp, int etus)
87 {
88     int value;
89
90     if (CANT_HAPPEN(etus < 0))
91         etus = 0;
92
93     if (sp->sct_own == 0)
94         return;
95     if (sp->sct_type == SCT_SANCT)
96         return;
97
98     value = sp->sct_mobil + ((float)etus * sect_mob_scale);
99     if (value > sect_mob_max)
100         value = sect_mob_max;
101     sp->sct_mobil = value;
102 }
103
104 /* Increase @sp's mobility for @etus ETUs */
105 void
106 mob_inc_ship(struct shpstr *sp, int etus)
107 {
108     int value;
109
110     if (CANT_HAPPEN(etus < 0))
111         etus = 0;
112
113     if (sp->shp_own == 0)
114         return;
115
116     value = sp->shp_mobil + (float)etus * ship_mob_scale;
117     if (value > ship_mob_max)
118         value = ship_mob_max;
119     sp->shp_mobil = (signed char)value;
120 }
121
122 /* Increase @lp's mobility for @etus ETUs */
123 void
124 mob_inc_land(struct lndstr *lp, int etus)
125 {
126     int value;
127
128     if (CANT_HAPPEN(etus < 0))
129         etus = 0;
130
131     if (lp->lnd_own == 0)
132         return;
133
134     value = lp->lnd_mobil + ((float)etus * land_mob_scale);
135     if (value > land_mob_max) {
136         if (lp->lnd_harden < land_mob_max && !opt_MOB_ACCESS) {
137             /*
138              * Automatic fortification on excess mobility.
139              * Disabled for MOB_ACCESS, because it leads to
140              * excessively deep recursion and thus miserable
141              * performance as the number of land units grows.
142              *
143              * Provide mobility to be used in lnd_fortify()
144              * without overflowing lnd_mobil.
145              */
146             lp->lnd_mobil = land_mob_max;
147             lnd_fortify(lp, value - land_mob_max);
148         }
149         value = land_mob_max;
150     }
151     lp->lnd_mobil = value;
152 }
153
154 /* Increase @pp's mobility for @etus ETUs */
155 void
156 mob_inc_plane(struct plnstr *pp, int etus)
157 {
158     int value;
159
160     if (CANT_HAPPEN(etus < 0))
161         etus = 0;
162
163     if (pp->pln_own == 0)
164         return;
165
166     value = pp->pln_mobil + ((float)etus * plane_mob_scale);
167     if (value > plane_mob_max)
168         value = plane_mob_max;
169     pp->pln_mobil = value;
170 }
171
172 /*
173  * Credit the turn's remaining MOB_ACCESS mobility.
174  * Exactly as if everything was accessed right now.
175  */
176 void
177 mob_access_all(void)
178 {
179     struct sctstr *sectp;
180     struct shpstr *sp;
181     struct plnstr *pp;
182     struct lndstr *lp;
183     int i;
184
185     if (CANT_HAPPEN(!opt_MOB_ACCESS))
186         return;
187
188     for (i = 0; (sectp = getsectid(i)); i++)
189         mob_inc_sect(sectp, game_reset_tick(&sectp->sct_access));
190
191     for (i = 0; (sp = getshipp(i)); i++)
192         mob_inc_ship(sp, game_reset_tick(&sp->shp_access));
193
194     for (i = 0; (pp = getplanep(i)); i++)
195         mob_inc_plane(pp, game_reset_tick(&pp->pln_access));
196
197     for (i = 0; (lp = getlandp(i)); i++)
198         mob_inc_land(lp, game_reset_tick(&lp->lnd_access));
199 }