Fix stuck travel for good
My fixes to the travel stuck oscillation did not fix all of them, and I've even seen a 3-step loop - which my fixes cannot detect. I guess there could be arbitrary-sized loops too. To definitely fix this, keep track of all the map locations travel has moved the hero through, and if it tries to go on a location already used, stop travel and give the unsure -message.
This commit is contained in:
@@ -938,6 +938,7 @@ struct instance_globals {
|
||||
/* hack.c */
|
||||
anything tmp_anything;
|
||||
int wc; /* current weight_cap(); valid after call to inv_weight() */
|
||||
struct selectionvar *travelmap;
|
||||
|
||||
/* insight.c */
|
||||
|
||||
|
||||
@@ -466,8 +466,7 @@ moveloop_core(void)
|
||||
}
|
||||
if (g.context.mv) {
|
||||
if (g.multi < COLNO && !--g.multi)
|
||||
g.context.travel = g.context.travel1 = g.context.mv =
|
||||
g.context.run = 0;
|
||||
end_running(TRUE);
|
||||
domove();
|
||||
} else {
|
||||
--g.multi;
|
||||
|
||||
@@ -3855,6 +3855,10 @@ reset_cmd_vars(boolean reset_cmdq)
|
||||
g.multi = 0;
|
||||
iflags.menu_requested = FALSE;
|
||||
g.context.travel = g.context.travel1 = 0;
|
||||
if (g.travelmap) {
|
||||
selection_free(g.travelmap, TRUE);
|
||||
g.travelmap = NULL;
|
||||
}
|
||||
if (reset_cmdq)
|
||||
cmdq_clear();
|
||||
}
|
||||
|
||||
@@ -422,8 +422,9 @@ const struct instance_globals g_init = {
|
||||
|
||||
|
||||
/* hack.c */
|
||||
UNDEFINED_VALUES,
|
||||
UNDEFINED_VALUE,
|
||||
UNDEFINED_VALUES, /* tmp_anything */
|
||||
UNDEFINED_VALUE, /* wc */
|
||||
NULL, /* travelmap */
|
||||
|
||||
/* invent.c */
|
||||
51, /* lastinvr */
|
||||
|
||||
25
src/hack.c
25
src/hack.c
@@ -1094,10 +1094,14 @@ test_move(int ux, int uy, int dx, int dy, int mode)
|
||||
* A shortest path is returned. If guess is TRUE, consider various
|
||||
* inaccessible locations as valid intermediate path points.
|
||||
* Returns TRUE if a path was found.
|
||||
* g.travelmap keeps track of map locations we've moved through
|
||||
* this travel session. It will be cleared once the travel stops.
|
||||
*/
|
||||
static boolean
|
||||
findtravelpath(int mode)
|
||||
{
|
||||
if (!g.travelmap)
|
||||
g.travelmap = selection_new();
|
||||
/* if travel to adjacent, reachable location, use normal movement rules */
|
||||
if ((mode == TRAVP_TRAVEL || mode == TRAVP_VALID) && g.context.travel1
|
||||
/* was '&& distmin(u.ux, u.uy, u.tx, u.ty) == 1' */
|
||||
@@ -1126,7 +1130,6 @@ findtravelpath(int mode)
|
||||
int set = 0; /* two sets current and previous */
|
||||
int radius = 1; /* search radius */
|
||||
int i;
|
||||
xchar guessx = -1, guessy = -1;
|
||||
|
||||
/* If guessing, first find an "obvious" goal location. The obvious
|
||||
* goal is the position the player knows of, or might figure out
|
||||
@@ -1229,19 +1232,21 @@ findtravelpath(int mode)
|
||||
|| (!Blind && couldsee(nx, ny)))) {
|
||||
if (nx == ux && ny == uy) {
|
||||
if (mode == TRAVP_TRAVEL || mode == TRAVP_VALID) {
|
||||
boolean visited =
|
||||
selection_getpoint(x, y, g.travelmap);
|
||||
u.dx = x - ux;
|
||||
u.dy = y - uy;
|
||||
if (mode == TRAVP_TRAVEL
|
||||
&& ((x == u.tx && y == u.ty)
|
||||
|| (x == guessx && y == guessy))) {
|
||||
&& ((x == u.tx && y == u.ty) || visited)) {
|
||||
nomul(0);
|
||||
/* reset run so domove run checks work */
|
||||
g.context.run = 8;
|
||||
if (x == guessx && y == guessy)
|
||||
if (visited)
|
||||
You("stop, unsure which way to go.");
|
||||
else
|
||||
iflags.travelcc.x = iflags.travelcc.y = 0;
|
||||
}
|
||||
selection_setpoint(u.ux, u.uy, g.travelmap, 1);
|
||||
return TRUE;
|
||||
}
|
||||
} else if (!travel[nx][ny]) {
|
||||
@@ -1309,8 +1314,10 @@ findtravelpath(int mode)
|
||||
/* no guesses, just go in the general direction */
|
||||
u.dx = sgn(u.tx - u.ux);
|
||||
u.dy = sgn(u.ty - u.uy);
|
||||
if (test_move(u.ux, u.uy, u.dx, u.dy, TEST_MOVE))
|
||||
if (test_move(u.ux, u.uy, u.dx, u.dy, TEST_MOVE)) {
|
||||
selection_setpoint(u.ux, u.uy, g.travelmap, 1);
|
||||
return TRUE;
|
||||
}
|
||||
goto found;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
@@ -1332,8 +1339,6 @@ findtravelpath(int mode)
|
||||
ty = py;
|
||||
ux = u.ux;
|
||||
uy = u.uy;
|
||||
guessx = u.ux - u.dx;
|
||||
guessy = u.uy - u.dy;
|
||||
set = 0;
|
||||
n = radius = 1;
|
||||
mode = TRAVP_TRAVEL;
|
||||
@@ -3439,7 +3444,11 @@ 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.travelmap) {
|
||||
selection_free(g.travelmap, TRUE);
|
||||
g.travelmap = NULL;
|
||||
}
|
||||
/* cancel multi */
|
||||
if (g.multi > 0)
|
||||
g.multi = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user