shpsub: Make shp_check_nav() return more useful information

Some callers have to second-guess shp_check_nav() to figure out
whether CN_LANDLOCKED means "too big to fit into the canal" or "can't
go there at all".

Fix that by returning d_navigation.  CN_LANDLOCKED becomes either
NAV_CANAL or NAV_NONE, CN_CONSTRUCTION becomes either NAV_02 or
NAV_60, and CN_NAVIGABLE becomes NAVOK.

The CN_NAVIGABLE, ... codes are now unused.  Drop them.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
This commit is contained in:
Markus Armbruster 2014-01-20 22:34:17 +01:00
parent 1fee5028a2
commit c03db4c5ef
6 changed files with 53 additions and 47 deletions

View file

@ -92,14 +92,6 @@ struct sctstr {
unsigned char sct_defense; /* Defensive value of a sector */ unsigned char sct_defense; /* Defensive value of a sector */
}; };
enum d_navigation {
NAV_NONE, /* ships can't navigate */
NAVOK, /* ships can always navigate */
NAV_02, /* requires 2% effic to navigate */
NAV_CANAL, /* requires 2% effic to navigate and M_CANAL capability */
NAV_60 /* requires 60% effic to navigate */
};
struct dchrstr { struct dchrstr {
unsigned char d_uid; unsigned char d_uid;
char d_mnem; /* map symbol */ char d_mnem; /* map symbol */

View file

@ -155,12 +155,6 @@ extern struct mchrstr mchr[SHP_TYPE_MAX + 2];
/* Work required for building 100% */ /* Work required for building 100% */
#define SHP_BLD_WORK(lcm, hcm) (20 + (lcm) + 2 * (hcm)) #define SHP_BLD_WORK(lcm, hcm) (20 + (lcm) + 2 * (hcm))
/* return codes from shp_check_nav */
#define CN_NAVIGABLE 0
#define CN_LANDLOCKED 1
#define CN_CONSTRUCTION 2
#define CN_ERROR -1
enum { enum {
SHP_AIROPS_EFF = 50, /* min. efficiency for air ops */ SHP_AIROPS_EFF = 50, /* min. efficiency for air ops */
SHP_TORP_SHELLS = 3 /* number of shells used by a torpedo */ SHP_TORP_SHELLS = 3 /* number of shells used by a torpedo */
@ -191,7 +185,7 @@ extern double shp_torp_hitchance(struct shpstr *, int);
extern void shp_sel(struct nstr_item *, struct emp_qelem *); extern void shp_sel(struct nstr_item *, struct emp_qelem *);
extern void shp_nav(struct emp_qelem *, double *, double *, int *, natid); extern void shp_nav(struct emp_qelem *, double *, double *, int *, natid);
extern int shp_sweep(struct emp_qelem *, int, int, natid); extern int shp_sweep(struct emp_qelem *, int, int, natid);
extern int shp_check_nav(struct sctstr *, struct shpstr *); extern enum d_navigation shp_check_nav(struct shpstr *, struct sctstr *);
extern int sect_has_dock(struct sctstr *); extern int sect_has_dock(struct sctstr *);
extern int shp_hardtarget(struct shpstr *); extern int shp_hardtarget(struct shpstr *);
extern int shp_nav_one_sector(struct emp_qelem *, int, natid, int); extern int shp_nav_one_sector(struct emp_qelem *, int, natid, int);

View file

@ -36,6 +36,14 @@
typedef unsigned char natid; /* NSC_NATID must match this */ typedef unsigned char natid; /* NSC_NATID must match this */
typedef short coord; typedef short coord;
enum d_navigation {
NAV_NONE, /* ships can't navigate */
NAVOK, /* ships can always navigate */
NAV_02, /* requires 2% effic to navigate */
NAV_CANAL, /* requires 2% effic to navigate and M_CANAL capability */
NAV_60 /* requires 60% effic to navigate */
};
struct bp; struct bp;
struct emp_qelem; struct emp_qelem;
struct empobj; struct empobj;

View file

@ -172,25 +172,27 @@ retreat_ship1(struct shpstr *sp, char code, int orig)
} }
getsect(sp->shp_x, sp->shp_y, &sect); getsect(sp->shp_x, sp->shp_y, &sect);
switch (shp_check_nav(&sect, sp)) { switch (shp_check_nav(sp, &sect)) {
case CN_CONSTRUCTION: case NAV_02:
case NAV_60:
wu(0, sp->shp_own, wu(0, sp->shp_own,
"%s %s,\nbut was caught in a construction zone, and couldn't retreat!\n", "%s %s,\nbut was caught in a construction zone, and couldn't retreat!\n",
prship(sp), conditions[findcondition(code)].desc[orig]); prship(sp), conditions[findcondition(code)].desc[orig]);
if (!orig) if (!orig)
putship(sp->shp_uid, sp); putship(sp->shp_uid, sp);
return 0; return 0;
case CN_LANDLOCKED: case NAV_NONE:
case NAV_CANAL:
wu(0, sp->shp_own, wu(0, sp->shp_own,
"%s %s,\nbut was landlocked, and couldn't retreat!\n", "%s %s,\nbut was landlocked, and couldn't retreat!\n",
prship(sp), conditions[findcondition(code)].desc[orig]); prship(sp), conditions[findcondition(code)].desc[orig]);
if (!orig) if (!orig)
putship(sp->shp_uid, sp); putship(sp->shp_uid, sp);
return 0; return 0;
case CN_NAVIGABLE: case NAVOK:
break; break;
case CN_ERROR:
default: default:
CANT_REACH();
wu(0, sp->shp_own, wu(0, sp->shp_own,
"%s %s,\nbut was subject to an empire error, and couldn't retreat!\n", "%s %s,\nbut was subject to an empire error, and couldn't retreat!\n",
prship(sp), conditions[findcondition(code)].desc[orig]); prship(sp), conditions[findcondition(code)].desc[orig]);
@ -242,7 +244,7 @@ retreat_ship1(struct shpstr *sp, char code, int orig)
mobcost = shp_mobcost(sp); mobcost = shp_mobcost(sp);
getsect(newx, newy, &sect); getsect(newx, newy, &sect);
if (shp_check_nav(&sect, sp) != CN_NAVIGABLE || if (shp_check_nav(sp, &sect) != NAVOK ||
(sect.sct_own (sect.sct_own
&& relations_with(sect.sct_own, sp->shp_own) < FRIENDLY)) { && relations_with(sect.sct_own, sp->shp_own) < FRIENDLY)) {
wu(0, sp->shp_own, "%s %s,\nbut could not retreat to %s!\n", wu(0, sp->shp_own, "%s %s,\nbut could not retreat to %s!\n",

View file

@ -138,17 +138,19 @@ shp_nav(struct emp_qelem *list, double *minmobp, double *maxmobp,
shp_stays(actor, "was sucked into the sky by a strange looking spaceship", mlp); /* heh -KHS */ shp_stays(actor, "was sucked into the sky by a strange looking spaceship", mlp); /* heh -KHS */
continue; continue;
} }
switch (shp_check_nav(&sect, sp)) { switch (shp_check_nav(sp, &sect)) {
case CN_CONSTRUCTION: case NAV_02:
case NAV_60:
shp_stays(actor, "is caught in a construction zone", mlp); shp_stays(actor, "is caught in a construction zone", mlp);
continue; continue;
case CN_LANDLOCKED: case NAV_NONE:
case NAV_CANAL:
shp_stays(actor, "is landlocked", mlp); shp_stays(actor, "is landlocked", mlp);
continue; continue;
case CN_NAVIGABLE: case NAVOK:
break; break;
case CN_ERROR:
default: default:
CANT_REACH();
shp_stays(actor, "was just swallowed by a big green worm", mlp); shp_stays(actor, "was just swallowed by a big green worm", mlp);
continue; continue;
} }
@ -292,31 +294,42 @@ shp_stays(natid actor, char *str, struct ulist *mlp)
free(mlp); free(mlp);
} }
int /*
shp_check_nav(struct sctstr *sect, struct shpstr *shp) * Can SP navigate in SECTP?
* Sector ownership is *not* considered!
* Return NAVOK when yes.
* Return NAV_02 when it could if the sector was at least 2% efficient.
* Return NAV_60 when it could if the sector was at least 60% efficient.
* Return NAV_CANAL when it lacks capability M_CANAL.
* Return NAV_NONE when this sector type isn't navigable at all.
*/
enum d_navigation
shp_check_nav(struct shpstr *sp, struct sctstr *sectp)
{ {
switch (dchr[sect->sct_type].d_nav) { switch (dchr[sectp->sct_type].d_nav) {
case NAVOK: case NAVOK:
break; break;
case NAV_CANAL: case NAV_CANAL:
if (mchr[(int)shp->shp_type].m_flags & M_CANAL) { if (mchr[sp->shp_type].m_flags & M_CANAL) {
if (sect->sct_effic < 2) if (sectp->sct_effic < 2)
return CN_CONSTRUCTION; return NAV_02;
} else } else
return CN_LANDLOCKED; return NAV_CANAL;
break; break;
case NAV_02: case NAV_02:
if (sect->sct_effic < 2) if (sectp->sct_effic < 2)
return CN_CONSTRUCTION; return NAV_02;
break; break;
case NAV_60: case NAV_60:
if (sect->sct_effic < 60) if (sectp->sct_effic < 60)
return CN_CONSTRUCTION; return NAV_60;
break; break;
default: default:
return CN_LANDLOCKED; CANT_REACH();
case NAV_NONE:
return NAV_NONE;
} }
return CN_NAVIGABLE; return NAVOK;
} }
int int
@ -748,13 +761,11 @@ shp_nav_one_sector(struct emp_qelem *list, int dir, natid actor,
newx = xnorm(mlp->unit.ship.shp_x + dx); newx = xnorm(mlp->unit.ship.shp_x + dx);
newy = ynorm(mlp->unit.ship.shp_y + dy); newy = ynorm(mlp->unit.ship.shp_y + dy);
getsect(newx, newy, &sect); getsect(newx, newy, &sect);
navigate = shp_check_nav(&sect, &mlp->unit.ship); navigate = shp_check_nav(&mlp->unit.ship, &sect);
if (navigate != CN_NAVIGABLE || if (navigate != NAVOK ||
(sect.sct_own (sect.sct_own
&& relations_with(sect.sct_own, actor) < FRIENDLY)) { && relations_with(sect.sct_own, actor) < FRIENDLY)) {
if (dchr[sect.sct_type].d_nav == NAV_CANAL && if (navigate == NAV_CANAL)
!(((struct mchrstr *)mlp->chrp)->m_flags & M_CANAL) &&
navigate == CN_LANDLOCKED)
sprintf(dp, sprintf(dp,
"is too large to fit into the canal system at %s", "is too large to fit into the canal system at %s",
xyas(newx, newy, actor)); xyas(newx, newy, actor));

View file

@ -247,8 +247,7 @@ sail_nav_fleet(struct fltheadstr *fltp)
fe->num, cname(fe->own)); fe->num, cname(fe->own));
error = 1; error = 1;
} }
if ((shp_check_nav(sectp, sp) == CN_LANDLOCKED) && if (shp_check_nav(sp, sectp) == NAV_CANAL) {
(dchr[sectp->sct_type].d_nav == NAV_CANAL)) {
wu(0, fltp->own, wu(0, fltp->own,
"Your ship #%d (%s) is too big to fit through the canal.\n", "Your ship #%d (%s) is too big to fit through the canal.\n",
fe->num, cname(fe->own)); fe->num, cname(fe->own));
@ -259,7 +258,7 @@ sail_nav_fleet(struct fltheadstr *fltp)
return 0; return 0;
sp = getshipp(fltp->leader); sp = getshipp(fltp->leader);
sectp = getsectp(fltp->x, fltp->y); sectp = getsectp(fltp->x, fltp->y);
if (shp_check_nav(sectp, sp) != CN_NAVIGABLE) if (shp_check_nav(sp, sectp) != NAVOK)
wu(0, fltp->own, "Your fleet lead by %d is trapped by land.\n", wu(0, fltp->own, "Your fleet lead by %d is trapped by land.\n",
fltp->leader); fltp->leader);
sp = getshipp(fltp->leader); sp = getshipp(fltp->leader);