Skip to content

Commit

Permalink
Refactored resistance to drain-life into it's own MR_DRAIN flag. This…
Browse files Browse the repository at this point in the history
… was in response to issue #497, where vampiric mplayers were not correctly inheriting drain resistance from their race.
  • Loading branch information
elunna committed Oct 8, 2023
1 parent 3aec9f5 commit 9fcff5a
Show file tree
Hide file tree
Showing 10 changed files with 256 additions and 174 deletions.
16 changes: 1 addition & 15 deletions include/mondata.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#define resists_ston(mon) ((mon_resistancebits(mon) & MR_STONE) != 0)
#define resists_psychic(mon) ((mon_resistancebits(mon) & MR_PSYCHIC) != 0)
#define resists_clob(mon) ((mon_resistancebits(mon) & MR_CLOB) != 0)
#define resists_drain(mon) ((mon_resistancebits(mon) & MR_DRAIN) != 0)

#define has_telepathy(mon) \
(telepathic(r_data(mon)) \
Expand Down Expand Up @@ -85,21 +86,6 @@
|| (ptr) == &mons[PM_ARCHANGEL] \
|| dmgtype((ptr), AD_RBRE)) /* Tiamat */

#define resists_drain(ptr) \
( is_undead(ptr) \
|| is_demon(ptr) \
|| is_were(ptr) \
|| (ptr) == &mons[PM_DEATH] \
|| (ptr) == &mons[PM_BABY_DEEP_DRAGON] \
|| (ptr) == &mons[PM_DEEP_DRAGON] \
|| (ptr) == &mons[PM_CERBERUS] \
|| (ptr) == &mons[PM_JUGGERNAUT] \
|| (ptr) == &mons[PM_SHADOW_OGRE] \
|| (ptr) == &mons[PM_SHADOW_WOLF] \
|| (ptr) == &mons[PM_UNDEAD_SLAYER] \
|| (ptr) == &mons[PM_VAMPIRIC] \
|| (ptr) == &mons[PM_WATER_MAGE] \
|| (ptr) == &mons[PM_NIGHTMARE])
/* is_were() doesn't handle hero in human form */

/* is_vampshifter(mon) in handled explicitly in zap.c */
Expand Down
1 change: 1 addition & 0 deletions include/monflag.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
#define MR_PSYCHIC 0x00000100L /* resists psychic */
#define MR_CLOB 0x00000200L /* resists knockback */
#define MR_SONIC 0x00000400L /* resists sonic */
#define MR_DRAIN 0x00000800L /* resists life-drain */

