From 53a4e3f80a498fc72c592407c1239013c4d63545 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 20 Dec 2022 14:44:19 -0800 Subject: [PATCH] unconscious hero vs Medusa Reported directly to devteam by entrez: a sleeping or unconscious hero would still meet a monster's gaze attack even though those are supposed to be eye-to-eye rather than just the monster looking at you. Don't meet the gaze when Unaware, despite the fact that the hero isn't blind and vision remains in operation. Initially being Unaware also blocked Medusa's gaze being reflected but I changed things so that that still affects her. It contradicts the eye-to-eye aspect but is more consistent with her looking at a blind hero who has reflection. --- doc/fixes3-7-0.txt | 1 + src/mhitu.c | 43 +++++++++++++++++++++++++++---------------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 117960254..941009c23 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1074,6 +1074,7 @@ if punished and iron ball was cursed and wielded--so welded to hand--falling when doors would drop it instead of keeping it welded if player's run-time config file had OPTIONS=role:Val and the environment had NETHACKOPTIONS='role:!Val' the hero would be a Val instead of !Val +sleeping or unconscious hero attacked by Medusa would meet her gaze Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/mhitu.c b/src/mhitu.c index 625ce6fa6..6e2d5366f 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1518,45 +1518,56 @@ gazemu(struct monst *mtmp, struct attack *mattk) "dulled", /* [7] */ }; int react = -1; - boolean cancelled = (mtmp->mcan != 0), already = FALSE; - boolean mcanseeu = canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) - && mtmp->mcansee; + boolean is_medusa, reflectable, + cancelled = (mtmp->mcan != 0), already = FALSE, + mcanseeu = (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) + && mtmp->mcansee); if (m_seenres(mtmp, cvt_adtyp_to_mseenres(mattk->adtyp))) return MM_MISS; + is_medusa = (mtmp->data == &mons[PM_MEDUSA]); + reflectable = (Reflecting && couldsee(mtmp->mx, mtmp->my) && is_medusa); /* assumes that hero has to see monster's gaze in order to be affected, rather than monster just having to look at hero; + Unaware: asleep or unconscious => not blind but won't see; when hallucinating, hero's brain doesn't register what it's seeing correctly so the gaze is usually ineffective [this could be taken a lot farther and select a gaze effect appropriate to what's currently being displayed, giving ordinary monsters a gaze attack when hero thinks he or she is facing a gazing creature, but let's not go that far...] */ - if (Hallucination && rn2(4)) + if ((Hallucination && rn2(4)) || (Unaware && !reflectable)) cancelled = TRUE; switch (mattk->adtyp) { case AD_STON: + /* note: Medusa is the only monster with stoning gaze, so + 'is_medusa' will always be True here */ if (cancelled || !mtmp->mcansee) { if (!canseemon(mtmp)) break; /* silently */ - pline("%s %s.", Monnam(mtmp), - (mtmp->data == &mons[PM_MEDUSA] && mtmp->mcan) - ? "doesn't look all that ugly" - : "gazes ineffectually"); + if (Unaware) { /* can't see attacker even though not blind */ + react = is_medusa ? 4 : 2; /* irritated or puzzled */ + break; + } + if (is_medusa && Hallucination && !rn2(3)) + pline("Someone seems overdue for a serpent cut."); + else + pline("%s %s.", Monnam(mtmp), + (is_medusa && mtmp->mcan && !react) + ? "doesn't look all that ugly" + : "gazes ineffectually"); break; - } - if (Reflecting && couldsee(mtmp->mx, mtmp->my) - && mtmp->data == &mons[PM_MEDUSA]) { + } + if (reflectable) { /* hero has line of sight to Medusa and she's not blind */ boolean useeit = canseemon(mtmp); if (useeit) (void) ureflects("%s gaze is reflected by your %s.", s_suffix(Monnam(mtmp))); - if (mon_reflects( - mtmp, !useeit ? (char *) 0 + if (mon_reflects(mtmp, !useeit ? (char *) 0 : "The gaze is reflected away by %s %s!")) break; if (!m_canseeu(mtmp)) { /* probably you're invisible */ @@ -1576,7 +1587,7 @@ gazemu(struct monst *mtmp, struct attack *mattk) return MM_AGR_DIED; } if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) - && !Stone_resistance) { + && !Stone_resistance && !Unaware) { You("meet %s gaze.", s_suffix(mon_nam(mtmp))); stop_occupation(); if (poly_when_stoned(gy.youmonst.data) && polymon(PM_STONE_GOLEM)) @@ -2270,11 +2281,11 @@ passiveum( tmp = 127; if (mtmp->mcansee && haseyes(mtmp->data) && rn2(3) && (perceives(mtmp->data) || !Invis)) { - if (Blind) + if (Blind) { pline("As a blind %s, you cannot defend yourself.", pmname(gy.youmonst.data, flags.female ? FEMALE : MALE)); - else { + } else { if (mon_reflects(mtmp, "Your gaze is reflected by %s %s.")) return 1;