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.
This commit is contained in:
PatR
2022-02-26 10:15:58 -08:00
parent f8cb7ae0b8
commit 020d3f76d5
2 changed files with 30 additions and 22 deletions

View File

@@ -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

View File

@@ -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);
boolean stdir = builds_up(&u.uz) ? dir : !dir;
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;
/* 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