00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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, §))
00106 continue;
00107 if (!item.ship.shp_own)
00108 continue;
00109
00110 if (shp_check_nav(§, &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(§)) {
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
00189 if (sect.sct_pstage == PLG_INFECT
00190 && item.ship.shp_pstage == PLG_HEALTHY)
00191 item.ship.shp_pstage = PLG_EXPOSED;
00192
00193 putsect(§);
00194 putship(item.ship.shp_uid, &item.ship);
00195 } else {
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
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
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, §))
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
00350 if (sect.sct_pstage == PLG_INFECT
00351 && item.land.lnd_pstage == PLG_HEALTHY)
00352 item.land.lnd_pstage = PLG_EXPOSED;
00353
00354 putsect(§);
00355 putland(item.land.lnd_uid, &item.land);
00356 } else {
00357 if (!player->argp[4])
00358 pr("%s is not in a supplied sector\n",
00359 prland(&item.land));
00360 if (!snxtitem(<ender, 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(<ender, &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
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
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 }