U453 and buglist item - travel command updates
I wrote to the devteam early last week: > Given my understanding of travel, it's supposed to be somewhat intelligent, > and "convenient", and should, therefore avoid walking into water, lava, > traps, or other things that distant movement would avoid, even if you're > right next it. Unless... the travel destination is the "bad" location > next to you when the travel starts. To that end... - add a context (iflags in 3.4.3 to maintain savefile compat) flag to differenciate the first travel step from later steps, to allow the detection of the final sentence, above. - several changes to set/reset the travel1 flag as needed - add code to findtravelpath to treat the first step specially if it's the only step, allowing forced travel into a "bad" location - correct the "don't travel over traps" code, which was getting confused because hero's starting location was being avoided - add code to avoid traveling into water and lava, duplicating checks used for non-travel running - fix some strange "guess" travel behavior: avoid zigzag paths when there's a more direct path (even though the number of moves is the same) - trunk change adds a new DISP_ALL tmp_at type, and uses it in some debug code for travel, debug changes not added to the 3.4.3 branch
This commit is contained in:
@@ -61,6 +61,8 @@ allow a crystal ball to detect ghosts-and-shades via space key, and display
|
|||||||
allow a crystal ball to detect boulders using the user-defined boulder symbol
|
allow a crystal ball to detect boulders using the user-defined boulder symbol
|
||||||
allow a crystal ball to detect mimics via ']'
|
allow a crystal ball to detect mimics via ']'
|
||||||
prevent boulder option from accepting a symbol that matches a monster symbol
|
prevent boulder option from accepting a symbol that matches a monster symbol
|
||||||
|
traveling while standing on a trap would sometime step in the wrong direction
|
||||||
|
avoid traveling into water/lava, using usual running rules
|
||||||
|
|
||||||
|
|
||||||
Platform- and/or Interface-Specific Fixes
|
Platform- and/or Interface-Specific Fixes
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ struct context_info {
|
|||||||
long stethoscope_move;
|
long stethoscope_move;
|
||||||
short stethoscope_movement;
|
short stethoscope_movement;
|
||||||
boolean travel; /* find way automatically to u.tx,u.ty */
|
boolean travel; /* find way automatically to u.tx,u.ty */
|
||||||
|
boolean travel1; /* first travel step */
|
||||||
boolean forcefight;
|
boolean forcefight;
|
||||||
boolean nopick; /* do not pickup objects (as when running) */
|
boolean nopick; /* do not pickup objects (as when running) */
|
||||||
boolean made_amulet;
|
boolean made_amulet;
|
||||||
|
|||||||
@@ -175,11 +175,12 @@
|
|||||||
* tmp_at() control calls.
|
* tmp_at() control calls.
|
||||||
*/
|
*/
|
||||||
#define DISP_BEAM (-1) /* Keep all glyphs showing & clean up at end. */
|
#define DISP_BEAM (-1) /* Keep all glyphs showing & clean up at end. */
|
||||||
#define DISP_FLASH (-2) /* Clean up each glyph before displaying new one. */
|
#define DISP_ALL (-2) /* Like beam, but still displayed if not visible. */
|
||||||
#define DISP_ALWAYS (-3) /* Like flash, but still displayed if not visible. */
|
#define DISP_FLASH (-3) /* Clean up each glyph before displaying new one. */
|
||||||
#define DISP_CHANGE (-4) /* Change glyph. */
|
#define DISP_ALWAYS (-4) /* Like flash, but still displayed if not visible. */
|
||||||
#define DISP_END (-5) /* Clean up. */
|
#define DISP_CHANGE (-5) /* Change glyph. */
|
||||||
#define DISP_FREEMEM (-6) /* Free all memory during exit only. */
|
#define DISP_END (-6) /* Clean up. */
|
||||||
|
#define DISP_FREEMEM (-7) /* Free all memory during exit only. */
|
||||||
|
|
||||||
|
|
||||||
/* Total number of cmap indices in the sheild_static[] array. */
|
/* Total number of cmap indices in the sheild_static[] array. */
|
||||||
|
|||||||
@@ -393,7 +393,8 @@ moveloop()
|
|||||||
}
|
}
|
||||||
if (context.mv) {
|
if (context.mv) {
|
||||||
if(multi < COLNO && !--multi)
|
if(multi < COLNO && !--multi)
|
||||||
context.travel = context.mv = context.run = 0;
|
context.travel = context.travel1 =
|
||||||
|
context.mv = context.run = 0;
|
||||||
domove();
|
domove();
|
||||||
} else {
|
} else {
|
||||||
--multi;
|
--multi;
|
||||||
|
|||||||
@@ -1845,7 +1845,7 @@ register char *cmd;
|
|||||||
}
|
}
|
||||||
/* handle most movement commands */
|
/* handle most movement commands */
|
||||||
do_walk = do_rush = prefix_seen = FALSE;
|
do_walk = do_rush = prefix_seen = FALSE;
|
||||||
context.travel = 0;
|
context.travel = context.travel1 = 0;
|
||||||
switch (*cmd) {
|
switch (*cmd) {
|
||||||
case 'g': if (movecmd(cmd[1])) {
|
case 'g': if (movecmd(cmd[1])) {
|
||||||
context.run = 2;
|
context.run = 2;
|
||||||
@@ -1901,6 +1901,7 @@ register char *cmd;
|
|||||||
case CMD_TRAVEL:
|
case CMD_TRAVEL:
|
||||||
if (flags.travelcmd) {
|
if (flags.travelcmd) {
|
||||||
context.travel = 1;
|
context.travel = 1;
|
||||||
|
context.travel1 = 1;
|
||||||
context.run = 8;
|
context.run = 8;
|
||||||
context.nopick = 1;
|
context.nopick = 1;
|
||||||
do_rush = TRUE;
|
do_rush = TRUE;
|
||||||
|
|||||||
@@ -834,6 +834,7 @@ tmp_at(x, y)
|
|||||||
|
|
||||||
switch (x) {
|
switch (x) {
|
||||||
case DISP_BEAM:
|
case DISP_BEAM:
|
||||||
|
case DISP_ALL:
|
||||||
case DISP_FLASH:
|
case DISP_FLASH:
|
||||||
case DISP_ALWAYS:
|
case DISP_ALWAYS:
|
||||||
if (!tglyph)
|
if (!tglyph)
|
||||||
@@ -868,7 +869,7 @@ tmp_at(x, y)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DISP_END:
|
case DISP_END:
|
||||||
if (tglyph->style == DISP_BEAM) {
|
if (tglyph->style == DISP_BEAM || tglyph->style == DISP_ALL) {
|
||||||
register int i;
|
register int i;
|
||||||
|
|
||||||
/* Erase (reset) from source to end */
|
/* Erase (reset) from source to end */
|
||||||
@@ -885,8 +886,9 @@ tmp_at(x, y)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default: /* do it */
|
default: /* do it */
|
||||||
if (tglyph->style == DISP_BEAM) {
|
if (tglyph->style == DISP_BEAM || tglyph->style == DISP_ALL) {
|
||||||
if (!cansee(x,y)) break;
|
if (tglyph->style != DISP_ALL && !cansee(x,y)) break;
|
||||||
|
if (tglyph->sidx >= COLNO) break; /* too many locations */
|
||||||
/* save pos for later erasing */
|
/* save pos for later erasing */
|
||||||
tglyph->saved[tglyph->sidx].x = x;
|
tglyph->saved[tglyph->sidx].x = x;
|
||||||
tglyph->saved[tglyph->sidx].y = y;
|
tglyph->saved[tglyph->sidx].y = y;
|
||||||
|
|||||||
92
src/hack.c
92
src/hack.c
@@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#include "hack.h"
|
#include "hack.h"
|
||||||
|
|
||||||
|
/* #define DEBUG */ /* uncomment for debugging */
|
||||||
|
|
||||||
STATIC_DCL void NDECL(maybe_wail);
|
STATIC_DCL void NDECL(maybe_wail);
|
||||||
STATIC_DCL int NDECL(moverock);
|
STATIC_DCL int NDECL(moverock);
|
||||||
STATIC_DCL int FDECL(still_chewing,(XCHAR_P,XCHAR_P));
|
STATIC_DCL int FDECL(still_chewing,(XCHAR_P,XCHAR_P));
|
||||||
@@ -633,11 +635,17 @@ int mode;
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* pick a path that does not require crossing a trap */
|
/* Pick travel path that does not require crossing a trap.
|
||||||
if (context.run == 8 && mode != DO_MOVE) {
|
* Avoid water and lava using the usual running rules.
|
||||||
|
* (but not u.ux/u.uy because findtravelpath walks toward u.ux/u.uy) */
|
||||||
|
if (context.run == 8 && mode != DO_MOVE && (x != u.ux || y != u.uy)) {
|
||||||
struct trap* t = t_at(x, y);
|
struct trap* t = t_at(x, y);
|
||||||
|
|
||||||
if (t && t->tseen) return FALSE;
|
if ((t && t->tseen) ||
|
||||||
|
(!Levitation && !Flying &&
|
||||||
|
!is_clinger(youmonst.data) &&
|
||||||
|
(is_pool(x, y) || is_lava(x, y)) && levl[x][y].seenv))
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ust = &levl[ux][uy];
|
ust = &levl[ux][uy];
|
||||||
@@ -684,6 +692,17 @@ int mode;
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
static boolean trav_debug = FALSE;
|
||||||
|
|
||||||
|
int
|
||||||
|
wiz_debug_cmd() /* in this case, toggle display of travel debug info */
|
||||||
|
{
|
||||||
|
trav_debug = !trav_debug;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find a path from the destination (u.tx,u.ty) back to (u.ux,u.uy).
|
* Find a path from the destination (u.tx,u.ty) back to (u.ux,u.uy).
|
||||||
* A shortest path is returned. If guess is TRUE, consider various
|
* A shortest path is returned. If guess is TRUE, consider various
|
||||||
@@ -694,6 +713,18 @@ static boolean
|
|||||||
findtravelpath(guess)
|
findtravelpath(guess)
|
||||||
boolean guess;
|
boolean guess;
|
||||||
{
|
{
|
||||||
|
/* if travel to adjacent, reachable location, use normal movement rules */
|
||||||
|
if (!guess && context.travel1 && distmin(u.ux, u.uy, u.tx, u.ty) == 1) {
|
||||||
|
context.run = 0;
|
||||||
|
if (test_move(u.ux, u.uy, u.tx-u.ux, u.ty-u.uy, TEST_MOVE)) {
|
||||||
|
u.dx = u.tx-u.ux;
|
||||||
|
u.dy = u.ty-u.uy;
|
||||||
|
nomul(0);
|
||||||
|
iflags.travelcc.x = iflags.travelcc.y = -1;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
context.run = 8;
|
||||||
|
}
|
||||||
if (u.tx != u.ux || u.ty != u.uy) {
|
if (u.tx != u.ux || u.ty != u.uy) {
|
||||||
xchar travel[COLNO][ROWNO];
|
xchar travel[COLNO][ROWNO];
|
||||||
xchar travelstepx[2][COLNO*ROWNO];
|
xchar travelstepx[2][COLNO*ROWNO];
|
||||||
@@ -770,7 +801,23 @@ boolean guess;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (trav_debug) {
|
||||||
|
/* Use of warning glyph is arbitrary. It stands out. */
|
||||||
|
tmp_at(DISP_ALL, warning_to_glyph(1));
|
||||||
|
for (i = 0; i < nn; ++i) {
|
||||||
|
tmp_at(travelstepx[1-set][i], travelstepy[1-set][i]);
|
||||||
|
}
|
||||||
|
delay_output();
|
||||||
|
if (flags.runmode == RUN_CRAWL) {
|
||||||
|
delay_output();
|
||||||
|
delay_output();
|
||||||
|
}
|
||||||
|
tmp_at(DISP_END,0);
|
||||||
|
}
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
n = nn;
|
n = nn;
|
||||||
set = 1-set;
|
set = 1-set;
|
||||||
radius++;
|
radius++;
|
||||||
@@ -779,15 +826,25 @@ boolean guess;
|
|||||||
/* if guessing, find best location in travel matrix and go there */
|
/* if guessing, find best location in travel matrix and go there */
|
||||||
if (guess) {
|
if (guess) {
|
||||||
int px = tx, py = ty; /* pick location */
|
int px = tx, py = ty; /* pick location */
|
||||||
int dist, nxtdist;
|
int dist, nxtdist, d2, nd2;
|
||||||
|
|
||||||
dist = distmin(ux, uy, tx, ty);
|
dist = distmin(ux, uy, tx, ty);
|
||||||
|
d2 = dist2(ux, uy, tx, ty);
|
||||||
for (tx = 1; tx < COLNO; ++tx)
|
for (tx = 1; tx < COLNO; ++tx)
|
||||||
for (ty = 0; ty < ROWNO; ++ty)
|
for (ty = 0; ty < ROWNO; ++ty)
|
||||||
if (travel[tx][ty]) {
|
if (travel[tx][ty]) {
|
||||||
nxtdist = distmin(ux, uy, tx, ty);
|
nxtdist = distmin(ux, uy, tx, ty);
|
||||||
if (nxtdist < dist && couldsee(tx, ty)) {
|
if (nxtdist == dist && couldsee(tx, ty)) {
|
||||||
px = tx; py = ty; dist = nxtdist;
|
nd2 = dist2(ux, uy, tx, ty);
|
||||||
|
if (nd2 < d2) {
|
||||||
|
/* prefer non-zigzag path */
|
||||||
|
px = tx; py = ty;
|
||||||
|
d2 = nd2;
|
||||||
|
}
|
||||||
|
} else if (nxtdist < dist && couldsee(tx, ty)) {
|
||||||
|
px = tx; py = ty;
|
||||||
|
dist = nxtdist;
|
||||||
|
d2 = dist2(ux, uy, tx, ty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -799,6 +856,21 @@ boolean guess;
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (trav_debug) {
|
||||||
|
/* Use of warning glyph is arbitrary. It stands out. */
|
||||||
|
tmp_at(DISP_ALL, warning_to_glyph(2));
|
||||||
|
tmp_at(px, py);
|
||||||
|
delay_output();
|
||||||
|
if (flags.runmode == RUN_CRAWL) {
|
||||||
|
delay_output();
|
||||||
|
delay_output();
|
||||||
|
delay_output();
|
||||||
|
delay_output();
|
||||||
|
}
|
||||||
|
tmp_at(DISP_END,0);
|
||||||
|
}
|
||||||
|
#endif /* DEBUG */
|
||||||
tx = px;
|
tx = px;
|
||||||
ty = py;
|
ty = py;
|
||||||
ux = u.ux;
|
ux = u.ux;
|
||||||
@@ -834,9 +906,11 @@ domove()
|
|||||||
|
|
||||||
u_wipe_engr(rnd(5));
|
u_wipe_engr(rnd(5));
|
||||||
|
|
||||||
if (context.travel)
|
if (context.travel) {
|
||||||
if (!findtravelpath(FALSE))
|
if (!findtravelpath(FALSE))
|
||||||
(void) findtravelpath(TRUE);
|
(void) findtravelpath(TRUE);
|
||||||
|
context.travel1 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if(((wtcap = near_capacity()) >= OVERLOADED
|
if(((wtcap = near_capacity()) >= OVERLOADED
|
||||||
|| (wtcap > SLT_ENCUMBER &&
|
|| (wtcap > SLT_ENCUMBER &&
|
||||||
@@ -2038,7 +2112,7 @@ nomul(nval)
|
|||||||
u.uinvulnerable = FALSE; /* Kludge to avoid ctrl-C bug -dlc */
|
u.uinvulnerable = FALSE; /* Kludge to avoid ctrl-C bug -dlc */
|
||||||
u.usleep = 0;
|
u.usleep = 0;
|
||||||
multi = nval;
|
multi = nval;
|
||||||
context.travel = context.mv = context.run = 0;
|
context.travel = context.travel1 = context.mv = context.run = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called when a non-movement, multi-turn action has completed */
|
/* called when a non-movement, multi-turn action has completed */
|
||||||
|
|||||||
Reference in New Issue
Block a user