Adjust seenres on visible gear removal
If a monster sees you remove some piece of gear that grants a resistance, it will remove that resistance from its list of remembered resistances and be willing to try attacking you with that adtyp again. This avoids the situation where you put on a ring of cold, get hit with one cold attack, and then can remove it because all the monsters nearby will permanently remember you as being cold resistant (but even after this change a wily hero could still step into a niche and do it without any monsters seeing, so trick them into thinking she's still cold resistant...). The hero could still be resistant if there were multiple sources to begin with, of course, but the monsters will test it and learn that again if necessary. It's a little weird that the monsters can recognize the intrinsic granted by the item being removed, but they display knowledge of unidentified (by the hero) objects in many other circumstances too, so I hope it's forgivable in the pursuit of having them act more cleverly about resuming previously-resisted attacks like this. Another approach that avoids the gear recognition, blanking seenres on any gear change, can result in odd situations like orcs treating their own cloaks as potential sources of many different resistances, which also seems silly.
This commit is contained in:
committed by
Pasi Kallinen
parent
99683d94b4
commit
38cda5ad52
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user