]> git.pond.sub.org Git - empserver/commitdiff
navigate: Require all ships to start in the same sector
authorMarkus Armbruster <armbru@pond.sub.org>
Sun, 28 Dec 2014 21:27:37 +0000 (22:27 +0100)
committerMarkus Armbruster <armbru@pond.sub.org>
Sat, 28 Feb 2015 15:13:14 +0000 (16:13 +0100)
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>
include/ship.h
info/navigate.t
src/lib/commands/navi.c
src/lib/subs/shpsub.c
tests/navi-march-test
tests/navi-march/01-navigate-1
tests/navi-march/final.xdump
tests/navi-march/journal.log
tests/navi-march/setup-POGO

index 826de914168a051cf66740ad6c8ef1b389148de7..32bec3baadf5bd2dd2b65ceb2a0e5dd192e5c0f9 100644 (file)
@@ -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 *);
index c42e772d00c802542e9f200372ef65e3d607210c..d10b36174b4b21b6731cf0304b80307a18908429 100644 (file)
@@ -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
 
index 54ab8c053bd9902ff84a1ceb1af8857287704489..e305193830d5aa5e1b44f09c3e7bf3a12b63864c 100644 (file)
@@ -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;
index d0f9aa43312e2ad6abd72bd1dde9c61a5a338908..b343951f8a857bf1d9541dd95de88ed09655b6ee 100644 (file)
@@ -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, &sect);
+
     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, &sect);
        stuck = shp_check_nav(&mlp->unit.ship, &sect);
        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, &sect);
        stuck = shp_check_nav(&mlp->unit.ship, &sect);
        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;
 }
index 776b739e85190448afb93e81703ac244d88b3dfe..f01446a061001858acdec6ced9e5dabe3cd56389 100755 (executable)
@@ -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
index e2ad06fc811209a092a66c7a1c5ab959bf471266..f9ae3e9fde8eb10aa8d3c00bc38b8c37c9d97886 100644 (file)
@@ -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
index 0388a37119fec962d6fc6b0cff31592d2f574feb..6cd302da567b94946cc759e537f57fa075d3e536 100644 (file)
@@ -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 () ""
index 42af4f6f62a11c2f7ce8300ad32f4b98b70a5e4f..c3cca2c950cecaad1cd9c0a58af54af8772d07f4 100644 (file)
     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)
     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
     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
index 90b1e6729a6d8dd1496dbbe2a4b67505707f0a6c..adc1c7842ba24a445b68536b9b6b166cf2aa1e03 100644 (file)
@@ -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