Unify ad_drli

This commit is contained in:
Pasi Kallinen
2020-12-04 09:30:14 +02:00
parent 518798d0d2
commit cfd819f1c1
4 changed files with 91 additions and 57 deletions
+1
View File
@@ -2759,6 +2759,7 @@ E void FDECL(mhitm_ad_rust, (struct monst *, struct attack *, struct monst *, st
E void FDECL(mhitm_ad_corr, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_corr, (struct monst *, struct attack *, struct monst *, struct mhitm_data *));
E void FDECL(mhitm_ad_dcay, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_dcay, (struct monst *, struct attack *, struct monst *, struct mhitm_data *));
E void FDECL(mhitm_ad_dren, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_dren, (struct monst *, struct attack *, struct monst *, struct mhitm_data *));
E void FDECL(mhitm_ad_drli, (struct monst *, struct attack *, struct monst *, struct mhitm_data *));
E int FDECL(damageum, (struct monst *, struct attack *, int)); E int FDECL(damageum, (struct monst *, struct attack *, int));
E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P));
E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int,
+3 -20
View File
@@ -1286,26 +1286,9 @@ int dieroll;
} }
break; break;
case AD_DRLI: /* drain life */ case AD_DRLI: /* drain life */
if (!cancelled && !rn2(3) && !resists_drli(mdef)) { mhitm_ad_drli(magr, mattk, mdef, &mhm);
mhm.damage = d(2, 6); /* Stormbringer uses monhp_per_lvl(usually 1d8) */ if (mhm.done)
if (g.vis && canspotmon(mdef)) return mhm.hitflags;
pline("%s becomes weaker!", Monnam(mdef));
if (mdef->mhpmax - mhm.damage > (int) mdef->m_lev) {
mdef->mhpmax -= mhm.damage;
} else {
/* limit floor of mhpmax reduction to current m_lev + 1;
avoid increasing it if somehow already less than that */
if (mdef->mhpmax > (int) mdef->m_lev)
mdef->mhpmax = (int) mdef->m_lev + 1;
}
if (mdef->m_lev == 0) /* automatic kill if drained past level 0 */
mhm.damage = mdef->mhp;
else
mdef->m_lev--;
/* unlike hitting with Stormbringer, wounded attacker doesn't
heal any from the drained life */
}
break; break;
case AD_SSEX: case AD_SSEX:
case AD_SITM: /* for now these are the same */ case AD_SITM: /* for now these are the same */
+3 -7
View File
@@ -1242,13 +1242,9 @@ register struct attack *mattk;
} }
break; break;
case AD_DRLI: /* drain life */ case AD_DRLI: /* drain life */
hitmsg(mtmp, mattk); mhitm_ad_drli(mtmp, mattk, &g.youmonst, &mhm);
if (uncancelled && !rn2(3) && !Drain_resistance) { if (mhm.done)
losexp("life drainage"); return mhm.hitflags;
/* unlike hitting with Stormbringer, wounded attacker doesn't
heal any from the drained life */
}
break; break;
case AD_LEGS: { case AD_LEGS: {
long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE;
+84 -30
View File
@@ -1852,10 +1852,6 @@ struct mhitm_data *mhm;
mhm->damage = 0; mhm->damage = 0;
} else if (mdef == &g.youmonst) { } else if (mdef == &g.youmonst) {
/* mhitu */ /* mhitu */
/* Next a cancellation factor.
* Use uncancelled when cancellation factor takes into account certain
* armor's special magic protection. Otherwise just use !mtmp->mcan.
*/
int armpro = magic_negation(mdef); int armpro = magic_negation(mdef);
boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro);
@@ -1876,6 +1872,87 @@ struct mhitm_data *mhm;
} }
} }
void
mhitm_ad_drli(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 */
int armpro = magic_negation(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)) {
mhm->damage = d(2, 6); /* Stormbringer uses monhp_per_lvl(usually 1d8) */
pline("%s becomes weaker!", Monnam(mdef));
if (mdef->mhpmax - mhm->damage > (int) mdef->m_lev) {
mdef->mhpmax -= mhm->damage;
} else {
/* limit floor of mhpmax reduction to current m_lev + 1;
avoid increasing it if somehow already less than that */
if (mdef->mhpmax > (int) mdef->m_lev)
mdef->mhpmax = (int) mdef->m_lev + 1;
}
mdef->mhp -= mhm->damage;
/* !m_lev: level 0 monster is killed regardless of hit points
rather than drop to level -1; note: some non-living creatures
(golems, vortices) are subject to life-drain */
if (DEADMONSTER(mdef) || !mdef->m_lev) {
pline("%s %s!", Monnam(mdef),
nonliving(mdef->data) ? "expires" : "dies");
xkilled(mdef, XKILL_NOMSG);
} else
mdef->m_lev--;
mhm->damage = 0; /* damage has already been inflicted */
/* unlike hitting with Stormbringer, wounded hero doesn't
heal any from the drained life */
}
} else if (mdef == &g.youmonst) {
/* mhitu */
int armpro = magic_negation(mdef);
boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro);
hitmsg(magr, mattk);
if (uncancelled && !rn2(3) && !Drain_resistance) {
losexp("life drainage");
/* unlike hitting with Stormbringer, wounded attacker doesn't
heal any from the drained life */
}
} else {
/* mhitm */
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 (g.vis && canspotmon(mdef))
pline("%s becomes weaker!", Monnam(mdef));
if (mdef->mhpmax - mhm->damage > (int) mdef->m_lev) {
mdef->mhpmax -= mhm->damage;
} else {
/* limit floor of mhpmax reduction to current m_lev + 1;
avoid increasing it if somehow already less than that */
if (mdef->mhpmax > (int) mdef->m_lev)
mdef->mhpmax = (int) mdef->m_lev + 1;
}
if (mdef->m_lev == 0) /* automatic kill if drained past level 0 */
mhm->damage = mdef->mhp;
else
mdef->m_lev--;
/* unlike hitting with Stormbringer, wounded attacker doesn't
heal any from the drained life */
}
}
}
/* Template for monster hits monster for AD_FOO. /* Template for monster hits monster for AD_FOO.
- replace "break" with return - replace "break" with return
- replace "return" with mhm->done = TRUE - replace "return" with mhm->done = TRUE
@@ -2126,32 +2203,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */
mhm.damage = 0; mhm.damage = 0;
break; break;
case AD_DRLI: /* drain life */ case AD_DRLI: /* drain life */
if (!negated && !rn2(3) && !resists_drli(mdef)) { mhitm_ad_drli(&g.youmonst, mattk, mdef, &mhm);
mhm.damage = d(2, 6); /* Stormbringer uses monhp_per_lvl(usually 1d8) */ if (mhm.done)
pline("%s becomes weaker!", Monnam(mdef)); return mhm.hitflags;
if (mdef->mhpmax - mhm.damage > (int) mdef->m_lev) {
mdef->mhpmax -= mhm.damage;
} else {
/* limit floor of mhpmax reduction to current m_lev + 1;
avoid increasing it if somehow already less than that */
if (mdef->mhpmax > (int) mdef->m_lev)
mdef->mhpmax = (int) mdef->m_lev + 1;
}
mdef->mhp -= mhm.damage;
/* !m_lev: level 0 monster is killed regardless of hit points
rather than drop to level -1; note: some non-living creatures
(golems, vortices) are subject to life-drain */
if (DEADMONSTER(mdef) || !mdef->m_lev) {
pline("%s %s!", Monnam(mdef),
nonliving(mdef->data) ? "expires" : "dies");
xkilled(mdef, XKILL_NOMSG);
} else
mdef->m_lev--;
mhm.damage = 0; /* damage has already been inflicted */
/* unlike hitting with Stormbringer, wounded hero doesn't
heal any from the drained life */
}
break; break;
case AD_RUST: case AD_RUST:
mhitm_ad_rust(&g.youmonst, mattk, mdef, &mhm); mhitm_ad_rust(&g.youmonst, mattk, mdef, &mhm);