dragon armor properties

Special abilities conferred by wearing dragon armor was implemented in
a somewhat half-assed fashion; extend it to 3/4-assed.  Abilities came
from wearing dragon armor but not from being poly'd into a dragon or
for monsters that were wearing dragon armor or actually were dragons.
This covers much of that.

There are umpteen calls of 'resists_foo(mon)' and some are now
'resists_foo(mon) || defended(mon, AD_FOO)' but the second part ought
to be incorporated into update_mon_intrinics() so that the extra
'|| defended()' doesn't have to be spread all over the place and the
ones being put in now could/should be removed.

While testing, I noticed that a monster wielding Fire Brand did not
resist being hit by a wand of fire.  This fixes that and should also
fix various comparable situations for other artifacts.  But so far it
has only been done for zapping (and any other actions which use the
zapping code).  Folding defended() checks into update_mon_intrinsics()
matters more than that probably sounds.
This commit is contained in:
PatR
2021-12-25 10:26:44 -08:00
parent 4b525374d0
commit 439b6b7779
8 changed files with 158 additions and 65 deletions

View File

@@ -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));