From d6ed41339edb7e7d875e1fc6ff343989f43fa7f7 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 22 Dec 2018 16:35:15 -0800 Subject: [PATCH] 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. --- doc/fixes36.2 | 2 ++ src/monmove.c | 58 ++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index d891d6e63..c719349ac 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -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 that spot immediately instead of waiting until its next move 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 diff --git a/src/monmove.c b/src/monmove.c index fbc2d419d..37b752346 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -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) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -896,7 +896,7 @@ register int after; mmoved = 1; goto postmov; } -not_special: + not_special: if (u.uswallow && !mtmp->mflee && u.ustuck != mtmp) return 1; omx = mtmp->mx; @@ -1157,7 +1157,7 @@ not_special: chi = i; mmoved = 1; } - nxti: + nxti: ; } } @@ -1201,6 +1201,7 @@ not_special: if ((info[chi] & ALLOW_M) || (nix == mtmp->mux && niy == mtmp->muy)) { struct monst *mtmp2; int mstatus; + mtmp2 = m_at(nix, niy); notonhead = mtmp2 && (nix != mtmp2->mx || niy != mtmp2->my); @@ -1224,6 +1225,7 @@ not_special: if ((info[chi] & ALLOW_MDISP)) { struct monst *mtmp2; int mstatus; + mtmp2 = m_at(nix, niy); mstatus = mdisplacem(mtmp, mtmp2, FALSE); if ((mstatus & MM_AGR_DIED) || (mstatus & MM_DEF_DIED)) @@ -1235,6 +1237,7 @@ not_special: if (!m_in_out_region(mtmp, nix, niy)) return 3; + remove_monster(omx, omy); place_monster(mtmp, nix, niy); for (j = MTSZ - 1; j > 0; j--) @@ -1252,18 +1255,49 @@ not_special: if (mtmp->wormno) worm_nomove(mtmp); } -postmov: + postmov: if (mmoved == 1 || mmoved == 3) { boolean canseeit = cansee(mtmp->mx, mtmp->my); if (mmoved == 1) { + /* normal monster move will already have , + 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 */ if (mintrap(mtmp) >= 2) { if (mtmp->mx) newsym(mtmp->mx, mtmp->my); 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 */ if (IS_DOOR(levl[mtmp->mx][mtmp->my].typ) @@ -1284,18 +1318,11 @@ postmov: btrapped = FALSE; } if ((here->doormask & (D_LOCKED | D_CLOSED)) != 0 - && (amorphous(ptr) - || (can_fog(mtmp) - && vamp_shift(mtmp, &mons[PM_FOG_CLOUD], - sawmon)))) { - /* update cached value for vamp_shift() case */ - ptr = mtmp->data; + && amorphous(ptr)) { if (flags.verbose && canseemon(mtmp)) pline("%s %s under the door.", Monnam(mtmp), (ptr == &mons[PM_FOG_CLOUD] - || ptr->mlet == S_LIGHT) - ? "flows" - : "oozes"); + || ptr->mlet == S_LIGHT) ? "flows" : "oozes"); } else if (here->doormask & D_LOCKED && can_unlock) { if (btrapped) { here->doormask = D_NODOOR; @@ -1684,6 +1711,9 @@ boolean domsg; pline("You %s %s where %s was.", !canseemon(mon) ? "now detect" : "observe", 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; -- 2.49.0