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:
parent
1fee5028a2
commit
c03db4c5ef
6 changed files with 53 additions and 47 deletions
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -172,25 +172,27 @@ retreat_ship1(struct shpstr *sp, char code, int orig)
|
||||||
}
|
}
|
||||||
|
|
||||||
getsect(sp->shp_x, sp->shp_y, §);
|
getsect(sp->shp_x, sp->shp_y, §);
|
||||||
switch (shp_check_nav(§, sp)) {
|
switch (shp_check_nav(sp, §)) {
|
||||||
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, §);
|
getsect(newx, newy, §);
|
||||||
if (shp_check_nav(§, sp) != CN_NAVIGABLE ||
|
if (shp_check_nav(sp, §) != 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",
|
||||||
|
|
|
@ -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(§, sp)) {
|
switch (shp_check_nav(sp, §)) {
|
||||||
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, §);
|
getsect(newx, newy, §);
|
||||||
navigate = shp_check_nav(§, &mlp->unit.ship);
|
navigate = shp_check_nav(&mlp->unit.ship, §);
|
||||||
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));
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue