From 231b2b16f8d70cc79137b79a25bce96be463b397 Mon Sep 17 00:00:00 2001 From: cohrs Date: Tue, 21 Oct 2003 02:27:43 +0000 Subject: [PATCH] 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 --- doc/fixes34.3 | 2 ++ include/context.h | 1 + include/display.h | 11 +++--- src/allmain.c | 3 +- src/cmd.c | 3 +- src/display.c | 8 +++-- src/hack.c | 92 ++++++++++++++++++++++++++++++++++++++++++----- 7 files changed, 101 insertions(+), 19 deletions(-) diff --git a/doc/fixes34.3 b/doc/fixes34.3 index 99bfc4904..df3749c64 100644 --- a/doc/fixes34.3 +++ b/doc/fixes34.3 @@ -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 diff --git a/include/context.h b/include/context.h index 2a233fa85..3cf517002 100644 --- a/include/context.h +++ b/include/context.h @@ -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; diff --git a/include/display.h b/include/display.h index a6e7bd723..093859dd8 100644 --- a/include/display.h +++ b/include/display.h @@ -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. */ diff --git a/src/allmain.c b/src/allmain.c index 8d30d3879..366787be6 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -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; diff --git a/src/cmd.c b/src/cmd.c index 9a60d8f53..7146f406e 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -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; diff --git a/src/display.c b/src/display.c index 3389e9edf..64e34d8db 100644 --- a/src/display.c +++ b/src/display.c @@ -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; diff --git a/src/hack.c b/src/hack.c index 51f5c9d02..4c850e5ca 100644 --- a/src/hack.c +++ b/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 */ -- 2.40.0