Skip to content

Commit

Permalink
fix github issue #594 - special attacks
Browse files Browse the repository at this point in the history
by the Riders that only damage the hero, not other monsters.

Noticed and diagnosed by vultur-cadens.  Attacks dishing out the
damage type AD_DETH (Death), AD_FAMN (Famine), AD_PEST (Pestilence),
and also AD_DISE (Demogorgon, Juiblex, Scorpius) did 0 damage if
inflicted against monsters.  That made Death harmless to other
monsters.  The others have additional attacks (in the two Rider's
cases, only if both instances of their special attack hit on the
same move so that the second one is converted into a stun attack)
and could manage to kill other monsters.

The uhitm case can't happen.  I suspect that the mhitm case was
originally intentionally omitted as something which won't happen,
but that's just a guess.

Fixes #594
  • Loading branch information
PatR committed Sep 30, 2021
1 parent 036169a commit 017a868
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 22 deletions.
2 changes: 2 additions & 0 deletions doc/fixes37.0
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,8 @@ Izchak occasionally stocks wands/scrolls/spellbooks of light
data tracking for #overview was mis-using u.urooms[] and after being in a
situation where hero was in multiple rooms at once, visiting other
levels might flag unvisisted rooms as having been visited
special damage attacks by the Riders and by fatal-illness inflictors such as
Demogorgon did no damage against other monsters, only against the hero


Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
Expand Down
86 changes: 64 additions & 22 deletions src/uhitm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2046,7 +2046,8 @@ mhitm_ad_fire(struct monst *magr, struct attack *mattk, struct monst *mdef,
mhm->done = TRUE;
return;
}
mhm->hitflags = (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
mhm->hitflags = (MM_DEF_DIED
| (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
mhm->done = TRUE;
return;
}
Expand Down Expand Up @@ -2242,6 +2243,7 @@ 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)
Expand Down Expand Up @@ -3155,9 +3157,13 @@ void
mhitm_ad_famn(struct monst *magr, struct attack *mattk UNUSED,
struct monst *mdef, struct mhitm_data *mhm)
{
struct permonst *pd = mdef->data;

if (magr == &g.youmonst) {
/* uhitm */
mhm->damage = 0;
/* uhitm; hero can't polymorph into anything with this attack
so this won't happen; if it could, it would be the same as
the mhitm case except for messaging */
goto mhitm_famn;
} else if (mdef == &g.youmonst) {
/* mhitu */
pline("%s reaches out, and your body shrivels.", Monnam(magr));
Expand All @@ -3166,28 +3172,39 @@ mhitm_ad_famn(struct monst *magr, struct attack *mattk UNUSED,
morehungry(rn1(40, 40));
/* plus the normal damage */
} else {
/* mhitm */
mhm->damage = 0;
mhitm_famn:
/* mhitm; it's possible for Famine to hit another monster;
if target is something that doesn't eat, it won't be harmed;
otherwise, just inflict the normal damage */
if (!(carnivorous(pd) || herbivorous(pd) || metallivorous(pd)))
mhm->damage = 0;
}
}

void
mhitm_ad_pest(struct monst *magr, struct attack *mattk UNUSED,
mhitm_ad_pest(struct monst *magr, struct attack *mattk,
struct monst *mdef, struct mhitm_data *mhm)
{
struct attack alt_attk;
struct permonst *pa = magr->data;

if (magr == &g.youmonst) {
/* uhitm */
mhm->damage = 0;
/* uhitm; hero can't polymorph into anything with this attack
so this won't happen; if it could, it would be the same as
the mhitm case except for messaging */
goto mhitm_pest;
} else if (mdef == &g.youmonst) {
/* mhitu */
pline("%s reaches out, and you feel fever and chills.", Monnam(magr));
(void) diseasemu(pa);
/* plus the normal damage */
} else {
/* mhitm */
mhm->damage = 0;
mhitm_pest:
/* mhitm; it's possible for Pestilence to hit another monster;
treat it the same as an attack for AD_DISE damage */
alt_attk = *mattk;
alt_attk.adtyp = AD_DISE;
mhitm_ad_dise(magr, &alt_attk, mdef, mhm);
}
}

Expand All @@ -3198,13 +3215,16 @@ mhitm_ad_deth(struct monst *magr, struct attack *mattk UNUSED,
struct permonst *pd = mdef->data;

if (magr == &g.youmonst) {
/* uhitm */
mhm->damage = 0;
/* uhitm; hero can't polymorph into anything with this attack
so this won't happen; if it could, it would be the same as
the mhitm case except for messaging */
goto mhitm_deth;
} else if (mdef == &g.youmonst) {
/* mhitu */
pline("%s reaches out with its deadly touch.", Monnam(magr));
if (is_undead(pd)) {
/* Still does normal damage */
/* still does some damage */
mhm->damage = (mhm->damage + 1) / 2;
pline("Was that the touch of death?");
return;
}
Expand All @@ -3220,7 +3240,7 @@ mhitm_ad_deth(struct monst *magr, struct attack *mattk UNUSED,
/*FALLTHRU*/
default: /* case 16: ... case 5: */
You_feel("your life force draining away...");
mhm->permdmg = 1; /* actual damage done below */
mhm->permdmg = 1; /* actual damage done by caller */
return;
case 4:
case 3:
Expand All @@ -3234,8 +3254,18 @@ mhitm_ad_deth(struct monst *magr, struct attack *mattk UNUSED,
return;
}
} else {
/* mhitm */
mhm->damage = 0;
mhitm_deth:
/* mhitm; it's possible for Death to hit another monster;
if target is undead, it will take some damage but less than an
undead hero would; otherwise, just inflict the normal damage */
if (is_undead(pd) && mhm->damage > 1)
mhm->damage = rnd(mhm->damage / 2);
/*
* FIXME?
* most monsters should be vulnerable to Death's touch
* instead of only receiving ordinary damage, but is it
* worth bothering with?
*/
}
}

Expand Down Expand Up @@ -3855,26 +3885,37 @@ 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)
{
struct permonst *pa = magr->data;
struct obj *mwep;
struct permonst *pa = magr->data, *pd = mdef->data;

if (magr == &g.youmonst) {
/* uhitm */
mhm->damage = 0;
/* uhitm; hero can't polymorph into anything with this attack so
this won't happen; if it could, it would be the same as the
mhitm case except for messaging */
goto mhitm_dise;
} else if (mdef == &g.youmonst) {
/* mhitu */
hitmsg(magr, mattk);
if (!diseasemu(pa))
mhm->damage = 0;
} else {
/* mhitm */
mhm->damage = 0;
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 */
if (pd->mlet == S_FUNGUS || pd == &mons[PM_GHOUL]
|| ((mwep = MON_WEP(mdef)) != 0 && defends(AD_DISE, mwep)))
mhm->damage = 0;
/* else does ordinary damage */
}
}

/* seduce and also steal item */
void
mhitm_ad_sedu(struct monst *magr, struct attack *mattk, struct monst *mdef,
struct mhitm_data *mhm)
Expand Down Expand Up @@ -3981,7 +4022,8 @@ mhitm_ad_sedu(struct monst *magr, struct attack *mattk, struct monst *mdef,
mdef->mstrategy &= ~STRAT_WAITFORU;
mselftouch(mdef, (const char *) 0, FALSE);
if (DEADMONSTER(mdef)) {
mhm->hitflags = (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
mhm->hitflags = (MM_DEF_DIED
| (grow_up(magr, mdef) ? 0 : MM_AGR_DIED));
mhm->done = TRUE;
return;
}
Expand Down

0 comments on commit 017a868

Please sign in to comment.