diff --git a/include/sect.h b/include/sect.h index ec577043..d2598c5c 100644 --- a/include/sect.h +++ b/include/sect.h @@ -164,7 +164,7 @@ extern int sctoff(coord x, coord y); extern struct dchrstr dchr[SCT_MAXDEF + 1]; extern struct dchrstr bigcity_dchr; -#define IS_BIG_CITY(sect) (dchr[(sect)].d_pkg == UPKG) +#define IS_BIG_CITY(type) (dchr[(type)].d_pkg == UPKG) /* Minimal efficiency of sectors that can be knocked down (bridges) */ #define SCT_MINEFF 20 @@ -178,10 +178,9 @@ extern struct dchrstr bigcity_dchr; #define MIN_MOBCOST 0.001 /* lowest cost a sector can have to move into */ #define FORTEFF 5 /* forts must be 5% efficient to fire. */ -#define MOB_NONE 0 -#define MOB_MOVE 1 -#define MOB_MARCH 2 -#define MOB_RAIL 3 +#define MOB_MOVE 0 +#define MOB_MARCH 1 +#define MOB_RAIL 2 #define INT_ROAD 0 #define INT_RAIL 1 diff --git a/src/lib/common/move.c b/src/lib/common/move.c index 093b5cb4..931a909d 100644 --- a/src/lib/common/move.c +++ b/src/lib/common/move.c @@ -41,7 +41,7 @@ #include "common.h" double -sector_mcost(struct sctstr *sp, int do_bonus) +sector_mcost(struct sctstr *sp, int mobtype) { double d; @@ -49,16 +49,15 @@ sector_mcost(struct sctstr *sp, int do_bonus) if (d <= 0) return -1.0; - if (do_bonus == MOB_MOVE || do_bonus == MOB_MARCH) { + if (mobtype == MOB_MOVE || mobtype == MOB_MARCH) { d = d / (1.0 + sp->sct_road / 122.0); - } else if (do_bonus == MOB_RAIL) { + } else if (mobtype == MOB_RAIL) { if (sp->sct_rail <= 0) return -1.0; d = d / (1.0 + sp->sct_rail / 100.0); - } else { - if (d < 2.0) - d = 2.0; - } + } else + CANT_REACH(); + if (d < 1.0) d = 1.0; if (dchr[sp->sct_type].d_mcst < 25) @@ -66,10 +65,10 @@ sector_mcost(struct sctstr *sp, int do_bonus) else d = (d * 10.0 - sp->sct_effic) / 115; - if (do_bonus == MOB_MOVE) + if (mobtype == MOB_MOVE) return MAX(d, MIN_MOBCOST); if (sp->sct_own != sp->sct_oldown && sp->sct_mobil <= 0 - && do_bonus != MOB_RAIL) + && mobtype != MOB_RAIL) return MAX(d, LND_MINMOBCOST); return MAX(d, 0.01); } diff --git a/src/lib/subs/attsub.c b/src/lib/subs/attsub.c index cffce1e5..effb37e4 100644 --- a/src/lib/subs/attsub.c +++ b/src/lib/subs/attsub.c @@ -783,21 +783,51 @@ att_ask_offense(int combat_mode, struct combat *off, struct combat *def, return 0; } +/* + * Return path cost for ATTACKER to enter sector given by DEF. + * MOBTYPE is a mobility type accepted by sector_mcost(). + */ +static double +att_mobcost(natid attacker, struct combat *def, int mobtype) +{ + struct sctstr sect; + int ok; + + if (CANT_HAPPEN(def->type != EF_SECTOR)) + return -1.0; + ok = getsect(def->x, def->y, §); + if (CANT_HAPPEN(!ok)) + return -1.0; + + /* + * We want the cost to move/march into the sector. If we just + * called sector_mcost(), we'd get the defender's cost. The + * attacker's cost is higher unless he's the old-owner. Note: if + * there are no civilians, a victorious attacker will become the + * old-owner. But he isn't now. + */ + sect.sct_own = attacker; + sect.sct_mobil = 0; + return sector_mcost(§, mobtype); +} + /* How many mil is off allowed to attack with when it attacks def? */ static int get_mob_support(int combat_mode, struct combat *off, struct combat *def) { int mob_support; + double mobcost; switch (combat_mode) { case A_ATTACK: - mob_support = off->mob / sector_mcost(getsectp(def->x, def->y), - MOB_MOVE); - if (mob_support < 0) - mob_support = 0; + mobcost = att_mobcost(off->own, def, MOB_MOVE); + if (mobcost < 0 || off->mob <= 0) + return 0; + mob_support = off->mob / mobcost; if (mob_support < off->troops) - pr("Sector %s has %d mobility which can only support %d mil,\n", xyas(off->x, off->y, player->cnum), off->mob, mob_support); + pr("Sector %s has %d mobility which can only support %d mil,\n", + xyas(off->x, off->y, player->cnum), off->mob, mob_support); else mob_support = off->troops; return mob_support; @@ -850,10 +880,9 @@ calc_mobcost(int combat_mode, struct combat *off, struct combat *def, return; switch (combat_mode) { case A_ATTACK: - off->mobcost += - MAX(1, - (int)(attacking_mil * - sector_mcost(getsectp(def->x, def->y), MOB_MOVE))); + off->mobcost += MAX(1, + (int)(attacking_mil + * att_mobcost(off->own, def, MOB_MOVE))); break; case A_LBOARD: off->mobcost += MAX(1, attacking_mil / 5); @@ -1008,8 +1037,8 @@ ask_olist(int combat_mode, struct combat *off, struct combat *def, } switch (combat_mode) { case A_ATTACK: - mobcost = - lnd_mobcost(&land, getsectp(def->x, def->y), MOB_NONE); + mobcost = lnd_pathcost(&land, + att_mobcost(off->own, def, MOB_MARCH)); if (land.lnd_mobil < mobcost) { pr("%s does not have enough mobility (%d needed)\n", prland(&land), (int)ceil(mobcost)); @@ -1103,10 +1132,6 @@ att_combat_eff(struct combat *com) return eff; } -/* - * Estimate the defense strength and give the attacker a chance to abort - * if the odds are less than 50% - */ int att_get_offense(int combat_mode, struct combat *off, struct emp_qelem *olist, struct combat *def) @@ -2441,7 +2466,7 @@ ask_move_in_off(struct combat *off, struct combat *def) return; if (off->own != player->cnum) return; - d = sector_mcost(getsectp(def->x, def->y), MOB_MOVE); + d = att_mobcost(off->own, def, MOB_MOVE); if ((mob_support = MIN(off->troops, (int)(off->mob / d))) <= 0) return; sprintf(prompt, "How many mil to move in from %s (%d max)? ", @@ -2503,8 +2528,8 @@ take_move_in_mob(int combat_mode, struct llist *llp, struct combat *off, switch (combat_mode) { case A_ATTACK: - mobcost = - lnd_mobcost(&llp->land, getsectp(def->x, def->y), MOB_NONE); + mobcost = lnd_pathcost(&llp->land, + att_mobcost(off->own, def, MOB_MARCH)); new = llp->land.lnd_mobil - mobcost; if (new < -127) new = -127;