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

@ -172,25 +172,27 @@ retreat_ship1(struct shpstr *sp, char code, int orig)
}
getsect(sp->shp_x, sp->shp_y, &sect);
switch (shp_check_nav(&sect, sp)) {
case CN_CONSTRUCTION:
switch (shp_check_nav(sp, &sect)) {
case NAV_02:
case NAV_60:
wu(0, sp->shp_own,
"%s %s,\nbut was caught in a construction zone, and couldn't retreat!\n",
prship(sp), conditions[findcondition(code)].desc[orig]);
if (!orig)
putship(sp->shp_uid, sp);
return 0;
case CN_LANDLOCKED:
case NAV_NONE:
case NAV_CANAL:
wu(0, sp->shp_own,
"%s %s,\nbut was landlocked, and couldn't retreat!\n",
prship(sp), conditions[findcondition(code)].desc[orig]);
if (!orig)
putship(sp->shp_uid, sp);
return 0;
case CN_NAVIGABLE:
case NAVOK:
break;
case CN_ERROR:
default:
CANT_REACH();
wu(0, sp->shp_own,
"%s %s,\nbut was subject to an empire error, and couldn't retreat!\n",
prship(sp), conditions[findcondition(code)].desc[orig]);
@ -242,7 +244,7 @@ retreat_ship1(struct shpstr *sp, char code, int orig)
mobcost = shp_mobcost(sp);
getsect(newx, newy, &sect);
if (shp_check_nav(&sect, sp) != CN_NAVIGABLE ||
if (shp_check_nav(sp, &sect) != NAVOK ||
(sect.sct_own
&& relations_with(sect.sct_own, sp->shp_own) < FRIENDLY)) {
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 */
continue;
}
switch (shp_check_nav(&sect, sp)) {
case CN_CONSTRUCTION:
switch (shp_check_nav(sp, &sect)) {
case NAV_02:
case NAV_60:
shp_stays(actor, "is caught in a construction zone", mlp);
continue;
case CN_LANDLOCKED:
case NAV_NONE:
case NAV_CANAL:
shp_stays(actor, "is landlocked", mlp);
continue;
case CN_NAVIGABLE:
case NAVOK:
break;
case CN_ERROR:
default:
CANT_REACH();
shp_stays(actor, "was just swallowed by a big green worm", mlp);
continue;
}
@ -292,31 +294,42 @@ shp_stays(natid actor, char *str, struct ulist *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:
break;
case NAV_CANAL:
if (mchr[(int)shp->shp_type].m_flags & M_CANAL) {
if (sect->sct_effic < 2)
return CN_CONSTRUCTION;
if (mchr[sp->shp_type].m_flags & M_CANAL) {
if (sectp->sct_effic < 2)
return NAV_02;
} else
return CN_LANDLOCKED;
return NAV_CANAL;
break;
case NAV_02:
if (sect->sct_effic < 2)
return CN_CONSTRUCTION;
if (sectp->sct_effic < 2)
return NAV_02;
break;
case NAV_60:
if (sect->sct_effic < 60)
return CN_CONSTRUCTION;
if (sectp->sct_effic < 60)
return NAV_60;
break;
default:
return CN_LANDLOCKED;
CANT_REACH();
case NAV_NONE:
return NAV_NONE;
}
return CN_NAVIGABLE;
return NAVOK;
}
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);
newy = ynorm(mlp->unit.ship.shp_y + dy);
getsect(newx, newy, &sect);
navigate = shp_check_nav(&sect, &mlp->unit.ship);
if (navigate != CN_NAVIGABLE ||
navigate = shp_check_nav(&mlp->unit.ship, &sect);
if (navigate != NAVOK ||
(sect.sct_own
&& relations_with(sect.sct_own, actor) < FRIENDLY)) {
if (dchr[sect.sct_type].d_nav == NAV_CANAL &&
!(((struct mchrstr *)mlp->chrp)->m_flags & M_CANAL) &&
navigate == CN_LANDLOCKED)
if (navigate == NAV_CANAL)
sprintf(dp,
"is too large to fit into the canal system at %s",
xyas(newx, newy, actor));

View file

@ -247,8 +247,7 @@ sail_nav_fleet(struct fltheadstr *fltp)
fe->num, cname(fe->own));
error = 1;
}
if ((shp_check_nav(sectp, sp) == CN_LANDLOCKED) &&
(dchr[sectp->sct_type].d_nav == NAV_CANAL)) {
if (shp_check_nav(sp, sectp) == NAV_CANAL) {
wu(0, fltp->own,
"Your ship #%d (%s) is too big to fit through the canal.\n",
fe->num, cname(fe->own));
@ -259,7 +258,7 @@ sail_nav_fleet(struct fltheadstr *fltp)
return 0;
sp = getshipp(fltp->leader);
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",
fltp->leader);
sp = getshipp(fltp->leader);