E void FDECL(mhitm_ad_poly, (struct monst *, struct attack *, struct monst *, struct mhitm_data *));
E void FDECL(mhitm_ad_famn, (struct monst *, struct attack *, struct monst *, struct mhitm_data *));
E void FDECL(mhitm_ad_pest, (struct monst *, struct attack *, struct monst *, struct mhitm_data *));
+E void FDECL(mhitm_ad_deth, (struct monst *, struct attack *, struct monst *, struct mhitm_data *));
E int FDECL(damageum, (struct monst *, struct attack *, int));
E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P));
E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int,
{
struct permonst *mdat = mtmp->data;
int uncancelled, ptmp;
- int armpro, permdmg, tmphp;
+ int armpro, tmphp;
char buf[BUFSZ];
struct permonst *olduasmon = g.youmonst.data;
int res;
struct mhitm_data mhm;
mhm.hitflags = MM_MISS;
+ mhm.permdmg = 0;
if (!canspotmon(mtmp))
map_invisible(mtmp->mx, mtmp->my);
armpro = magic_negation(&g.youmonst);
uncancelled = !mtmp->mcan && (rn2(10) >= 3 * armpro);
- permdmg = 0;
/* Now, adjust damages via resistances or specific attacks */
switch (mattk->adtyp) {
case AD_PHYS:
return mhm.hitflags;
break;
case AD_DETH:
- pline("%s reaches out with its deadly touch.", Monnam(mtmp));
- if (is_undead(g.youmonst.data)) {
- /* Still does normal damage */
- pline("Was that the touch of death?");
- break;
- }
- switch (rn2(20)) {
- case 19:
- case 18:
- case 17:
- if (!Antimagic) {
- g.killer.format = KILLED_BY_AN;
- Strcpy(g.killer.name, "touch of death");
- done(DIED);
- mhm.damage = 0;
- break;
- }
- /*FALLTHRU*/
- default: /* case 16: ... case 5: */
- You_feel("your life force draining away...");
- permdmg = 1; /* actual damage done below */
- break;
- case 4:
- case 3:
- case 2:
- case 1:
- case 0:
- if (Antimagic)
- shieldeff(u.ux, u.uy);
- pline("Lucky for you, it didn't work!");
- mhm.damage = 0;
- break;
- }
+ mhitm_ad_deth(mtmp, mattk, &g.youmonst, &mhm);
+ if (mhm.done)
+ return mhm.hitflags;
break;
case AD_PEST:
mhitm_ad_pest(mtmp, mattk, &g.youmonst, &mhm);
|| is_vampshifter(mtmp))))
mhm.damage = (mhm.damage + 1) / 2;
- if (permdmg) { /* Death's life force drain */
+ if (mhm.permdmg) { /* Death's life force drain */
int lowerlimit, *hpmax_p;
/*
* Apply some of the damage to permanent hit points:
* otherwise 0..50%
* Never reduces hpmax below 1 hit point per level.
*/
- permdmg = rn2(mhm.damage / 2 + 1);
+ mhm.permdmg = rn2(mhm.damage / 2 + 1);
if (Upolyd || u.uhpmax > 25 * u.ulevel)
- permdmg = mhm.damage;
+ mhm.permdmg = mhm.damage;
else if (u.uhpmax > 10 * u.ulevel)
- permdmg += mhm.damage / 2;
+ mhm.permdmg += mhm.damage / 2;
else if (u.uhpmax > 5 * u.ulevel)
- permdmg += mhm.damage / 4;
+ mhm.permdmg += mhm.damage / 4;
if (Upolyd) {
hpmax_p = &u.mhmax;
hpmax_p = &u.uhpmax;
lowerlimit = u.ulevel;
}
- if (*hpmax_p - permdmg > lowerlimit)
- *hpmax_p -= permdmg;
+ if (*hpmax_p - mhm.permdmg > lowerlimit)
+ *hpmax_p -= mhm.permdmg;
else if (*hpmax_p > lowerlimit)
*hpmax_p = lowerlimit;
/* else unlikely...
}
}
+void
+mhitm_ad_deth(magr, mattk, mdef, mhm)
+struct monst *magr;
+struct attack *mattk;
+struct monst *mdef;
+struct mhitm_data *mhm;
+{
+ struct permonst *pd = mdef->data;
+
+ if (magr == &g.youmonst) {
+ /* uhitm */
+ mhm->damage = 0;
+ } else if (mdef == &g.youmonst) {
+ /* mhitu */
+ pline("%s reaches out with its deadly touch.", Monnam(magr));
+ if (is_undead(pd)) {
+ /* Still does normal damage */
+ pline("Was that the touch of death?");
+ return;
+ }
+ switch (rn2(20)) {
+ case 19:
+ case 18:
+ case 17:
+ if (!Antimagic) {
+ g.killer.format = KILLED_BY_AN;
+ Strcpy(g.killer.name, "touch of death");
+ done(DIED);
+ mhm->damage = 0;
+ return;
+ }
+ /*FALLTHRU*/
+ default: /* case 16: ... case 5: */
+ You_feel("your life force draining away...");
+ mhm->permdmg = 1; /* actual damage done below */
+ return;
+ case 4:
+ case 3:
+ case 2:
+ case 1:
+ case 0:
+ if (Antimagic)
+ shieldeff(u.ux, u.uy);
+ pline("Lucky for you, it didn't work!");
+ mhm->damage = 0;
+ return;
+ }
+ } else {
+ /* mhitm */
+ mhm->damage = 0;
+ }
+}
+
/* Template for monster hits monster for AD_FOO.
- replace "break" with return
struct mhitm_data mhm;
mhm.damage = d((int) mattk->damn, (int) mattk->damd);
mhm.hitflags = MM_MISS;
+ mhm.permdmg = 0;
armpro = magic_negation(mdef);
/* since hero can't be cancelled, only defender's armor applies */