]> granicus.if.org Git - nethack/commitdiff
fix #H7173 / github #101 - vault exit
authorPatR <rankin@nethack.org>
Sun, 3 Feb 2019 01:37:06 +0000 (17:37 -0800)
committerPatR <rankin@nethack.org>
Sun, 3 Feb 2019 01:37:06 +0000 (17:37 -0800)
Fixes #101

If you tell the vault guard your name, drop carried gold, wait one
turn, then pick up the gold again, the guard will move a step away
during the wait.  If you teleport away, the guard will seal vault
walls and then park himself on the one-square (so far) temporary
corridor adjacent to the vault wall.  Periodically he'll say "Move
along!" and the hero will hear it, regardless of location on the
level.  Unless you dig a corridor to rescue him, or one or more of
the vault's walls get breached again, he will never move.

The report emphasized that you could use this to steal the vault's
gold, but it relies on being able to teleport beyond the gaurd's
reach and if you can do that, you might as well do so before the
guard comes.  The stranded guard, and him saying "Move along!" when
no longer leading hero out of the vault, are more significant bugs.

Bonus fix:  if the game ends and the guard seals up the vault while
the hero is in a spot that gets fixed up (vault wall or temporary
corridor) don't give the "You are encased in the rock" message if
game end was due to death rather than quit.

doc/fixes36.2
include/extern.h
src/hack.c
src/teleport.c
src/vault.c

index 8bca59c5395a8ea1b2ce25f6ee7b11678630736c..ea3ce46a2b2ca1bb712702d66504c74adb16c5f1 100644 (file)
@@ -1,4 +1,4 @@
-$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.244 $ $NHDT-Date: 1549075239 2019/02/02 02:40:39 $
+$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.245 $ $NHDT-Date: 1549157810 2019/02/03 01:36:50 $
 
 This fixes36.2 file is here to capture information about updates in the 3.6.x
 lineage following the release of 3.6.1 in April 2018. Please note, however,
@@ -359,6 +359,12 @@ monster with multiple items in inventory could trigger 'dealloc_obj with nobj'
        panic when turned into a statue if separate mon->minvent items merged
 lock picking context could end up with stale container pointer if container
        being forced/unlocked/locked got destroyed or sent to another level
+teleporting out a vault after guard appears could result in the guard being
+       stranded in a one-square long temporary corridor adjacent to vault
+       wall and periodically saying "Move along!"
+if game ends while hero is in a vault wall breach or in guard's temporary
+       corridor, a message "you are encased in the rock" could be given when
+       guard repairs things (for possible bones); suppress it if hero is dead
 
 
 Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
index 47f38254aae7d26fc0d230791841ad778bcb4dc4..af0e6147f8008d18b3cc32a91348e599f9f2c64d 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 extern.h        $NHDT-Date: 1548982186 2019/02/01 00:49:46 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.691 $ */
+/* NetHack 3.6 extern.h        $NHDT-Date: 1549157811 2019/02/03 01:36:51 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.692 $ */
 /* Copyright (c) Steve Creps, 1988.                              */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -2586,8 +2586,10 @@ E int FDECL(hide_privileges, (BOOLEAN_P));
 E void FDECL(newegd, (struct monst *));
 E void FDECL(free_egd, (struct monst *));
 E boolean FDECL(grddead, (struct monst *));
+E struct monst *NDECL(findgd);
 E void NDECL(vault_summon_gd);
 E char FDECL(vault_occupied, (char *));
+E void FDECL(uleftvault, (struct monst *));
 E void NDECL(invault);
 E int FDECL(gd_move, (struct monst *));
 E void NDECL(paygd);
index a42334c920fc5f4eb50c2a099fcddd558247efec..c925e2c494d389a9ba68afb376cec030484212aa 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 hack.c  $NHDT-Date: 1546656413 2019/01/05 02:46:53 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.203 $ */
+/* NetHack 3.6 hack.c  $NHDT-Date: 1549157812 2019/02/03 01:36:52 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.206 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Derek S. Ray, 2015. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -2269,9 +2269,9 @@ register int typewanted;
     int typefound, min_x, min_y, max_x, max_y_offset, step;
     register struct rm *lev;
 
-#define goodtype(rno)   \
-    (!typewanted                                                    \
-     || (typefound = rooms[rno - ROOMOFFSET].rtype) == typewanted   \
+#define goodtype(rno) \
+    (!typewanted                                                         \
+     || (typefound = (rooms[rno - ROOMOFFSET].rtype == typewanted)) != 0 \
      || (typewanted == SHOPBASE && typefound > SHOPBASE))
 
     switch (rno = levl[x][y].roomno) {
index fb99e633155f646c312e66dbc8622085d2264554..488e4477b5a41829105a33c22ab805794f1fd100 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 teleport.c      $NHDT-Date: 1546655319 2019/01/05 02:28:39 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.83 $ */
+/* NetHack 3.6 teleport.c      $NHDT-Date: 1549157815 2019/02/03 01:36:55 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.84 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2011. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -252,6 +252,7 @@ register int nux, nuy;
 boolean allow_drag;
 {
     boolean ball_active, ball_still_in_range;
+    struct monst *vault_guard = vault_occupied(u.urooms) ? findgd() : 0;
 
     if (u.utraptype == TT_BURIEDBALL) {
         /* unearth it */
