]> granicus.if.org Git - nethack/commitdiff
U453 and buglist item - travel command updates
authorcohrs <cohrs>
Tue, 21 Oct 2003 02:27:43 +0000 (02:27 +0000)
committercohrs <cohrs>
Tue, 21 Oct 2003 02:27:43 +0000 (02:27 +0000)
I wrote to the devteam early last week:
> Given my understanding of travel, it's supposed to be somewhat intelligent,
> and "convenient", and should, therefore avoid walking into water, lava,
> traps, or other things that distant movement would avoid, even if you're
> right next it.  Unless...  the travel destination is the "bad" location
> next to you when the travel starts.
To that end...
- add a context (iflags in 3.4.3 to maintain savefile compat) flag to
differenciate the first travel step from later steps, to allow the
detection of the final sentence, above.
- several changes to set/reset the travel1 flag as needed
- add code to findtravelpath to treat the first step specially if it's
the only step, allowing forced travel into a "bad" location
- correct the "don't travel over traps" code, which was getting confused
because hero's starting location was being avoided
- add code to avoid traveling into water and lava, duplicating
checks used for non-travel running
- fix some strange "guess" travel behavior: avoid zigzag paths when there's
a more direct path (even though the number of moves is the same)
- trunk change adds a new DISP_ALL tmp_at type, and uses it in some debug
code for travel, debug changes not added to the 3.4.3 branch

doc/fixes34.3
include/context.h
include/display.h
src/allmain.c
src/cmd.c
src/display.c
src/hack.c

index 99bfc4904972b105c51602c05b16cc221fc5c6a2..df3749c64d53b06a90cac98523afd3c7725ca65c 100644 (file)
@@ -61,6 +61,8 @@ allow a crystal ball to detect ghosts-and-shades via space key,  and display
 allow a crystal ball to detect boulders using the user-defined boulder symbol
 allow a crystal ball to detect mimics via ']'
 prevent boulder option from accepting a symbol that matches a monster symbol
+traveling while standing on a trap would sometime step in the wrong direction
+avoid traveling into water/lava, using usual running rules
 
 
 Platform- and/or Interface-Specific Fixes
index 2a233fa85c950a1eecc5c3ee95ff8c5629d2f447..3cf517002955640fcbe2b350d80d5105c93a2420 100644 (file)
@@ -77,6 +77,7 @@ struct context_info {
        long stethoscope_move;
        short stethoscope_movement;
        boolean  travel;        /* find way automatically to u.tx,u.ty */
+       boolean  travel1;       /* first travel step */
        boolean  forcefight;
        boolean  nopick;        /* do not pickup objects (as when running) */
        boolean  made_amulet;
index a6e7bd7232dd5e37f7609e10d4280df559f5c100..093859dd8d305a8e048f68f5613ac0db4e5ca2dc 100644 (file)
  * tmp_at() control calls.
  */
 #define DISP_BEAM    (-1)  /* Keep all glyphs showing & clean up at end. */
-#define DISP_FLASH   (-2)  /* Clean up each glyph before displaying new one. */
-#define DISP_ALWAYS  (-3)  /* Like flash, but still displayed if not visible. */
-#define DISP_CHANGE  (-4)  /* Change glyph. */
-#define DISP_END     (-5)  /* Clean up. */
-#define DISP_FREEMEM (-6)  /* Free all memory during exit only. */
+#define DISP_ALL     (-2)  /* Like beam, but still displayed if not visible. */
+#define DISP_FLASH   (-3)  /* Clean up each glyph before displaying new one. */
+#define DISP_ALWAYS  (-4)  /* Like flash, but still displayed if not visible. */
+#define DISP_CHANGE  (-5)  /* Change glyph. */
+#define DISP_END     (-6)  /* Clean up. */
+#define DISP_FREEMEM (-7)  /* Free all memory during exit only. */
 
 
 /* Total number of cmap indices in the sheild_static[] array. */
index 8d30d38797d3e0cfb3dfe9e07dd07b96d5cd1c2c..366787be615c4ae92893976d1e157c31bc7b275a 100644 (file)
@@ -393,7 +393,8 @@ moveloop()
            }
            if (context.mv) {
                if(multi < COLNO && !--multi)
-                   context.travel = context.mv = context.run = 0;
+                   context.travel = context.travel1 =
+                       context.mv = context.run = 0;
                domove();
            } else {
                --multi;
index 9a60d8f53b78cb7ea788b16c1958f149c9c5a07d..7146f406e2e2d24f57094803f911adbf486c8688 100644 (file)
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -1845,7 +1845,7 @@ register char *cmd;
         }
        /* handle most movement commands */
        do_walk = do_rush = prefix_seen = FALSE;
