From a024dbb8a398a254a03af811440ba17a45d04cb2 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sun, 28 Dec 2014 22:27:37 +0100 Subject: [PATCH] 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 --- include/ship.h | 4 +-- info/navigate.t | 7 ++-- src/lib/commands/navi.c | 12 +++---- src/lib/subs/shpsub.c | 62 ++++++++++------------------------ tests/navi-march-test | 1 - tests/navi-march/01-navigate-1 | 3 ++ tests/navi-march/final.xdump | 1 + tests/navi-march/journal.log | 12 ++++++- tests/navi-march/setup-POGO | 2 ++ 9 files changed, 44 insertions(+), 60 deletions(-) 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