fix #H7749 - "you detect it"

'Detect' is used for observing a vampire shape change without being
able to see the vampire.  The problem here is that it changed from
bat form to fog cloud form in order to pass under a closed door,
and the message was being delivered when it was already at the door
location instead of before the move from a visible spot to that door.

I'm not happy with this fix, but any other alternative I considered
seemed to be worse.  Having the shape change use up the monster's
move is probably a better way to go.  Then on its next move it will
be in the right form to make a normal flow-under-door move.
This commit is contained in:
PatR
2018-12-22 16:35:15 -08:00
parent 8dfc10d8c6
commit d6ed41339e
2 changed files with 46 additions and 14 deletions

View File

@@ -300,6 +300,8 @@ identifying or forgetting gem types now adjusts prices for gems already on
when fire converts an ice location into a water location, dunk any monster on when fire converts an ice location into a water location, dunk any monster on
that spot immediately instead of waiting until its next move that spot immediately instead of waiting until its next move
training riding skill had an off-by-one bug when counting turns riding training riding skill had an off-by-one bug when counting turns riding
message sequencing when vampire shifts to fog cloud to pass under closed door:
when in sight, give form change message before moving to door spot
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 monmove.c $NHDT-Date: 1544442712 2018/12/10 11:51:52 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.109 $ */ /* NetHack 3.6 monmove.c $NHDT-Date: 1545525307 2018/12/23 00:35:07 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.110 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2006. */ /*-Copyright (c) Michael Allison, 2006. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -896,7 +896,7 @@ register int after;
mmoved = 1; mmoved = 1;
goto postmov; goto postmov;
} }
not_special: not_special:
if (u.uswallow && !mtmp->mflee && u.ustuck != mtmp) if (u.uswallow && !mtmp->mflee && u.ustuck != mtmp)
return 1; return 1;
omx = mtmp->mx; omx = mtmp->mx;
@@ -1157,7 +1157,7 @@ not_special:
chi = i; chi = i;
mmoved = 1; mmoved = 1;
} }
nxti: nxti:
; ;
} }
} }
@@ -1201,6 +1201,7 @@ not_special:
if ((info[chi] & ALLOW_M) || (nix == mtmp->mux && niy == mtmp->muy)) { if ((info[chi] & ALLOW_M) || (nix == mtmp->mux && niy == mtmp->muy)) {
struct monst *mtmp2; struct monst *mtmp2;
int mstatus; int mstatus;
mtmp2 = m_at(nix, niy); mtmp2 = m_at(nix, niy);
notonhead = mtmp2 && (nix != mtmp2->mx || niy != mtmp2->my); notonhead = mtmp2 && (nix != mtmp2->mx || niy != mtmp2->my);
@@ -1224,6 +1225,7 @@ not_special:
if ((info[chi] & ALLOW_MDISP)) { if ((info[chi] & ALLOW_MDISP)) {
struct monst *mtmp2; struct monst *mtmp2;
int mstatus; int mstatus;
mtmp2 = m_at(nix, niy); mtmp2 = m_at(nix, niy);
mstatus = mdisplacem(mtmp, mtmp2, FALSE); mstatus = mdisplacem(mtmp, mtmp2, FALSE);
if ((mstatus & MM_AGR_DIED) || (mstatus & MM_DEF_DIED)) if ((mstatus & MM_AGR_DIED) || (mstatus & MM_DEF_DIED))
@@ -1235,6 +1237,7 @@ not_special:
if (!m_in_out_region(mtmp, nix, niy)) if (!m_in_out_region(mtmp, nix, niy))
return 3; return 3;
remove_monster(omx, omy); remove_monster(omx, omy);
place_monster(mtmp, nix, niy); place_monster(mtmp, nix, niy);
for (j = MTSZ - 1; j > 0; j--) for (j = MTSZ - 1; j > 0; j--)
@@ -1252,18 +1255,49 @@ not_special:
if (mtmp->wormno) if (mtmp->wormno)
worm_nomove(mtmp); worm_nomove(mtmp);
} }
postmov: postmov:
if (mmoved == 1 || mmoved == 3) { if (mmoved == 1 || mmoved == 3) {
boolean canseeit = cansee(mtmp->mx, mtmp->my); boolean canseeit = cansee(mtmp->mx, mtmp->my);
if (mmoved == 1) { if (mmoved == 1) {
/* normal monster move will already have <nix,niy>,
but pet dog_move() with 'goto postmov' won't */
nix = mtmp->mx, niy = mtmp->my;
/* sequencing issue: when monster movement decides that a
monster can move to a door location, it moves the monster
there before dealing with the door rather than after;
so a vampire/bat that is going to shift to fog cloud and
pass under the door is already there but transformation
into fog form--and its message, when in sight--has not
happened yet; we have to move monster back to previous
location before performing the vamp_shift() to make the
message happen at right time, then back to the door again
[if we did the shift above, before moving the monster,
we would need to duplicate it in dog_move()...] */
if (is_vampshifter(mtmp) && !amorphous(mtmp->data)
&& IS_DOOR(levl[nix][niy].typ)
&& ((levl[nix][niy].doormask & (D_LOCKED | D_CLOSED)) != 0)
&& can_fog(mtmp)) {
if (sawmon) {
remove_monster(nix, niy), place_monster(mtmp, omx, omy);
newsym(nix, niy), newsym(omx, omy);
}
if (vamp_shift(mtmp, &mons[PM_FOG_CLOUD], sawmon)) {
ptr = mtmp->data; /* update cached value */
}
if (sawmon) {
remove_monster(omx, omy), place_monster(mtmp, nix, niy);
newsym(omx, omy), newsym(nix, niy);
}
}
newsym(omx, omy); /* update the old position */ newsym(omx, omy); /* update the old position */
if (mintrap(mtmp) >= 2) { if (mintrap(mtmp) >= 2) {
if (mtmp->mx) if (mtmp->mx)
newsym(mtmp->mx, mtmp->my); newsym(mtmp->mx, mtmp->my);
return 2; /* it died */ return 2; /* it died */
} }
ptr = mtmp->data; ptr = mtmp->data; /* in case mintrap() caused polymorph */
/* open a door, or crash through it, if 'mtmp' can */ /* open a door, or crash through it, if 'mtmp' can */
if (IS_DOOR(levl[mtmp->mx][mtmp->my].typ) if (IS_DOOR(levl[mtmp->mx][mtmp->my].typ)
@@ -1284,18 +1318,11 @@ postmov:
btrapped = FALSE; btrapped = FALSE;
} }
if ((here->doormask & (D_LOCKED | D_CLOSED)) != 0 if ((here->doormask & (D_LOCKED | D_CLOSED)) != 0
&& (amorphous(ptr) && amorphous(ptr)) {
|| (can_fog(mtmp)
&& vamp_shift(mtmp, &mons[PM_FOG_CLOUD],
sawmon)))) {
/* update cached value for vamp_shift() case */
ptr = mtmp->data;
if (flags.verbose && canseemon(mtmp)) if (flags.verbose && canseemon(mtmp))
pline("%s %s under the door.", Monnam(mtmp), pline("%s %s under the door.", Monnam(mtmp),
(ptr == &mons[PM_FOG_CLOUD] (ptr == &mons[PM_FOG_CLOUD]
|| ptr->mlet == S_LIGHT) || ptr->mlet == S_LIGHT) ? "flows" : "oozes");
? "flows"
: "oozes");
} else if (here->doormask & D_LOCKED && can_unlock) { } else if (here->doormask & D_LOCKED && can_unlock) {
if (btrapped) { if (btrapped) {
here->doormask = D_NODOOR; here->doormask = D_NODOOR;
@@ -1684,6 +1711,9 @@ boolean domsg;
pline("You %s %s where %s was.", pline("You %s %s where %s was.",
!canseemon(mon) ? "now detect" : "observe", !canseemon(mon) ? "now detect" : "observe",
noname_monnam(mon, ARTICLE_A), oldmtype); noname_monnam(mon, ARTICLE_A), oldmtype);
/* this message is given when it turns into a fog cloud
in order to move under a closed door */
display_nhwindow(WIN_MESSAGE, FALSE);
} }
return reslt; return reslt;