Redesign automatic supply interface
The automatic supply interface has design flaws that make it hard to
use correctly. Its current uses are in fact all wrong (until commit
0179fd86, the update had a few uses that might have been correct).
Some of the bugs can only bite with land unit capability combinations
that don't exist in the stock game, though.
Automatic supply draws supplies from supply sources in range. Since
that can update any supply source in range, all copies of potential
supply sources a caller may keep can get invalidated. Writing back
such an invalid copy wipes out the deduction of supplies and mobility
from a source, triggering a seqno mismatch oops.
This commit redesigns the interface so that callers can safely keep a
copy of the object drawing the supplies (the "supply sink"). The idea
is to pass the sink to the supply code, so it can avoid using it as
source. The actual avoiding will be implemented in a later commit.
Copies other than the supply sink still need to be eliminated. See
commit 65410d16
for an example.
Other improvements to help avoid common errors:
* Supply functions are commonly used to ensure the sink has a certain
amount of supplies. A common error is to fetch that amount
regardless of how many the sink already has. It's more convenient
for such users to pass how many they need to have instead of how
many to get.
* A common use of supply functions is to get supplies for immediate
use. If that use turns out not to be possible after all, the
supplies need to be added somewhere, which is all too easy to
forget. Many bugs of this kind have been fixed over time, and there
are still some left. This class of bugs can be avoided by adding
the supplies to the sink automatically.
In fact, this commit fixes precisely such bugs in mission_pln_equip()
and shp_missile_defense(): plane interception and support missions,
missile interception (abms), launch of ballistic missiles and
anti-sats could all lose shells, or supply more than needed.
Replace supply_commod() by new sct_supply(), shp_supply(),
lnd_supply(), and resupply_all() by new lnd_supply_all(). Simplify
users accordingly.
There's just one use of resupply_commod() left, in landmine(). Use
lnd_supply_all() there, and remove resupply_commod().
This commit is contained in:
parent
6ac9ad66e1
commit
322f96ecb7
9 changed files with 109 additions and 121 deletions
|
@ -679,9 +679,10 @@ extern void snxtsct_all(struct nstr_sect *);
|
||||||
extern void snxtsct_rewind(struct nstr_sect *);
|
extern void snxtsct_rewind(struct nstr_sect *);
|
||||||
extern void snxtsct_dist(struct nstr_sect *, coord, coord, int);
|
extern void snxtsct_dist(struct nstr_sect *, coord, coord, int);
|
||||||
/* supply.c */
|
/* supply.c */
|
||||||
extern void resupply_all(struct lndstr *);
|
extern int sct_supply(struct sctstr *, i_type, int);
|
||||||
extern void resupply_commod(struct lndstr *, i_type);
|
extern int shp_supply(struct shpstr *, i_type, int);
|
||||||
extern int supply_commod(int, int, int, i_type, int);
|
extern int lnd_supply(struct lndstr *, i_type, int);
|
||||||
|
extern int lnd_supply_all(struct lndstr *);
|
||||||
extern int lnd_in_supply(struct lndstr *);
|
extern int lnd_in_supply(struct lndstr *);
|
||||||
extern int lnd_could_be_supplied(struct lndstr *);
|
extern int lnd_could_be_supplied(struct lndstr *);
|
||||||
/* takeover.c */
|
/* takeover.c */
|
||||||
|
|
|
@ -644,17 +644,19 @@ load_land_ship(struct sctstr *sectp, struct shpstr *sp, int noisy,
|
||||||
gift(sp->shp_own, player->cnum, &land, buf);
|
gift(sp->shp_own, player->cnum, &land, buf);
|
||||||
land.lnd_ship = sp->shp_uid;
|
land.lnd_ship = sp->shp_uid;
|
||||||
land.lnd_harden = 0;
|
land.lnd_harden = 0;
|
||||||
|
putland(land.lnd_uid, &land);
|
||||||
#if 0
|
#if 0
|
||||||
/*
|
/*
|
||||||
* FIXME if this supplies from the sector, the putsect in
|
* FIXME if this supplies from the sector, the putsect in
|
||||||
* load() / lload() duplicates those supplies, causing a
|
* load() / lload() duplicates those supplies, causing a
|
||||||
* seqno mismatch
|
* seqno mismatch
|
||||||
*/
|
*/
|
||||||
resupply_all(&land);
|
if (!lnd_supply_all(&land))
|
||||||
#endif
|
pr("WARNING: %s is out of supply!\n", prland(&land));
|
||||||
putland(land.lnd_uid, &land);
|
#else
|
||||||
if (!lnd_in_supply(&land))
|
if (!lnd_in_supply(&land))
|
||||||
pr("WARNING: %s is out of supply!\n", prland(&land));
|
pr("WARNING: %s is out of supply!\n", prland(&land));
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
sprintf(buf, "unloaded in your %s at %s",
|
sprintf(buf, "unloaded in your %s at %s",
|
||||||
dchr[sectp->sct_type].d_name,
|
dchr[sectp->sct_type].d_name,
|
||||||
|
@ -994,13 +996,15 @@ load_land_land(struct sctstr *sectp, struct lndstr *lp, int noisy,
|
||||||
gift(lp->lnd_own, player->cnum, &land, buf);
|
gift(lp->lnd_own, player->cnum, &land, buf);
|
||||||
land.lnd_land = lp->lnd_uid;
|
land.lnd_land = lp->lnd_uid;
|
||||||
land.lnd_harden = 0;
|
land.lnd_harden = 0;
|
||||||
|
putland(land.lnd_uid, &land);
|
||||||
#if 0
|
#if 0
|
||||||
/* FIXME same issue as in load_land_ship() */
|
/* FIXME same issue as in load_land_ship() */
|
||||||
resupply_all(&land);
|
if (!lnd_supply_all(&land))
|
||||||
#endif
|
pr("WARNING: %s is out of supply!\n", prland(&land));
|
||||||
putland(land.lnd_uid, &land);
|
#else
|
||||||
if (!lnd_in_supply(&land))
|
if (!lnd_in_supply(&land))
|
||||||
pr("WARNING: %s is out of supply!\n", prland(&land));
|
pr("WARNING: %s is out of supply!\n", prland(&land));
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
sprintf(buf, "unloaded in your %s at %s",
|
sprintf(buf, "unloaded in your %s at %s",
|
||||||
dchr[sectp->sct_type].d_name,
|
dchr[sectp->sct_type].d_name,
|
||||||
|
|
|
@ -94,7 +94,7 @@ landmine(void)
|
||||||
struct lndstr land;
|
struct lndstr land;
|
||||||
struct sctstr sect;
|
struct sctstr sect;
|
||||||
struct nstr_item ni;
|
struct nstr_item ni;
|
||||||
int shells, todo;
|
int todo;
|
||||||
int mines_wanted;
|
int mines_wanted;
|
||||||
int mines_laid;
|
int mines_laid;
|
||||||
int total_mines_laid;
|
int total_mines_laid;
|
||||||
|
@ -137,20 +137,15 @@ landmine(void)
|
||||||
todo = MIN(mines_wanted, land.lnd_mobil);
|
todo = MIN(mines_wanted, land.lnd_mobil);
|
||||||
total_mines_laid = 0;
|
total_mines_laid = 0;
|
||||||
do {
|
do {
|
||||||
shells = land.lnd_item[I_SHELL];
|
lnd_supply(&land, I_SHELL, todo);
|
||||||
if (shells < todo)
|
mines_laid = MIN(todo, land.lnd_item[I_SHELL]);
|
||||||
shells += supply_commod(land.lnd_own,
|
land.lnd_item[I_SHELL] -= mines_laid;
|
||||||
land.lnd_x, land.lnd_y, I_SHELL,
|
|
||||||
todo - shells);
|
|
||||||
mines_laid = MIN(todo, shells);
|
|
||||||
land.lnd_item[I_SHELL] = shells - mines_laid;
|
|
||||||
land.lnd_mobil -= mines_laid;
|
land.lnd_mobil -= mines_laid;
|
||||||
putland(land.lnd_uid, &land);
|
putland(land.lnd_uid, &land);
|
||||||
total_mines_laid += mines_laid;
|
total_mines_laid += mines_laid;
|
||||||
todo -= mines_laid;
|
todo -= mines_laid;
|
||||||
} while (todo && mines_laid);
|
} while (todo && mines_laid);
|
||||||
resupply_commod(&land, I_SHELL);
|
lnd_supply_all(&land);
|
||||||
putland(land.lnd_uid, &land);
|
|
||||||
getsect(sect.sct_x, sect.sct_y, §);
|
getsect(sect.sct_x, sect.sct_y, §);
|
||||||
sect.sct_mines = MIN(sect.sct_mines + total_mines_laid, MINES_MAX);
|
sect.sct_mines = MIN(sect.sct_mines + total_mines_laid, MINES_MAX);
|
||||||
putsect(§);
|
putsect(§);
|
||||||
|
|
|
@ -51,9 +51,7 @@ supp(void)
|
||||||
if (!player->owner || land.lnd_own == 0)
|
if (!player->owner || land.lnd_own == 0)
|
||||||
continue;
|
continue;
|
||||||
nunits++;
|
nunits++;
|
||||||
resupply_all(&land);
|
if (lnd_supply_all(&land))
|
||||||
putland(land.lnd_uid, &land);
|
|
||||||
if (lnd_in_supply(&land))
|
|
||||||
pr("%s has supplies\n", prland(&land));
|
pr("%s has supplies\n", prland(&land));
|
||||||
else
|
else
|
||||||
pr("%s is out of supply\n", prland(&land));
|
pr("%s is out of supply\n", prland(&land));
|
||||||
|
|
|
@ -1072,9 +1072,7 @@ ask_olist(int combat_mode, struct combat *off, struct combat *def,
|
||||||
pr("%s has no offensive strength\n", prland(&land));
|
pr("%s has no offensive strength\n", prland(&land));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
resupply_all(&land);
|
if (!lnd_supply_all(&land)) {
|
||||||
putland(land.lnd_uid, &land);
|
|
||||||
if (!lnd_in_supply(&land)) {
|
|
||||||
pr("%s is out of supply, and cannot %s\n",
|
pr("%s is out of supply, and cannot %s\n",
|
||||||
prland(&land), att_mode[combat_mode]);
|
prland(&land), att_mode[combat_mode]);
|
||||||
continue;
|
continue;
|
||||||
|
@ -1235,9 +1233,7 @@ get_dlist(struct combat *def, struct emp_qelem *list, int a_spy,
|
||||||
}
|
}
|
||||||
memset(llp, 0, sizeof(struct ulist));
|
memset(llp, 0, sizeof(struct ulist));
|
||||||
emp_insque(&llp->queue, list);
|
emp_insque(&llp->queue, list);
|
||||||
resupply_all(&land);
|
llp->supplied = lnd_supply_all(&land);
|
||||||
putland(land.lnd_uid, &land);
|
|
||||||
llp->supplied = lnd_in_supply(&land);
|
|
||||||
if (!get_land(A_DEFEND, def, land.lnd_uid, llp, 1))
|
if (!get_land(A_DEFEND, def, land.lnd_uid, llp, 1))
|
||||||
continue;
|
continue;
|
||||||
if (lnd_spyval(&land) > *d_spyp)
|
if (lnd_spyval(&land) > *d_spyp)
|
||||||
|
@ -1501,15 +1497,8 @@ att_reacting_units(struct combat *def, struct emp_qelem *list, int a_spy,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Only supplied units can react */
|
/* Only supplied units can react */
|
||||||
if (list) {
|
if (list ? !lnd_supply_all(&land) : !lnd_could_be_supplied(&land))
|
||||||
resupply_all(&land);
|
continue;
|
||||||
putland(land.lnd_uid, &land);
|
|
||||||
if (!lnd_in_supply(&land))
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
if (!lnd_could_be_supplied(&land))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!in_oparea((struct empobj *)&land, def->x, def->y))
|
if (!in_oparea((struct empobj *)&land, def->x, def->y))
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -86,18 +86,14 @@ int
|
||||||
fort_fire(struct sctstr *sp)
|
fort_fire(struct sctstr *sp)
|
||||||
{
|
{
|
||||||
int guns = sp->sct_item[I_GUN];
|
int guns = sp->sct_item[I_GUN];
|
||||||
int shells;
|
|
||||||
|
|
||||||
if (sp->sct_type != SCT_FORTR || sp->sct_effic < FORTEFF)
|
if (sp->sct_type != SCT_FORTR || sp->sct_effic < FORTEFF)
|
||||||
return -1;
|
return -1;
|
||||||
if (sp->sct_item[I_MILIT] < 5 || guns == 0)
|
if (sp->sct_item[I_MILIT] < 5 || guns == 0)
|
||||||
return -1;
|
return -1;
|
||||||
shells = sp->sct_item[I_SHELL];
|
if (!sct_supply(sp, I_SHELL, 1))
|
||||||
shells += supply_commod(sp->sct_own, sp->sct_x, sp->sct_y,
|
|
||||||
I_SHELL, 1 - shells);
|
|
||||||
if (shells == 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
sp->sct_item[I_SHELL] = shells - 1;
|
sp->sct_item[I_SHELL]--;
|
||||||
return (int)fortgun(sp->sct_effic, guns);
|
return (int)fortgun(sp->sct_effic, guns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +105,7 @@ fort_fire(struct sctstr *sp)
|
||||||
int
|
int
|
||||||
shp_fire(struct shpstr *sp)
|
shp_fire(struct shpstr *sp)
|
||||||
{
|
{
|
||||||
int guns, shells;
|
int guns;
|
||||||
|
|
||||||
if (sp->shp_effic < 60)
|
if (sp->shp_effic < 60)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -117,13 +113,11 @@ shp_fire(struct shpstr *sp)
|
||||||
guns = MIN(guns, (sp->shp_item[I_MILIT] + 1) / 2);
|
guns = MIN(guns, (sp->shp_item[I_MILIT] + 1) / 2);
|
||||||
if (guns == 0)
|
if (guns == 0)
|
||||||
return -1;
|
return -1;
|
||||||
shells = sp->shp_item[I_SHELL];
|
shp_supply(sp, I_SHELL, (guns + 1) / 2);
|
||||||
shells += supply_commod(sp->shp_own, sp->shp_x, sp->shp_y,
|
guns = MIN(guns, sp->shp_item[I_SHELL] * 2);
|
||||||
I_SHELL, (guns + 1) / 2 - shells);
|
|
||||||
guns = MIN(guns, shells * 2);
|
|
||||||
if (guns == 0)
|
if (guns == 0)
|
||||||
return -1;
|
return -1;
|
||||||
sp->shp_item[I_SHELL] = shells - (guns + 1) / 2;
|
sp->shp_item[I_SHELL] -= (guns + 1) / 2;
|
||||||
return (int)seagun(sp->shp_effic, guns);
|
return (int)seagun(sp->shp_effic, guns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,19 +129,17 @@ shp_fire(struct shpstr *sp)
|
||||||
int
|
int
|
||||||
shp_dchrg(struct shpstr *sp)
|
shp_dchrg(struct shpstr *sp)
|
||||||
{
|
{
|
||||||
int shells, dchrgs;
|
int dchrgs;
|
||||||
|
|
||||||
if (sp->shp_effic < 60 || (mchr[sp->shp_type].m_flags & M_DCH) == 0)
|
if (sp->shp_effic < 60 || (mchr[sp->shp_type].m_flags & M_DCH) == 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (sp->shp_item[I_MILIT] == 0)
|
if (sp->shp_item[I_MILIT] == 0)
|
||||||
return -1;
|
return -1;
|
||||||
shells = sp->shp_item[I_SHELL];
|
shp_supply(sp, I_SHELL, 2);
|
||||||
shells += supply_commod(sp->shp_own, sp->shp_x, sp->shp_y,
|
dchrgs = MIN(2, sp->shp_item[I_SHELL]);
|
||||||
I_SHELL, 2 - shells);
|
if (dchrgs == 0)
|
||||||
if (shells == 0)
|
return -1;
|
||||||
return -1;
|
sp->shp_item[I_SHELL] -= dchrgs;
|
||||||
dchrgs = MIN(2, shells);
|
|
||||||
sp->shp_item[I_SHELL] = shells - dchrgs;
|
|
||||||
return (int)seagun(sp->shp_effic, 2 * dchrgs - 1);
|
return (int)seagun(sp->shp_effic, 2 * dchrgs - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,20 +151,15 @@ shp_dchrg(struct shpstr *sp)
|
||||||
int
|
int
|
||||||
shp_torp(struct shpstr *sp, int usemob)
|
shp_torp(struct shpstr *sp, int usemob)
|
||||||
{
|
{
|
||||||
int shells;
|
|
||||||
|
|
||||||
if (sp->shp_effic < 60 || (mchr[sp->shp_type].m_flags & M_TORP) == 0)
|
if (sp->shp_effic < 60 || (mchr[sp->shp_type].m_flags & M_TORP) == 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (sp->shp_item[I_MILIT] == 0 || sp->shp_item[I_GUN] == 0)
|
if (sp->shp_item[I_MILIT] == 0 || sp->shp_item[I_GUN] == 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (usemob && sp->shp_mobil <= 0)
|
if (usemob && sp->shp_mobil <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
shells = sp->shp_item[I_SHELL];
|
if (!shp_supply(sp, I_SHELL, SHP_TORP_SHELLS))
|
||||||
shells += supply_commod(sp->shp_own, sp->shp_x, sp->shp_y,
|
return -1;
|
||||||
I_SHELL, SHP_TORP_SHELLS - shells);
|
sp->shp_item[I_SHELL] -= SHP_TORP_SHELLS;
|
||||||
if (shells < SHP_TORP_SHELLS)
|
|
||||||
return -1;
|
|
||||||
sp->shp_item[I_SHELL] = shells - SHP_TORP_SHELLS;
|
|
||||||
if (usemob)
|
if (usemob)
|
||||||
sp->shp_mobil -= (int)shp_mobcost(sp) / 2.0;
|
sp->shp_mobil -= (int)shp_mobcost(sp) / 2.0;
|
||||||
return TORP_DAMAGE();
|
return TORP_DAMAGE();
|
||||||
|
@ -202,9 +189,8 @@ lnd_fire(struct lndstr *lp)
|
||||||
ammo = lchr[lp->lnd_type].l_ammo;
|
ammo = lchr[lp->lnd_type].l_ammo;
|
||||||
if (CANT_HAPPEN(ammo == 0))
|
if (CANT_HAPPEN(ammo == 0))
|
||||||
ammo = 1;
|
ammo = 1;
|
||||||
|
lnd_supply(lp, I_SHELL, ammo);
|
||||||
shells = lp->lnd_item[I_SHELL];
|
shells = lp->lnd_item[I_SHELL];
|
||||||
shells += supply_commod(lp->lnd_own, lp->lnd_x, lp->lnd_y,
|
|
||||||
I_SHELL, ammo - shells);
|
|
||||||
if (shells == 0)
|
if (shells == 0)
|
||||||
return -1;
|
return -1;
|
||||||
d = landunitgun(lp->lnd_effic, guns);
|
d = landunitgun(lp->lnd_effic, guns);
|
||||||
|
@ -212,7 +198,7 @@ lnd_fire(struct lndstr *lp)
|
||||||
d *= (double)shells / (double)ammo;
|
d *= (double)shells / (double)ammo;
|
||||||
ammo = shells;
|
ammo = shells;
|
||||||
}
|
}
|
||||||
lp->lnd_item[I_SHELL] = shells - ammo;
|
lp->lnd_item[I_SHELL] -= ammo;
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -939,11 +939,14 @@ mission_pln_equip(struct plist *plp, struct ichrstr *ip, int flags,
|
||||||
if (itype != I_NONE && needed <= 0)
|
if (itype != I_NONE && needed <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (itype != I_NONE) {
|
if (itype != I_NONE) {
|
||||||
if (itype == I_SHELL && item[itype] < needed)
|
if (itype == I_SHELL && item[itype] < needed) {
|
||||||
item[itype] += supply_commod(plp->plane.pln_own,
|
if (pp->pln_ship >= 0)
|
||||||
plp->plane.pln_x,
|
shp_supply(&ship, I_SHELL, needed);
|
||||||
plp->plane.pln_y,
|
else if (pp->pln_land >= 0)
|
||||||
I_SHELL, needed);
|
lnd_supply(&land, I_SHELL, needed);
|
||||||
|
else
|
||||||
|
sct_supply(§, I_SHELL, needed);
|
||||||
|
}
|
||||||
if (item[itype] < needed)
|
if (item[itype] < needed)
|
||||||
return -1;
|
return -1;
|
||||||
item[itype] -= needed;
|
item[itype] -= needed;
|
||||||
|
|
|
@ -824,7 +824,6 @@ shp_missile_defense(coord dx, coord dy, natid bombown, int hardtarget)
|
||||||
struct nstr_item ni;
|
struct nstr_item ni;
|
||||||
struct shpstr ship;
|
struct shpstr ship;
|
||||||
int hitchance;
|
int hitchance;
|
||||||
int shell;
|
|
||||||
double gun, eff, teff;
|
double gun, eff, teff;
|
||||||
|
|
||||||
snxtitem_dist(&ni, EF_SHIP, dx, dy, 1);
|
snxtitem_dist(&ni, EF_SHIP, dx, dy, 1);
|
||||||
|
@ -842,17 +841,14 @@ shp_missile_defense(coord dx, coord dy, natid bombown, int hardtarget)
|
||||||
if (ship.shp_effic < 60)
|
if (ship.shp_effic < 60)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
shell = ship.shp_item[I_SHELL];
|
|
||||||
if (ship.shp_item[I_MILIT] < 1) /* do we have mil? */
|
if (ship.shp_item[I_MILIT] < 1) /* do we have mil? */
|
||||||
continue;
|
continue;
|
||||||
if (shell < 2) { /* do we need shells */
|
|
||||||
shell += supply_commod(ship.shp_own, ship.shp_x, ship.shp_y,
|
|
||||||
I_SHELL, 2);
|
|
||||||
if (shell < 2)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (ship.shp_item[I_GUN] < 1) /* we need at least 1 gun */
|
if (ship.shp_item[I_GUN] < 1) /* we need at least 1 gun */
|
||||||
continue;
|
continue;
|
||||||
|
if (!shp_supply(&ship, I_SHELL, 2))
|
||||||
|
continue;
|
||||||
|
ship.shp_item[I_SHELL] -= 2;
|
||||||
|
putship(ship.shp_uid, &ship);
|
||||||
|
|
||||||
/* now calculate the odds */
|
/* now calculate the odds */
|
||||||
gun = shp_usable_guns(&ship);
|
gun = shp_usable_guns(&ship);
|
||||||
|
@ -870,9 +866,6 @@ shp_missile_defense(coord dx, coord dy, natid bombown, int hardtarget)
|
||||||
mpr(ship.shp_own, "Ship #%i anti-missile system activated!\n",
|
mpr(ship.shp_own, "Ship #%i anti-missile system activated!\n",
|
||||||
ship.shp_uid);
|
ship.shp_uid);
|
||||||
mpr(ship.shp_own, "%d%% hitchance...", hitchance);
|
mpr(ship.shp_own, "%d%% hitchance...", hitchance);
|
||||||
/* use ammo */
|
|
||||||
ship.shp_item[I_SHELL] = shell - 2;
|
|
||||||
putship(ship.shp_uid, &ship);
|
|
||||||
|
|
||||||
if (roll(100) <= hitchance) {
|
if (roll(100) <= hitchance) {
|
||||||
mpr(bombown, "KABOOOM!! Missile destroyed\n\n");
|
mpr(bombown, "KABOOOM!! Missile destroyed\n\n");
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
* supply.c: Supply subroutines
|
* supply.c: Supply subroutines
|
||||||
*
|
*
|
||||||
* Known contributors to this file:
|
* Known contributors to this file:
|
||||||
*
|
* Markus Armbruster, 2009
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
@ -43,47 +43,44 @@
|
||||||
#include "sect.h"
|
#include "sect.h"
|
||||||
#include "ship.h"
|
#include "ship.h"
|
||||||
|
|
||||||
static int get_minimum(struct lndstr *, i_type);
|
static int supply_commod(int, int, int, i_type, int);
|
||||||
static int s_commod(int, int, int, i_type, int, int);
|
static int s_commod(int, int, int, i_type, int, int);
|
||||||
|
static int get_minimum(struct lndstr *, i_type);
|
||||||
|
|
||||||
/*
|
int
|
||||||
* We want to get enough guns to be maxed out, enough shells to
|
sct_supply(struct sctstr *sp, i_type type, int wanted)
|
||||||
* 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)
|
|
||||||
*
|
|
||||||
* May want to put code to resupply with SAMs here, later --ts
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
resupply_all(struct lndstr *lp)
|
|
||||||
{
|
{
|
||||||
if (!opt_NOFOOD)
|
if (sp->sct_item[type] < wanted) {
|
||||||
resupply_commod(lp, I_FOOD);
|
sp->sct_item[type] += supply_commod(sp->sct_own,
|
||||||
resupply_commod(lp, I_SHELL);
|
sp->sct_x, sp->sct_y, type,
|
||||||
|
wanted - sp->sct_item[type]);
|
||||||
|
putsect(sp);
|
||||||
|
}
|
||||||
|
return sp->sct_item[type] >= wanted;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
int
|
||||||
* If the unit has less than it's minimum level of a
|
shp_supply(struct shpstr *sp, i_type type, int wanted)
|
||||||
* certain commodity, fill it, to the best of our abilities.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
resupply_commod(struct lndstr *lp, i_type type)
|
|
||||||
{
|
{
|
||||||
int amt;
|
if (sp->shp_item[type] < wanted) {
|
||||||
|
sp->shp_item[type] += supply_commod(sp->shp_own,
|
||||||
amt = get_minimum(lp, type) - lp->lnd_item[type];
|
sp->shp_x, sp->shp_y, type,
|
||||||
if (amt > 0) {
|
wanted - sp->shp_item[type]);
|
||||||
lp->lnd_item[type] += supply_commod(lp->lnd_own,
|
putship(sp->shp_uid, sp);
|
||||||
lp->lnd_x, lp->lnd_y,
|
|
||||||
type, amt);
|
|
||||||
}
|
}
|
||||||
|
return sp->shp_item[type] >= wanted;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
lnd_supply(struct lndstr *lp, i_type type, int wanted)
|
||||||
|
{
|
||||||
|
if (lp->lnd_item[type] < wanted) {
|
||||||
|
lp->lnd_item[type] += supply_commod(lp->lnd_own,
|
||||||
|
lp->lnd_x, lp->lnd_y, type,
|
||||||
|
wanted - lp->lnd_item[type]);
|
||||||
|
putland(lp->lnd_uid, lp);
|
||||||
|
}
|
||||||
|
return lp->lnd_item[type] >= wanted;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -96,10 +93,21 @@ lnd_in_supply(struct lndstr *lp)
|
||||||
return lp->lnd_item[I_SHELL] >= get_minimum(lp, I_SHELL);
|
return lp->lnd_item[I_SHELL] >= get_minimum(lp, I_SHELL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
lnd_supply_all(struct lndstr *lp)
|
||||||
|
{
|
||||||
|
int fail = 0;
|
||||||
|
|
||||||
|
if (!opt_NOFOOD)
|
||||||
|
fail |= !lnd_supply(lp, I_FOOD, get_minimum(lp, I_FOOD));
|
||||||
|
fail |= !lnd_supply(lp, I_SHELL, get_minimum(lp, I_SHELL));
|
||||||
|
return !fail;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Actually get the commod
|
* Actually get the commod
|
||||||
*/
|
*/
|
||||||
int
|
static int
|
||||||
supply_commod(int own, int x, int y, i_type type, int total_wanted)
|
supply_commod(int own, int x, int y, i_type type, int total_wanted)
|
||||||
{
|
{
|
||||||
if (total_wanted <= 0)
|
if (total_wanted <= 0)
|
||||||
|
@ -119,7 +127,18 @@ try_supply_commod(int own, int x, int y, i_type type, int total_wanted)
|
||||||
return s_commod(own, x, y, type, total_wanted, 0);
|
return s_commod(own, x, y, type, total_wanted, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get supplies of a certain type */
|
/*
|
||||||
|
* Actually get the commod
|
||||||
|
*
|
||||||
|
* First, 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)
|
||||||
|
*
|
||||||
|
* May want to put code to resupply with SAMs here, later --ts
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
s_commod(int own, int x, int y, i_type type, int total_wanted,
|
s_commod(int own, int x, int y, i_type type, int total_wanted,
|
||||||
int actually_doit)
|
int actually_doit)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue