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.
This commit is contained in:
Pasi Kallinen
2021-05-17 20:01:11 +03:00
parent 2a10b3003d
commit 2288452278
19 changed files with 164 additions and 21 deletions
+1
View File
@@ -990,6 +990,7 @@ using 'f' while quiver is empty and 'autoquiver' is Off when wielding a
the quiver (inspired by xNetHack) the quiver (inspired by xNetHack)
3.6's tribute: add one new passage to Sourcery, three to Small Gods, one to 3.6's tribute: add one new passage to Sourcery, three to Small Gods, one to
Lords and Ladies, two to Soul Music Lords and Ladies, two to Soul Music
monsters can see and remember hero resistances
Platform- and/or Interface-Specific New Features Platform- and/or Interface-Specific New Features
+2
View 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 char *on_fire(struct permonst *, struct attack *);
extern const struct permonst *raceptr(struct monst *); extern const struct permonst *raceptr(struct monst *);
extern boolean olfaction(struct permonst *); extern boolean olfaction(struct permonst *);
unsigned long cvt_adtyp_to_mseenres(uchar);
extern void monstseesu(unsigned long);
/* ### monmove.c ### */ /* ### monmove.c ### */
+18
View File
@@ -68,6 +68,23 @@ enum m_ap_types {
#define M_AP_TYPE(m) ((m)->m_ap_type & M_AP_TYPMASK) #define M_AP_TYPE(m) ((m)->m_ap_type & M_AP_TYPMASK)
#define M_AP_FLAG(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 {
struct monst *nmon; struct monst *nmon;
struct permonst *data; struct permonst *data;
@@ -90,6 +107,7 @@ struct monst {
schar mtame; /* level of tameness, implies peaceful */ schar mtame; /* level of tameness, implies peaceful */
unsigned short mextrinsics; /* low 8 correspond to mresists */ 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 */ int mspec_used; /* monster's special ability attack timeout */
Bitfield(female, 1); /* is female */ Bitfield(female, 1); /* is female */
+1 -1
View File
@@ -17,7 +17,7 @@
* Incrementing EDITLEVEL can be used to force invalidation of old bones * Incrementing EDITLEVEL can be used to force invalidation of old bones
* and save files. * and save files.
*/ */
#define EDITLEVEL 32 #define EDITLEVEL 33
/* /*
* Development status possibilities. * Development status possibilities.
+4
View File
@@ -529,6 +529,10 @@ explode(
g.context.botl = 1; 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 (u.uhp <= 0 || (Upolyd && u.mh <= 0)) {
if (Upolyd) { if (Upolyd) {
rehumanize(); rehumanize();
+3 -2
View File
@@ -542,9 +542,10 @@ drinksink(void)
break; break;
case 2: case 2:
You("take a sip of scalding hot %s.", hliquid("water")); You("take a sip of scalding hot %s.", hliquid("water"));
if (Fire_resistance) if (Fire_resistance) {
pline("It seems quite tasty."); pline("It seems quite tasty.");
else monstseesu(M_SEEN_FIRE);
} else
losehp(rnd(6), "sipping boiling water", KILLED_BY); losehp(rnd(6), "sipping boiling water", KILLED_BY);
/* boiling water burns considered fire damage */ /* boiling water burns considered fire damage */
break; break;
+1
View File
@@ -1237,6 +1237,7 @@ makemon(register struct permonst *ptr,
place_monster(mtmp, x, y); place_monster(mtmp, x, y);
mtmp->mcansee = mtmp->mcanmove = TRUE; mtmp->mcansee = mtmp->mcanmove = TRUE;
mtmp->seen_resistance = M_SEEN_NOTHING;
mtmp->mpeaceful = (mmflags & MM_ANGRY) ? FALSE : peace_minded(ptr); mtmp->mpeaceful = (mmflags & MM_ANGRY) ? FALSE : peace_minded(ptr);
switch (ptr->mlet) { switch (ptr->mlet) {
+18 -2
View File
@@ -292,6 +292,7 @@ castmu(register struct monst *mtmp,
if (Fire_resistance) { if (Fire_resistance) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
pline("But you resist the effects."); pline("But you resist the effects.");
monstseesu(M_SEEN_FIRE);
dmg = 0; dmg = 0;
} }
burn_away_slime(); burn_away_slime();
@@ -301,6 +302,7 @@ castmu(register struct monst *mtmp,
if (Cold_resistance) { if (Cold_resistance) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
pline("But you resist the effects."); pline("But you resist the effects.");
monstseesu(M_SEEN_COLD);
dmg = 0; dmg = 0;
} }
break; break;
@@ -309,6 +311,7 @@ castmu(register struct monst *mtmp,
if (Antimagic) { if (Antimagic) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
pline_The("missiles bounce off!"); pline_The("missiles bounce off!");
monstseesu(M_SEEN_MAGR);
dmg = 0; dmg = 0;
} else } else
dmg = d((int) mtmp->m_lev / 2 + 1, 6); 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); done(DIED);
} }
} else { } else {
if (Antimagic) if (Antimagic) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_MAGR);
}
pline("Lucky for you, it didn't work!"); pline("Lucky for you, it didn't work!");
} }
dmg = 0; dmg = 0;
@@ -425,6 +430,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
case MGC_DESTRY_ARMR: case MGC_DESTRY_ARMR:
if (Antimagic) { if (Antimagic) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_MAGR);
pline("A field of force surrounds you!"); pline("A field of force surrounds you!");
} else if (!destroy_arm(some_armor(&g.youmonst))) { } else if (!destroy_arm(some_armor(&g.youmonst))) {
Your("skin itches."); Your("skin itches.");
@@ -434,6 +440,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
case MGC_WEAKEN_YOU: /* drain strength */ case MGC_WEAKEN_YOU: /* drain strength */
if (Antimagic) { if (Antimagic) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_MAGR);
You_feel("momentarily weakened."); You_feel("momentarily weakened.");
} else { } else {
You("suddenly feel weaker!"); You("suddenly feel weaker!");
@@ -461,6 +468,7 @@ cast_wizard_spell(struct monst *mtmp, int dmg, int spellnum)
case MGC_STUN_YOU: case MGC_STUN_YOU:
if (Antimagic || Free_action) { if (Antimagic || Free_action) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_MAGR);
if (!Stunned) if (!Stunned)
You_feel("momentarily disoriented."); You_feel("momentarily disoriented.");
make_stunned(1L, FALSE); 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. */ made the spell virtually harmless to players with magic res. */
if (Antimagic) { if (Antimagic) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_MAGR);
dmg = (dmg + 1) / 2; dmg = (dmg + 1) / 2;
} }
if (dmg <= 5) 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!"); pline("A pillar of fire strikes all around you!");
if (Fire_resistance) { if (Fire_resistance) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_FIRE);
dmg = 0; dmg = 0;
} else } else
dmg = d(8, 6); dmg = d(8, 6);
@@ -549,8 +559,11 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum)
if (reflects || Shock_resistance) { if (reflects || Shock_resistance) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
dmg = 0; dmg = 0;
if (reflects) if (reflects) {
monstseesu(M_SEEN_REFL);
break; break;
}
monstseesu(M_SEEN_ELEC);
} else } else
dmg = d(8, 6); dmg = d(8, 6);
if (Half_spell_damage) if (Half_spell_damage)
@@ -660,6 +673,7 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum)
case CLC_PARALYZE: case CLC_PARALYZE:
if (Antimagic || Free_action) { if (Antimagic || Free_action) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_MAGR);
if (g.multi >= 0) if (g.multi >= 0)
You("stiffen briefly."); You("stiffen briefly.");
nomul(-1); nomul(-1);
@@ -679,6 +693,7 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum)
case CLC_CONFUSE_YOU: case CLC_CONFUSE_YOU:
if (Antimagic) { if (Antimagic) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_MAGR);
You_feel("momentarily dizzy."); You_feel("momentarily dizzy.");
} else { } else {
boolean oldprop = !!Confusion; boolean oldprop = !!Confusion;
@@ -700,6 +715,7 @@ cast_cleric_spell(struct monst *mtmp, int dmg, int spellnum)
case CLC_OPEN_WOUNDS: case CLC_OPEN_WOUNDS:
if (Antimagic) { if (Antimagic) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_MAGR);
dmg = (dmg + 1) / 2; dmg = (dmg + 1) / 2;
} }
if (dmg <= 5) if (dmg <= 5)
+7 -1
View File
@@ -1233,6 +1233,7 @@ gulpmu(struct monst *mtmp, struct attack *mattk)
case AD_ACID: case AD_ACID:
if (Acid_resistance) { if (Acid_resistance) {
You("are covered with a seemingly harmless goo."); You("are covered with a seemingly harmless goo.");
monstseesu(M_SEEN_ACID);
tmp = 0; tmp = 0;
} else { } else {
if (Hallucination) if (Hallucination)
@@ -1264,6 +1265,7 @@ gulpmu(struct monst *mtmp, struct attack *mattk)
if (Shock_resistance) { if (Shock_resistance) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
You("seem unhurt."); You("seem unhurt.");
monstseesu(M_SEEN_ELEC);
ugolemeffects(AD_ELEC, tmp); ugolemeffects(AD_ELEC, tmp);
tmp = 0; tmp = 0;
} }
@@ -1275,6 +1277,7 @@ gulpmu(struct monst *mtmp, struct attack *mattk)
if (Cold_resistance) { if (Cold_resistance) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
You_feel("mildly chilly."); You_feel("mildly chilly.");
monstseesu(M_SEEN_COLD);
ugolemeffects(AD_COLD, tmp); ugolemeffects(AD_COLD, tmp);
tmp = 0; tmp = 0;
} else } else
@@ -1287,6 +1290,7 @@ gulpmu(struct monst *mtmp, struct attack *mattk)
if (Fire_resistance) { if (Fire_resistance) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
You_feel("mildly hot."); You_feel("mildly hot.");
monstseesu(M_SEEN_FIRE);
ugolemeffects(AD_FIRE, tmp); ugolemeffects(AD_FIRE, tmp);
tmp = 0; tmp = 0;
} else } else
@@ -1393,7 +1397,8 @@ explmu(struct monst *mtmp, struct attack *mattk, boolean ufound)
if (physical_damage) if (physical_damage)
tmp = Maybe_Half_Phys(tmp); tmp = Maybe_Half_Phys(tmp);
mdamageu(mtmp, tmp); mdamageu(mtmp, tmp);
} } else
monstseesu_ad(mattk->adtyp);
break; break;
case AD_BLND: case AD_BLND:
@@ -1596,6 +1601,7 @@ gazemu(struct monst *mtmp, struct attack *mattk)
stop_occupation(); stop_occupation();
if (Fire_resistance) { if (Fire_resistance) {
pline_The("fire doesn't feel hot!"); pline_The("fire doesn't feel hot!");
monstseesu(M_SEEN_FIRE);
dmg = 0; dmg = 0;
} }
burn_away_slime(); burn_away_slime();
+32
View File
@@ -1223,4 +1223,36 @@ olfaction(struct permonst* mdat)
return TRUE; 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*/ /*mondata.c*/
+9
View File
@@ -89,6 +89,7 @@ thitu(
if (is_acid && Acid_resistance) { if (is_acid && Acid_resistance) {
pline("It doesn't seem to hurt you."); pline("It doesn't seem to hurt you.");
monstseesu(M_SEEN_ACID);
} else if (obj && obj->oclass == POTION_CLASS) { } else if (obj && obj->oclass == POTION_CLASS) {
/* an explosion which scatters objects might hit hero with one /* an explosion which scatters objects might hit hero with one
(potions deliberately thrown at hero are handled by m_throw) */ (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; 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 (!mtmp->mspec_used && rn2(3)) {
if ((typ >= AD_MAGM) && (typ <= AD_ACID)) { if ((typ >= AD_MAGM) && (typ <= AD_ACID)) {
boolean utarget = (mtarg == &g.youmonst); boolean utarget = (mtarg == &g.youmonst);
+26 -13
View File
@@ -1183,7 +1183,8 @@ boolean
find_offensive(struct monst* mtmp) find_offensive(struct monst* mtmp)
{ {
register struct obj *obj; 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); struct obj *helmet = which_armor(mtmp, W_ARMH);
g.m.offensive = (struct obj *) 0; g.m.offensive = (struct obj *) 0;
@@ -1208,42 +1209,50 @@ find_offensive(struct monst* mtmp)
for (obj = mtmp->minvent; obj; obj = obj->nobj) { for (obj = mtmp->minvent; obj; obj = obj->nobj) {
if (!reflection_skip) { if (!reflection_skip) {
nomore(MUSE_WAN_DEATH); 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.offensive = obj;
g.m.has_offense = MUSE_WAN_DEATH; g.m.has_offense = MUSE_WAN_DEATH;
} }
nomore(MUSE_WAN_SLEEP); 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.offensive = obj;
g.m.has_offense = MUSE_WAN_SLEEP; g.m.has_offense = MUSE_WAN_SLEEP;
} }
nomore(MUSE_WAN_FIRE); 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.offensive = obj;
g.m.has_offense = MUSE_WAN_FIRE; g.m.has_offense = MUSE_WAN_FIRE;
} }
nomore(MUSE_FIRE_HORN); 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.offensive = obj;
g.m.has_offense = MUSE_FIRE_HORN; g.m.has_offense = MUSE_FIRE_HORN;
} }
nomore(MUSE_WAN_COLD); 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.offensive = obj;
g.m.has_offense = MUSE_WAN_COLD; g.m.has_offense = MUSE_WAN_COLD;
} }
nomore(MUSE_FROST_HORN); 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.offensive = obj;
g.m.has_offense = MUSE_FROST_HORN; g.m.has_offense = MUSE_FROST_HORN;
} }
nomore(MUSE_WAN_LIGHTNING); 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.offensive = obj;
g.m.has_offense = MUSE_WAN_LIGHTNING; g.m.has_offense = MUSE_WAN_LIGHTNING;
} }
nomore(MUSE_WAN_MAGIC_MISSILE); 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.offensive = obj;
g.m.has_offense = MUSE_WAN_MAGIC_MISSILE; g.m.has_offense = MUSE_WAN_MAGIC_MISSILE;
} }
@@ -1251,7 +1260,8 @@ find_offensive(struct monst* mtmp)
nomore(MUSE_WAN_UNDEAD_TURNING); nomore(MUSE_WAN_UNDEAD_TURNING);
m_use_undead_turning(mtmp, obj); m_use_undead_turning(mtmp, obj);
nomore(MUSE_WAN_STRIKING); 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.offensive = obj;
g.m.has_offense = MUSE_WAN_STRIKING; g.m.has_offense = MUSE_WAN_STRIKING;
} }
@@ -1285,12 +1295,14 @@ find_offensive(struct monst* mtmp)
g.m.has_offense = MUSE_POT_CONFUSION; g.m.has_offense = MUSE_POT_CONFUSION;
} }
nomore(MUSE_POT_SLEEPING); 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.offensive = obj;
g.m.has_offense = MUSE_POT_SLEEPING; g.m.has_offense = MUSE_POT_SLEEPING;
} }
nomore(MUSE_POT_ACID); 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.offensive = obj;
g.m.has_offense = MUSE_POT_ACID; g.m.has_offense = MUSE_POT_ACID;
} }
@@ -1315,7 +1327,8 @@ find_offensive(struct monst* mtmp)
nomore(MUSE_SCR_FIRE); nomore(MUSE_SCR_FIRE);
if (obj->otyp == SCR_FIRE && resists_fire(mtmp) if (obj->otyp == SCR_FIRE && resists_fire(mtmp)
&& dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 2 && 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.offensive = obj;
g.m.has_offense = MUSE_SCR_FIRE; g.m.has_offense = MUSE_SCR_FIRE;
} }
+4 -1
View File
@@ -796,6 +796,7 @@ peffects(struct obj *otmp)
break; break;
case POT_SLEEPING: case POT_SLEEPING:
if (Sleep_resistance || Free_action) { if (Sleep_resistance || Free_action) {
monstseesu(M_SEEN_SLEEP);
You("yawn."); You("yawn.");
} else { } else {
You("suddenly fall asleep!"); You("suddenly fall asleep!");
@@ -1729,8 +1730,10 @@ potionbreathe(struct obj *obj)
g.multi_reason = "sleeping off a magical draught"; g.multi_reason = "sleeping off a magical draught";
g.nomovemsg = You_can_move_again; g.nomovemsg = You_can_move_again;
exercise(A_DEX, FALSE); exercise(A_DEX, FALSE);
} else } else {
You("yawn."); You("yawn.");
monstseesu(M_SEEN_SLEEP);
}
break; break;
case POT_SPEED: case POT_SPEED:
if (!Fast) if (!Fast)
+3
View File
@@ -597,9 +597,11 @@ god_zaps_you(aligntyp resp_god)
pline("For some reason you're unaffected."); pline("For some reason you're unaffected.");
else else
(void) ureflects("%s reflects from your %s.", "It"); (void) ureflects("%s reflects from your %s.", "It");
monstseesu(M_SEEN_REFL);
} else if (Shock_resistance) { } else if (Shock_resistance) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
pline("It seems not to affect you."); pline("It seems not to affect you.");
monstseesu(M_SEEN_ELEC);
} else } else
fry_by_god(resp_god, FALSE); fry_by_god(resp_god, FALSE);
} }
@@ -635,6 +637,7 @@ god_zaps_you(aligntyp resp_god)
} else { } else {
You("bask in its %s glow for a minute...", NH_BLACK); You("bask in its %s glow for a minute...", NH_BLACK);
godvoice(resp_god, "I believe it not!"); godvoice(resp_god, "I believe it not!");
monstseesu(M_SEEN_DISINT);
} }
if (Is_astralevel(&u.uz) || Is_sanctum(&u.uz)) { if (Is_astralevel(&u.uz) || Is_sanctum(&u.uz)) {
/* one more try for high altars */ /* one more try for high altars */
+1
View File
@@ -1628,6 +1628,7 @@ seffects(struct obj *sobj) /* sobj - scroll or fake spellbook for spell */
} }
else if (Fire_resistance) { else if (Fire_resistance) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_FIRE);
if (!Blind) if (!Blind)
pline("Oh, look, what a pretty fire in your %s.", pline("Oh, look, what a pretty fire in your %s.",
makeplural(body_part(HAND))); makeplural(body_part(HAND)));
+1
View File
@@ -1002,6 +1002,7 @@ inside_gas_cloud(genericptr_t p1, genericptr_t p2)
return FALSE; return FALSE;
} else { } else {
You("cough!"); You("cough!");
monstseesu(M_SEEN_POISON);
return FALSE; return FALSE;
} }
} else { /* A monster is inside the cloud */ } else { /* A monster is inside the cloud */
+5
View File
@@ -1251,6 +1251,7 @@ trapeffect_slp_gas_trap(
seetrap(trap); seetrap(trap);
if (Sleep_resistance || breathless(g.youmonst.data)) { if (Sleep_resistance || breathless(g.youmonst.data)) {
You("are enveloped in a cloud of gas!"); You("are enveloped in a cloud of gas!");
monstseesu(M_SEEN_SLEEP);
} else { } else {
pline("A cloud of gas puts you to sleep!"); pline("A cloud of gas puts you to sleep!");
fall_asleep(-rnd(25), TRUE); fall_asleep(-rnd(25), TRUE);
@@ -3525,6 +3526,7 @@ dofiretrap(
the(box ? xname(box) : surface(u.ux, u.uy))); the(box ? xname(box) : surface(u.ux, u.uy)));
if (Fire_resistance) { if (Fire_resistance) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_FIRE);
num = rn2(2); num = rn2(2);
} else if (Upolyd) { } else if (Upolyd) {
num = d(2, 4); num = d(2, 4);
@@ -5331,6 +5333,7 @@ chest_trap(
if (Shock_resistance) { if (Shock_resistance) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
You("don't seem to be affected."); You("don't seem to be affected.");
monstseesu(M_SEEN_ELEC);
dmg = 0; dmg = 0;
} else } else
dmg = d(4, 4); dmg = d(4, 4);
@@ -5763,6 +5766,8 @@ lava_effects(void)
You("sink into the %s%s!", hliquid("lava"), You("sink into the %s%s!", hliquid("lava"),
!boil_away ? ", but it only burns slightly" !boil_away ? ", but it only burns slightly"
: " and are about to be immolated"); : " and are about to be immolated");
if (Fire_resistance)
monstseesu(M_SEEN_FIRE);
if (u.uhp > 1) if (u.uhp > 1)
losehp(!boil_away ? 1 : (u.uhp / 2), lava_killer, losehp(!boil_away ? 1 : (u.uhp / 2), lava_killer,
KILLED_BY); /* lava damage */ KILLED_BY); /* lava damage */
+13 -1
View File
@@ -2004,6 +2004,7 @@ mhitm_ad_fire(struct monst *magr, struct attack *mattk, struct monst *mdef,
return; return;
} else if (Fire_resistance) { } else if (Fire_resistance) {
pline_The("fire doesn't feel hot!"); pline_The("fire doesn't feel hot!");
monstseesu(M_SEEN_FIRE);
mhm->damage = 0; mhm->damage = 0;
} }
if ((int) magr->m_lev > rn2(20)) 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!"); pline("You're covered in frost!");
if (Cold_resistance) { if (Cold_resistance) {
pline_The("frost doesn't seem cold!"); pline_The("frost doesn't seem cold!");
monstseesu(M_SEEN_COLD);
mhm->damage = 0; mhm->damage = 0;
} }
if ((int) magr->m_lev > rn2(20)) 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!"); You("get zapped!");
if (Shock_resistance) { if (Shock_resistance) {
pline_The("zap doesn't shock you!"); pline_The("zap doesn't shock you!");
monstseesu(M_SEEN_ELEC);
mhm->damage = 0; mhm->damage = 0;
} }
if ((int) magr->m_lev > rn2(20)) 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) { if (Acid_resistance) {
pline("You're covered in %s, but it seems harmless.", pline("You're covered in %s, but it seems harmless.",
hliquid("acid")); hliquid("acid"));
monstseesu(M_SEEN_ACID);
mhm->damage = 0; mhm->damage = 0;
} else { } else {
pline("You're covered in %s! It burns!", hliquid("acid")); 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); hitmsg(magr, mattk);
if (uncancelled && g.multi >= 0 && !rn2(5)) { if (uncancelled && g.multi >= 0 && !rn2(5)) {
if (Sleep_resistance) if (Sleep_resistance) {
monstseesu(M_SEEN_SLEEP);
return; return;
}
fall_asleep(-rnd(10), TRUE); fall_asleep(-rnd(10), TRUE);
if (Blind) if (Blind)
You("are put to sleep!"); You("are put to sleep!");
@@ -4881,6 +4887,8 @@ passive(struct monst *mon,
if (!Acid_resistance) if (!Acid_resistance)
mdamageu(mon, tmp); mdamageu(mon, tmp);
else
monstseesu(M_SEEN_ACID);
if (!rn2(30)) if (!rn2(30))
erode_armor(&g.youmonst, ERODE_CORRODE); erode_armor(&g.youmonst, ERODE_CORRODE);
} }
@@ -4945,6 +4953,7 @@ passive(struct monst *mon,
/* wrath of gods for attacking Oracle */ /* wrath of gods for attacking Oracle */
if (Antimagic) { if (Antimagic) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
monstseesu(M_SEEN_MAGR);
pline("A hail of magic missiles narrowly misses you!"); pline("A hail of magic missiles narrowly misses you!");
} else { } else {
You("are hit by magic missiles appearing from thin air!"); You("are hit by magic missiles appearing from thin air!");
@@ -5021,6 +5030,7 @@ passive(struct monst *mon,
if (Cold_resistance) { if (Cold_resistance) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
You_feel("a mild chill."); You_feel("a mild chill.");
monstseesu(M_SEEN_COLD);
ugolemeffects(AD_COLD, tmp); ugolemeffects(AD_COLD, tmp);
break; break;
} }
@@ -5044,6 +5054,7 @@ passive(struct monst *mon,
if (Fire_resistance) { if (Fire_resistance) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
You_feel("mildly warm."); You_feel("mildly warm.");
monstseesu(M_SEEN_FIRE);
ugolemeffects(AD_FIRE, tmp); ugolemeffects(AD_FIRE, tmp);
break; break;
} }
@@ -5055,6 +5066,7 @@ passive(struct monst *mon,
if (Shock_resistance) { if (Shock_resistance) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
You_feel("a mild tingle."); You_feel("a mild tingle.");
monstseesu(M_SEEN_ELEC);
ugolemeffects(AD_ELEC, tmp); ugolemeffects(AD_ELEC, tmp);
break; break;
} }
+15
View File
@@ -2411,6 +2411,7 @@ zapyourself(struct obj *obj, boolean ordinary)
if (Antimagic) { if (Antimagic) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
pline("Boing!"); pline("Boing!");
monstseesu(M_SEEN_MAGR);
} else { } else {
if (ordinary) { if (ordinary) {
You("bash yourself!"); You("bash yourself!");
@@ -2430,6 +2431,7 @@ zapyourself(struct obj *obj, boolean ordinary)
} else { } else {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
You("zap yourself, but seem unharmed."); You("zap yourself, but seem unharmed.");
monstseesu(M_SEEN_ELEC);
ugolemeffects(AD_ELEC, d(12, 6)); ugolemeffects(AD_ELEC, d(12, 6));
} }
destroy_item(WAND_CLASS, AD_ELEC); destroy_item(WAND_CLASS, AD_ELEC);
@@ -2447,6 +2449,7 @@ zapyourself(struct obj *obj, boolean ordinary)
if (Fire_resistance) { if (Fire_resistance) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
You_feel("rather warm."); You_feel("rather warm.");
monstseesu(M_SEEN_FIRE);
ugolemeffects(AD_FIRE, d(12, 6)); ugolemeffects(AD_FIRE, d(12, 6));
} else { } else {
pline("You've set yourself afire!"); pline("You've set yourself afire!");
@@ -2468,6 +2471,7 @@ zapyourself(struct obj *obj, boolean ordinary)
if (Cold_resistance) { if (Cold_resistance) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
You_feel("a little chill."); You_feel("a little chill.");
monstseesu(M_SEEN_COLD);
ugolemeffects(AD_COLD, d(12, 6)); ugolemeffects(AD_COLD, d(12, 6));
} else { } else {
You("imitate a popsicle!"); You("imitate a popsicle!");
@@ -2482,6 +2486,7 @@ zapyourself(struct obj *obj, boolean ordinary)
if (Antimagic) { if (Antimagic) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
pline_The("missiles bounce!"); pline_The("missiles bounce!");
monstseesu(M_SEEN_MAGR);
} else { } else {
damage = d(4, 6); damage = d(4, 6);
pline("Idiot! You've shot yourself!"); pline("Idiot! You've shot yourself!");
@@ -2551,6 +2556,7 @@ zapyourself(struct obj *obj, boolean ordinary)
if (Sleep_resistance) { if (Sleep_resistance) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
You("don't feel sleepy!"); You("don't feel sleepy!");
monstseesu(M_SEEN_SLEEP);
} else { } else {
pline_The("sleep ray hits you!"); pline_The("sleep ray hits you!");
fall_asleep(-rnd(50), TRUE); fall_asleep(-rnd(50), TRUE);
@@ -3875,6 +3881,7 @@ zhitu(int type, int nd, const char *fltxt, xchar sx, xchar sy)
if (Antimagic) { if (Antimagic) {
shieldeff(sx, sy); shieldeff(sx, sy);
pline_The("missiles bounce off!"); pline_The("missiles bounce off!");
monstseesu(M_SEEN_MAGR);
} else { } else {
dam = d(nd, 6); dam = d(nd, 6);
exercise(A_STR, FALSE); exercise(A_STR, FALSE);
@@ -3884,6 +3891,7 @@ zhitu(int type, int nd, const char *fltxt, xchar sx, xchar sy)
if (Fire_resistance) { if (Fire_resistance) {
shieldeff(sx, sy); shieldeff(sx, sy);
You("don't feel hot!"); You("don't feel hot!");
monstseesu(M_SEEN_FIRE);
ugolemeffects(AD_FIRE, d(nd, 6)); ugolemeffects(AD_FIRE, d(nd, 6));
} else { } else {
dam = d(nd, 6); dam = d(nd, 6);
@@ -3905,6 +3913,7 @@ zhitu(int type, int nd, const char *fltxt, xchar sx, xchar sy)
if (Cold_resistance) { if (Cold_resistance) {
shieldeff(sx, sy); shieldeff(sx, sy);
You("don't feel cold."); You("don't feel cold.");
monstseesu(M_SEEN_COLD);
ugolemeffects(AD_COLD, d(nd, 6)); ugolemeffects(AD_COLD, d(nd, 6));
} else { } else {
dam = d(nd, 6); dam = d(nd, 6);
@@ -3916,6 +3925,7 @@ zhitu(int type, int nd, const char *fltxt, xchar sx, xchar sy)
if (Sleep_resistance) { if (Sleep_resistance) {
shieldeff(u.ux, u.uy); shieldeff(u.ux, u.uy);
You("don't feel sleepy."); You("don't feel sleepy.");
monstseesu(M_SEEN_SLEEP);
} else { } else {
fall_asleep(-d(nd, 25), TRUE); /* sleep ray */ 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 (abstyp == ZT_BREATH(ZT_DEATH)) {
if (Disint_resistance) { if (Disint_resistance) {
You("are not disintegrated."); You("are not disintegrated.");
monstseesu(M_SEEN_DISINT);
break; break;
} else if (uarms) { } else if (uarms) {
/* destroy shield; other possessions are safe */ /* destroy shield; other possessions are safe */
@@ -3948,6 +3959,7 @@ zhitu(int type, int nd, const char *fltxt, xchar sx, xchar sy)
break; break;
} else if (Antimagic) { } else if (Antimagic) {
shieldeff(sx, sy); shieldeff(sx, sy);
monstseesu(M_SEEN_MAGR);
You("aren't affected."); You("aren't affected.");
break; break;
} }
@@ -3961,6 +3973,7 @@ zhitu(int type, int nd, const char *fltxt, xchar sx, xchar sy)
if (Shock_resistance) { if (Shock_resistance) {
shieldeff(sx, sy); shieldeff(sx, sy);
You("aren't affected."); You("aren't affected.");
monstseesu(M_SEEN_ELEC);
ugolemeffects(AD_ELEC, d(nd, 6)); ugolemeffects(AD_ELEC, d(nd, 6));
} else { } else {
dam = d(nd, 6); dam = d(nd, 6);
@@ -3977,6 +3990,7 @@ zhitu(int type, int nd, const char *fltxt, xchar sx, xchar sy)
case ZT_ACID: case ZT_ACID:
if (Acid_resistance) { if (Acid_resistance) {
pline_The("%s doesn't hurt.", hliquid("acid")); pline_The("%s doesn't hurt.", hliquid("acid"));
monstseesu(M_SEEN_ACID);
dam = 0; dam = 0;
} else { } else {
pline_The("%s burns!", hliquid("acid")); pline_The("%s burns!", hliquid("acid"));
@@ -4309,6 +4323,7 @@ dobuzz(int type, int nd, xchar sx, xchar sy, int dx, int dy,
"it"); "it");
} else } else
pline("For some reason you are not affected."); pline("For some reason you are not affected.");
monstseesu(M_SEEN_REFL);
dx = -dx; dx = -dx;
dy = -dy; dy = -dy;
shieldeff(sx, sy); shieldeff(sx, sy);