From 2288452278ecc1ba7a12fe66f775cd4d7b759f34 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 17 May 2021 19:01:09 +0300 Subject: [PATCH] Monsters can see player resistances If monsters see you resist something, generally elemental or magical attack, or if they see you reflect an attack, they learn that and will adjust their attack accordingly. Originally from SporkHack, but this version comes via EvilHack with some minor changes. --- doc/fixes37.0 | 1 + include/extern.h | 2 ++ include/monst.h | 18 ++++++++++++++++++ include/patchlevel.h | 2 +- src/explode.c | 4 ++++ src/fountain.c | 5 +++-- src/makemon.c | 1 + src/mcastu.c | 20 ++++++++++++++++++-- src/mhitu.c | 8 +++++++- src/mondata.c | 32 ++++++++++++++++++++++++++++++++ src/mthrowu.c | 9 +++++++++ src/muse.c | 39 ++++++++++++++++++++++++++------------- src/potion.c | 5 ++++- src/pray.c | 3 +++ src/read.c | 1 + src/region.c | 1 + src/trap.c | 5 +++++ src/uhitm.c | 14 +++++++++++++- src/zap.c | 15 +++++++++++++++ 19 files changed, 164 insertions(+), 21 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 78a2ad62c..e692295e8 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -990,6 +990,7 @@ using 'f' while quiver is empty and 'autoquiver' is Off when wielding a the quiver (inspired by xNetHack) 3.6's tribute: add one new passage to Sourcery, three to Small Gods, one to Lords and Ladies, two to Soul Music +monsters can see and remember hero resistances Platform- and/or Interface-Specific New Features diff --git a/include/extern.h b/include/extern.h index d14b4875f..230948f51 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1491,6 +1491,8 @@ extern const char *stagger(const struct permonst *, const char *); extern const char *on_fire(struct permonst *, struct attack *); extern const struct permonst *raceptr(struct monst *); extern boolean olfaction(struct permonst *); +unsigned long cvt_adtyp_to_mseenres(uchar); +extern void monstseesu(unsigned long); /* ### monmove.c ### */ diff --git a/include/monst.h b/include/monst.h index 9b99a6ca6..30dd4ceac 100644 --- a/include/monst.h +++ b/include/monst.h @@ -68,6 +68,23 @@ enum m_ap_types { #define M_AP_TYPE(m) ((m)->m_ap_type & M_AP_TYPMASK) #define M_AP_FLAG(m) ((m)->m_ap_type & ~M_AP_TYPMASK) +enum m_seen_resistance { + M_SEEN_NOTHING = 0x0000, + M_SEEN_MAGR = 0x0001, /* Antimagic, AD_MAGM */ + M_SEEN_FIRE = 0x0002, /* Fire_resistance, AD_FIRE */ + M_SEEN_COLD = 0x0004, /* Cold_resistance, AD_COLD */ + M_SEEN_SLEEP = 0x0008, /* Sleep_resistance, AD_SLEE */ + M_SEEN_DISINT = 0x0010, /* Disint_resistance, AD_DISN */ + M_SEEN_ELEC = 0x0020, /* Shock_resistance, AD_ELEC */ + M_SEEN_POISON = 0x0040, /* AD_DRST */ + M_SEEN_ACID = 0x0080, /* Acid_resistance, AD_ACID */ + M_SEEN_REFL = 0x0100, /* reflection, no corresponding AD_foo */ +}; + +#define m_seenres(mon, mask) ((mon)->seen_resistance & (mask)) +#define m_setseenres(mon, mask) ((mon)->seen_resistance |= (mask)) +#define monstseesu_ad(adtyp) monstseesu(cvt_adtyp_to_mseenres(adtyp)) + struct monst { struct monst *nmon; struct permonst *data; @@ -90,6 +107,7 @@ struct monst { schar mtame; /* level of tameness, implies peaceful */ unsigned short mextrinsics; /* low 8 correspond to mresists */ + unsigned long seen_resistance; /* M_SEEN_x; saw you resist an effect */ int mspec_used; /* monster's special ability attack timeout */ Bitfield(female, 1); /* is female */ diff --git a/include/patchlevel.h b/include/patchlevel.h index 567bdded3..700a80582 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -17,7 +17,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 32 +#define EDITLEVEL 33 /* * Development status possibilities. diff --git a/src/explode.c b/src/explode.c index 257aee97c..2a2e993db 100644 --- a/src/explode.c +++ b/src/explode.c @@ -529,6 +529,10 @@ explode( g.context.botl = 1; } + /* You resisted the damage, lets not keep that to ourselves */ + if (uhurt == 1) + monstseesu_ad(adtyp); + if (u.uhp <= 0 || (Upolyd && u.mh <= 0)) { if (Upolyd) { rehumanize(); diff --git a/src/fountain.c b/src/fountain.c index 36b1d5219..1cf621606 100644 --- a/src/fountain.c +++ b/src/fountain.c @@ -542,9 +542,10 @@ drinksink(void) break; case 2: You("take a sip of scalding hot %s.", hliquid("water")); - if (Fire_resistance) + if (Fire_resistance) { pline("It seems quite tasty."); - else + monstseesu(M_SEEN_FIRE); + } else losehp(rnd(6), "sipping boiling water", KILLED_BY); /* boiling water burns considered fire damage */ break; diff --git a/src/makemon.c b/src/makemon.c index 87bd30d0a..9066292b9 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1237,6 +1237,7 @@ makemon(register struct permonst *ptr, place_monster(mtmp, x, y); mtmp->mcansee = mtmp->mcanmove = TRUE; + mtmp->seen_resistance = M_SEEN_NOTHING; mtmp->mpeaceful = (mmflags & MM_ANGRY) ? FALSE : peace_minded(ptr); switch (ptr->mlet) { diff --git a/src/mcastu.c b/src/mcastu.c index f51da0e82..829a2dee1 100644 --- a/src/mcastu.c +++ b/src/mcastu.c @@ -292,6 +292,7 @@ castmu(register struct monst *mtmp, if (Fire_resistance) { shieldeff(u.ux, u.uy); pline("But you resist the effects."); + monstseesu(M_SEEN_FIRE); dmg = 0; } burn_away_slime(); @@ -301,6 +302,7 @@ castmu(register struct monst *mtmp, if (Cold_resistance) { shieldeff(u.ux, u.uy); pline("But you resist the effects."); + monstseesu(M_SEEN_COLD); dmg = 0; } break; @@ -309,6 +311,7 @@ castmu(register struct monst *mtmp, if (Antimagic) { shieldeff(u.ux, u.uy); pline_The("missiles bounce off!"); + monstseesu(M_SEEN_MAGR); dmg = 0; } else dmg = d((int) mtmp->m_lev / 2 + 1, 6); @@ -375,8 +378,10 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum) done(DIED); } } else { - if (Antimagic) + if (Antimagic) { shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_MAGR); + } pline("Lucky for you, it didn't work!"); } dmg = 0; @@ -425,6 +430,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum) case MGC_DESTRY_ARMR: if (Antimagic) { shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_MAGR); pline("A field of force surrounds you!"); } else if (!destroy_arm(some_armor(&g.youmonst))) { Your("skin itches."); @@ -434,6 +440,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum) case MGC_WEAKEN_YOU: /* drain strength */ if (Antimagic) { shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_MAGR); You_feel("momentarily weakened."); } else { You("suddenly feel weaker!"); @@ -461,6 +468,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum) case MGC_STUN_YOU: if (Antimagic || Free_action) { shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_MAGR); if (!Stunned) You_feel("momentarily disoriented."); make_stunned(1L, FALSE); @@ -485,6 +493,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum) made the spell virtually harmless to players with magic res. */ if (Antimagic) { shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_MAGR); dmg = (dmg + 1) / 2; } if (dmg <= 5) @@ -528,6 +537,7 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum) pline("A pillar of fire strikes all around you!"); if (Fire_resistance) { shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_FIRE); dmg = 0; } else dmg = d(8, 6); @@ -549,8 +559,11 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum) if (reflects || Shock_resistance) { shieldeff(u.ux, u.uy); dmg = 0; - if (reflects) + if (reflects) { + monstseesu(M_SEEN_REFL); break; + } + monstseesu(M_SEEN_ELEC); } else dmg = d(8, 6); if (Half_spell_damage) @@ -660,6 +673,7 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum) case CLC_PARALYZE: if (Antimagic || Free_action) { shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_MAGR); if (g.multi >= 0) You("stiffen briefly."); nomul(-1); @@ -679,6 +693,7 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum) case CLC_CONFUSE_YOU: if (Antimagic) { shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_MAGR); You_feel("momentarily dizzy."); } else { boolean oldprop = !!Confusion; @@ -700,6 +715,7 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum) case CLC_OPEN_WOUNDS: if (Antimagic) { shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_MAGR); dmg = (dmg + 1) / 2; } if (dmg <= 5) diff --git a/src/mhitu.c b/src/mhitu.c index f548dca0f..3050c35ce 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1233,6 +1233,7 @@ gulpmu(struct monst *mtmp, struct attack *mattk) case AD_ACID: if (Acid_resistance) { You("are covered with a seemingly harmless goo."); + monstseesu(M_SEEN_ACID); tmp = 0; } else { if (Hallucination) @@ -1264,6 +1265,7 @@ gulpmu(struct monst *mtmp, struct attack *mattk) if (Shock_resistance) { shieldeff(u.ux, u.uy); You("seem unhurt."); + monstseesu(M_SEEN_ELEC); ugolemeffects(AD_ELEC, tmp); tmp = 0; } @@ -1275,6 +1277,7 @@ gulpmu(struct monst *mtmp, struct attack *mattk) if (Cold_resistance) { shieldeff(u.ux, u.uy); You_feel("mildly chilly."); + monstseesu(M_SEEN_COLD); ugolemeffects(AD_COLD, tmp); tmp = 0; } else @@ -1287,6 +1290,7 @@ gulpmu(struct monst *mtmp, struct attack *mattk) if (Fire_resistance) { shieldeff(u.ux, u.uy); You_feel("mildly hot."); + monstseesu(M_SEEN_FIRE); ugolemeffects(AD_FIRE, tmp); tmp = 0; } else @@ -1393,7 +1397,8 @@ explmu(struct monst *mtmp, struct attack *mattk, boolean ufound) if (physical_damage) tmp = Maybe_Half_Phys(tmp); mdamageu(mtmp, tmp); - } + } else + monstseesu_ad(mattk->adtyp); break; case AD_BLND: @@ -1596,6 +1601,7 @@ gazemu(struct monst *mtmp, struct attack *mattk) stop_occupation(); if (Fire_resistance) { pline_The("fire doesn't feel hot!"); + monstseesu(M_SEEN_FIRE); dmg = 0; } burn_away_slime(); diff --git a/src/mondata.c b/src/mondata.c index 28e4e65b5..2dc28bb0e 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -1223,4 +1223,36 @@ olfaction(struct permonst* mdat) return TRUE; } +/* Convert attack damage type AD_foo to M_SEEN_bar */ +unsigned long +cvt_adtyp_to_mseenres(uchar adtyp) +{ + switch (adtyp) { + case AD_MAGM: return M_SEEN_MAGR; + case AD_FIRE: return M_SEEN_FIRE; + case AD_COLD: return M_SEEN_COLD; + case AD_SLEE: return M_SEEN_SLEEP; + case AD_DISN: return M_SEEN_DISINT; + case AD_ELEC: return M_SEEN_ELEC; + case AD_DRST: return M_SEEN_POISON; + case AD_ACID: return M_SEEN_ACID; + /* M_SEEN_REFL has no corresponding AD_foo type */ + default: return M_SEEN_NOTHING; + } +} + +/* Monsters remember hero resisting effect M_SEEN_foo */ +void +monstseesu(unsigned long seenres) +{ + struct monst *mtmp; + + if (seenres == M_SEEN_NOTHING) + return; + + for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) + if (!DEADMONSTER(mtmp) && m_canseeu(mtmp)) + m_setseenres(mtmp, seenres); +} + /*mondata.c*/ diff --git a/src/mthrowu.c b/src/mthrowu.c index a65b09c16..6142c10a7 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -89,6 +89,7 @@ thitu( if (is_acid && Acid_resistance) { pline("It doesn't seem to hurt you."); + monstseesu(M_SEEN_ACID); } else if (obj && obj->oclass == POTION_CLASS) { /* an explosion which scatters objects might hit hero with one (potions deliberately thrown at hero are handled by m_throw) */ @@ -821,6 +822,14 @@ breamm(struct monst* mtmp, struct attack* mattk, struct monst* mtarg) } return MM_MISS; } + + /* if we've seen the actual resistance, don't bother, or + * if we're close by and they reflect, just jump the player */ + if (m_seenres(mtmp, cvt_adtyp_to_mseenres(typ)) + || (m_seenres(mtmp, M_SEEN_REFL) + && monnear(mtmp, mtmp->mux, mtmp->muy))) + return MM_HIT; + if (!mtmp->mspec_used && rn2(3)) { if ((typ >= AD_MAGM) && (typ <= AD_ACID)) { boolean utarget = (mtarg == &g.youmonst); diff --git a/src/muse.c b/src/muse.c index 58bbf75cd..e57c2bdb1 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1183,7 +1183,8 @@ boolean find_offensive(struct monst* mtmp) { register struct obj *obj; - boolean reflection_skip = (Reflecting && rn2(2)); + boolean reflection_skip = m_seenres(mtmp, M_SEEN_REFL) != 0 + || monnear(mtmp, mtmp->mux, mtmp->muy); struct obj *helmet = which_armor(mtmp, W_ARMH); g.m.offensive = (struct obj *) 0; @@ -1208,42 +1209,50 @@ find_offensive(struct monst* mtmp) for (obj = mtmp->minvent; obj; obj = obj->nobj) { if (!reflection_skip) { nomore(MUSE_WAN_DEATH); - if (obj->otyp == WAN_DEATH && obj->spe > 0) { + if (obj->otyp == WAN_DEATH && obj->spe > 0 + && !m_seenres(mtmp, M_SEEN_MAGR)) { g.m.offensive = obj; g.m.has_offense = MUSE_WAN_DEATH; } nomore(MUSE_WAN_SLEEP); - if (obj->otyp == WAN_SLEEP && obj->spe > 0 && g.multi >= 0) { + if (obj->otyp == WAN_SLEEP && obj->spe > 0 && g.multi >= 0 + && !m_seenres(mtmp, M_SEEN_SLEEP)) { g.m.offensive = obj; g.m.has_offense = MUSE_WAN_SLEEP; } nomore(MUSE_WAN_FIRE); - if (obj->otyp == WAN_FIRE && obj->spe > 0) { + if (obj->otyp == WAN_FIRE && obj->spe > 0 + && !m_seenres(mtmp, M_SEEN_FIRE)) { g.m.offensive = obj; g.m.has_offense = MUSE_WAN_FIRE; } nomore(MUSE_FIRE_HORN); - if (obj->otyp == FIRE_HORN && obj->spe > 0 && can_blow(mtmp)) { + if (obj->otyp == FIRE_HORN && obj->spe > 0 && can_blow(mtmp) + && !m_seenres(mtmp, M_SEEN_FIRE)) { g.m.offensive = obj; g.m.has_offense = MUSE_FIRE_HORN; } nomore(MUSE_WAN_COLD); - if (obj->otyp == WAN_COLD && obj->spe > 0) { + if (obj->otyp == WAN_COLD && obj->spe > 0 + && !m_seenres(mtmp, M_SEEN_COLD)) { g.m.offensive = obj; g.m.has_offense = MUSE_WAN_COLD; } nomore(MUSE_FROST_HORN); - if (obj->otyp == FROST_HORN && obj->spe > 0 && can_blow(mtmp)) { + if (obj->otyp == FROST_HORN && obj->spe > 0 && can_blow(mtmp) + && !m_seenres(mtmp, M_SEEN_COLD)) { g.m.offensive = obj; g.m.has_offense = MUSE_FROST_HORN; } nomore(MUSE_WAN_LIGHTNING); - if (obj->otyp == WAN_LIGHTNING && obj->spe > 0) { + if (obj->otyp == WAN_LIGHTNING && obj->spe > 0 + && !m_seenres(mtmp, M_SEEN_ELEC)) { g.m.offensive = obj; g.m.has_offense = MUSE_WAN_LIGHTNING; } nomore(MUSE_WAN_MAGIC_MISSILE); - if (obj->otyp == WAN_MAGIC_MISSILE && obj->spe > 0) { + if (obj->otyp == WAN_MAGIC_MISSILE && obj->spe > 0 + && !m_seenres(mtmp, M_SEEN_MAGR)) { g.m.offensive = obj; g.m.has_offense = MUSE_WAN_MAGIC_MISSILE; } @@ -1251,7 +1260,8 @@ find_offensive(struct monst* mtmp) nomore(MUSE_WAN_UNDEAD_TURNING); m_use_undead_turning(mtmp, obj); nomore(MUSE_WAN_STRIKING); - if (obj->otyp == WAN_STRIKING && obj->spe > 0) { + if (obj->otyp == WAN_STRIKING && obj->spe > 0 + && !m_seenres(mtmp, M_SEEN_MAGR)) { g.m.offensive = obj; g.m.has_offense = MUSE_WAN_STRIKING; } @@ -1285,12 +1295,14 @@ find_offensive(struct monst* mtmp) g.m.has_offense = MUSE_POT_CONFUSION; } nomore(MUSE_POT_SLEEPING); - if (obj->otyp == POT_SLEEPING) { + if (obj->otyp == POT_SLEEPING + && !m_seenres(mtmp, M_SEEN_SLEEP)) { g.m.offensive = obj; g.m.has_offense = MUSE_POT_SLEEPING; } nomore(MUSE_POT_ACID); - if (obj->otyp == POT_ACID) { + if (obj->otyp == POT_ACID + && !m_seenres(mtmp, M_SEEN_ACID)) { g.m.offensive = obj; g.m.has_offense = MUSE_POT_ACID; } @@ -1315,7 +1327,8 @@ find_offensive(struct monst* mtmp) nomore(MUSE_SCR_FIRE); if (obj->otyp == SCR_FIRE && resists_fire(mtmp) && dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 2 - && mtmp->mcansee && haseyes(mtmp->data)) { + && mtmp->mcansee && haseyes(mtmp->data) + && !m_seenres(mtmp, M_SEEN_FIRE)) { g.m.offensive = obj; g.m.has_offense = MUSE_SCR_FIRE; } diff --git a/src/potion.c b/src/potion.c index 516f4d9bd..b9148f556 100644 --- a/src/potion.c +++ b/src/potion.c @@ -796,6 +796,7 @@ peffects(struct obj *otmp) break; case POT_SLEEPING: if (Sleep_resistance || Free_action) { + monstseesu(M_SEEN_SLEEP); You("yawn."); } else { You("suddenly fall asleep!"); @@ -1729,8 +1730,10 @@ potionbreathe(struct obj *obj) g.multi_reason = "sleeping off a magical draught"; g.nomovemsg = You_can_move_again; exercise(A_DEX, FALSE); - } else + } else { You("yawn."); + monstseesu(M_SEEN_SLEEP); + } break; case POT_SPEED: if (!Fast) diff --git a/src/pray.c b/src/pray.c index 6642e9678..478edd1cc 100644 --- a/src/pray.c +++ b/src/pray.c @@ -597,9 +597,11 @@ god_zaps_you(aligntyp resp_god) pline("For some reason you're unaffected."); else (void) ureflects("%s reflects from your %s.", "It"); + monstseesu(M_SEEN_REFL); } else if (Shock_resistance) { shieldeff(u.ux, u.uy); pline("It seems not to affect you."); + monstseesu(M_SEEN_ELEC); } else fry_by_god(resp_god, FALSE); } @@ -635,6 +637,7 @@ god_zaps_you(aligntyp resp_god) } else { You("bask in its %s glow for a minute...", NH_BLACK); godvoice(resp_god, "I believe it not!"); + monstseesu(M_SEEN_DISINT); } if (Is_astralevel(&u.uz) || Is_sanctum(&u.uz)) { /* one more try for high altars */ diff --git a/src/read.c b/src/read.c index 4e9e70971..7e1ebdf4f 100644 --- a/src/read.c +++ b/src/read.c @@ -1628,6 +1628,7 @@ seffects(struct obj *sobj) /* sobj - scroll or fake spellbook for spell */ } else if (Fire_resistance) { shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_FIRE); if (!Blind) pline("Oh, look, what a pretty fire in your %s.", makeplural(body_part(HAND))); diff --git a/src/region.c b/src/region.c index b62257c9c..9f08c0b0d 100644 --- a/src/region.c +++ b/src/region.c @@ -1002,6 +1002,7 @@ inside_gas_cloud(genericptr_t p1, genericptr_t p2) return FALSE; } else { You("cough!"); + monstseesu(M_SEEN_POISON); return FALSE; } } else { /* A monster is inside the cloud */ diff --git a/src/trap.c b/src/trap.c index 075b8a20e..499c5fb16 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1251,6 +1251,7 @@ trapeffect_slp_gas_trap( seetrap(trap); if (Sleep_resistance || breathless(g.youmonst.data)) { You("are enveloped in a cloud of gas!"); + monstseesu(M_SEEN_SLEEP); } else { pline("A cloud of gas puts you to sleep!"); fall_asleep(-rnd(25), TRUE); @@ -3525,6 +3526,7 @@ dofiretrap( the(box ? xname(box) : surface(u.ux, u.uy))); if (Fire_resistance) { shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_FIRE); num = rn2(2); } else if (Upolyd) { num = d(2, 4); @@ -5331,6 +5333,7 @@ chest_trap( if (Shock_resistance) { shieldeff(u.ux, u.uy); You("don't seem to be affected."); + monstseesu(M_SEEN_ELEC); dmg = 0; } else dmg = d(4, 4); @@ -5763,6 +5766,8 @@ lava_effects(void) You("sink into the %s%s!", hliquid("lava"), !boil_away ? ", but it only burns slightly" : " and are about to be immolated"); + if (Fire_resistance) + monstseesu(M_SEEN_FIRE); if (u.uhp > 1) losehp(!boil_away ? 1 : (u.uhp / 2), lava_killer, KILLED_BY); /* lava damage */ diff --git a/src/uhitm.c b/src/uhitm.c index f777bed4c..b93796306 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -2004,6 +2004,7 @@ mhitm_ad_fire(struct monst *magr, struct attack *mattk, struct monst *mdef, return; } else if (Fire_resistance) { pline_The("fire doesn't feel hot!"); + monstseesu(M_SEEN_FIRE); mhm->damage = 0; } if ((int) magr->m_lev > rn2(20)) @@ -2094,6 +2095,7 @@ mhitm_ad_cold(struct monst *magr, struct attack *mattk, struct monst *mdef, pline("You're covered in frost!"); if (Cold_resistance) { pline_The("frost doesn't seem cold!"); + monstseesu(M_SEEN_COLD); mhm->damage = 0; } if ((int) magr->m_lev > rn2(20)) @@ -2158,6 +2160,7 @@ mhitm_ad_elec(struct monst *magr, struct attack *mattk, struct monst *mdef, You("get zapped!"); if (Shock_resistance) { pline_The("zap doesn't shock you!"); + monstseesu(M_SEEN_ELEC); mhm->damage = 0; } if ((int) magr->m_lev > rn2(20)) @@ -2205,6 +2208,7 @@ mhitm_ad_acid(struct monst *magr, struct attack *mattk, struct monst *mdef, if (Acid_resistance) { pline("You're covered in %s, but it seems harmless.", hliquid("acid")); + monstseesu(M_SEEN_ACID); mhm->damage = 0; } else { pline("You're covered in %s! It burns!", hliquid("acid")); @@ -2881,8 +2885,10 @@ mhitm_ad_slee(struct monst *magr, struct attack *mattk, struct monst *mdef, hitmsg(magr, mattk); if (uncancelled && g.multi >= 0 && !rn2(5)) { - if (Sleep_resistance) + if (Sleep_resistance) { + monstseesu(M_SEEN_SLEEP); return; + } fall_asleep(-rnd(10), TRUE); if (Blind) You("are put to sleep!"); @@ -4881,6 +4887,8 @@ passive(struct monst *mon, if (!Acid_resistance) mdamageu(mon, tmp); + else + monstseesu(M_SEEN_ACID); if (!rn2(30)) erode_armor(&g.youmonst, ERODE_CORRODE); } @@ -4945,6 +4953,7 @@ passive(struct monst *mon, /* wrath of gods for attacking Oracle */ if (Antimagic) { shieldeff(u.ux, u.uy); + monstseesu(M_SEEN_MAGR); pline("A hail of magic missiles narrowly misses you!"); } else { You("are hit by magic missiles appearing from thin air!"); @@ -5021,6 +5030,7 @@ passive(struct monst *mon, if (Cold_resistance) { shieldeff(u.ux, u.uy); You_feel("a mild chill."); + monstseesu(M_SEEN_COLD); ugolemeffects(AD_COLD, tmp); break; } @@ -5044,6 +5054,7 @@ passive(struct monst *mon, if (Fire_resistance) { shieldeff(u.ux, u.uy); You_feel("mildly warm."); + monstseesu(M_SEEN_FIRE); ugolemeffects(AD_FIRE, tmp); break; } @@ -5055,6 +5066,7 @@ passive(struct monst *mon, if (Shock_resistance) { shieldeff(u.ux, u.uy); You_feel("a mild tingle."); + monstseesu(M_SEEN_ELEC); ugolemeffects(AD_ELEC, tmp); break; } diff --git a/src/zap.c b/src/zap.c index a226bc3d4..f9e81498f 100644 --- a/src/zap.c +++ b/src/zap.c @@ -2411,6 +2411,7 @@ zapyourself(struct obj *obj, boolean ordinary) if (Antimagic) { shieldeff(u.ux, u.uy); pline("Boing!"); + monstseesu(M_SEEN_MAGR); } else { if (ordinary) { You("bash yourself!"); @@ -2430,6 +2431,7 @@ zapyourself(struct obj *obj, boolean ordinary) } else { shieldeff(u.ux, u.uy); You("zap yourself, but seem unharmed."); + monstseesu(M_SEEN_ELEC); ugolemeffects(AD_ELEC, d(12, 6)); } destroy_item(WAND_CLASS, AD_ELEC); @@ -2447,6 +2449,7 @@ zapyourself(struct obj *obj, boolean ordinary) if (Fire_resistance) { shieldeff(u.ux, u.uy); You_feel("rather warm."); + monstseesu(M_SEEN_FIRE); ugolemeffects(AD_FIRE, d(12, 6)); } else { pline("You've set yourself afire!"); @@ -2468,6 +2471,7 @@ zapyourself(struct obj *obj, boolean ordinary) if (Cold_resistance) { shieldeff(u.ux, u.uy); You_feel("a little chill."); + monstseesu(M_SEEN_COLD); ugolemeffects(AD_COLD, d(12, 6)); } else { You("imitate a popsicle!"); @@ -2482,6 +2486,7 @@ zapyourself(struct obj *obj, boolean ordinary) if (Antimagic) { shieldeff(u.ux, u.uy); pline_The("missiles bounce!"); + monstseesu(M_SEEN_MAGR); } else { damage = d(4, 6); pline("Idiot! You've shot yourself!"); @@ -2551,6 +2556,7 @@ zapyourself(struct obj *obj, boolean ordinary) if (Sleep_resistance) { shieldeff(u.ux, u.uy); You("don't feel sleepy!"); + monstseesu(M_SEEN_SLEEP); } else { pline_The("sleep ray hits you!"); fall_asleep(-rnd(50), TRUE); @@ -3875,6 +3881,7 @@ zhitu(int type, int nd, const char *fltxt, xchar sx, xchar sy) if (Antimagic) { shieldeff(sx, sy); pline_The("missiles bounce off!"); + monstseesu(M_SEEN_MAGR); } else { dam = d(nd, 6); exercise(A_STR, FALSE); @@ -3884,6 +3891,7 @@ zhitu(int type, int nd, const char *fltxt, xchar sx, xchar sy) if (Fire_resistance) { shieldeff(sx, sy); You("don't feel hot!"); + monstseesu(M_SEEN_FIRE); ugolemeffects(AD_FIRE, d(nd, 6)); } else { dam = d(nd, 6); @@ -3905,6 +3913,7 @@ zhitu(int type, int nd, const char *fltxt, xchar sx, xchar sy) if (Cold_resistance) { shieldeff(sx, sy); You("don't feel cold."); + monstseesu(M_SEEN_COLD); ugolemeffects(AD_COLD, d(nd, 6)); } else { dam = d(nd, 6); @@ -3916,6 +3925,7 @@ zhitu(int type, int nd, const char *fltxt, xchar sx, xchar sy) if (Sleep_resistance) { shieldeff(u.ux, u.uy); You("don't feel sleepy."); + monstseesu(M_SEEN_SLEEP); } else { fall_asleep(-d(nd, 25), TRUE); /* sleep ray */ } @@ -3924,6 +3934,7 @@ zhitu(int type, int nd, const char *fltxt, xchar sx, xchar sy) if (abstyp == ZT_BREATH(ZT_DEATH)) { if (Disint_resistance) { You("are not disintegrated."); + monstseesu(M_SEEN_DISINT); break; } else if (uarms) { /* destroy shield; other possessions are safe */ @@ -3948,6 +3959,7 @@ zhitu(int type, int nd, const char *fltxt, xchar sx, xchar sy) break; } else if (Antimagic) { shieldeff(sx, sy); + monstseesu(M_SEEN_MAGR); You("aren't affected."); break; } @@ -3961,6 +3973,7 @@ zhitu(int type, int nd, const char *fltxt, xchar sx, xchar sy) if (Shock_resistance) { shieldeff(sx, sy); You("aren't affected."); + monstseesu(M_SEEN_ELEC); ugolemeffects(AD_ELEC, d(nd, 6)); } else { dam = d(nd, 6); @@ -3977,6 +3990,7 @@ zhitu(int type, int nd, const char *fltxt, xchar sx, xchar sy) case ZT_ACID: if (Acid_resistance) { pline_The("%s doesn't hurt.", hliquid("acid")); + monstseesu(M_SEEN_ACID); dam = 0; } else { pline_The("%s burns!", hliquid("acid")); @@ -4309,6 +4323,7 @@ dobuzz(int type, int nd, xchar sx, xchar sy, int dx, int dy, "it"); } else pline("For some reason you are not affected."); + monstseesu(M_SEEN_REFL); dx = -dx; dy = -dy; shieldeff(sx, sy);