src/lib/commands/fuel.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  *  fuel.c: fuel ships/land units
00029  * 
00030  *  Known contributors to this file:
00031  *     
00032  */
00033 
00034 #include <config.h>
00035 
00036 #include <ctype.h>
00037 #include "commands.h"
00038 #include "empobj.h"
00039 #include "optlist.h"
00040 #include "plague.h"
00041 
00042 int
00043 fuel(void)
00044 {
00045     static int shp_or_lnd[] = { EF_SHIP, EF_LAND, EF_BAD };
00046     struct nstr_item ni;
00047     union empobj_storage item, item2;
00048     int type;
00049     struct mchrstr *mp;
00050     struct lchrstr *lcp;
00051     char *p;
00052     int fueled;
00053     int land_fuel, ship_fuel;
00054     int oil_amt, pet_amt, fuel_amt, tot_fuel, max_amt;
00055     int move_amt;
00056     double extra;
00057     struct sctstr sect;
00058     struct natstr *natp;
00059     int harbor, sector;
00060     int fuelled_ship = -1;
00061     struct nstr_item tender, ltender;
00062     char prompt[128];
00063     char buf[1024];
00064 
00065     if (opt_FUEL == 0) {
00066         pr("Option 'FUEL' not enabled\n");
00067         return RET_SYN;
00068     }
00069     if ((p =
00070          getstarg(player->argp[1], "Ship or land unit (s,l)? ", buf)) == 0)
00071         return RET_SYN;
00072     type = ef_byname_from(p, shp_or_lnd);
00073     if (type < 0) {
00074         pr("Ships or land units only! (s, l)\n");
00075         return RET_SYN;
00076     }
00077     sprintf(prompt, "%s(s)? ", ef_nameof(type));
00078     p = getstarg(player->argp[2], prompt, buf);
00079     if (!snxtitem(&ni, type, p))
00080         return RET_SYN;
00081     if (isdigit(*p))
00082         fuelled_ship = atoi(p);
00083     p = getstarg(player->argp[3], "Amount: ", buf);
00084     if (p == 0 || *p == 0)
00085         return RET_SYN;
00086     fuel_amt = atoi(p);
00087     if (fuel_amt <= 0) {
00088         pr("Fuel amount must be positive!\n");
00089         return RET_FAIL;
00090     }
00091 
00092     while (nxtitem(&ni, &item)) {
00093         fueled = 0;
00094         if (type == EF_SHIP) {
00095             if (item.ship.shp_own != player->cnum) {
00096                 int rel;
00097 
00098                 if (item.ship.shp_uid != fuelled_ship)
00099                     continue;
00100                 natp = getnatp(player->cnum);
00101                 rel = getrel(natp, item.ship.shp_own);
00102                 if (rel < FRIENDLY)
00103                     continue;
00104             }
00105             if (!getsect(item.ship.shp_x, item.ship.shp_y, &sect))
00106                 continue;
00107             if (!item.ship.shp_own)
00108                 continue;
00109 
00110             if (shp_check_nav(&sect, &item.ship) == CN_LANDLOCKED) {
00111                 pr("%s is landlocked and cannot be fueled.\n",
00112                    prship(&item.ship));
00113                 continue;
00114             }
00115 
00116             mp = &mchr[(int)item.ship.shp_type];
00117 
00118             harbor = 0;
00119             if (sect_has_dock(&sect)) {
00120                 harbor = 1;
00121                 oil_amt = sect.sct_item[I_OIL];
00122                 pet_amt = sect.sct_item[I_PETROL];
00123                 if ((oil_amt + pet_amt) == 0)
00124                     harbor = 0;
00125 
00126                 if (sect.sct_effic < 2) {
00127                     pr("The harbor at %s is not 2%% efficient yet.\n",
00128                        xyas(item.ship.shp_x, item.ship.shp_y,
00129                             player->cnum));
00130                     harbor = 0;
00131                 }
00132                 if ((sect.sct_own != player->cnum) && sect.sct_own)
00133                     harbor = 0;
00134             }
00135 
00136             if ((mp->m_fuelu == 0) && (item.ship.shp_own == player->cnum)) {
00137                 pr("%s does not use fuel!\n", prship(&item.ship));
00138                 continue;
00139             }
00140 
00141             if (harbor) {
00142                 ship_fuel = item.ship.shp_fuel;
00143                 oil_amt = sect.sct_item[I_OIL];
00144                 pet_amt = sect.sct_item[I_PETROL];
00145                 max_amt = mp->m_fuelc - ship_fuel;
00146 
00147                 if (max_amt == 0) {
00148                     pr("%s already has a full fuel load.\n",
00149                        prship(&item.ship));
00150                     continue;
00151                 }
00152                 tot_fuel = (oil_amt * 50 + pet_amt * 5);
00153                 if (tot_fuel == 0) {
00154                     pr("No fuel in the harbor at %s!\n",
00155                        xyas(sect.sct_x, sect.sct_y, player->cnum));
00156                     continue;
00157                 }
00158                 move_amt = MIN(tot_fuel, fuel_amt);
00159                 move_amt = MIN(move_amt, max_amt);
00160 
00161                 if (move_amt == 0)
00162                     continue;
00163 
00164                 item.ship.shp_fuel += move_amt;
00165 
00166                 fueled = 1;
00167                 if ((pet_amt * 5) >= move_amt) {
00168                     extra = move_amt / 5.0 - move_amt / 5;
00169                     if (extra > 0.0)
00170                         sect.sct_item[I_PETROL]
00171                             = MAX((pet_amt - move_amt / 5) - 1, 0);
00172                     else
00173                         sect.sct_item[I_PETROL]
00174                             = MAX((pet_amt - move_amt / 5), 0);
00175                 } else {
00176                     sect.sct_item[I_PETROL] = 0;
00177                     move_amt -= pet_amt * 5;
00178                     extra = move_amt / 50.0 - move_amt / 50;
00179                     sect.sct_item[I_OIL] = MAX(oil_amt - move_amt / 50, 0);
00180                     if (extra > 0.0)
00181                         sect.sct_item[I_OIL]
00182                             = MAX((oil_amt - move_amt / 50) - 1, 0);
00183                     else
00184                         sect.sct_item[I_OIL]
00185                             = MAX((oil_amt - move_amt / 50), 0);
00186                 }
00187 
00188                 /* load plague */
00189                 if (sect.sct_pstage == PLG_INFECT
00190                     && item.ship.shp_pstage == PLG_HEALTHY)
00191                     item.ship.shp_pstage = PLG_EXPOSED;
00192 
00193                 putsect(&sect);
00194                 putship(item.ship.shp_uid, &item.ship);
00195             } else {            /* not in a harbor */
00196                 if (!player->argp[4])
00197                     pr("%s is not in a supplied, efficient harbor\n",
00198                        prship(&item.ship));
00199                 if (!snxtitem(&tender, EF_SHIP,
00200                               getstarg(player->argp[4], "Oiler? ", buf)))
00201                     continue;
00202 
00203                 if (!check_ship_ok(&item.ship))
00204                     continue;
00205 
00206                 if (!nxtitem(&tender, &item2))
00207                     continue;
00208 
00209                 if (!(mchr[(int)item2.ship.shp_type].m_flags & M_OILER)) {
00210                     pr("%s is not an oiler!\n", prship(&item2.ship));
00211                     continue;
00212                 }
00213                 if (item2.ship.shp_own != player->cnum) {
00214                     pr("You don't own that oiler!\n");
00215                     continue;
00216                 }
00217 
00218                 if ((item2.ship.shp_x != item.ship.shp_x) ||
00219                     (item2.ship.shp_y != item.ship.shp_y)) {
00220                     pr("Not in the same sector!\n");
00221                     continue;
00222                 }
00223                 ship_fuel = item.ship.shp_fuel;
00224                 oil_amt = item2.ship.shp_item[I_OIL];
00225                 pet_amt = item2.ship.shp_item[I_PETROL];
00226                 max_amt = mp->m_fuelc - ship_fuel;
00227 
00228                 if (max_amt == 0) {
00229                     pr("%s already has a full fuel load.\n",
00230                        prship(&item.ship));
00231                     continue;
00232                 }
00233                 tot_fuel = oil_amt * 50 + pet_amt * 5;
00234                 move_amt = MIN(tot_fuel, fuel_amt);
00235                 move_amt = MIN(move_amt, max_amt);
00236 
00237                 if (move_amt == 0)
00238                     continue;
00239 
00240                 item.ship.shp_fuel += move_amt;
00241 
00242                 fueled = 1;
00243                 if ((pet_amt * 5) >= move_amt) {
00244                     extra = move_amt / 5.0 - move_amt / 5;
00245                     if (extra > 0.0)
00246                         item2.ship.shp_item[I_PETROL]
00247                             = MAX((pet_amt - move_amt / 5) - 1, 0);
00248                     else
00249                         item2.ship.shp_item[I_PETROL]
00250                             = MAX((pet_amt - move_amt / 5), 0);
00251                 } else {
00252                     item2.ship.shp_item[I_PETROL] = 0;
00253                     move_amt -= pet_amt * 5;
00254                     extra = move_amt / 50.0 - move_amt / 50;
00255                     item2.ship.shp_item[I_OIL]
00256                         = MAX(oil_amt - (move_amt / 50), 0);
00257                     if (extra > 0.0)
00258                         item2.ship.shp_item[I_OIL]
00259                             = MAX((oil_amt - move_amt / 50) - 1, 0);
00260                     else
00261                         item2.ship.shp_item[I_OIL]
00262                             = MAX((oil_amt - move_amt / 50), 0);
00263                 }
00264 
00265                 /* load plague */
00266                 if (item2.ship.shp_pstage == PLG_INFECT
00267                     && item.ship.shp_pstage == PLG_HEALTHY)
00268                     item.ship.shp_pstage = PLG_EXPOSED;
00269 
00270                 putship(item.ship.shp_uid, &item.ship);
00271                 /* quick hack -KHS */
00272                 if (item.ship.shp_uid == item2.ship.shp_uid)
00273                     item2.ship.shp_fuel = item.ship.shp_fuel;
00274                 putship(item2.ship.shp_uid, &item2.ship);
00275             }
00276             pr("%s", prship(&item.ship));
00277         } else {
00278             if (item.land.lnd_own != player->cnum)
00279                 continue;
00280 
00281             if (!getsect(item.land.lnd_x, item.land.lnd_y, &sect))
00282                 continue;
00283 
00284             if (!player->owner)
00285                 continue;
00286 
00287             lcp = &lchr[(int)item.land.lnd_type];
00288 
00289             sector = 1;
00290             oil_amt = sect.sct_item[I_OIL];
00291             pet_amt = sect.sct_item[I_PETROL];
00292 
00293             if ((oil_amt + pet_amt) == 0)
00294                 sector = 0;
00295 
00296             if ((item.land.lnd_fuelu == 0)
00297                 && (item.land.lnd_own == player->cnum)) {
00298                 pr("%s does not use fuel!\n", prland(&item.land));
00299                 continue;
00300             }
00301 
00302             if (sector) {
00303                 land_fuel = item.land.lnd_fuel;
00304                 oil_amt = sect.sct_item[I_OIL];
00305                 pet_amt = sect.sct_item[I_PETROL];
00306                 max_amt = item.land.lnd_fuelc - land_fuel;
00307 
00308                 if (max_amt == 0) {
00309                     pr("%s already has a full fuel load.\n",
00310                        prland(&item.land));
00311                     continue;
00312                 }
00313                 tot_fuel = (oil_amt * 50 + pet_amt * 5);
00314                 if (tot_fuel == 0) {
00315                     pr("No fuel in the sector at %s!\n",
00316                        xyas(sect.sct_x, sect.sct_y, player->cnum));
00317                     continue;
00318                 }
00319                 move_amt = MIN(tot_fuel, fuel_amt);
00320                 move_amt = MIN(move_amt, max_amt);
00321 
00322                 if (move_amt == 0)
00323                     continue;
00324 
00325                 item.land.lnd_fuel += move_amt;
00326 
00327                 fueled = 1;
00328                 if ((pet_amt * 5) >= move_amt) {
00329                     extra = move_amt / 5.0 - move_amt / 5;
00330                     if (extra > 0.0)
00331                         sect.sct_item[I_PETROL]
00332                             = MAX((pet_amt - move_amt / 5) - 1, 0);
00333                     else
00334                         sect.sct_item[I_PETROL]
00335                             = MAX((pet_amt - move_amt / 5), 0);
00336                 } else {
00337                     sect.sct_item[I_PETROL] = 0;
00338                     move_amt -= pet_amt * 5;
00339                     extra = move_amt / 50.0 - move_amt / 50;
00340                     sect.sct_item[I_OIL] = MAX(oil_amt - move_amt / 50, 0);
00341                     if (extra > 0.0)
00342                         sect.sct_item[I_OIL]
00343                             = MAX((oil_amt - move_amt / 50) - 1, 0);
00344                     else
00345                         sect.sct_item[I_OIL]
00346                             = MAX((oil_amt - move_amt / 50), 0);
00347                 }
00348 
00349                 /* load plague */
00350                 if (sect.sct_pstage == PLG_INFECT
00351                     && item.land.lnd_pstage == PLG_HEALTHY)
00352                     item.land.lnd_pstage = PLG_EXPOSED;
00353 
00354                 putsect(&sect);
00355                 putland(item.land.lnd_uid, &item.land);
00356             } else {            /* not in a sector */
00357                 if (!player->argp[4])
00358                     pr("%s is not in a supplied sector\n",
00359                        prland(&item.land));
00360                 if (!snxtitem(&ltender, EF_LAND,
00361                               getstarg(player->argp[4], "Supply unit? ",
00362                                        buf)))
00363                     continue;
00364 
00365                 if (!check_land_ok(&item.land))
00366                     continue;
00367 
00368                 if (!nxtitem(&ltender, &item2))
00369                     continue;
00370 
00371                 if (!(lchr[(int)item2.land.lnd_type].l_flags & L_SUPPLY)) {
00372                     pr("%s is not a supply unit!\n", prland(&item2.land));
00373                     continue;
00374                 }
00375                 if (item2.land.lnd_own != player->cnum) {
00376                     pr("You don't own that unit!\n");
00377                     continue;
00378                 }
00379 
00380                 if ((item2.land.lnd_x != item.land.lnd_x) ||
00381                     (item2.land.lnd_y != item.land.lnd_y)) {
00382                     pr("Not in the same sector!\n");
00383                     continue;
00384                 }
00385                 land_fuel = item.land.lnd_fuel;
00386                 oil_amt = item2.land.lnd_item[I_OIL];
00387                 pet_amt = item2.land.lnd_item[I_PETROL];
00388                 max_amt = item.land.lnd_fuelc - land_fuel;
00389 
00390                 if (max_amt == 0) {
00391                     pr("%s already has a full fuel load.\n",
00392                        prland(&item.land));
00393                     continue;
00394                 }
00395                 tot_fuel = oil_amt * 50 + pet_amt * 5;
00396                 move_amt = MIN(tot_fuel, fuel_amt);
00397                 move_amt = MIN(move_amt, max_amt);
00398 
00399                 if (move_amt == 0)
00400                     continue;
00401 
00402                 item.land.lnd_fuel += move_amt;
00403 
00404                 fueled = 1;
00405                 if ((pet_amt * 5) >= move_amt) {
00406                     extra = move_amt / 5.0 - move_amt / 5;
00407                     if (extra > 0.0)
00408                         item2.land.lnd_item[I_PETROL]
00409                             = MAX((pet_amt - move_amt / 5) - 1, 0);
00410                     else
00411                         item2.land.lnd_item[I_PETROL]
00412                             = MAX((pet_amt - move_amt / 5), 0);
00413                 } else {
00414                     item2.land.lnd_item[I_PETROL] = 0;
00415                     move_amt -= pet_amt * 5;
00416                     extra = move_amt / 50.0 - move_amt / 50;
00417                     item2.land.lnd_item[I_OIL]
00418                         = MAX(oil_amt - move_amt / 50, 0);
00419                     if (extra > 0.0)
00420                         item2.land.lnd_item[I_OIL]
00421                             = MAX((oil_amt - move_amt / 50) - 1, 0);
00422                     else
00423                         item2.land.lnd_item[I_OIL]
00424                             = MAX((oil_amt - move_amt / 50), 0);
00425                 }
00426 
00427                 /* load plague */
00428                 if (item2.land.lnd_pstage == PLG_INFECT
00429                     && item.land.lnd_pstage == PLG_HEALTHY)
00430                     item.land.lnd_pstage = PLG_EXPOSED;
00431 
00432                 putland(item.land.lnd_uid, &item.land);
00433                 /* quick hack -KHS */
00434                 if (item2.land.lnd_uid == item.land.lnd_uid)
00435                     item2.land.lnd_fuel = item.land.lnd_fuel;
00436                 putland(item2.land.lnd_uid, &item2.land);
00437             }
00438             pr("%s", prland(&item.land));
00439         }
00440         if (fueled) {
00441             pr(" takes on %d fuel in %s\n",
00442                move_amt,
00443                xyas(item.ship.shp_x, item.ship.shp_y, player->cnum));
00444             if (player->cnum != item.ship.shp_own)
00445                 wu(0, item.ship.shp_own,
00446                    "%s takes on %d fuel in %s courtesy of %s\n",
00447                    prship(&item.ship),
00448                    move_amt,
00449                    xyas(item.ship.shp_x, item.ship.shp_y,
00450                         item.ship.shp_own), cname(player->cnum));
00451         }
00452     }
00453     return RET_OK;
00454 }

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