From: PatR Date: Sat, 26 Feb 2022 18:15:58 +0000 (-0800) Subject: choose_stairs() revisited X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=020d3f76d5a82064cfe5b4ca04419142c318e6cb;p=nethack choose_stairs() revisited Rewrite choose_stairs(). Use of '&& !builds_up()' was a no-op in normal branches and forced picking the down stairs/ladder in Vlad's Tower (or Sokoban) rather than reversing the usual up/down choice. Also, the logic used was backwards: Kops always surrounded the up stairs instead of the down stairs as intended. Non-Kops picked the opposite direction of what the arguments asked for but since they based their choice of up versus down on hidden mon->m_id, the reversal wasn't noticeable. Extend the choosing so that if nothing in the requested direction can be found, it tries the opposite direction. Otherwise when Vlad's m_id happens to force the direction to be 'up', he has nowhere to teleport to now that being in his Tower doesn't force 'down' anymore. He goes to down ladder when on the top level but if you level teleport to the next level down and he accompanies you, he might go to either the down ladder or the up ladder when he tries to get away from you to heal. --- diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 9e8b35ab5..2d6aa7ef9 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1067,6 +1067,8 @@ rearranging first-kill and first-hit gamelog messages to get hit before kill counting "just picked up" items when deciding what pseudo-classes should be included for the 'I' command's object class prompt was operating on an uninitialized varaible +changes to stair internals resulted in summoned Kops blockcading the stairs up + rather than intended stairs down curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/src/wizard.c b/src/wizard.c index e1d435104..89fc73a26 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -310,35 +310,41 @@ strategy(struct monst *mtmp) return dstrat; } +/* pick a destination for a covetous monster to flee to so that it can + heal or for guardians (Kops) to congregate at to block hero's progress */ void -choose_stairs(xchar *sx, xchar *sy, boolean dir) +choose_stairs( + xchar *sx, xchar *sy, /* output; left as-is if no spot found */ + boolean dir) /* True: forward, False: backtrack (usually up) */ { - xchar x = 0, y = 0; stairway *stway; - boolean stdir = dir && !builds_up(&u.uz); - - if ((stway = stairway_find_type_dir(FALSE, stdir)) != 0) { - /* stairs in direction 'stdir' */ - x = stway->sx; - y = stway->sy; - } else if ((stway = stairway_find_type_dir(TRUE, stdir)) != 0) { - /* ladder in direction 'stdir' */ - x = stway->sx; - y = stway->sy; - } else { - /* branch stairs in any direction */ - for (stway = g.stairs; stway; stway = stway->next) - if (stway->tolev.dnum != u.uz.dnum) { - x = stway->sx; - y = stway->sy; - break; + boolean stdir = builds_up(&u.uz) ? dir : !dir; + + /* look for stairs in direction 'stdir' (True: up, False: down) */ + stway = stairway_find_type_dir(FALSE, stdir); + if (!stway) { + /* no stairs; look for ladder it that direction */ + stway = stairway_find_type_dir(TRUE, stdir); + if (!stway) { + /* no ladder either; look for branch stairs or ladder in any + direction */ + for (stway = g.stairs; stway; stway = stway->next) + if (stway->tolev.dnum != u.uz.dnum) + break; + /* if no branch stairs/ladder, check for regular stairs in + opposite direction, then for regular ladder if necessary */ + if (!stway) { + stway = stairway_find_type_dir(FALSE, !stdir); + if (!stway) + stway = stairway_find_type_dir(TRUE, !stdir); } + } + /* [note: 'stway' could still be Null if the only access to this + level is via magic portal] */ } - if (isok(x, y)) { - *sx = x; - *sy = y; - } + if (stway) + *sx = stway->sx, *sy = stway->sy; } DISABLE_WARNING_UNREACHABLE_CODE