fix #H7173 / github #101 - vault exit

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.
This commit is contained in:
PatR
2019-02-02 17:37:06 -08:00
parent b43b3f617c
commit 7cc718ea0e
5 changed files with 62 additions and 11 deletions

View 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;