]> git.pond.sub.org Git - empserver/commitdiff
navigate march: Nicer error messages for sub-command 'm'
authorMarkus Armbruster <armbru@pond.sub.org>
Mon, 29 Dec 2014 18:49:39 +0000 (19:49 +0100)
committerMarkus Armbruster <armbru@pond.sub.org>
Sat, 28 Feb 2015 15:13:15 +0000 (16:13 +0100)
Don't report every incapable ship or land unit.  Complain only when
there are no capable ships or land units available.

The ships are all in the same sector, so complain about the sector
type just once instead of once per capable ship or land unit.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
src/lib/subs/lndsub.c
src/lib/subs/shpsub.c
tests/navi-march/journal.log

index ab21fc6f63837095b64f6bfa2483c2db285975fd..94a1e41a44a4cb8327465087c16fab25d9344c3e 100644 (file)
@@ -57,6 +57,20 @@ static void lnd_stays(natid, char *, struct ulist *);
 static int lnd_hit_mine(struct lndstr *);
 static int has_helpful_engineer(coord, coord, natid);
 
+static struct ulist *
+lnd_find_capable(struct emp_qelem *list, int flags)
+{
+    struct emp_qelem *qp;
+    struct ulist *llp;
+
+    for (qp = list->q_back; qp != list; qp = qp->q_back) {
+       llp = (struct ulist *)qp;
+       if (lchr[llp->unit.land.lnd_type].l_flags & flags)
+           return llp;
+    }
+    return NULL;
+}
+
 double
 attack_val(int combat_mode, struct lndstr *lp)
 {
@@ -578,9 +592,11 @@ lnd_put_one(struct ulist *llp)
 
 /*
  * Sweep landmines with engineers in LAND_LIST for ACTOR.
+ * All land units in LAND_LIST must be in the same sector.
  * If EXPLICIT is non-zero, this is for an explicit sweep command from
  * a player.  Else it's an automatic "on the move" sweep.
  * If TAKEMOB is non-zero, require and charge mobility.
+ * Return non-zero when the land units should stop.
  */
 int
 lnd_sweep(struct emp_qelem *land_list, int explicit, int takemob,
@@ -593,36 +609,43 @@ lnd_sweep(struct emp_qelem *land_list, int explicit, int takemob,
     int mines, m, max, sshells, lshells;
     int stopping = 0;
 
+    llp = lnd_find_capable(land_list, L_ENGINEER);
+    if (!llp) {
+       if (explicit)
+           mpr(actor, "No engineers!\n");
+       return 0;
+    }
+
+    getsect(llp->unit.land.lnd_x, llp->unit.land.lnd_y, &sect);
+    if (!explicit
+       && relations_with(sect.sct_oldown, actor) == ALLIED)
+       return 0;
+    if (SCT_MINES_ARE_SEAMINES(&sect)) {
+       if (explicit)
+           mpr(actor, "%s is a %s.  No landmines there!\n",
+               xyas(sect.sct_x, sect.sct_y, actor),
+               dchr[sect.sct_type].d_name);
+       return 0;
+    }
+
     for (qp = land_list->q_back; qp != land_list; qp = next) {
        next = qp->q_back;
        llp = (struct ulist *)qp;
-       if (!(lchr[llp->unit.land.lnd_type].l_flags & L_ENGINEER)) {
-           if (explicit)
-               mpr(actor, "%s is not an engineer!\n",
-                   prland(&llp->unit.land));
-           continue;
-       }
-       if (takemob && llp->mobil <= 0.0) {
-           if (explicit)
-               mpr(actor, "%s is out of mobility!\n",
-                   prland(&llp->unit.land));
-           continue;
-       }
-       getsect(llp->unit.land.lnd_x, llp->unit.land.lnd_y, &sect);
-       if (!explicit && relations_with(sect.sct_oldown, actor) == ALLIED)
-           continue;
-       if (SCT_MINES_ARE_SEAMINES(&sect)) {
-           if (explicit)
-               mpr(actor, "%s is in a %s sector.  No landmines there!\n",
-                   prland(&llp->unit.land), dchr[sect.sct_type].d_name);
+       if (!(lchr[llp->unit.land.lnd_type].l_flags & L_ENGINEER))
            continue;
-       }
        if (takemob) {
+           if (llp->mobil <= 0.0) {
+               if (explicit)
+                   mpr(actor, "%s is out of mobility!\n",
+                       prland(&llp->unit.land));
+               continue;
+           }
            llp->mobil -= lnd_pathcost(&llp->unit.land, 0.2);
            llp->unit.land.lnd_mobil = (int)llp->mobil;
            llp->unit.land.lnd_harden = 0;
        }
        putland(llp->unit.land.lnd_uid, &llp->unit.land);
+       getsect(llp->unit.land.lnd_x, llp->unit.land.lnd_y, &sect);
        if (!(mines = sect.sct_mines))
            continue;
        max = lchr[llp->unit.land.lnd_type].l_item[I_SHELL];
index 9692e8e44d7b7e6399df9ce05fd91d9e46635b32..2c8423c3a35428ceb77e646aaf0a94513e9048b2 100644 (file)
@@ -58,6 +58,20 @@ static int shp_check_one_mines(struct ulist *);
 static int shp_hit_mine(struct shpstr *);
 static void shp_stays(natid, char *, struct ulist *);
 
+static struct ulist *
+shp_find_capable(struct emp_qelem *list, int flags)
+{
+    struct emp_qelem *qp;
+    struct ulist *mlp;
+
+    for (qp = list->q_back; qp != list; qp = qp->q_back) {
+       mlp = (struct ulist *)qp;
+       if (mchr[mlp->unit.ship.shp_type].m_flags & flags)
+           return mlp;
+    }
+    return NULL;
+}
+
 void
 shp_sel(struct nstr_item *ni, struct emp_qelem *list)
 {
@@ -192,8 +206,17 @@ shp_nav_put_one(struct ulist *mlp)
     free(mlp);
 }
 
+/*
+ * Sweep seamines with engineers in SHIP_LIST for ACTOR.
+ * All ships in SHIP_LIST must be in the same sector.
+ * If EXPLICIT is non-zero, this is for an explicit sweep command from
+ * a player.  Else it's an automatic "on the move" sweep.
+ * If TAKEMOB is non-zero, require and charge mobility.
+ * Return non-zero when the ships should stop.
+ */
 int
-shp_sweep(struct emp_qelem *ship_list, int verbose, int takemob, natid actor)
+shp_sweep(struct emp_qelem *ship_list, int explicit, int takemob,
+         natid actor)
 {
     struct emp_qelem *qp;
     struct emp_qelem *next;
@@ -203,33 +226,39 @@ shp_sweep(struct emp_qelem *ship_list, int verbose, int takemob, natid actor)
     int changed = 0;
     int stopping = 0;
 
+    mlp = shp_find_capable(ship_list, M_SWEEP);
+    if (!mlp) {
+       if (explicit)
+           mpr(actor, "No minesweepers!\n");
+       return 0;
+    }
+
+    getsect(mlp->unit.ship.shp_x, mlp->unit.ship.shp_y, &sect);
+    if (sect.sct_type != SCT_WATER) {
+       if (explicit)
+           mpr(actor, "%s is a %s.  No seamines there!\n",
+              xyas(sect.sct_x, sect.sct_y, actor),
+              dchr[sect.sct_type].d_name);
+       return 0;
+    }
+
     for (qp = ship_list->q_back; qp != ship_list; qp = next) {
        next = qp->q_back;
        mlp = (struct ulist *)qp;
-       if (!(mchr[mlp->unit.ship.shp_type].m_flags & M_SWEEP)) {
-           if (verbose)
-               mpr(actor, "%s doesn't have minesweeping capability!\n",
-                   prship(&mlp->unit.ship));
+       if (!(mchr[mlp->unit.ship.shp_type].m_flags & M_SWEEP))
            continue;
-       }
-       if (takemob && mlp->mobil <= 0.0) {
-           if (verbose)
-               mpr(actor, "%s is out of mobility!\n",
-                   prship(&mlp->unit.ship));
-           continue;
-       }
-       getsect(mlp->unit.ship.shp_x, mlp->unit.ship.shp_y, &sect);
-       if (sect.sct_type != SCT_WATER) {
-           if (verbose)
-               mpr(actor, "%s is not at sea.  No mines there!\n",
-                   prship(&mlp->unit.ship));
-           continue;
-       }
        if (takemob) {
+           if (mlp->mobil <= 0.0) {
+               if (explicit)
+                   mpr(actor, "%s is out of mobility!\n",
+                       prship(&mlp->unit.ship));
+               continue;
+           }
            mlp->mobil -= shp_mobcost(&mlp->unit.ship);
            mlp->unit.ship.shp_mobil = (int)mlp->mobil;
        }
        putship(mlp->unit.ship.shp_uid, &mlp->unit.ship);
+       getsect(mlp->unit.ship.shp_x, mlp->unit.ship.shp_y, &sect);
        if (!(mines = sect.sct_mines))
            continue;
        max = mchr[mlp->unit.ship.shp_type].m_item[I_SHELL];
index b2d9d09840091ce26664f7a4f429a66f4d89e8a0..93c6e639200fbe28c9373550719dad5399b72482 100644 (file)
     Play#1 input navi 0/1 mh
     Play#1 command navigate
     Play#1 output Play#1 1 Flagship is pt   patrol boat (#0)
-    Play#1 output Play#1 1 pt   patrol boat (#0) doesn't have minesweeping capability!
-    Play#1 output Play#1 1 cs   cargo ship (#1) doesn't have minesweeping capability!
+    Play#1 output Play#1 1 No minesweepers!
     Play#1 output Play#1 1 pt   patrol boat (#0) stopped at 1,1
     Play#1 output Play#1 1 cs   cargo ship (#1) stopped at 1,1
     Play#1 output Play#1 6 0 594
     Play#1 input navi 5 mh
     Play#1 command navigate
     Play#1 output Play#1 1 Flagship is ms   minesweeper (#5)
-    Play#1 output Play#1 1 ms   minesweeper (#5) is not at sea.  No mines there!
+    Play#1 output Play#1 1 1,1 is a harbor.  No seamines there!
     Play#1 output Play#1 1 ms   minesweeper (#5) stopped at 1,1
     Play#1 output Play#1 6 0 593
     Play#1 input navi 121/122/128 j
     Play#1 output Play#1 1  . .
     Play#1 output Play#1 4 <117.8:76.0: 11,-5>
     Play#1 input mmmh
-    Play#1 output Play#1 1 pt   patrol boat (#135) doesn't have minesweeping capability!
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Kawhomp! Mine detected in 11,-5!
     Play#1 output Play#1 1     ms   minesweeper (#130) takes 15
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Kawhomp! Mine detected in 11,-5!
     Play#1 output Play#1 1     ms   minesweeper (#131) takes 10
-    Play#1 output Play#1 1 pt   patrol boat (#136) doesn't have minesweeping capability!
-    Play#1 output Play#1 1 pt   patrol boat (#137) doesn't have minesweeping capability!
-    Play#1 output Play#1 1 pt   patrol boat (#138) doesn't have minesweeping capability!
-    Play#1 output Play#1 1 pt   patrol boat (#139) doesn't have minesweeping capability!
-    Play#1 output Play#1 1 pt   patrol boat (#135) doesn't have minesweeping capability!
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
-    Play#1 output Play#1 1 pt   patrol boat (#136) doesn't have minesweeping capability!
-    Play#1 output Play#1 1 pt   patrol boat (#137) doesn't have minesweeping capability!
-    Play#1 output Play#1 1 pt   patrol boat (#138) doesn't have minesweeping capability!
-    Play#1 output Play#1 1 pt   patrol boat (#139) doesn't have minesweeping capability!
-    Play#1 output Play#1 1 pt   patrol boat (#135) doesn't have minesweeping capability!
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Kawhomp! Mine detected in 11,-5!
     Play#1 output Play#1 1     ms   minesweeper (#131) takes 11
-    Play#1 output Play#1 1 pt   patrol boat (#136) doesn't have minesweeping capability!
-    Play#1 output Play#1 1 pt   patrol boat (#137) doesn't have minesweeping capability!
-    Play#1 output Play#1 1 pt   patrol boat (#138) doesn't have minesweeping capability!
-    Play#1 output Play#1 1 pt   patrol boat (#139) doesn't have minesweeping capability!
     Play#1 output Play#1 1 pt   patrol boat (#135) stopped at 11,-5
     Play#1 output Play#1 1 ms   minesweeper (#130) stopped at 11,-5
     Play#1 output Play#1 1 ms   minesweeper (#131) stopped at 11,-5
     Play#1 input march 0/2 mh
     Play#1 command march
     Play#1 output Play#1 1 Leader is cav  cavalry #0
-    Play#1 output Play#1 1 cav  cavalry #0 is not an engineer!
-    Play#1 output Play#1 1 spy  infiltrator #2 is not an engineer!
+    Play#1 output Play#1 1 No engineers!
     Play#1 output Play#1 1 cav  cavalry #0 stopped at 1,1
     Play#1 output Play#1 1 spy  infiltrator #2 stopped at 1,1
     Play#1 output Play#1 6 0 550
     Play#1 input march 120 mh
     Play#1 command march
     Play#1 output Play#1 1 Leader is eng  engineer #120
-    Play#1 output Play#1 1 eng  engineer #120 is in a bridge span sector.  No landmines there!
+    Play#1 output Play#1 1 2,0 is a bridge span.  No landmines there!
     Play#1 output Play#1 1 eng  engineer #120 stopped at 2,0
     Play#1 output Play#1 6 0 549
     Play#1 input march 121/128 j
     Play#1 output Play#1 1  m m
     Play#1 output Play#1 4 <104.7:86.0: 8,6>
     Play#1 input mmmh
-    Play#1 output Play#1 1 cav  cavalry #135 is not an engineer!
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
-    Play#1 output Play#1 1 cav  cavalry #136 is not an engineer!
-    Play#1 output Play#1 1 cav  cavalry #137 is not an engineer!
-    Play#1 output Play#1 1 cav  cavalry #138 is not an engineer!
-    Play#1 output Play#1 1 cav  cavalry #139 is not an engineer!
-    Play#1 output Play#1 1 cav  cavalry #135 is not an engineer!
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Blammo! Landmines detected in 8,6!
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
-    Play#1 output Play#1 1 cav  cavalry #136 is not an engineer!
-    Play#1 output Play#1 1 cav  cavalry #137 is not an engineer!
-    Play#1 output Play#1 1 cav  cavalry #138 is not an engineer!
-    Play#1 output Play#1 1 cav  cavalry #139 is not an engineer!
-    Play#1 output Play#1 1 cav  cavalry #135 is not an engineer!
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
     Play#1 output Play#1 1 Sweep...
-    Play#1 output Play#1 1 cav  cavalry #136 is not an engineer!
-    Play#1 output Play#1 1 cav  cavalry #137 is not an engineer!
-    Play#1 output Play#1 1 cav  cavalry #138 is not an engineer!
-    Play#1 output Play#1 1 cav  cavalry #139 is not an engineer!
     Play#1 output Play#1 1 cav  cavalry #135 stopped at 8,6
     Play#1 output Play#1 1 eng  engineer #130 stopped at 8,6
     Play#1 output Play#1 1 eng  engineer #131 stopped at 8,6