Fix travel moving player back and forth infinitely
This fixes a bug where hundreds of turns are wasted by the travel system moving the player back and forth when the player targets an unreachable space and sight-blocking obstacles occur in certain formations in-between. The player will only be stopped if they're interrupted externally, e.g. growing hungry or being hit by a monster. See the comment in the code for full details. Based on DynaHack commit 02da53e (Fix travel moving player back and forth repeatedly) by me.
This commit is contained in:
37
src/hack.c
37
src/hack.c
@@ -929,7 +929,42 @@ boolean guess;
|
||||
int nx = x + xdir[ordered[dir]];
|
||||
int ny = y + ydir[ordered[dir]];
|
||||
|
||||
if (!isok(nx, ny))
|
||||
/*
|
||||
* When guessing and trying to travel as close as possible
|
||||
* to an unreachable target space, don't include spaces
|
||||
* that would never be picked as a guessed target in the
|
||||
* travel matrix describing player-reachable spaces.
|
||||
* This stops travel from getting confused and moving the
|
||||
* player back and forth in certain degenerate configurations
|
||||
* of sight-blocking obstacles, e.g.
|
||||
*
|
||||
* T 1. Dig this out and carry enough to not be
|
||||
* #### able to squeeze through diagonal gaps.
|
||||
* #--.--- Stand at @ and target travel at space T.
|
||||
* @.....
|
||||
* |.....
|
||||
*
|
||||
* T 2. couldsee() marks spaces marked a and x as
|
||||
* #### eligible guess spaces to move the player
|
||||
* a--.--- towards. Space a is closest to T, so it gets
|
||||
* @xxxxx chosen. Travel system moves @ right to travel
|
||||
* |xxxxx to space a.
|
||||
*
|
||||
* T 3. couldsee() marks spaces marked b, c and x
|
||||
* #### as eligible guess spaces to move the player
|
||||
* a--c--- towards. Since findtravelpath() is called
|
||||
* b@xxxx repeatedly during travel, it doesn't remember
|
||||
* |xxxxx that it wanted to go to space a, so in
|
||||
* comparing spaces b and c, b is chosen, since
|
||||
* it seems like the closest eligible space to T.
|
||||
* Travel system moves @ left to go to space b.
|
||||
*
|
||||
* 4. Go to 2.
|
||||
*
|
||||
* By limiting the travel matrix here, space a in the example
|
||||
* above is never included in it, preventing the cycle.
|
||||
*/
|
||||
if (!isok(nx, ny) || (guess && !couldsee(nx, ny)))
|
||||
continue;
|
||||
if ((!Passes_walls && !can_ooze(&youmonst)
|
||||
&& closed_door(x, y)) || sobj_at(BOULDER, x, y)
|
||||
|
||||
Reference in New Issue
Block a user