src/lib/update/mobility.c

Go to the documentation of this file.
00001 /*
00002  *  Empire - A multi-player, client/server Internet based war game.
00003  *  Copyright (C) 1986-2007, Dave Pare, Jeff Bailey, Thomas Ruschak,
00004  *                           Ken Stevens, Steve McClure
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  *  ---
00021  *
00022  *  See files README, COPYING and CREDITS in the root of the source
00023  *  tree for related information and legal notices.  It is expected
00024  *  that future projects/authors will amend these files as needed.
00025  *
00026  *  ---
00027  *
00028  *  mobility.c: Add mobility to each of the items which accumulate mobility.
00029  * 
00030  *  Known contributors to this file:
00031  *     Dave Pare, 1986
00032  *     Steve McClure, 1998-1999
00033  *     Markus Armbruster, 2004-2007
00034  */
00035 
00036 #include <config.h>
00037 
00038 #include "game.h"
00039 #include "land.h"
00040 #include "plane.h"
00041 #include "server.h"
00042 #include "ship.h"
00043 #include "update.h"
00044 
00045 static int do_upd_checking;
00046 
00047 static void do_mob_land(struct lndstr *, int);
00048 static void do_mob_plane(struct plnstr *, int);
00049 static void do_mob_sect(struct sctstr *sp, int etus);
00050 static void do_mob_ship(struct shpstr *, int);
00051 
00052 void
00053 sct_do_upd_mob(struct sctstr *sp)
00054 {
00055     int etus;
00056 
00057     if (do_upd_checking || update_running)
00058         return;
00059     if (sp->sct_own == 0)
00060         return;
00061     if (sp->sct_type == SCT_SANCT)
00062         return;
00063     etus = game_tick_to_now(&sp->sct_access);
00064     if (etus == 0)
00065         return;
00066 
00067     do_upd_checking = 1;        /* avoid recursion */
00068     do_mob_sect(sp, etus);
00069     do_upd_checking = 0;
00070 }
00071 
00072 void
00073 shp_do_upd_mob(struct shpstr *sp)
00074 {
00075     int etus;
00076 
00077     if (do_upd_checking || update_running)
00078         return;
00079     if (sp->shp_own == 0)
00080         return;
00081     etus = game_tick_to_now(&sp->shp_access);
00082     if (etus == 0)
00083         return;
00084 
00085     do_upd_checking = 1;        /* avoid recursion */
00086     do_mob_ship(sp, etus);
00087     do_upd_checking = 0;
00088 }
00089 
00090 void
00091 lnd_do_upd_mob(struct lndstr *lp)
00092 {
00093     int etus;
00094 
00095     if (do_upd_checking || update_running)
00096         return;
00097     if (lp->lnd_own == 0)
00098         return;
00099     etus = game_tick_to_now(&lp->lnd_access);
00100     if (etus == 0)
00101         return;
00102 
00103     do_upd_checking = 1;        /* avoid recursion */
00104     do_mob_land(lp, etus);
00105     do_upd_checking = 0;
00106 }
00107 
00108 void
00109 pln_do_upd_mob(struct plnstr *pp)
00110 {
00111     int etus;
00112 
00113     if (do_upd_checking || update_running)
00114         return;
00115     if (pp->pln_own == 0)
00116         return;
00117     etus = game_tick_to_now(&pp->pln_access);
00118     if (etus == 0)
00119         return;
00120 
00121     do_upd_checking = 1;        /* avoid recursion */
00122     do_mob_plane(pp, etus);
00123     do_upd_checking = 0;
00124 }
00125 
00126 void
00127 mob_sect(void)
00128 {
00129     struct sctstr *sp;
00130     int n, etus;
00131     time_t now;
00132 
00133     time(&now);
00134     for (n = 0; NULL != (sp = getsectid(n)); n++) {
00135         sp->sct_timestamp = now;
00136         if (opt_MOB_ACCESS)
00137             etus = game_reset_tick(&sp->sct_access);
00138         else
00139             etus = etu_per_update;
00140         do_mob_sect(sp, etus);
00141     }
00142 }
00143 
00144 static void
00145 do_mob_sect(struct sctstr *sp, int etus)
00146 {
00147     int value;
00148 
00149     if (CANT_HAPPEN(etus < 0))
00150         etus = 0;
00151 
00152     if (sp->sct_own == 0)
00153         return;
00154     if (sp->sct_type == SCT_SANCT)
00155         return;
00156 
00157     value = sp->sct_mobil + ((float)etus * sect_mob_scale);
00158     if (value > sect_mob_max)
00159         value = sect_mob_max;
00160     sp->sct_mobil = value;
00161 }
00162 
00163 void
00164 mob_ship(void)
00165 {
00166     struct shpstr *sp;
00167     int n, etus;
00168     time_t now;
00169 
00170     time(&now);
00171     for (n = 0; NULL != (sp = getshipp(n)); n++) {
00172         sp->shp_timestamp = now;
00173         if (opt_MOB_ACCESS)
00174             etus = game_reset_tick(&sp->shp_access);
00175         else
00176             etus = etu_per_update;
00177         do_mob_ship(sp, etus);
00178     }
00179 }
00180 
00181 static void
00182 do_mob_ship(struct shpstr *sp, int etus)
00183 {
00184     int newfuel = 0;
00185     int value;
00186     int can_add, have_fuel_for, total_add;
00187     double d;
00188 
00189     if (CANT_HAPPEN(etus < 0))
00190         etus = 0;
00191 
00192     if (sp->shp_own == 0)
00193         return;
00194 
00195     if (opt_FUEL == 0 || mchr[(int)sp->shp_type].m_fuelu == 0) {
00196         value = sp->shp_mobil + (float)etus * ship_mob_scale;
00197         if (value > ship_mob_max)
00198             value = ship_mob_max;
00199         sp->shp_mobil = (signed char)value;
00200     } else {
00201         if (sp->shp_mobil >= ship_mob_max) {
00202             sp->shp_mobil = ship_mob_max;
00203             return;
00204         }
00205         can_add = ship_mob_max - sp->shp_mobil;
00206         if (can_add > (float)etus * ship_mob_scale)
00207             can_add = (float)etus * ship_mob_scale;
00208         have_fuel_for = ldround(((double)sp->shp_fuel /
00209                                  (double)mchr[(int)sp->shp_type].m_fuelu)
00210                                 * (double)fuel_mult, 1);
00211 
00212         if (can_add > have_fuel_for) {
00213             int need;
00214             need = can_add - have_fuel_for;
00215             d = need;
00216             d *= mchr[(int)sp->shp_type].m_fuelu;
00217             d /= fuel_mult;
00218             d /= 5.0;
00219             if (d - (int)d > 0.0)
00220                 d++;
00221             need = (int)d;
00222             newfuel = supply_commod(sp->shp_own, sp->shp_x, sp->shp_y,
00223                                     I_PETROL, need);
00224             sp->shp_fuel += newfuel * 5;
00225         }
00226 
00227         have_fuel_for = ldround(((double)sp->shp_fuel /
00228                                  (double)mchr[(int)sp->shp_type].m_fuelu)
00229                                 * (double)fuel_mult, 1);
00230 
00231         if (can_add > have_fuel_for) {
00232             int need;
00233             need = can_add - have_fuel_for;
00234             d = need;
00235             d *= mchr[(int)sp->shp_type].m_fuelu;
00236             d /= fuel_mult;
00237             d /= 50.0;
00238             if (d - (int)d > 0.0)
00239                 d++;
00240             need = (int)d;
00241             newfuel = supply_commod(sp->shp_own, sp->shp_x, sp->shp_y,
00242                                     I_OIL, need);
00243             sp->shp_fuel += newfuel * 50;
00244         }
00245 
00246         have_fuel_for = ldround(((double)sp->shp_fuel /
00247                                  (double)mchr[(int)sp->shp_type].m_fuelu)
00248                                 * (double)fuel_mult, 1);
00249 
00250         if (can_add > have_fuel_for)
00251             total_add = have_fuel_for;
00252         else
00253             total_add = can_add;
00254         d = total_add;
00255         d *= mchr[(int)sp->shp_type].m_fuelu;
00256         d /= fuel_mult;
00257         sp->shp_fuel -= ldround(d, 1);
00258         sp->shp_fuel = MIN(sp->shp_fuel, mchr[(int)sp->shp_type].m_fuelc);
00259         sp->shp_mobil += total_add;
00260     }
00261 }
00262 
00263 void
00264 mob_land(void)
00265 {
00266     struct lndstr *lp;
00267     int n, etus;
00268     time_t now;
00269 
00270     time(&now);
00271     for (n = 0; NULL != (lp = getlandp(n)); n++) {
00272         lp->lnd_timestamp = now;
00273         if (opt_MOB_ACCESS)
00274             etus = game_reset_tick(&lp->lnd_access);
00275         else
00276             etus = etu_per_update;
00277         do_mob_land(lp, etus);
00278     }
00279 }
00280 
00281 static void
00282 do_mob_land(struct lndstr *lp, int etus)
00283 {
00284     int newfuel = 0;
00285     int value;
00286     int can_add, have_fuel_for, total_add;
00287     double d;
00288 
00289     if (CANT_HAPPEN(etus < 0))
00290         etus = 0;
00291 
00292     if (lp->lnd_own == 0)
00293         return;
00294 
00295     if (opt_FUEL == 0 || lp->lnd_fuelu == 0) {
00296         value = lp->lnd_mobil + ((float)etus * land_mob_scale);
00297         if (value > land_mob_max) {
00298             if (lp->lnd_harden < land_mob_max && !opt_MOB_ACCESS) {
00299                 /*
00300                  * Automatic fortification on excess mobility.
00301                  * Disabled for MOB_ACCESS, because it leads to
00302                  * excessively deep recursion and thus miserable
00303                  * performance as the number of land units grows.
00304                  *
00305                  * Provide mobility to be used in lnd_fortify()
00306                  * without overflowing lnd_mobil.
00307                  */
00308                 lp->lnd_mobil = land_mob_max;
00309                 lnd_fortify(lp, value - land_mob_max);
00310             }
00311             value = land_mob_max;
00312         }
00313         lp->lnd_mobil = value;
00314 
00315     } else {
00316         if (lp->lnd_mobil >= land_mob_max) {
00317             lp->lnd_mobil = land_mob_max;
00318             return;
00319         }
00320 
00321         can_add = land_mob_max - lp->lnd_mobil;
00322 
00323         if (can_add > (float)etus * land_mob_scale)
00324             can_add = (float)etus * land_mob_scale;
00325 
00326         have_fuel_for = (lp->lnd_fuel / lp->lnd_fuelu) * fuel_mult;
00327 
00328         if (can_add > have_fuel_for) {
00329             int need;
00330             need = can_add - have_fuel_for;
00331             d = need;
00332             d *= lp->lnd_fuelu;
00333             d /= fuel_mult;
00334             d /= 5.0;
00335             if (d - (int)d > 0.0)
00336                 d++;
00337             need = (int)d;
00338             newfuel = supply_commod(lp->lnd_own, lp->lnd_x, lp->lnd_y,
00339                                     I_PETROL, need);
00340             lp->lnd_fuel += newfuel * 5;
00341         }
00342 
00343         have_fuel_for = (lp->lnd_fuel / lp->lnd_fuelu) * fuel_mult;
00344 
00345         if (can_add > have_fuel_for) {
00346             int need;
00347             need = can_add - have_fuel_for;
00348             d = need;
00349             d *= lp->lnd_fuelu;
00350             d /= fuel_mult;
00351             d /= 50.0;
00352             if (d - (int)d > 0.0)
00353                 d++;
00354             need = (int)d;
00355             newfuel = supply_commod(lp->lnd_own, lp->lnd_x, lp->lnd_y,
00356                                     I_OIL, need);
00357             lp->lnd_fuel += newfuel * 50;
00358         }
00359 
00360         have_fuel_for = (lp->lnd_fuel / lp->lnd_fuelu) * fuel_mult;
00361 
00362         if (can_add > have_fuel_for) {
00363             total_add = have_fuel_for;
00364         } else
00365             total_add = can_add;
00366         d = total_add;
00367         d *= lp->lnd_fuelu;
00368         d /= fuel_mult;
00369         lp->lnd_fuel -= ldround(d, 1);
00370         lp->lnd_fuel = MIN(lp->lnd_fuel, lp->lnd_fuelc);
00371         lp->lnd_mobil += total_add;
00372         /* No excess mobility here, hence no automatic fortification */
00373     }
00374 }
00375 
00376 void
00377 mob_plane(void)
00378 {
00379     struct plnstr *pp;
00380     int n, etus;
00381     time_t now;
00382 
00383     time(&now);
00384     for (n = 0; NULL != (pp = getplanep(n)); n++) {
00385         pp->pln_timestamp = now;
00386         if (opt_MOB_ACCESS)
00387             etus = game_reset_tick(&pp->pln_access);
00388         else
00389             etus = etu_per_update;
00390         do_mob_plane(pp, etus);
00391     }
00392 }
00393 
00394 static void
00395 do_mob_plane(struct plnstr *pp, int etus)
00396 {
00397     int value;
00398 
00399     if (CANT_HAPPEN(etus < 0))
00400         etus = 0;
00401 
00402     if (pp->pln_own == 0)
00403         return;
00404 
00405     value = pp->pln_mobil + ((float)etus * plane_mob_scale);
00406     if (value > plane_mob_max)
00407         value = plane_mob_max;
00408     pp->pln_mobil = value;
00409 }

Generated on Fri Mar 28 11:01:16 2008 for empserver by  doxygen 1.5.2