diff --git a/include/extern.h b/include/extern.h index 3fd48ac1d..6fa48fd2e 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1495,6 +1495,7 @@ extern struct attack *attacktype_fordmg(struct permonst *, int, int); extern boolean attacktype(struct permonst *, int); extern boolean noattacks(struct permonst *); extern boolean poly_when_stoned(struct permonst *); +extern boolean defended(struct monst *, int); extern boolean resists_drli(struct monst *); extern boolean resists_magm(struct monst *); extern boolean resists_blnd(struct monst *); diff --git a/src/artifact.c b/src/artifact.c index 3458f1855..d94487642 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -384,7 +384,7 @@ restrict_name(struct obj *otmp, const char *name) static boolean attacks(int adtyp, struct obj *otmp) { - register const struct artifact *weap; + const struct artifact *weap; if ((weap = get_artifact(otmp)) != 0) return (boolean) (weap->attk.adtyp == adtyp); @@ -394,10 +394,48 @@ attacks(int adtyp, struct obj *otmp) boolean defends(int adtyp, struct obj *otmp) { - register const struct artifact *weap; + struct artifact *weap; if ((weap = get_artifact(otmp)) != 0) return (boolean) (weap->defn.adtyp == adtyp); + if (Is_dragon_armor(otmp)) { + int otyp = otmp->otyp; + + /* convert mail to scales to simplify testing */ + if (Is_dragon_mail(otmp)) + otyp += GRAY_DRAGON_SCALES - GRAY_DRAGON_SCALE_MAIL; + + switch (adtyp) { + case AD_MAGM: /* magic missiles => general magic resistance */ + return (otyp == GRAY_DRAGON_SCALES); + case AD_HALU: /* confers hallucination resistance */ + return (otyp == GOLD_DRAGON_SCALES); + case AD_FIRE: + /*case AD_BLND: -- gives infravision but does not prevent blindness */ + return (otyp == RED_DRAGON_SCALES); /* red but not gold */ + case AD_COLD: + /*case AD_FAMN: -- slows digestion but does not override Famine */ + return (otyp == WHITE_DRAGON_SCALES); /* white but not silver */ + case AD_DRST: /* drain strength => poison */ + case AD_DISE: /* blocks disease but not slime */ + return (otyp == GREEN_DRAGON_SCALES); + case AD_SLEE: /* sleep */ + case AD_PLYS: /* paralysis => free action */ + return (otyp == ORANGE_DRAGON_SCALES); + case AD_DISN: /* disintegration */ + case AD_DRLI: /* level drain resistance */ + return (otyp == BLACK_DRAGON_SCALES); + case AD_ELEC: /* electricity == lightning */ + case AD_SLOW: /* confers speed so blocks speed removal */ + return (otyp == BLUE_DRAGON_SCALES); + case AD_ACID: + case AD_STON: /* petrification resistance */ + return (otyp == YELLOW_DRAGON_SCALES); + default: + /* SILVER_DRAGON_SCALES don't resist any particular attack type */ + break; + } + } return FALSE; } @@ -405,7 +443,7 @@ defends(int adtyp, struct obj *otmp) boolean defends_when_carried(int adtyp, struct obj *otmp) { - register const struct artifact *weap; + const struct artifact *weap; if ((weap = get_artifact(otmp)) != 0) return (boolean) (weap->cary.adtyp == adtyp); @@ -739,11 +777,9 @@ spec_applies(const struct artifact *weap, struct monst *mtmp) : (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)) + if (defended(mtmp, (int) weap->attk.adtyp)) return FALSE; + switch (weap->attk.adtyp) { case AD_FIRE: return !(yours ? Fire_resistance : resists_fire(mtmp)); diff --git a/src/mhitm.c b/src/mhitm.c index 234515594..e3bf647b6 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1064,7 +1064,7 @@ paralyze_monst(struct monst *mon, int amt) int sleep_monst(struct monst *mon, int amt, int how) { - if (resists_sleep(mon) + if (resists_sleep(mon) || defended(mon, AD_SLEE) || (how >= 0 && resist(mon, (char) how, 0, NOTELL))) { shieldeff(mon->mx, mon->my); } else if (mon->mcanmove) { diff --git a/src/mhitu.c b/src/mhitu.c index c4446ba9d..99adda4a2 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1392,7 +1392,7 @@ explmu(struct monst *mtmp, struct attack *mattk, boolean ufound) return MM_MISS; tmp = d((int) mattk->damn, (int) mattk->damd); - not_affected = defends((int) mattk->adtyp, uwep); + not_affected = defended(mtmp, (int) mattk->adtyp); if (!ufound) { pline("%s explodes at a spot in %s!", @@ -1642,7 +1642,7 @@ gazemu(struct monst *mtmp, struct attack *mattk) break; case AD_SLOW: if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) && mtmp->mcansee - && (HFast & (INTRINSIC | TIMEOUT)) && !defends(AD_SLOW, uwep) + && (HFast & (INTRINSIC | TIMEOUT)) && !defended(mtmp, AD_SLOW) && !rn2(4)) { if (cancelled) { react = 7; /* "dulled" */ diff --git a/src/mondata.c b/src/mondata.c index 8e11b89c1..a45e7b871 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -76,7 +76,7 @@ noattacks(struct permonst* ptr) /* does monster-type transform into something else when petrified? */ boolean -poly_when_stoned(struct permonst* ptr) +poly_when_stoned(struct permonst *ptr) { /* non-stone golems turn into stone golems unless latter is genocided */ return (boolean) (is_golem(ptr) && ptr != &mons[PM_STONE_GOLEM] @@ -84,20 +84,56 @@ poly_when_stoned(struct permonst* ptr) /* allow G_EXTINCT */ } +/* is 'mon' (possibly youmonst) protected against damage type 'adtype' via + wielded weapon or worn dragon scales? [or by virtue of being a dragon?] */ +boolean +defended(struct monst *mon, int adtyp) +{ + struct obj *o, otemp; + int mndx; + boolean is_you = (mon == &g.youmonst); + + /* is 'mon' wielding an artifact that protects against 'adtyp'? */ + o = is_you ? uwep : MON_WEP(mon); + if (o && o->oartifact && defends(adtyp, o)) + return TRUE; + + /* if 'mon' is an adult dragon, treat it as if it was wearing scales + so that it has the same benefit as a hero wearing dragon scales */ + mndx = monsndx(mon->data); + if (mndx >= PM_GRAY_DRAGON && mndx <= PM_YELLOW_DRAGON) { + /* a dragon is its own suit... if mon is poly'd hero, we don't + care about embedded scales (uskin) because being a dragon with + embedded scales is no better than just being a dragon */ + otemp = cg.zeroobj; + otemp.oclass = ARMOR_CLASS; + otemp.otyp = GRAY_DRAGON_SCALES + (mndx - PM_GRAY_DRAGON); + /* defends() and Is_dragon_armor() only care about otyp so ignore + the rest of otemp's fields */ + o = &otemp; + } else { + /* ordinary case: not an adult dragon */ + o = is_you ? uarm : which_armor(mon, W_ARM); + } + /* is 'mon' wearing dragon scales that protect against 'adtyp'? */ + if (o && Is_dragon_armor(o) && defends(adtyp, o)) + return TRUE; + + return FALSE; +} + /* returns True if monster is drain-life resistant */ boolean -resists_drli(struct monst* mon) +resists_drli(struct monst *mon) { struct permonst *ptr = mon->data; - struct obj *wep; if (is_undead(ptr) || is_demon(ptr) || is_were(ptr) /* is_were() doesn't handle hero in human form */ || (mon == &g.youmonst && u.ulycn >= LOW_PM) || ptr == &mons[PM_DEATH] || is_vampshifter(mon)) return TRUE; - wep = (mon == &g.youmonst) ? uwep : MON_WEP(mon); - return (boolean) (wep && wep->oartifact && defends(AD_DRLI, wep)); + return defended(mon, AD_DRLI); } /* True if monster is magic-missile (actually, general magic) resistant */ diff --git a/src/uhitm.c b/src/uhitm.c index 61ea2213a..8303c0090 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1905,8 +1905,9 @@ mhitm_ad_dren(struct monst *magr, struct attack *mattk, struct monst *mdef, } void -mhitm_ad_drli(struct monst *magr, struct attack *mattk, struct monst *mdef, - struct mhitm_data *mhm) +mhitm_ad_drli( + struct monst *magr, struct attack *mattk, + struct monst *mdef, struct mhitm_data *mhm) { if (magr == &g.youmonst) { /* uhitm */ @@ -1914,7 +1915,8 @@ mhitm_ad_drli(struct monst *magr, struct attack *mattk, struct monst *mdef, /* since hero can't be cancelled, only defender's armor applies */ boolean negated = !(rn2(10) >= 3 * armpro); - if (!negated && !rn2(3) && !resists_drli(mdef)) { + if (!negated && !rn2(3) + && !(resists_drli(mdef) || defended(mdef, AD_FIRE))) { mhm->damage = d(2, 6); /* Stormbringer uses monhp_per_lvl * (usually 1d8) */ pline("%s becomes weaker!", Monnam(mdef)); @@ -1958,8 +1960,9 @@ mhitm_ad_drli(struct monst *magr, struct attack *mattk, struct monst *mdef, int armpro = magic_negation(mdef); boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); - if (!cancelled && !rn2(3) && !resists_drli(mdef)) { - mhm->damage = d(2, 6); /* Stormbringer uses monhp_per_lvl(usually 1d8) */ + if (!cancelled && !rn2(3) + && !(resists_drli(mdef) || defended(mdef, AD_DRLI))) { + mhm->damage = d(2, 6); /* Stormbringer uses monhp_per_lvl (1d8) */ if (g.vis && canspotmon(mdef)) pline("%s becomes weaker!", Monnam(mdef)); if (mdef->mhpmax - mhm->damage > (int) mdef->m_lev) { @@ -1982,8 +1985,9 @@ mhitm_ad_drli(struct monst *magr, struct attack *mattk, struct monst *mdef, } void -mhitm_ad_fire(struct monst *magr, struct attack *mattk, struct monst *mdef, - struct mhitm_data *mhm) +mhitm_ad_fire( + struct monst *magr, struct attack *mattk, + struct monst *mdef, struct mhitm_data *mhm) { struct permonst *pd = mdef->data; @@ -2017,7 +2021,7 @@ mhitm_ad_fire(struct monst *magr, struct attack *mattk, struct monst *mdef, } mhm->damage += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE); mhm->damage += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE); - if (resists_fire(mdef)) { + if (resists_fire(mdef) || defended(mdef, AD_FIRE)) { if (!Blind) pline_The("fire doesn't heat %s!", mon_nam(mdef)); golemeffects(mdef, AD_FIRE, mhm->damage); @@ -2087,7 +2091,7 @@ mhitm_ad_fire(struct monst *magr, struct attack *mattk, struct monst *mdef, } mhm->damage += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE); mhm->damage += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE); - if (resists_fire(mdef)) { + if (resists_fire(mdef) || defended(mdef, AD_FIRE)) { if (g.vis && canseemon(mdef)) pline_The("fire doesn't seem to burn %s!", mon_nam(mdef)); shieldeff(mdef->mx, mdef->my); @@ -2101,8 +2105,9 @@ mhitm_ad_fire(struct monst *magr, struct attack *mattk, struct monst *mdef, } void -mhitm_ad_cold(struct monst *magr, struct attack *mattk, struct monst *mdef, - struct mhitm_data *mhm) +mhitm_ad_cold( + struct monst *magr, struct attack *mattk, + struct monst *mdef, struct mhitm_data *mhm) { if (magr == &g.youmonst) { /* uhitm */ @@ -2116,7 +2121,7 @@ mhitm_ad_cold(struct monst *magr, struct attack *mattk, struct monst *mdef, } if (!Blind) pline("%s is covered in frost!", Monnam(mdef)); - if (resists_cold(mdef)) { + if (resists_cold(mdef) || defended(mdef, AD_COLD)) { shieldeff(mdef->mx, mdef->my); if (!Blind) pline_The("frost doesn't chill %s!", mon_nam(mdef)); @@ -2152,7 +2157,7 @@ mhitm_ad_cold(struct monst *magr, struct attack *mattk, struct monst *mdef, } if (g.vis && canseemon(mdef)) pline("%s is covered in frost!", Monnam(mdef)); - if (resists_cold(mdef)) { + if (resists_cold(mdef) || defended(mdef, AD_COLD)) { if (g.vis && canseemon(mdef)) pline_The("frost doesn't seem to chill %s!", mon_nam(mdef)); shieldeff(mdef->mx, mdef->my); @@ -2164,8 +2169,9 @@ mhitm_ad_cold(struct monst *magr, struct attack *mattk, struct monst *mdef, } void -mhitm_ad_elec(struct monst *magr, struct attack *mattk, struct monst *mdef, - struct mhitm_data *mhm) +mhitm_ad_elec( + struct monst *magr, struct attack *mattk, + struct monst *mdef, struct mhitm_data *mhm) { if (magr == &g.youmonst) { /* uhitm */ @@ -2180,7 +2186,7 @@ mhitm_ad_elec(struct monst *magr, struct attack *mattk, struct monst *mdef, if (!Blind) pline("%s is zapped!", Monnam(mdef)); mhm->damage += destroy_mitem(mdef, WAND_CLASS, AD_ELEC); - if (resists_elec(mdef)) { + if (resists_elec(mdef) || defended(mdef, AD_ELEC)) { if (!Blind) pline_The("zap doesn't shock %s!", mon_nam(mdef)); golemeffects(mdef, AD_ELEC, mhm->damage); @@ -2220,7 +2226,7 @@ mhitm_ad_elec(struct monst *magr, struct attack *mattk, struct monst *mdef, if (g.vis && canseemon(mdef)) pline("%s gets zapped!", Monnam(mdef)); mhm->damage += destroy_mitem(mdef, WAND_CLASS, AD_ELEC); - if (resists_elec(mdef)) { + if (resists_elec(mdef) || defended(mdef, AD_ELEC)) { if (g.vis && canseemon(mdef)) pline_The("zap doesn't shock %s!", mon_nam(mdef)); shieldeff(mdef->mx, mdef->my); @@ -2233,12 +2239,13 @@ mhitm_ad_elec(struct monst *magr, struct attack *mattk, struct monst *mdef, } void -mhitm_ad_acid(struct monst *magr, struct attack *mattk, struct monst *mdef, - struct mhitm_data *mhm) +mhitm_ad_acid( + struct monst *magr, struct attack *mattk, + struct monst *mdef, struct mhitm_data *mhm) { if (magr == &g.youmonst) { /* uhitm */ - if (resists_acid(mdef)) + if (resists_acid(mdef) || defended(mdef, AD_ACID)) mhm->damage = 0; } else if (mdef == &g.youmonst) { /* mhitu */ @@ -2261,7 +2268,7 @@ mhitm_ad_acid(struct monst *magr, struct attack *mattk, struct monst *mdef, mhm->damage = 0; return; } - if (resists_acid(mdef)) { + if (resists_acid(mdef) || defended(mdef, AD_ACID)) { if (g.vis && canseemon(mdef)) pline("%s is covered in %s, but it seems harmless.", Monnam(mdef), hliquid("acid")); @@ -2279,8 +2286,9 @@ mhitm_ad_acid(struct monst *magr, struct attack *mattk, struct monst *mdef, /* steal gold */ void -mhitm_ad_sgld(struct monst *magr, struct attack *mattk, struct monst *mdef, - struct mhitm_data *mhm) +mhitm_ad_sgld( + struct monst *magr, struct attack *mattk, + struct monst *mdef, struct mhitm_data *mhm) { struct permonst *pa = magr->data; struct permonst *pd = mdef->data; @@ -3085,9 +3093,13 @@ mhitm_ad_ench(struct monst *magr, struct attack *mattk, struct monst *mdef, } void -mhitm_ad_slow(struct monst *magr, struct attack *mattk, struct monst *mdef, - struct mhitm_data *mhm UNUSED) +mhitm_ad_slow( + struct monst *magr, struct attack *mattk, + struct monst *mdef, struct mhitm_data *mhm UNUSED) { + if (defended(mdef, AD_SLOW)) + return; + if (magr == &g.youmonst) { /* uhitm */ int armpro = magic_negation(mdef); @@ -3107,7 +3119,7 @@ mhitm_ad_slow(struct monst *magr, struct attack *mattk, struct monst *mdef, boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); hitmsg(magr, mattk); - if (uncancelled && HFast && !defends(AD_SLOW, uwep) && !rn2(4)) + if (uncancelled && HFast && !rn2(4)) u_slow_down(); } else { /* mhitm */ @@ -3930,10 +3942,10 @@ mhitm_ad_samu(struct monst *magr, struct attack *mattk, struct monst *mdef, /* disease */ void -mhitm_ad_dise(struct monst *magr, struct attack *mattk, struct monst *mdef, - struct mhitm_data *mhm) +mhitm_ad_dise( + struct monst *magr, struct attack *mattk, + struct monst *mdef, struct mhitm_data *mhm) { - struct obj *mwep; struct permonst *pa = magr->data, *pd = mdef->data; if (magr == &g.youmonst) { @@ -3948,11 +3960,11 @@ mhitm_ad_dise(struct monst *magr, struct attack *mattk, struct monst *mdef, mhm->damage = 0; } else { mhitm_dise: - /* mhitm; protected monsters use the same criteria as for - poly'd hero gaining sick resistance combined with any hero - [hypothetically] wielding a weapon that guards against disease */ + /* mhitm; protected monsters use the same criteria as for poly'd + hero gaining sick resistance combined with any hero wielding a + weapon or wearing dragon scales/mail that guards against disease */ if (pd->mlet == S_FUNGUS || pd == &mons[PM_GHOUL] - || ((mwep = MON_WEP(mdef)) != 0 && defends(AD_DISE, mwep))) + || defended(mdef, AD_DISE)) mhm->damage = 0; /* else does ordinary damage */ } @@ -3960,8 +3972,9 @@ mhitm_ad_dise(struct monst *magr, struct attack *mattk, struct monst *mdef, /* seduce and also steal item */ void -mhitm_ad_sedu(struct monst *magr, struct attack *mattk, struct monst *mdef, - struct mhitm_data *mhm) +mhitm_ad_sedu( + struct monst *magr, struct attack *mattk, + struct monst *mdef, struct mhitm_data *mhm) { struct permonst *pa = magr->data; diff --git a/src/worn.c b/src/worn.c index a774b0b02..9252e33a8 100644 --- a/src/worn.c +++ b/src/worn.c @@ -337,7 +337,8 @@ mon_adjust_speed(struct monst *mon, but objects[ALCHEMY_SMOCK].oc_oprop can only describe one of them; if it is poison resistance, alternate property is acid resistance; if someone changes it to acid resistance, alt becomes posion resist; - if someone changes it to hallucination resistance, all bets are off */ + if someone changes it to hallucination resistance, all bets are off + [TODO: handle alternate propertices conferred by dragon scales/mail] */ #define altprop(o) \ (((o)->otyp == ALCHEMY_SMOCK) \ ? (POISON_RES + ACID_RES - objects[(o)->otyp].oc_oprop) \ @@ -346,8 +347,11 @@ mon_adjust_speed(struct monst *mon, /* armor put on or taken off; might be magical variety [TODO: rename to 'update_mon_extrinsics()' and change all callers...] */ void -update_mon_intrinsics(struct monst *mon, struct obj *obj, boolean on, - boolean silently) +update_mon_intrinsics( + struct monst *mon, + struct obj *obj, /* armor being worn or taken off */ + boolean on, + boolean silently) { int unseen; uchar mask; @@ -356,7 +360,7 @@ update_mon_intrinsics(struct monst *mon, struct obj *obj, boolean on, altwhich = altprop(obj); unseen = !canseemon(mon); - if (!which) + if (!which && !altwhich) goto maybe_blocks; again: @@ -376,6 +380,7 @@ update_mon_intrinsics(struct monst *mon, struct obj *obj, boolean on, /* properties handled elsewhere */ case ANTIMAGIC: case REFLECTING: + case PROTECTION: break; /* properties which have no effect for monsters */ case CLAIRVOYANT: @@ -384,16 +389,17 @@ update_mon_intrinsics(struct monst *mon, struct obj *obj, boolean on, break; /* properties which should have an effect but aren't implemented */ case LEVITATION: + case FLYING: case WWALKING: break; /* properties which maybe should have an effect but don't */ case DISPLACED: case FUMBLING: case JUMPING: - case PROTECTION: break; default: - if (which <= 8) { /* 1 thru 8 correspond to MR_xxx mask values */ + /* 1 through 8 correspond to MR_xxx mask values */ + if (which >= 1 && which <= 8) { /* FIRE,COLD,SLEEP,DISINT,SHOCK,POISON,ACID,STONE */ mask = (uchar) (1 << (which - 1)); mon->mextrinsics |= (unsigned short) mask; diff --git a/src/zap.c b/src/zap.c index 56fc9eaac..5afd48f59 100644 --- a/src/zap.c +++ b/src/zap.c @@ -3757,7 +3757,7 @@ zhitm( *ootmp = (struct obj *) 0; switch (abstype) { case ZT_MAGIC_MISSILE: - if (resists_magm(mon)) { + if (resists_magm(mon) || defended(mon, AD_MAGM)) { sho_shieldeff = TRUE; break; } @@ -3766,7 +3766,7 @@ zhitm( tmp = spell_damage_bonus(tmp); break; case ZT_FIRE: - if (resists_fire(mon)) { + if (resists_fire(mon) || defended(mon, AD_FIRE)) { sho_shieldeff = TRUE; break; } @@ -3788,7 +3788,7 @@ zhitm( } break; case ZT_COLD: - if (resists_cold(mon)) { + if (resists_cold(mon) || defended(mon, AD_COLD)) { sho_shieldeff = TRUE; break; } @@ -3801,6 +3801,7 @@ zhitm( (void) destroy_mitem(mon, POTION_CLASS, AD_COLD); break; case ZT_SLEEP: + /* possibly resistance and shield effect handled by sleep_monst() */ tmp = 0; (void) sleep_monst(mon, d(nd, 25), type == ZT_WAND(ZT_SLEEP) ? WAND_CLASS : '\0'); @@ -3825,18 +3826,18 @@ zhitm( } else { struct obj *otmp2; - if (resists_disint(mon)) { + if (resists_disint(mon) || defended(mon, AD_DISN)) { sho_shieldeff = TRUE; } else if (mon->misc_worn_check & W_ARMS) { /* destroy shield; victim survives */ *ootmp = which_armor(mon, W_ARMS); } else if (mon->misc_worn_check & W_ARM) { - /* destroy body armor, also cloak if present */ + /* destroy suit, also cloak if present */ *ootmp = which_armor(mon, W_ARM); if ((otmp2 = which_armor(mon, W_ARMC)) != 0) m_useup(mon, otmp2); } else { - /* no body armor, victim dies; destroy cloak + /* no suit, victim dies; destroy cloak and shirt now in case target gets life-saved */ tmp = MAGIC_COOKIE; if ((otmp2 = which_armor(mon, W_ARMC)) != 0) @@ -3850,7 +3851,7 @@ zhitm( tmp = mon->mhp + 1; break; case ZT_LIGHTNING: - if (resists_elec(mon)) { + if (resists_elec(mon) || defended(mon, AD_ELEC)) { sho_shieldeff = TRUE; tmp = 0; /* can still blind the monster */ @@ -3874,14 +3875,14 @@ zhitm( (void) destroy_mitem(mon, RING_CLASS, AD_ELEC); break; case ZT_POISON_GAS: - if (resists_poison(mon)) { + if (resists_poison(mon) || defended(mon, AD_DRST)) { sho_shieldeff = TRUE; break; } tmp = d(nd, 6); break; case ZT_ACID: - if (resists_acid(mon)) { + if (resists_acid(mon) || defended(mon, AD_ACID)) { sho_shieldeff = TRUE; break; }