diff --git a/include/extern.h b/include/extern.h index c4e33ba70..14a48f6a1 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1694,7 +1694,9 @@ extern const char *msummon_environ(struct permonst *, const char **); extern const struct permonst *raceptr(struct monst *); extern boolean olfaction(struct permonst *); unsigned long cvt_adtyp_to_mseenres(uchar); +unsigned long cvt_prop_to_mseenres(uchar); extern void monstseesu(unsigned long); +extern void monstunseesu(unsigned long); extern boolean resist_conflict(struct monst *); extern boolean mon_knows_traps(struct monst *, int); extern void mon_learns_traps(struct monst *, int); diff --git a/include/monst.h b/include/monst.h index 8bed8cf6e..2f4800283 100644 --- a/include/monst.h +++ b/include/monst.h @@ -88,7 +88,9 @@ enum m_seen_resistance { #define m_seenres(mon, mask) ((mon)->seen_resistance & (mask)) #define m_setseenres(mon, mask) ((mon)->seen_resistance |= (mask)) +#define m_clearseenres(mon, mask) ((mon)->seen_resistance &= ~(mask)) #define monstseesu_ad(adtyp) monstseesu(cvt_adtyp_to_mseenres(adtyp)) +#define monstunseesu_prop(prop) monstunseesu(cvt_prop_to_mseenres(prop)) struct monst { struct monst *nmon; diff --git a/src/mondata.c b/src/mondata.c index 312920c75..282da195a 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -1450,7 +1450,25 @@ cvt_adtyp_to_mseenres(uchar adtyp) } } -/* Monsters remember hero resisting effect M_SEEN_foo */ +/* Convert property resistance to M_SEEN_bar */ +unsigned long +cvt_prop_to_mseenres(uchar prop) +{ + switch (prop) { + case ANTIMAGIC: return M_SEEN_MAGR; + case FIRE_RES: return M_SEEN_FIRE; + case COLD_RES: return M_SEEN_COLD; + case SLEEP_RES: return M_SEEN_SLEEP; + case DISINT_RES: return M_SEEN_DISINT; + case POISON_RES: return M_SEEN_POISON; + case SHOCK_RES: return M_SEEN_ELEC; + case ACID_RES: return M_SEEN_ACID; + case REFLECTING: return M_SEEN_REFL; + default: return M_SEEN_NOTHING; + } +} + +/* Monsters in line of sight remember hero resisting effect M_SEEN_foo */ void monstseesu(unsigned long seenres) { @@ -1464,6 +1482,20 @@ monstseesu(unsigned long seenres) m_setseenres(mtmp, seenres); } +/* Monsters in line of sight forget hero resistance to M_SEEN_foo */ +void +monstunseesu(unsigned long seenres) +{ + struct monst *mtmp; + + if (seenres == M_SEEN_NOTHING || u.uswallow) + return; + + for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) + if (!DEADMONSTER(mtmp) && m_canseeu(mtmp)) + m_clearseenres(mtmp, seenres); +} + /* Can monster resist conflict caused by hero? High-CHA heroes will be able to 'convince' monsters diff --git a/src/worn.c b/src/worn.c index f09ea5374..96ba2ddd2 100644 --- a/src/worn.c +++ b/src/worn.c @@ -71,6 +71,10 @@ setworn(struct obj *obj, long mask) p = objects[oobj->otyp].oc_oprop; u.uprops[p].extrinsic = u.uprops[p].extrinsic & ~wp->w_mask; + /* if the hero removed an extrinsic-granting item, + nearby monsters will notice and attempt attacks of + that type again */ + monstunseesu_prop(p); if ((p = w_blocks(oobj, mask)) != 0) u.uprops[p].blocked &= ~wp->w_mask; if (oobj->oartifact) @@ -132,6 +136,7 @@ setnotworn(struct obj *obj) *(wp->w_obj) = (struct obj *) 0; p = objects[obj->otyp].oc_oprop; u.uprops[p].extrinsic = u.uprops[p].extrinsic & ~wp->w_mask; + monstunseesu_prop(p); /* remove this extrinsic from seenres */ obj->owornmask &= ~wp->w_mask; if (obj->oartifact) set_artifact_intrinsic(obj, 0, wp->w_mask);