diff --git a/include/ship.h b/include/ship.h index 826de914..32bec3ba 100644 --- a/include/ship.h +++ b/include/ship.h @@ -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 *); diff --git a/info/navigate.t b/info/navigate.t index c42e772d..d10b3617 100644 --- a/info/navigate.t +++ b/info/navigate.t @@ -3,7 +3,8 @@ .LV Basic .SY "navigate " 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 diff --git a/src/lib/commands/navi.c b/src/lib/commands/navi.c index 54ab8c05..e3051938 100644 --- a/src/lib/commands/navi.c +++ b/src/lib/commands/navi.c @@ -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; diff --git a/src/lib/subs/shpsub.c b/src/lib/subs/shpsub.c index d0f9aa43..b343951f 100644 --- a/src/lib/subs/shpsub.c +++ b/src/lib/subs/shpsub.c @@ -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; } diff --git a/tests/navi-march-test b/tests/navi-march-test index 776b739e..f01446a0 100755 --- a/tests/navi-march-test +++ b/tests/navi-march-test @@ -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 diff --git a/tests/navi-march/01-navigate-1 b/tests/navi-march/01-navigate-1 index e2ad06fc..f9ae3e9f 100644 --- a/tests/navi-march/01-navigate-1 +++ b/tests/navi-march/01-navigate-1 @@ -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 diff --git a/tests/navi-march/final.xdump b/tests/navi-march/final.xdump index 0388a371..6cd302da 100644 --- a/tests/navi-march/final.xdump +++ b/tests/navi-march/final.xdump @@ -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 () "" diff --git a/tests/navi-march/journal.log b/tests/navi-march/journal.log index 42af4f6f..c3cca2c9 100644 --- a/tests/navi-march/journal.log +++ b/tests/navi-march/journal.log @@ -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 diff --git a/tests/navi-march/setup-POGO b/tests/navi-march/setup-POGO index 90b1e672..adc1c784 100644 --- a/tests/navi-march/setup-POGO +++ b/tests/navi-march/setup-POGO @@ -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