]> granicus.if.org Git - nethack/commitdiff
Monsters can see player resistances
authorPasi Kallinen <paxed@alt.org>
Mon, 17 May 2021 16:01:09 +0000 (19:01 +0300)
committerPasi Kallinen <paxed@alt.org>
Mon, 17 May 2021 17:01:11 +0000 (20:01 +0300)
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.

19 files changed:
doc/fixes37.0
include/extern.h
include/monst.h
include/patchlevel.h
src/explode.c
src/fountain.c
src/makemon.c
src/mcastu.c
src/mhitu.c
src/mondata.c
src/mthrowu.c
src/muse.c
src/potion.c
src/pray.c
src/read.c
src/region.c
src/trap.c
src/uhitm.c
src/zap.c

index 78a2ad62c002de6817b3cebc00687c2fc3384104..e692295e88ab0fb1c4d05d6e56c01d3a8cfec19f 100644 (file)
@@ -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
index d14b4875fa0a29ba463dcabcb98d728ba3310d22..230948f510f8d5558e8824775be71a18f0e3a441 100644 (file)
@@ -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 ### */
 
index 9b99a6ca6569195254f5df394f8c13659ab3a000..30dd4ceac37e10c9475be4a2cc14da300aa9e643 100644 (file)
@@ -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 */
index 567bdded345cf71acafa03ccd58c548dfc4b4e11..700a805821b04528cc7e516ae9dda84157284c95 100644 (file)
@@ -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.
index 257aee97ca36624935584a85bb9e1949e94e5a0a..2a2e993dbc371d1ec1cd120e33b4667ffbf8c222 100644 (file)
@@ -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();
index 36b1d5219d16ffe5a70ef0e293227480fdd3c896..1cf6216060ace55ca172d66fc66b8f4d1929d4d2 100644 (file)
@@ -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;
index 87bd30d0a501bce7809df555b52e9d07b975c7f4..9066292b9736fd4946a681b7e7b03bc211b0d2fe 100644 (file)
@@ -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) {
index f51da0e829bf67336c87691cec94f528e2addac9..829a2dee1f99438cefb9aa1f5a333cc2cc623608 100644 (file)
@@ -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)
index f548dca0f78720111e9dbb58a3b54b878e1fc0f1..3050c35ced2c778fd528cb9612a9d3f8c9020b0b 100644 (file)
@@ -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();
index 28e4e65b5f501e721f803b6b73b12d6b38b3235c..2dc28bb0eb37703b41950a9b61b25f76c2a4389f 100644 (file)
@@ -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*/
index a65b09c16f8b219de3b1cff4c8a893cdbf77fe52..6142c10a7a62e36caa5e0931210911fb0f41720a 100644 (file)
@@ -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);
index 58bbf75cd884f7226f0fb237ff16f2b7ecf684c1..e57c2bdb1a821c3c889a670f830a30e3942d9744 100644 (file)
@@ -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;
         }
index 516f4d9bd84dc03d505accbb6f76c7b7a9a9ea0c..b9148f55651f751a1ae60f81bf9cee6d9010b273 100644 (file)
@@ -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)
index 6642e9678b9a6f38eec58599818ce7bc125d5166..478edd1ccf11eb67880f3d58dbea6b287fd9c513 100644 (file)
@@ -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 */
index 4e9e70971c59a96df710cad2e8a75ba79676bcd8..7e1ebdf4f41a517304166166033b601d23c720f4 100644 (file)
@@ -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)));
index b62257c9c6331ec9148e6e414e52ae3b94f8f910..9f08c0b0dc76b95607efad67812993cc9c9e8bdc 100644 (file)
@@ -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 */
index 075b8a20e56b75ea201c536f331afb1dea91675c..499c5fb16f4e792cc7a28e65462c3b6774dae260 100644 (file)
@@ -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 */
index f777bed4c22459b096f937029b74ff8eb2e9f875..b93796306c3fa5ab0c2d991397c24513c6b18999 100644 (file)
@@ -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;
             }
index a226bc3d4bf808f6d91a7484c487a3dc7a5fc474..f9e81498fa43a239be17be103a1e140758216077 100644 (file)
--- 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);