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:
@@ -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 *);
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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" */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
83
src/uhitm.c
83
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;
|
||||
|
||||
|
||||
18
src/worn.c
18
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;
|
||||
|
||||
19
src/zap.c
19
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user