-       context.travel = 0;
+       context.travel = context.travel1 = 0;
        switch (*cmd) {
         case 'g':  if (movecmd(cmd[1])) {
                        context.run = 2;
@@ -1901,6 +1901,7 @@ register char *cmd;
         case CMD_TRAVEL:
                    if (flags.travelcmd) {
                            context.travel = 1;
+                           context.travel1 = 1;
                            context.run = 8;
                            context.nopick = 1;
                            do_rush = TRUE;
index 3389e9edfb51d259ac509f1ba3d5740b829aaee2..64e34d8dbf90c713000f8b368997d0edd9b25b76 100644 (file)
@@ -834,6 +834,7 @@ tmp_at(x, y)
 
     switch (x) {
        case DISP_BEAM:
+       case DISP_ALL:
        case DISP_FLASH:
        case DISP_ALWAYS:
            if (!tglyph)
@@ -868,7 +869,7 @@ tmp_at(x, y)
            break;
 
        case DISP_END:
-           if (tglyph->style == DISP_BEAM) {
+           if (tglyph->style == DISP_BEAM || tglyph->style == DISP_ALL) {
                register int i;
 
                /* Erase (reset) from source to end */
@@ -885,8 +886,9 @@ tmp_at(x, y)
            break;
 
        default:        /* do it */
-           if (tglyph->style == DISP_BEAM) {
-               if (!cansee(x,y)) break;
+           if (tglyph->style == DISP_BEAM || tglyph->style == DISP_ALL) {
+               if (tglyph->style != DISP_ALL && !cansee(x,y)) break;
+               if (tglyph->sidx >= COLNO) break; /* too many locations */
                /* save pos for later erasing */
                tglyph->saved[tglyph->sidx].x = x;
                tglyph->saved[tglyph->sidx].y = y;
index 51f5c9d02f97c8ffb58118b8fbb6999ac54d503d..4c850e5cabc36bf987820f1e2991e1eec59cafff 100644 (file)
@@ -4,6 +4,8 @@
 
 #include "hack.h"
 
+/* #define DEBUG */    /* uncomment for debugging */
+
 STATIC_DCL void NDECL(maybe_wail);
 STATIC_DCL int NDECL(moverock);
 STATIC_DCL int FDECL(still_chewing,(XCHAR_P,XCHAR_P));
@@ -633,11 +635,17 @@ int mode;
            return FALSE;
        }
     }
-    /* pick a path that does not require crossing a trap */
-    if (context.run == 8 && mode != DO_MOVE) {
+    /* Pick travel path that does not require crossing a trap.
+     * Avoid water and lava using the usual running rules.
+     * (but not u.ux/u.uy because findtravelpath walks toward u.ux/u.uy) */
+    if (context.run == 8 && mode != DO_MOVE && (x != u.ux || y != u.uy)) {
        struct trap* t = t_at(x, y);
 
-       if (t && t->tseen) return FALSE;
+       if ((t && t->tseen) ||
+           (!Levitation && !Flying &&
+            !is_clinger(youmonst.data) &&
+            (is_pool(x, y) || is_lava(x, y)) && levl[x][y].seenv))
+           return FALSE;
     }
 
     ust = &levl[ux][uy];
@@ -684,6 +692,17 @@ int mode;
     return TRUE;
 }
 
+#ifdef DEBUG
+static boolean trav_debug = FALSE;
+
+int
+wiz_debug_cmd() /* in this case, toggle display of travel debug info */
+{
+       trav_debug = !trav_debug;
+       return 0;
+}
+#endif /* DEBUG */
+
 /*
  * Find a path from the destination (u.tx,u.ty) back to (u.ux,u.uy).
  * A shortest path is returned.  If guess is TRUE, consider various
@@ -694,6 +713,18 @@ static boolean
 findtravelpath(guess)
 boolean guess;
 {
+    /* if travel to adjacent, reachable location, use normal movement rules */
+    if (!guess && context.travel1 && distmin(u.ux, u.uy, u.tx, u.ty) == 1) {
+       context.run = 0;
+       if (test_move(u.ux, u.uy, u.tx-u.ux, u.ty-u.uy, TEST_MOVE)) {
+           u.dx = u.tx-u.ux;
+           u.dy = u.ty-u.uy;
+           nomul(0);
+           iflags.travelcc.x = iflags.travelcc.y = -1;
+           return TRUE;
+       }
+       context.run = 8;
+    }
     if (u.tx != u.ux || u.ty != u.uy) {
        xchar travel[COLNO][ROWNO];
        xchar travelstepx[2][COLNO*ROWNO];
@@ -770,7 +801,23 @@ boolean guess;
                    }
                }
            }
-           
+
+#ifdef DEBUG
+           if (trav_debug) {
+               /* Use of warning glyph is arbitrary. It stands out. */
+               tmp_at(DISP_ALL, warning_to_glyph(1));
+               for (i = 0; i < nn; ++i) {
+                   tmp_at(travelstepx[1-set][i], travelstepy[1-set][i]);
+               }
+               delay_output();
+               if (flags.runmode == RUN_CRAWL) {
+                   delay_output();
+                   delay_output();
+               }
+               tmp_at(DISP_END,0);
+           }
+#endif /* DEBUG */
+
            n = nn;
            set = 1-set;
            radius++;
@@ -779,15 +826,25 @@ boolean guess;
        /* if guessing, find best location in travel matrix and go there */
        if (guess) {
            int px = tx, py = ty;       /* pick location */
-           int dist, nxtdist;
+           int dist, nxtdist, d2, nd2;
 
            dist = distmin(ux, uy, tx, ty);
+           d2 = dist2(ux, uy, tx, ty);
            for (tx = 1; tx < COLNO; ++tx)
                for (ty = 0; ty < ROWNO; ++ty)
                    if (travel[tx][ty]) {
                        nxtdist = distmin(ux, uy, tx, ty);
-                       if (nxtdist < dist && couldsee(tx, ty)) {
-                           px = tx; py = ty; dist = nxtdist;
+                       if (nxtdist == dist && couldsee(tx, ty)) {
+                           nd2 = dist2(ux, uy, tx, ty);
+                           if (nd2 < d2) {
+                               /* prefer non-zigzag path */
+                               px = tx; py = ty;
+                               d2 = nd2;
+                           }
+                       } else if (nxtdist < dist && couldsee(tx, ty)) {
+                           px = tx; py = ty;
+                           dist = nxtdist;
+                           d2 = dist2(ux, uy, tx, ty);
                        }
                    }
 
@@ -799,6 +856,21 @@ boolean guess;
                    return TRUE;
                goto found;
            }
+#ifdef DEBUG
+           if (trav_debug) {
+               /* Use of warning glyph is arbitrary. It stands out. */
+               tmp_at(DISP_ALL, warning_to_glyph(2));
+               tmp_at(px, py);
+               delay_output();
+               if (flags.runmode == RUN_CRAWL) {
+                   delay_output();
+                   delay_output();
+                   delay_output();
+                   delay_output();
+               }
+               tmp_at(DISP_END,0);
+           }
+#endif /* DEBUG */
            tx = px;
            ty = py;
            ux = u.ux;
@@ -834,9 +906,11 @@ domove()
 
        u_wipe_engr(rnd(5));
 
-       if (context.travel)
+       if (context.travel) {
            if (!findtravelpath(FALSE))
                (void) findtravelpath(TRUE);
+           context.travel1 = 0;
+       }
 
        if(((wtcap = near_capacity()) >= OVERLOADED
            || (wtcap > SLT_ENCUMBER &&
@@ -2038,7 +2112,7 @@ nomul(nval)
        u.uinvulnerable = FALSE;        /* Kludge to avoid ctrl-C bug -dlc */
        u.usleep = 0;
        multi = nval;
-       context.travel = context.mv = context.run = 0;
+       context.travel = context.travel1 = context.mv = context.run = 0;
 }
 
 /* called when a non-movement, multi-turn action has completed */