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 mimics via ']'
|
||||
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
|
||||
|
||||
@@ -77,6 +77,7 @@ struct context_info {
|
||||
long stethoscope_move;
|
||||
short stethoscope_movement;
|
||||
boolean travel; /* find way automatically to u.tx,u.ty */
|
||||
boolean travel1; /* first travel step */
|
||||
boolean forcefight;
|
||||
boolean nopick; /* do not pickup objects (as when running) */
|
||||
boolean made_amulet;
|
||||
|
||||
@@ -175,11 +175,12 @@
|
||||
* tmp_at() control calls.
|
||||
*/
|
||||
#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_ALWAYS (-3) /* Like flash, but still displayed if not visible. */
|
||||
#define DISP_CHANGE (-4) /* Change glyph. */
|
||||
#define DISP_END (-5) /* Clean up. */
|
||||
#define DISP_FREEMEM (-6) /* Free all memory during exit only. */
|
||||
#define DISP_ALL (-2) /* Like beam, but still displayed if not visible. */
|
||||
#define DISP_FLASH (-3) /* Clean up each glyph before displaying new one. */
|
||||
#define DISP_ALWAYS (-4) /* Like flash, but still displayed if not visible. */
|
||||
#define DISP_CHANGE (-5) /* Change glyph. */
|
||||
#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. */
|
||||
|
||||
@@ -393,7 +393,8 @@ moveloop()
|
||||
}
|
||||
if (context.mv) {
|
||||
if(multi < COLNO && !--multi)
|
||||
context.travel = context.mv = context.run = 0;
|
||||
context.travel = context.travel1 =
|
||||
context.mv = context.run = 0;
|
||||
domove();
|
||||
} else {
|
||||
--multi;
|
||||
|
||||
@@ -1845,7 +1845,7 @@ register char *cmd;
|
||||
}
|
||||
/* handle most movement commands */
|
||||
do_walk = do_rush = prefix_seen = FALSE;
|
||||
context.travel = 0;
|
||||
context.travel = context.travel1 = 0;
|
||||
switch (*cmd) {
|
||||
case 'g': if (movecmd(cmd[1])) {
|
||||
context.run = 2;
|
||||
@@ -1901,6 +1901,7 @@ register char *cmd;
|
||||
case CMD_TRAVEL:
|
||||
if (flags.travelcmd) {
|
||||
context.travel = 1;
|
||||
context.travel1 = 1;
|
||||
context.run = 8;
|
||||
context.nopick = 1;
|
||||
do_rush = TRUE;
|
||||
|
||||
@@ -834,6 +834,7 @@ tmp_at(x, y)
|
||||
|
||||
switch (x) {
|
||||
case DISP_BEAM:
|
||||
case DISP_ALL:
|
||||
case DISP_FLASH:
|
||||
case DISP_ALWAYS:
|
||||
if (!tglyph)
|
||||
@@ -868,7 +869,7 @@ tmp_at(x, y)
|
||||
break;
|
||||
|
||||
case DISP_END:
|
||||
if (tglyph->style == DISP_BEAM) {
|
||||
if (tglyph->style == DISP_BEAM || tglyph->style == DISP_ALL) {
|
||||
register int i;
|
||||
|
||||
/* Erase (reset) from source to end */
|
||||
@@ -885,8 +886,9 @@ tmp_at(x, y)
|
||||
break;
|
||||
|
||||
default: /* do it */
|
||||
if (tglyph->style == DISP_BEAM) {
|
||||
if (!cansee(x,y)) break;
|
||||
if (tglyph->style == DISP_BEAM || tglyph->style == DISP_ALL) {
|
||||
if (tglyph->style != DISP_ALL && !cansee(x,y)) break;
|
||||
if (tglyph->sidx >= COLNO) break; /* too many locations */
|
||||
/* save pos for later erasing */
|
||||
tglyph->saved[tglyph->sidx].x = x;
|
||||
tglyph->saved[tglyph->sidx].y = y;
|
||||
|
||||
92
src/hack.c
92
src/hack.c
@@ -4,6 +4,8 @@
|
||||
|
||||
#include "hack.h"
|
||||
|
||||
/* #define DEBUG */ /* uncomment for debugging */
|
||||
|
||||
STATIC_DCL void NDECL(maybe_wail);
|
||||
STATIC_DCL int NDECL(moverock);
|
||||
STATIC_DCL int FDECL(still_chewing,(XCHAR_P,XCHAR_P));
|
||||
@@ -633,11 +635,17 @@ int mode;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/* pick a path that does not require crossing a trap */
|
||||
if (context.run == 8 && mode != DO_MOVE) {
|
||||
/* Pick travel path that does not require crossing a trap.
|
||||
* 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);
|
||||
|
||||
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];
|
||||
@@ -684,6 +692,17 @@ int mode;
|
||||
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).
|
||||
* A shortest path is returned. If guess is TRUE, consider various
|
||||
@@ -694,6 +713,18 @@ static boolean
|
||||
findtravelpath(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) {
|
||||
xchar travel[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;
|
||||
set = 1-set;
|
||||
radius++;
|
||||
@@ -779,15 +826,25 @@ boolean guess;
|
||||
/* if guessing, find best location in travel matrix and go there */
|
||||
if (guess) {
|
||||
int px = tx, py = ty; /* pick location */
|
||||
int dist, nxtdist;
|
||||
int dist, nxtdist, d2, nd2;
|
||||
|
||||
dist = distmin(ux, uy, tx, ty);
|
||||
d2 = dist2(ux, uy, tx, ty);
|
||||
for (tx = 1; tx < COLNO; ++tx)
|
||||
for (ty = 0; ty < ROWNO; ++ty)
|
||||
if (travel[tx][ty]) {
|
||||
nxtdist = distmin(ux, uy, tx, ty);
|
||||
if (nxtdist < dist && couldsee(tx, ty)) {
|
||||
px = tx; py = ty; dist = nxtdist;
|
||||
if (nxtdist == dist && couldsee(tx, ty)) {
|
||||
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;
|
||||
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;
|
||||
ty = py;
|
||||
ux = u.ux;
|
||||
@@ -834,9 +906,11 @@ domove()
|
||||
|
||||
u_wipe_engr(rnd(5));
|
||||
|
||||
if (context.travel)
|
||||
if (context.travel) {
|
||||
if (!findtravelpath(FALSE))
|
||||
(void) findtravelpath(TRUE);
|
||||
context.travel1 = 0;
|
||||
}
|
||||
|
||||
if(((wtcap = near_capacity()) >= OVERLOADED
|
||||
|| (wtcap > SLT_ENCUMBER &&
|
||||
@@ -2038,7 +2112,7 @@ nomul(nval)
|
||||
u.uinvulnerable = FALSE; /* Kludge to avoid ctrl-C bug -dlc */
|
||||
u.usleep = 0;
|
||||
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 */
|
||||
|
||||
Reference in New Issue
Block a user