]> granicus.if.org Git - nethack/commitdiff
choose_stairs() revisited
authorPatR <rankin@nethack.org>
Sat, 26 Feb 2022 18:15:58 +0000 (10:15 -0800)
committerPatR <rankin@nethack.org>
Sat, 26 Feb 2022 18:15:58 +0000 (10:15 -0800)
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.

doc/fixes3-7-0.txt
src/wizard.c

index 9e8b35ab5b47ec9bd6a74c12f15af9db0bf2ad8c..2d6aa7ef9ebe5f3c6a5bdac1074cd9744656d961 100644 (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
index e1d4351041235cc0e89acbea8cdcb50ec625fbe0..89fc73a26d2dc8433f756ffc3eaf4e34d1d0a91e 100644 (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);
-
-    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