navigate: Require all ships to start in the same sector
The capability to navigate ships spread over several sectors is obscure and rarely useful. Accidental use is probably more frequent than intentional use. Issues: * Interactive prompts show only the flagship's position, and give no clue that some ships are actually elsewhere. * Path finding is supported only when all navigating ships are in the same sector. * Interdiction becomes rather complex. For each movement, every sector entered is interdicted independently. This means the same fort, ship, land unit or plane can interdict multiple times. Interdiction order depends on the order the code examines ships. which the player can control. This is all pretty much undocumented. * Complicates the code and its maintenance. Multiplies the number of test cases needed to cover navigate. I feel we're better off without this feature. Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
This commit is contained in:
parent
69c99a0f29
commit
a024dbb8a3
9 changed files with 44 additions and 60 deletions
|
@ -171,12 +171,12 @@ extern double shp_torp_hitchance(struct shpstr *, int);
|
|||
/* src/lib/subs/shpsub.c */
|
||||
extern void shp_sel(struct nstr_item *, struct emp_qelem *);
|
||||
extern struct ulist *shp_insque(struct shpstr *, struct emp_qelem *);
|
||||
extern void shp_nav(struct emp_qelem *, double *, double *, int *, natid);
|
||||
extern void shp_nav(struct emp_qelem *, double *, double *, natid);
|
||||
extern int shp_sweep(struct emp_qelem *, int, int, natid);
|
||||
extern enum shp_stuck shp_check_nav(struct shpstr *, struct sctstr *);
|
||||
extern int sect_has_dock(struct sctstr *);
|
||||
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);
|
||||
extern int shp_missile_defense(coord, coord, natid, int);
|
||||
extern void shp_missdef(struct shpstr *, natid);
|
||||
extern double shp_mobcost(struct shpstr *);
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
.LV Basic
|
||||
.SY "navigate <SHIP/FLEET> <ROUTE|DESTINATION>"
|
||||
The navigate command is the \*Qmove\*U command applied to the sea.
|
||||
You can control one ship or an entire fleet with it.
|
||||
You can control one ship or an entire fleet with it, but they must all
|
||||
start in the same sector.
|
||||
.s1
|
||||
A ship must have at least one crew
|
||||
(which may be civilian or military,
|
||||
|
@ -114,10 +115,6 @@ For example,
|
|||
patrol boat #18 stopped at -6,-2
|
||||
.FI
|
||||
.s1
|
||||
Note that if you are navigating multiple ships, you may only specify a
|
||||
destination sector on the command line if all the ships start in the
|
||||
same sector.
|
||||
.s1
|
||||
The formula for the movement cost for 1 sector is:
|
||||
.NF
|
||||
|
||||
|
|
|
@ -50,17 +50,16 @@ navi(void)
|
|||
struct nstr_item ni_ship;
|
||||
struct emp_qelem ship_list;
|
||||
double minmob, maxmob;
|
||||
int together;
|
||||
int together = 1;
|
||||
|
||||
if (!snxtitem(&ni_ship, EF_SHIP, player->argp[1], NULL))
|
||||
return RET_SYN;
|
||||
shp_sel(&ni_ship, &ship_list);
|
||||
shp_nav(&ship_list, &minmob, &maxmob, &together, player->cnum);
|
||||
shp_nav(&ship_list, &minmob, &maxmob, player->cnum);
|
||||
if (QEMPTY(&ship_list)) {
|
||||
pr("No ships\n");
|
||||
return RET_FAIL;
|
||||
}
|
||||
|
||||
return do_unit_move(&ship_list, &together, &minmob, &maxmob);
|
||||
}
|
||||
|
||||
|
@ -99,7 +98,7 @@ do_unit_move(struct emp_qelem *ulist, int *together,
|
|||
if (cp == NULL || *cp == '\0' || stopping) {
|
||||
stopping = 0;
|
||||
if (type == EF_SHIP)
|
||||
shp_nav(ulist, minmob, maxmob, together, player->cnum);
|
||||
shp_nav(ulist, minmob, maxmob, player->cnum);
|
||||
else
|
||||
lnd_mar(ulist, minmob, maxmob, player->cnum);
|
||||
if (QEMPTY(ulist)) {
|
||||
|
@ -126,7 +125,7 @@ do_unit_move(struct emp_qelem *ulist, int *together,
|
|||
* at the prompt, we call shp_nav() or lnd_mar() again.
|
||||
*/
|
||||
if (type == EF_SHIP)
|
||||
shp_nav(ulist, minmob, maxmob, together, player->cnum);
|
||||
shp_nav(ulist, minmob, maxmob, player->cnum);
|
||||
else
|
||||
lnd_mar(ulist, minmob, maxmob, player->cnum);
|
||||
if (QEMPTY(ulist)) {
|
||||
|
@ -152,8 +151,7 @@ do_unit_move(struct emp_qelem *ulist, int *together,
|
|||
dir = chkdir(*cp, DIR_STOP, DIR_LAST);
|
||||
if (dir >= 0) {
|
||||
if (type == EF_SHIP)
|
||||
stopping |= shp_nav_one_sector(ulist, dir,
|
||||
player->cnum, *together);
|
||||
stopping |= shp_nav_one_sector(ulist, dir, player->cnum);
|
||||
else {
|
||||
if (!moved && !lnd_abandon_askyn(ulist))
|
||||
return RET_FAIL;
|
||||
|
|
|
@ -106,20 +106,16 @@ shp_insque(struct shpstr *sp, struct emp_qelem *list)
|
|||
/* This function assumes that the list was created by shp_sel */
|
||||
void
|
||||
shp_nav(struct emp_qelem *list, double *minmobp, double *maxmobp,
|
||||
int *togetherp, natid actor)
|
||||
natid actor)
|
||||
{
|
||||
struct emp_qelem *qp;
|
||||
struct emp_qelem *next;
|
||||
struct ulist *mlp;
|
||||
struct shpstr *sp;
|
||||
struct shpstr *sp, *flg = NULL;
|
||||
struct sctstr sect;
|
||||
coord allx;
|
||||
coord ally;
|
||||
int first = 1;
|
||||
|
||||
*minmobp = 9876.0;
|
||||
*maxmobp = -9876.0;
|
||||
*togetherp = 1;
|
||||
for (qp = list->q_back; qp != list; qp = next) {
|
||||
next = qp->q_back;
|
||||
mlp = (struct ulist *)qp;
|
||||
|
@ -155,13 +151,12 @@ shp_nav(struct emp_qelem *list, double *minmobp, double *maxmobp,
|
|||
shp_stays(actor, "is landlocked", mlp);
|
||||
continue;
|
||||
}
|
||||
if (first) {
|
||||
allx = sp->shp_x;
|
||||
ally = sp->shp_y;
|
||||
first = 0;
|
||||
if (!flg)
|
||||
flg = sp;
|
||||
else if (sp->shp_x != flg->shp_x || sp->shp_y != flg->shp_y) {
|
||||
shp_stays(actor, "is not with the flagship", mlp);
|
||||
continue;
|
||||
}
|
||||
if (sp->shp_x != allx || sp->shp_y != ally)
|
||||
*togetherp = 0;
|
||||
if (sp->shp_mobil + 1 < (int)mlp->mobil) {
|
||||
mlp->mobil = sp->shp_mobil;
|
||||
}
|
||||
|
@ -749,14 +744,12 @@ shp_hit_mine(struct shpstr *sp)
|
|||
}
|
||||
|
||||
int
|
||||
shp_nav_one_sector(struct emp_qelem *list, int dir, natid actor,
|
||||
int together)
|
||||
shp_nav_one_sector(struct emp_qelem *list, int dir, natid actor)
|
||||
{
|
||||
struct sctstr sect;
|
||||
struct emp_qelem *qp;
|
||||
struct emp_qelem *next;
|
||||
struct ulist *mlp;
|
||||
struct emp_qelem done;
|
||||
coord dx;
|
||||
coord dy;
|
||||
coord newx;
|
||||
|
@ -767,6 +760,9 @@ shp_nav_one_sector(struct emp_qelem *list, int dir, natid actor,
|
|||
double mobcost;
|
||||
char dp[80];
|
||||
|
||||
if (CANT_HAPPEN(QEMPTY(list)))
|
||||
return 1;
|
||||
|
||||
if (dir <= DIR_STOP || dir >= DIR_VIEW) {
|
||||
shp_nav_put(list, actor);
|
||||
return 1;
|
||||
|
@ -774,13 +770,15 @@ shp_nav_one_sector(struct emp_qelem *list, int dir, natid actor,
|
|||
dx = diroff[dir][0];
|
||||
dy = diroff[dir][1];
|
||||
|
||||
mlp = (struct ulist *)list->q_back;
|
||||
newx = xnorm(mlp->unit.ship.shp_x + dx);
|
||||
newy = ynorm(mlp->unit.ship.shp_y + dy);
|
||||
getsect(newx, newy, §);
|
||||
|
||||
move = 0;
|
||||
for (qp = list->q_back; qp != list; qp = next) {
|
||||
next = qp->q_back;
|
||||
mlp = (struct ulist *)qp;
|
||||
newx = xnorm(mlp->unit.ship.shp_x + dx);
|
||||
newy = ynorm(mlp->unit.ship.shp_y + dy);
|
||||
getsect(newx, newy, §);
|
||||
stuck = shp_check_nav(&mlp->unit.ship, §);
|
||||
if (stuck == SHP_STUCK_NOT &&
|
||||
(!sect.sct_own
|
||||
|
@ -791,9 +789,6 @@ shp_nav_one_sector(struct emp_qelem *list, int dir, natid actor,
|
|||
for (qp = list->q_back; qp != list; qp = next) {
|
||||
next = qp->q_back;
|
||||
mlp = (struct ulist *)qp;
|
||||
newx = xnorm(mlp->unit.ship.shp_x + dx);
|
||||
newy = ynorm(mlp->unit.ship.shp_y + dy);
|
||||
getsect(newx, newy, §);
|
||||
stuck = shp_check_nav(&mlp->unit.ship, §);
|
||||
if (stuck != SHP_STUCK_NOT ||
|
||||
(sect.sct_own
|
||||
|
@ -804,7 +799,7 @@ shp_nav_one_sector(struct emp_qelem *list, int dir, natid actor,
|
|||
xyas(newx, newy, actor));
|
||||
else
|
||||
sprintf(dp, "can't go to %s", xyas(newx, newy, actor));
|
||||
if (together && !move) {
|
||||
if (!move) {
|
||||
mpr(actor, "%s\n", dp);
|
||||
return 1;
|
||||
} else {
|
||||
|
@ -842,28 +837,7 @@ shp_nav_one_sector(struct emp_qelem *list, int dir, natid actor,
|
|||
stopping |= shp_check_mines(list);
|
||||
if (QEMPTY(list))
|
||||
return stopping;
|
||||
|
||||
/* interdict ships sector by sector */
|
||||
emp_initque(&done);
|
||||
while (!QEMPTY(list)) {
|
||||
mlp = (struct ulist *)list->q_back;
|
||||
newx = mlp->unit.ship.shp_x;
|
||||
newy = mlp->unit.ship.shp_y;
|
||||
stopping |= shp_interdict(list, newx, newy, actor);
|
||||
/* move survivors in this sector to done */
|
||||
for (qp = list->q_back; qp != list; qp = next) {
|
||||
next = qp->q_back;
|
||||
mlp = (struct ulist *)qp;
|
||||
if (mlp->unit.ship.shp_x == newx &&
|
||||
mlp->unit.ship.shp_y == newy) {
|
||||
emp_remque(qp);
|
||||
emp_insque(qp, &done);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* assign surviving ships back to list */
|
||||
emp_insque(list, &done);
|
||||
emp_remque(&done);
|
||||
stopping |= shp_interdict(list, newx, newy, actor);
|
||||
|
||||
return stopping;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ WORLD_Y 16
|
|||
MARKET 1
|
||||
EOF
|
||||
customize big-city
|
||||
# TODO cover scattered navigate
|
||||
# TODO cover RAILWAYS 0
|
||||
|
||||
begin_test "$srcdir"/tests/navi-march/setup-POGO
|
||||
|
|
|
@ -19,6 +19,9 @@ navi 24/26 yh
|
|||
navi 25 h
|
||||
| landlocked in 1,-1
|
||||
navi 27 h
|
||||
| not with flagship
|
||||
nav 28/10 yh
|
||||
__cmd added 1 1 0
|
||||
|| get stuck on the way
|
||||
| sink, by hitting mine in 11,-5
|
||||
| #31 hits a mine, #30 doesn't
|
||||
|
|
|
@ -142,6 +142,7 @@ uid owner xloc yloc type effic mobil off tech opx opy mission radius fleet civil
|
|||
25 1 4 2 9 100 127 0 40 4 2 none 0 "" 0 2 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 "" 1 1 1 () ""
|
||||
26 1 2 2 2 100 127 0 20 0 0 none 0 "" 0 5 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 "" 1 1 1 () ""
|
||||
27 1 1 -1 9 100 127 0 40 1 -1 none 0 "" 0 2 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 "" 1 1 1 () ""
|
||||
28 1 3 -1 9 100 117 0 40 4 0 none 0 "" 0 2 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 "" 1 1 1 () ""
|
||||
30 1 10 -6 9 100 108 0 40 9 -5 none 0 "" 0 2 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 "" 1 1 1 () ""
|
||||
31 0 11 -5 9 0 53 0 40 9 -5 none 0 "" 0 2 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 "" 1 1 1 () ""
|
||||
32 1 10 -6 9 75 105 0 40 9 -5 none 0 "" 0 1 0 0 0 0 0 0 0 0 0 0 0 0 healthy 0 0 "" 1 1 1 () ""
|
||||
|
|
|
@ -114,6 +114,15 @@
|
|||
Play#1 output Play#1 1 No ships
|
||||
Play#1 output Play#1 1 command failed
|
||||
Play#1 output Play#1 6 0 630
|
||||
Play#1 input nav 28/10 yh
|
||||
Play#1 command navigate
|
||||
Play#1 output Play#1 1 pt patrol boat (#10) is not with the flagship & stays in -1,-1
|
||||
Play#1 output Play#1 1 Flagship is pt patrol boat (#28)
|
||||
Play#1 output Play#1 1 pt patrol boat (#28) stopped at 3,-1
|
||||
Play#1 output Play#1 6 0 629
|
||||
Play#1 input __cmd added 1 1 0
|
||||
Play#1 command __cmd
|
||||
Play#1 output Play#1 6 0 630
|
||||
Play#1 input navi 31/30 jX
|
||||
Play#1 command navigate
|
||||
Play#1 output Play#1 1 Flagship is pt patrol boat (#31)
|
||||
|
@ -1393,6 +1402,7 @@
|
|||
Play#0 output Play#0 1 1 25 pt patrol boat 4,2 100% 0 2 0 0 0 0 0 0 127 40
|
||||
Play#0 output Play#0 1 1 26 cs cargo ship 2,2 100% 0 5 0 0 0 0 0 0 127 20
|
||||
Play#0 output Play#0 1 1 27 pt patrol boat 1,-1 100% 0 2 0 0 0 0 0 0 127 40
|
||||
Play#0 output Play#0 1 1 28 pt patrol boat 3,-1 100% 0 2 0 0 0 0 0 0 117 40
|
||||
Play#0 output Play#0 1 1 30 pt patrol boat 10,-6 100% 0 2 0 0 0 0 0 0 108 40
|
||||
Play#0 output Play#0 1 1 32 pt patrol boat 10,-6 75% 0 1 0 0 0 0 0 0 105 40
|
||||
Play#0 output Play#0 1 1 33 pt patrol boat 10,-6 80% 0 1 0 0 0 0 0 0 106 40
|
||||
|
@ -1445,7 +1455,7 @@
|
|||
Play#0 output Play#0 1 1 137 pt patrol boat 11,-5 100% 0 2 0 0 0 0 0 0 117 40
|
||||
Play#0 output Play#0 1 1 138 pt patrol boat 11,-5 80% 0 1 0 0 0 0 0 0 93 40
|
||||
Play#0 output Play#0 1 1 139 pt patrol boat 11,-5 74% 0 1 0 0 0 0 0 0 86 40
|
||||
Play#0 output Play#0 1 70 ships
|
||||
Play#0 output Play#0 1 71 ships
|
||||
Play#0 output Play#0 6 0 640
|
||||
Play#0 input carg * ?shell#0
|
||||
Play#0 command cargo
|
||||
|
|
|
@ -88,6 +88,8 @@ edit s 0 U 24 L 2,2 U 25 L 4,2
|
|||
edit s 1 U 26 L 2,2
|
||||
| landlocked in 1,-1
|
||||
edit s 0 U 27 L 1,-1
|
||||
| at sea, away from #10
|
||||
edit s 0 U 28 L 4,0
|
||||
| next to minefield 11,-5
|
||||
edit s 0 U 30 L 9,-5 U 31 E 20
|
||||
edit s 30 U 32 m 1 U 33 U 34 U 35 U 36 U 37 U 38 U 39
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue