/*
* Empire - A multi-player, client/server Internet based war game.
- * Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ * Copyright (C) 1986-2009, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* ---
*
* supply.c: Supply subroutines
- *
+ *
* Known contributors to this file:
- *
+ *
*/
#include <config.h>
/*
* We want to get enough guns to be maxed out, enough shells to
- * fire once, one update's worth of food, enough fuel for
- * one update.
+ * fire once, one update's worth of food.
*
* Firts, try to forage in the sector
* Second look for a warehouse or headquarters to leech
* Third, look for a ship we own in a harbor
* Fourth, look for supplies in a supply unit we own
- * (one good reason to do this last is that the supply
- * unit will then call resupply, taking more time)
+ * (one good reason to do this last is that the supply
+ * unit will then call resupply, taking more time)
*
* May want to put code to resupply with SAMs here, later --ts
*/
if (!opt_NOFOOD)
resupply_commod(lp, I_FOOD);
resupply_commod(lp, I_SHELL);
- if (opt_FUEL)
- resupply_commod(lp, I_PETROL);
}
/*
resupply_commod(struct lndstr *lp, i_type type)
{
int amt;
- struct shpstr ship;
- /* Ok, do we now have enough? */
amt = get_minimum(lp, type) - lp->lnd_item[type];
if (amt > 0) {
lp->lnd_item[type] += supply_commod(lp->lnd_own,
lp->lnd_x, lp->lnd_y,
type, amt);
- amt = get_minimum(lp, type) - lp->lnd_item[type];
}
- /* Now, check again to see if we have enough. */
- if (amt > 0) {
- /* Are we on a ship? if so, try to get it from the ship first. */
- if (lp->lnd_ship >= 0) {
- getship(lp->lnd_ship, &ship);
- /* Now, determine how much we can get */
- if (amt > ship.shp_item[type])
- amt = ship.shp_item[type];
- /* Now, add and subtract */
- lp->lnd_item[type] += amt;
- ship.shp_item[type] -= amt;
- putship(lp->lnd_ship, &ship);
- }
- }
-
- if (opt_FUEL && type == I_PETROL) {
- int fuel_needed = lchr[lp->lnd_type].l_fuelu
- * ((float)etu_per_update * land_mob_scale) / 10.0;
+}
- while ((lp->lnd_fuel < fuel_needed) && lp->lnd_item[I_PETROL]) {
- lp->lnd_fuel += 10;
- if (lp->lnd_fuel > lchr[lp->lnd_type].l_fuelc)
- lp->lnd_fuel = lchr[lp->lnd_type].l_fuelc;
- lp->lnd_item[I_PETROL]--;
- }
+int
+lnd_in_supply(struct lndstr *lp)
+{
+ if (!opt_NOFOOD) {
+ if (lp->lnd_item[I_FOOD] < get_minimum(lp, I_FOOD))
+ return 0;
}
+ return lp->lnd_item[I_SHELL] >= get_minimum(lp, I_SHELL);
}
/*
int
supply_commod(int own, int x, int y, i_type type, int total_wanted)
{
- if (total_wanted < 0)
+ if (total_wanted <= 0)
return 0;
return s_commod(own, x, y, type, total_wanted, !player->simulation);
}
static int
try_supply_commod(int own, int x, int y, i_type type, int total_wanted)
{
- if (total_wanted < 0)
+ if (total_wanted <= 0)
return 0;
return s_commod(own, x, y, type, total_wanted, 0);
struct shpstr ship;
struct lndstr land;
/* leave at least 1 military in sectors/ships */
- int minimum = (type == I_MILIT ? 1 : 0);
+ int minimum = 0;
int can_move;
double move_cost, weight, mobcost;
int packing;
getsect(x, y, &dest);
getsect(x, y, §);
if (sect.sct_own == own) {
+ if (!opt_NOFOOD && type == I_FOOD)
+ minimum = 1 + (int)ceil(food_needed(sect.sct_item,
+ etu_per_update));
if (sect.sct_item[type] - wanted >= minimum) {
sect.sct_item[type] -= wanted;
if (actually_doit)
sect.sct_item[type] -= wanted;
/* take off mobility for delivering sect */
- n = roundavg(total_wanted * weight * move_cost);
+ n = roundavg(wanted * weight * move_cost);
if (n < 0)
n = 0;
if (n > sect.sct_mobil)
if ((land.lnd_ship >= 0) && (sect.sct_effic < 2))
continue;
+#if 0
+ /*
+ * Recursive supply is disabled for now. It can introduce
+ * cycles into the "resupplies from" relation. The code below
+ * attempts to break these cycles by temporarily zapping the
+ * commodity being supplied. That puts the land file in a
+ * funny state temporarily, risking loss of supplies when
+ * something goes wrong on the way. Worse, it increases
+ * lnd_seqno even when !actually_doit, which can lead to
+ * spurious seqno mismatch oopses in users of
+ * lnd_could_be_supplied(). I can't be bothered to clean up
+ * this mess right now, because recursive resupply is too dumb
+ * to be really useful anyway: each step uses the first source
+ * it finds, without consideration of mobility cost. If you
+ * re-enable it, don't forget to uncomment its documentation
+ * in supply.t as well.
+ */
if (land.lnd_item[type] - wanted < get_minimum(&land, type)) {
struct lndstr save;
save = land;
land.lnd_item[type] = 0;
putland(land.lnd_uid, &land);
+ save.lnd_seqno = land.lnd_seqno;
land.lnd_item[type] =
save.lnd_item[type] + s_commod(own, land.lnd_x, land.lnd_y,
else
putland(save.lnd_uid, &save);
}
+#endif
min = get_minimum(&land, type);
ip = &ichr[type];
if (can_move >= wanted) {
land.lnd_item[type] -= wanted;
-
- /* resupply the supply unit */
- resupply_commod(&land, type);
-
land.lnd_mobil -= roundavg(wanted * weight * move_cost);
if (actually_doit)
/*
* We want to get enough shells to fire once,
- * one update's worth of food, enough fuel for
- * one update.
+ * one update's worth of food.
*/
static int
case I_SHELL:
want = lcp->l_ammo;
break;
-
- /*
- * return the amount of pet we'd need to get to
- * enough fuel for 1 update
- */
- case I_PETROL:
- if (opt_FUEL == 0)
- return 0;
- want = lcp->l_fuelu * ((float)etu_per_update * land_mob_scale)
- / 10.0;
- want -= lp->lnd_fuel;
- if (want > 0) {
- want = want / 10;
- if (want == 0)
- want++;
- }
-
- max = want;
- break;
default:
return 0;
}
}
int
-has_supply(struct lndstr *lp)
+lnd_could_be_supplied(struct lndstr *lp)
{
int shells_needed, shells, keepshells;
int food, food_needed, keepfood;
- int fuel_needed, fuel, petrol_needed, petrol, keeppetrol;
if (!opt_NOFOOD) {
food_needed = get_minimum(lp, I_FOOD);
if (shells < shells_needed)
return 0;
- if (opt_FUEL) {
- fuel_needed = lchr[lp->lnd_type].l_fuelu;
- fuel = lp->lnd_fuel;
- if (fuel < fuel_needed) {
- petrol_needed =
- ldround((fuel_needed - fuel) / 10.0, 1);
- petrol = keeppetrol = lp->lnd_item[I_PETROL];
- if (petrol < petrol_needed) {
- lp->lnd_item[I_PETROL] = 0;
- putland(lp->lnd_uid, lp);
- petrol += try_supply_commod(lp->lnd_own,
- lp->lnd_x, lp->lnd_y,
- I_PETROL,
- (petrol_needed - petrol));
- lp->lnd_item[I_PETROL] = keeppetrol;
- putland(lp->lnd_uid, lp);
- }
- fuel += petrol * 10;
- }
-
- if (fuel < fuel_needed)
- return 0;
- }
- /* end opt_FUEL */
return 1;
}