/* TRUE iff monster is resistant to light-induced blindness */ boolean resists_blnd(const struct monst * mon) { const struct permonst *ptr = mon->data; boolean is_you = (mon == &youmonst); struct obj *o; if (is_you ? Blind : (mon->mblinded || !mon->mcansee || !haseyes(ptr) || /* BUG: temporary sleep sets mfrozen, but since paralysis does too, we can't check it */ mon->msleeping)) return TRUE; /* yellow light, Archon; !dust vortex, !cobra, !raven */ if (dmgtype_fromattack(ptr, AD_BLND, AT_EXPL) || dmgtype_fromattack(ptr, AD_BLND, AT_GAZE)) return TRUE; o = is_you ? uwep : MON_WEP(mon); if (o && o->oartifact && defends(AD_BLND, o)) return TRUE; o = is_you ? invent : mon->minvent; for (; o; o = o->nobj) if (o->oartifact && protects(AD_BLND, o)) return TRUE; return FALSE; }
/* returns TRUE if monster is drain-life resistant */ boolean resists_drli(struct monst *mon) { const struct permonst *ptr = mon->data; struct obj *wep = ((mon == &youmonst) ? uwep : MON_WEP(mon)); return (boolean)(is_undead(ptr) || is_demon(ptr) || is_were(ptr) || ptr == &mons[PM_DEATH] || (wep && wep->oartifact && defends(AD_DRLI, wep))); }
/* decide whether an artifact's special attacks apply against mtmp */ static int spec_applies(const struct artifact *weap, struct monst *mtmp) { const struct permonst *ptr; boolean yours; if (!(weap->spfx & (SPFX_DBONUS | SPFX_ATTK))) return weap->attk.adtyp == AD_PHYS; yours = (mtmp == &youmonst); ptr = mtmp->data; if (weap->spfx & SPFX_DMONS) { return ptr == &mons[(int)weap->mtype]; } else if (weap->spfx & SPFX_DCLAS) { return weap->mtype == (unsigned long)ptr->mlet; } else if (weap->spfx & SPFX_DFLAG1) { return (ptr->mflags1 & weap->mtype) != 0L; } else if (weap->spfx & SPFX_DFLAG2) { return ((ptr->mflags2 & weap->mtype) || (yours && ((!Upolyd && (urace.selfmask & weap->mtype)) || ((weap->mtype & M2_WERE) && u.ulycn >= LOW_PM)))); } else if (weap->spfx & SPFX_DALIGN) { return yours ? (u.ualign.type != weap->alignment) : (ptr->maligntyp == A_NONE || sgn(ptr->maligntyp) != weap->alignment); } else if (weap->spfx & SPFX_ATTK) { struct obj *defending_weapon = (yours ? uwep : MON_WEP(mtmp)); if (defending_weapon && defending_weapon->oartifact && defends((int)weap->attk.adtyp, defending_weapon)) return FALSE; switch(weap->attk.adtyp) { case AD_FIRE: return !(yours ? Fire_resistance : resists_fire(mtmp)); case AD_COLD: return !(yours ? Cold_resistance : resists_cold(mtmp)); case AD_ELEC: return !(yours ? Shock_resistance : resists_elec(mtmp)); case AD_MAGM: case AD_STUN: return !(yours ? Antimagic : (rn2(100) < ptr->mr)); case AD_DRST: return !(yours ? Poison_resistance : resists_poison(mtmp)); case AD_DRLI: return !(yours ? Drain_resistance : resists_drli(mtmp)); case AD_STON: return !(yours ? Stone_resistance : resists_ston(mtmp)); default: impossible("Weird weapon special attack."); } } return 0; }
/* TRUE if monster is magic-missile resistant */ boolean resists_magm(struct monst *mon) { const struct permonst *ptr = mon->data; struct obj *o; /* as of 3.2.0: gray dragons, Angels, Oracle, Yeenoghu */ if (dmgtype(ptr, AD_MAGM) || ptr == &mons[PM_BABY_GRAY_DRAGON] || dmgtype(ptr, AD_RBRE)) /* Chromatic Dragon */ return TRUE; /* check for magic resistance granted by wielded weapon */ o = (mon == &youmonst) ? uwep : MON_WEP(mon); if (o && o->oartifact && defends(AD_MAGM, o)) return TRUE; /* check for magic resistance granted by worn or carried items */ o = (mon == &youmonst) ? invent : mon->minvent; for ( ; o; o = o->nobj) if ((o->owornmask && objects[o->otyp].oc_oprop == ANTIMAGIC) || (o->oartifact && protects(AD_MAGM, o))) return TRUE; return FALSE; }