From: Pasi Kallinen Date: Sat, 2 Apr 2022 15:16:19 +0000 (+0300) Subject: Fix stuck travel for good X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6977aef436bc338c82e28f66364f6dcad499bdfa;p=nethack 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. --- diff --git a/include/decl.h b/include/decl.h index 4b69f03f8..c0a50aff3 100644 --- a/include/decl.h +++ b/include/decl.h @@ -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 */ diff --git a/src/allmain.c b/src/allmain.c index d13d86160..2b637509b 100644 --- a/src/allmain.c +++ b/src/allmain.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; diff --git a/src/cmd.c b/src/cmd.c index d5a6d642d..2821bab5d 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -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(); } diff --git a/src/decl.c b/src/decl.c index 8a1777084..88602704c 100644 --- a/src/decl.c +++ b/src/decl.c @@ -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 */ diff --git a/src/hack.c b/src/hack.c index 4096bc71b..e10c2a144 100644 --- a/src/hack.c +++ b/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; }