@@ -354,6 +355,21 @@ boolean allow_drag;
         else
             telescroll = 0; /* no discovery by scrolltele()'s caller */
     }
+    /* sequencing issue:  we want guard's alarm, if any, to occur before
+       room entry message, if any, so need to check for vault exit prior
+       to spoteffects; but spoteffects() sets up new value for u.urooms
+       and vault code depends upon that value, so we need to fake it */
+    if (vault_guard) {
+        char save_urooms[5]; /* [sizeof u.urooms] */
+
+        Strcpy(save_urooms, u.urooms);
+        Strcpy(u.urooms, in_rooms(u.ux, u.uy, VAULT));
+        /* if hero has left vault, make guard notice */
+        if (!vault_occupied(u.urooms))
+            uleftvault(vault_guard);
+        Strcpy(u.urooms, save_urooms); /* reset prior to spoteffects() */
+    }
+    /* possible shop entry message comes after guard's shrill whistle */
     spoteffects(TRUE);
     invocation_message();
 }
index 3945f215de65ca8fc7164a3fab402c5238be041f..669cc52e37d1c3589d69e36edcfceb6fb02f9f0f 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 vault.c $NHDT-Date: 1545269451 2018/12/20 01:30:51 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.59 $ */
+/* NetHack 3.6 vault.c $NHDT-Date: 1549157816 2019/02/03 01:36:56 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.60 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2011. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -10,7 +10,6 @@ STATIC_DCL void FDECL(blackout, (int, int));
 STATIC_DCL void FDECL(restfakecorr, (struct monst *));
 STATIC_DCL void FDECL(parkguard, (struct monst *));
 STATIC_DCL boolean FDECL(in_fcorridor, (struct monst *, int, int));
-STATIC_DCL struct monst *NDECL(findgd);
 STATIC_DCL boolean FDECL(find_guard_dest, (struct monst *, xchar *, xchar *));
 STATIC_DCL void FDECL(move_gold, (struct obj *, int));
 STATIC_DCL void FDECL(wallify_vault, (struct monst *));
@@ -104,7 +103,9 @@ boolean forceshow;
     }
     if (sawcorridor)
         pline_The("corridor disappears.");
-    if (IS_ROCK(levl[u.ux][u.uy].typ))
+    /* only give encased message if hero is still alive (might get here
+       via paygd() when game is over; died: no message, quit: message) */
+    if (IS_ROCK(levl[u.ux][u.uy].typ) && (Upolyd ? u.mh : u.uhp) > 0)
         You("are encased in rock.");
     return TRUE;
 }
@@ -199,7 +200,6 @@ int x, y;
     return FALSE;
 }
 
-STATIC_OVL
 struct monst *
 findgd()
 {
@@ -233,6 +233,33 @@ char *array;
     return '\0';
 }
 
+/* hero has teleported out of vault while a guard is active */
+void
+uleftvault(grd)
+struct monst *grd;
+{
+    /* only called if caller has checked vault_occupied() and findgd() */
+    if (!grd || !grd->isgd || DEADMONSTER(grd)) {
+        impossible("escaping vault without guard?");
+        return;
+    }
+    /* if carrying gold and arriving anywhere other than next to the guard,
+       set the guard loose */
+    if ((money_cnt(invent) || hidden_gold())
+        && um_dist(grd->mx, grd->my, 1)) {
+        if (grd->mpeaceful) {
+            if (canspotmon(grd)) /* see or sense via telepathy */
+                pline("%s becomes irate.", Monnam(grd));
+            grd->mpeaceful = 0; /* bypass setmangry() */
+        }
+        /* if arriving outside guard's temporary corridor, give the
+           guard an extra move to deliver message(s) and to teleport
+           out of and remove that corridor */
+        if (!in_fcorridor(grd, u.ux, u.uy))
+            (void) gd_move(grd);
+    }
+}
+
 STATIC_OVL boolean
 find_guard_dest(guard, rx, ry)
 struct monst *guard;