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 */
|
/* hack.c */
|
||||||
anything tmp_anything;
|
anything tmp_anything;
|
||||||
int wc; /* current weight_cap(); valid after call to inv_weight() */
|
int wc; /* current weight_cap(); valid after call to inv_weight() */
|
||||||
|
struct selectionvar *travelmap;
|
||||||
|
|
||||||
/* insight.c */
|
/* insight.c */
|
||||||
|
|
||||||
|
|||||||
@@ -466,8 +466,7 @@ moveloop_core(void)
|
|||||||
}
|
}
|
||||||
if (g.context.mv) {
|
if (g.context.mv) {
|
||||||
if (g.multi < COLNO && !--g.multi)
|
if (g.multi < COLNO && !--g.multi)
|
||||||
g.context.travel = g.context.travel1 = g.context.mv =
|
end_running(TRUE);
|
||||||
g.context.run = 0;
|
|
||||||
domove();
|
domove();
|
||||||
} else {
|
} else {
|
||||||
--g.multi;
|
--g.multi;
|
||||||
|
|||||||
@@ -3855,6 +3855,10 @@ reset_cmd_vars(boolean reset_cmdq)
|
|||||||
g.multi = 0;
|
g.multi = 0;
|
||||||
iflags.menu_requested = FALSE;
|
iflags.menu_requested = FALSE;
|
||||||
g.context.travel = g.context.travel1 = 0;
|
g.context.travel = g.context.travel1 = 0;
|
||||||
|
if (g.travelmap) {
|
||||||
|
selection_free(g.travelmap, TRUE);
|
||||||
|
g.travelmap = NULL;
|
||||||
|
}
|
||||||
if (reset_cmdq)
|
if (reset_cmdq)
|
||||||
cmdq_clear();
|
cmdq_clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -422,8 +422,9 @@ const struct instance_globals g_init = {
|
|||||||
|
|
||||||
|
|
||||||
/* hack.c */
|
/* hack.c */
|
||||||
UNDEFINED_VALUES,
|
UNDEFINED_VALUES, /* tmp_anything */
|
||||||
UNDEFINED_VALUE,
|
UNDEFINED_VALUE, /* wc */
|
||||||
|
NULL, /* travelmap */
|
||||||
|
|
||||||
/* invent.c */
|
/* invent.c */
|
||||||
51, /* lastinvr */
|
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
|
* A shortest path is returned. If guess is TRUE, consider various
|
||||||
* inaccessible locations as valid intermediate path points.
|
* inaccessible locations as valid intermediate path points.
|
||||||
* Returns TRUE if a path was found.
|
* 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
|
static boolean
|
||||||
findtravelpath(int mode)
|
findtravelpath(int mode)
|
||||||
{
|
{
|
||||||
|
if (!g.travelmap)
|
||||||
|
g.travelmap = selection_new();
|
||||||
/* if travel to adjacent, reachable location, use normal movement rules */
|
/* if travel to adjacent, reachable location, use normal movement rules */
|
||||||
if ((mode == TRAVP_TRAVEL || mode == TRAVP_VALID) && g.context.travel1
|
if ((mode == TRAVP_TRAVEL || mode == TRAVP_VALID) && g.context.travel1
|
||||||
/* was '&& distmin(u.ux, u.uy, u.tx, u.ty) == 1' */
|
/* 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 set = 0; /* two sets current and previous */
|
||||||
int radius = 1; /* search radius */
|
int radius = 1; /* search radius */
|
||||||
int i;
|
int i;
|
||||||
xchar guessx = -1, guessy = -1;
|
|
||||||
|
|
||||||
/* If guessing, first find an "obvious" goal location. The obvious
|
/* If guessing, first find an "obvious" goal location. The obvious
|
||||||
* goal is the position the player knows of, or might figure out
|
* goal is the position the player knows of, or might figure out
|
||||||
@@ -1229,19 +1232,21 @@ findtravelpath(int mode)
|
|||||||
|| (!Blind && couldsee(nx, ny)))) {
|
|| (!Blind && couldsee(nx, ny)))) {
|
||||||
if (nx == ux && ny == uy) {
|
if (nx == ux && ny == uy) {
|
||||||
if (mode == TRAVP_TRAVEL || mode == TRAVP_VALID) {
|
if (mode == TRAVP_TRAVEL || mode == TRAVP_VALID) {
|
||||||
|
boolean visited =
|
||||||
|
selection_getpoint(x, y, g.travelmap);
|
||||||
u.dx = x - ux;
|
u.dx = x - ux;
|
||||||
u.dy = y - uy;
|
u.dy = y - uy;
|
||||||
if (mode == TRAVP_TRAVEL
|
if (mode == TRAVP_TRAVEL
|
||||||
&& ((x == u.tx && y == u.ty)
|
&& ((x == u.tx && y == u.ty) || visited)) {
|
||||||
|| (x == guessx && y == guessy))) {
|
|
||||||
nomul(0);
|
nomul(0);
|
||||||
/* reset run so domove run checks work */
|
/* reset run so domove run checks work */
|
||||||
g.context.run = 8;
|
g.context.run = 8;
|
||||||
if (x == guessx && y == guessy)
|
if (visited)
|
||||||
You("stop, unsure which way to go.");
|
You("stop, unsure which way to go.");
|
||||||
else
|
else
|
||||||
iflags.travelcc.x = iflags.travelcc.y = 0;
|
iflags.travelcc.x = iflags.travelcc.y = 0;
|
||||||
}
|
}
|
||||||
|
selection_setpoint(u.ux, u.uy, g.travelmap, 1);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
} else if (!travel[nx][ny]) {
|
} else if (!travel[nx][ny]) {
|
||||||
@@ -1309,8 +1314,10 @@ findtravelpath(int mode)
|
|||||||
/* no guesses, just go in the general direction */
|
/* no guesses, just go in the general direction */
|
||||||
u.dx = sgn(u.tx - u.ux);
|
u.dx = sgn(u.tx - u.ux);
|
||||||
u.dy = sgn(u.ty - u.uy);
|
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;
|
return TRUE;
|
||||||
|
}
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@@ -1332,8 +1339,6 @@ findtravelpath(int mode)
|
|||||||
ty = py;
|
ty = py;
|
||||||
ux = u.ux;
|
ux = u.ux;
|
||||||
uy = u.uy;
|
uy = u.uy;
|
||||||
guessx = u.ux - u.dx;
|
|
||||||
guessy = u.uy - u.dy;
|
|
||||||
set = 0;
|
set = 0;
|
||||||
n = radius = 1;
|
n = radius = 1;
|
||||||
mode = TRAVP_TRAVEL;
|
mode = TRAVP_TRAVEL;
|
||||||
@@ -3439,7 +3444,11 @@ end_running(boolean and_travel)
|
|||||||
all clear it too */
|
all clear it too */
|
||||||
if (and_travel)
|
if (and_travel)
|
||||||
g.context.travel = g.context.travel1 = g.context.mv = 0;
|
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)
|
if (g.multi > 0)
|
||||||
g.multi = 0;
|
g.multi = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user