/* other resistances: magic, sickness */
/* other conveyances: teleport, teleport control, telepathy */
Expand Down
8 changes: 4 additions & 4 deletions src/mhitm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2213,7 +2213,7 @@ struct obj **ootmp; /* to return worn armor for caller to disintegrate */
}
break;
case AD_DRLI: {
boolean resists_drain = (resists_drli(mdef) || defended(mdef, AD_DRLI));
boolean unaffected = (resists_drli(mdef) || defended(mdef, AD_DRLI));
boolean V2V = is_vampiric(mdef->data) && is_vampiric(magr->data);

if (!cancelled) {
Expand All @@ -2232,7 +2232,7 @@ struct obj **ootmp; /* to return worn armor for caller to disintegrate */
EDOG(magr)->hungrytime +=
((int) ((mdef->data)->cnutrit / 20) + 1);
}
if (!rn2(3) && (!resists_drain || V2V)) {
if (!rn2(3) && (!unaffected || V2V)) {
tmp = d(2, 6);
if (vis && canspotmon(mdef))
pline("%s suddenly seems weaker!", Monnam(mdef));
Expand Down Expand Up @@ -3457,9 +3457,9 @@ struct obj *mwep;
}
break;
case AD_DRLI: {
boolean resists_drain = (resists_drli(magr) || defended(magr, AD_DRLI));
boolean unaffected = (resists_drli(magr) || defended(magr, AD_DRLI));
if (mhit && !magr->mcan && !rn2(3)) {
if ((!resists_drain)) {
if ((!unaffected)) {
tmp = d(2, 6);
if (vis && canspotmon(magr))
pline("%s suddenly seems weaker!", Monnam(magr));
Expand Down
4 changes: 2 additions & 2 deletions src/mhitu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1937,12 +1937,12 @@ register struct attack *mattk;
break;
case AD_DRLI:
hitmsg(mtmp, mattk);
boolean resists_drain = Drain_resistance || defended(&youmonst, AD_DRLI);
boolean unaffected = Drain_resistance || defended(&youmonst, AD_DRLI);
boolean V2V = maybe_polyd(is_vampiric(youmonst.data), Race_if(PM_VAMPIRIC))
&& (is_vampiric(mtmp->data) || mtmp->data == &mons[PM_BLOOD_IMP]);

if (!shield_blockable(mtmp, mattk) && uncancelled && !rn2(3)) {
if (mattk->aatyp == AT_BITE && (!resists_drain || V2V)) {
if (mattk->aatyp == AT_BITE && (!unaffected || V2V)) {
/* if vampire biting (and also a pet) */
Your("blood is being drained!");
if (mtmp->mtame && !mtmp->isminion)
Expand Down
3 changes: 2 additions & 1 deletion src/mondata.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,12 @@ struct monst *mon;
struct obj *armor;
long slotmask;

if (resists_drain(ptr) || is_vampshifter(mon)
if (resists_drain(mon) || is_vampshifter(mon)
|| (mon == &youmonst && (u.ulycn >= LOW_PM || Invulnerable)))
return TRUE;
armor = (mon == &youmonst) ? invent : mon->minvent;
slotmask = W_ARMOR | W_ACCESSORY;

/* check for drain res object property */
for (; armor; armor = armor->nobj) {
if ((armor->owornmask & slotmask) != 0L
Expand Down
389 changes: 241 additions & 148 deletions src/monst.c

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/pager.c
Original file line number Diff line number Diff line change
Expand Up @@ -876,7 +876,7 @@ struct permonst * pm;
ADDRESIST(pm_resistance(pm, MR_SONIC), "sonic");
ADDRESIST(pm_resistance(pm, MR_PSYCHIC), "psionic attacks");
ADDRESIST(pm_resistance(pm, MR_CLOB), "hurtle");
ADDRESIST(resists_drain(pm), "life-drain");
ADDRESIST(pm_resistance(pm, MR_DRAIN), "life-drain");
ADDRESIST(resists_sick(pm), "sickness");
ADDRESIST(resists_mgc(pm), "magic");
ADDRESIST(resists_stun(pm), "stun");
Expand Down
2 changes: 1 addition & 1 deletion src/polyself.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ set_uasmon()
PROPSET(STONE_RES, resists_ston(&youmonst));
PROPSET(SONIC_RES, resists_sonic(&youmonst));
PROPSET(PSYCHIC_RES, resists_psychic(&youmonst));
PROPSET(DRAIN_RES, resists_drain(racedat));
PROPSET(DRAIN_RES, resists_drain(&youmonst));
PROPSET(STUN_RES, resists_stun(racedat));

/* Vulnerablilties */
Expand Down
4 changes: 2 additions & 2 deletions src/uhitm.c
Original file line number Diff line number Diff line change
Expand Up @@ -3354,11 +3354,11 @@ int specialdmg; /* blessed and/or silver bonus against various things */
tmp = 0;
break;
case AD_DRLI: {
boolean resists_drain = (resists_drli(mdef) || defended(mdef, AD_DRLI));
boolean unaffected = (resists_drli(mdef) || defended(mdef, AD_DRLI));
boolean V2V = maybe_polyd(is_vampiric(youmonst.data), Race_if(PM_VAMPIRIC))
&& is_vampiric(mdef->data);

if (!negated && !rn2(3) && (!resists_drain || V2V)) {
if (!negated && !rn2(3) && (!unaffected || V2V)) {
int xtmp = d(2, 6);
if (mdef->mhp < xtmp)
xtmp = mdef->mhp;
Expand Down
1 change: 1 addition & 0 deletions util/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@
"MR_POISON": "resists poison",
"MR_ACID": "resists acid",
"MR_STONE": "resists petrification",
"MR_DRAIN": "resists drain-life",
"MR_PSYCHIC": "resists psychic",
"MR_CLOB": "resists clobber",
"MR_SONIC": "resists sonic",
Expand Down

0 comments on commit 9fcff5a

Please sign in to comment.