]> granicus.if.org Git - nethack/commitdiff
fix pull request #487 - one-step diagonal travel
authorPatR <rankin@nethack.org>
Mon, 5 Apr 2021 00:23:46 +0000 (17:23 -0700)
committerPatR <rankin@nethack.org>
Mon, 5 Apr 2021 00:23:46 +0000 (17:23 -0700)
When travel destination is one step away the code stops probing
for a path and reverts to normal movement, but it wasn't handling
the case where the one step was an impossible diagonal except for
hero being a grid bug.  If the situation was a diagonal that's
too narrow to squeeze through, travel would end and regular move
would fail.

I've rejected the suggested fix and done it differently, without
attempting to figure out why the change to end_running() would
have been wrong.  Clearly it was code that called end_running()
which needed to be fixed.

The test case was
 ..x|.
 ..|@.
 .....
while carrying enough that directly moving from '@' to 'x' will
not be allowed.  '@' would move one step south west and then stop
because findtravelpath() had ended travel due to single step move.
A similar case is
   ###
  |x-#-
  |0@.|
where 'x' is a doorway with intact open door and '0' is a boulder.
Prior to this fix, player would get "a boulder blocks the way" and
not move.  After, '@' will move northeast then northwest then west
to get into orthogonal position and finally south into the doorway.

Even though it definitely fixes both mentioned test cases, I won't
be surprised if this results in regressions for other situations.

Fixes #487

doc/fixes37.0
src/hack.c

index 7d0f5221086cab73d2a4bbcd08466f71247867ac..b74a0cae460dbc38848c61a250b9b0f8e75ddb4f 100644 (file)
@@ -442,6 +442,9 @@ for menustyle:full, the 'A' menu choice to auto-select everything now only
        does so if no other choices have been picked; when any have (object
        class or BUCX state or both), it auto-selects every item that matches
        those choices (so still skips the second menu) rather than every item
+using travel to move one step diagonally where that step was blocked by being
+       too narrow to squeeze through stopped travel instead of considering
+       alternate routes to the destination
 
 
 Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
index 4e1aa363aedcb0ebc78087b77a22f836039be8de..5422e4a03f37ad77ef999f8e9566ac1521a51ad3 100644 (file)
@@ -958,8 +958,10 @@ findtravelpath(int mode)
 {
     /* if travel to adjacent, reachable location, use normal movement rules */
     if ((mode == TRAVP_TRAVEL || mode == TRAVP_VALID) && g.context.travel1
-        && distmin(u.ux, u.uy, u.tx, u.ty) == 1
-        && !(u.ux != u.tx && u.uy != u.ty && NODIAG(u.umonnum))) {
+        /* was '&& distmin(u.ux, u.uy, u.tx, u.ty) == 1' */
+        && distu(u.tx, u.ty) <= 2 /* one step away */
+        /* handle restricted diagonals */
+        && crawl_destination(u.tx, u.ty)) {
         end_running(FALSE);
         if (test_move(u.ux, u.uy, u.tx - u.ux, u.ty - u.uy, TEST_MOVE)) {
             if (mode == TRAVP_TRAVEL) {
@@ -2939,7 +2941,8 @@ doorless_door(int x, int y)
     return !(lev_p->doormask & ~(D_NODOOR | D_BROKEN));
 }
 
-/* used by drown() to check whether hero can crawl from water to <x,y> */
+/* used by drown() to check whether hero can crawl from water to <x,y>;
+   also used by findtravelpath() when destination is one step away */
 boolean
 crawl_destination(int x, int y)
 {
@@ -3002,9 +3005,8 @@ end_running(boolean and_travel)
        all clear it too */
     if (and_travel)
         g.context.travel = g.context.travel1 = g.context.mv = 0;
-    
-    // Cancel mutli
-    if (g.multi > 0) 
+    /* cancel mutli */
+    if (g.multi > 0)
         g.multi = 0;
 }