From: PatR Date: Mon, 5 Apr 2021 00:23:46 +0000 (-0700) Subject: fix pull request #487 - one-step diagonal travel X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7d77267f930f2f7d7cb52c2518f9edf66a5b17ff;p=nethack fix pull request #487 - one-step diagonal travel 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 --- diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 7d0f52210..b74a0cae4 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -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 diff --git a/src/hack.c b/src/hack.c index 4e1aa363a..5422e4a03 100644 --- a/src/hack.c +++ b/src/hack.c @@ -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 */ +/* used by drown() to check whether hero can crawl from water to ; + 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; }