From: Pasi Kallinen Date: Mon, 18 Apr 2022 16:14:40 +0000 (+0300) Subject: Unify mhitm magic attack negation checks X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=262e1782436c33ce5cd97cf9febd726aee465993;p=nethack Unify mhitm magic attack negation checks --- diff --git a/src/uhitm.c b/src/uhitm.c index 51923d3c1..09e2369e9 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -8,6 +8,7 @@ static const char brief_feeling[] = "have a %s feeling for a moment, then it passes."; +static boolean mhitm_mgc_atk_negated(struct monst *, struct monst *); static boolean known_hitum(struct monst *, struct obj *, int *, int, int, struct attack *, int); static boolean theft_petrifies(struct obj *); @@ -30,6 +31,18 @@ static boolean shade_aware(struct obj *); #define PROJECTILE(obj) ((obj) && is_ammo(obj)) +static boolean +mhitm_mgc_atk_negated(struct monst *magr, struct monst *mdef) +{ + int armpro = magic_negation(mdef); + boolean negated = !(rn2(10) >= 3 * armpro); + + /* since hero can't be cancelled, only defender's armor applies */ + if (magr == &g.youmonst) + return negated; + return magr->mcan || negated; +} + /* multi_reason is usually a literal string; here we generate one that has the causing monster's type included */ void @@ -1952,31 +1965,22 @@ void mhitm_ad_dren(struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { + boolean negated = mhitm_mgc_atk_negated(magr, mdef); + 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(4)) xdrainenergym(mdef, TRUE); mhm->damage = 0; } 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(4)) /* 25% chance */ + if (!negated && !rn2(4)) /* 25% chance */ drain_en(mhm->damage); mhm->damage = 0; } else { /* mhitm */ - /* cancellation factor is the same as when attacking the hero */ - int armpro = magic_negation(mdef); - boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); - - if (!cancelled && !rn2(4)) + if (!negated && !rn2(4)) xdrainenergym(mdef, (boolean) (g.vis && canspotmon(mdef) && mattk->aatyp != AT_ENGL)); mhm->damage = 0; @@ -1988,12 +1992,10 @@ mhitm_ad_drli( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { + boolean negated = mhitm_mgc_atk_negated(magr, mdef); + 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) || defended(mdef, AD_DRLI))) { mhm->damage = d(2, 6); /* Stormbringer uses monhp_per_lvl @@ -2024,11 +2026,8 @@ mhitm_ad_drli( } } 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) { + if (!negated && !rn2(3) && !Drain_resistance) { losexp("life drainage"); /* unlike hitting with Stormbringer, wounded attacker doesn't @@ -2036,13 +2035,11 @@ mhitm_ad_drli( } } else { /* mhitm */ - int armpro = magic_negation(mdef); - boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); /* mhitm_ad_deth gets redirected here for Death's touch */ boolean is_death = (mattk->adtyp == AD_DETH); if (is_death - || (!cancelled && !rn2(3) + || (!negated && !rn2(3) && !(resists_drli(mdef) || defended(mdef, AD_DRLI)))) { if (!is_death) mhm->damage = d(2, 6); /* Stormbringer uses monhp_per_lvl (1d8) */ @@ -2072,14 +2069,11 @@ mhitm_ad_fire( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { + boolean negated = mhitm_mgc_atk_negated(magr, mdef); 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) { mhm->damage = 0; return; @@ -2116,11 +2110,8 @@ mhitm_ad_fire( ignite_items(mdef->minvent); } else if (mdef == &g.youmonst) { /* mhitu */ - int armpro = magic_negation(mdef); - boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); - hitmsg(magr, mattk); - if (uncancelled) { + if (!negated) { pline("You're %s!", on_fire(pd, mattk)); if (completelyburns(pd)) { /* paper or straw golem */ You("go up in flames!"); @@ -2145,10 +2136,7 @@ mhitm_ad_fire( mhm->damage = 0; } else { /* mhitm */ - int armpro = magic_negation(mdef); - boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); - - if (cancelled) { + if (negated) { mhm->damage = 0; return; } @@ -2192,12 +2180,10 @@ mhitm_ad_cold( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { + boolean negated = mhitm_mgc_atk_negated(magr, mdef); + 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) { mhm->damage = 0; return; @@ -2214,11 +2200,8 @@ mhitm_ad_cold( mhm->damage += destroy_mitem(mdef, POTION_CLASS, AD_COLD); } else if (mdef == &g.youmonst) { /* mhitu */ - int armpro = magic_negation(mdef); - boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); - hitmsg(magr, mattk); - if (uncancelled) { + if (!negated) { pline("You're covered in frost!"); if (Cold_resistance) { pline_The("frost doesn't seem cold!"); @@ -2231,10 +2214,7 @@ mhitm_ad_cold( mhm->damage = 0; } else { /* mhitm */ - int armpro = magic_negation(mdef); - boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); - - if (cancelled) { + if (negated) { mhm->damage = 0; return; } @@ -2256,12 +2236,10 @@ mhitm_ad_elec( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { + boolean negated = mhitm_mgc_atk_negated(magr, mdef); + 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) { mhm->damage = 0; return; @@ -2280,11 +2258,8 @@ mhitm_ad_elec( mhm->damage += destroy_mitem(mdef, RING_CLASS, AD_ELEC); } else if (mdef == &g.youmonst) { /* mhitu */ - int armpro = magic_negation(mdef); - boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); - hitmsg(magr, mattk); - if (uncancelled) { + if (!negated) { You("get zapped!"); if (Shock_resistance) { pline_The("zap doesn't shock you!"); @@ -2299,10 +2274,7 @@ mhitm_ad_elec( mhm->damage = 0; } else { /* mhitm */ - int armpro = magic_negation(mdef); - boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); - - if (cancelled) { + if (negated) { mhm->damage = 0; return; } @@ -2439,12 +2411,10 @@ void mhitm_ad_tlpt(struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { + boolean negated = mhitm_mgc_atk_negated(magr, mdef); + 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 (mhm->damage <= 0) mhm->damage = 1; if (!negated) { @@ -2464,12 +2434,10 @@ mhitm_ad_tlpt(struct monst *magr, struct attack *mattk, struct monst *mdef, } } else if (mdef == &g.youmonst) { /* mhitu */ - int armpro = magic_negation(mdef); - boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); int tmphp; hitmsg(magr, mattk); - if (uncancelled) { + if (!negated) { if (flags.verbose) Your("position suddenly seems %suncertain!", (Teleport_control && !Stunned && !unconscious()) ? "" @@ -2508,10 +2476,7 @@ mhitm_ad_tlpt(struct monst *magr, struct attack *mattk, struct monst *mdef, } } else { /* mhitm */ - int armpro = magic_negation(mdef); - boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); - - if (!cancelled && mhm->damage < mdef->mhp && !tele_restrict(mdef)) { + if (!negated && mhm->damage < mdef->mhp && !tele_restrict(mdef)) { char mdef_Monnam[BUFSZ]; boolean wasseen = canspotmon(mdef); @@ -2674,14 +2639,11 @@ void mhitm_ad_drst(struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { + boolean negated = mhitm_mgc_atk_negated(magr, mdef); struct permonst *pa = magr->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(8)) { Your("%s was poisoned!", mpoisons_subj(magr, mattk)); if (resists_poison(mdef)) { @@ -2696,8 +2658,6 @@ mhitm_ad_drst(struct monst *magr, struct attack *mattk, struct monst *mdef, } } else if (mdef == &g.youmonst) { /* mhitu */ - int armpro = magic_negation(mdef); - boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); int ptmp = A_STR; /* A_STR == 0 */ char buf[BUFSZ]; @@ -2707,17 +2667,14 @@ mhitm_ad_drst(struct monst *magr, struct attack *mattk, struct monst *mdef, case AD_DRCO: ptmp = A_CON; break; } hitmsg(magr, mattk); - if (uncancelled && !rn2(8)) { + if (!negated && !rn2(8)) { Sprintf(buf, "%s %s", s_suffix(Monnam(magr)), mpoisons_subj(magr, mattk)); poisoned(buf, ptmp, pmname(pa, Mgender(magr)), 30, FALSE); } } else { /* mhitm */ - int armpro = magic_negation(mdef); - boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); - - if (!cancelled && !rn2(8)) { + if (!negated && !rn2(8)) { if (g.vis && canspotmon(magr)) pline("%s %s was poisoned!", s_suffix(Monnam(magr)), mpoisons_subj(magr, mattk)); @@ -2842,31 +2799,22 @@ mhitm_ad_stck( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { + boolean negated = mhitm_mgc_atk_negated(magr, mdef); 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 && !sticks(pd) && next2u(mdef->mx, mdef->my)) set_ustuck(mdef); /* it's now stuck to you */ } else if (mdef == &g.youmonst) { /* mhitu */ - int armpro = magic_negation(mdef); - boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); - hitmsg(magr, mattk); - if (uncancelled && !u.ustuck && !sticks(pd)) { + if (!negated && !u.ustuck && !sticks(pd)) { set_ustuck(magr); } } else { /* mhitm */ - int armpro = magic_negation(mdef); - boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); - - if (cancelled) + if (negated) mhm->damage = 0; } } @@ -2949,12 +2897,10 @@ void mhitm_ad_plys(struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { + boolean negated = mhitm_mgc_atk_negated(magr, mdef); + 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 && mdef->mcanmove && !rn2(3) && mhm->damage < mdef->mhp) { if (!Blind) pline("%s is frozen by you!", Monnam(mdef)); @@ -2962,11 +2908,8 @@ mhitm_ad_plys(struct monst *magr, struct attack *mattk, struct monst *mdef, } } else if (mdef == &g.youmonst) { /* mhitu */ - int armpro = magic_negation(mdef); - boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); - hitmsg(magr, mattk); - if (uncancelled && g.multi >= 0 && !rn2(3)) { + if (!negated && g.multi >= 0 && !rn2(3)) { if (Free_action) { You("momentarily stiffen."); } else { @@ -2984,10 +2927,7 @@ mhitm_ad_plys(struct monst *magr, struct attack *mattk, struct monst *mdef, } } else { /* mhitm */ - int armpro = magic_negation(mdef); - boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); - - if (!cancelled && mdef->mcanmove) { + if (!negated && mdef->mcanmove) { if (g.vis && canspotmon(mdef)) { char buf[BUFSZ]; Strcpy(buf, Monnam(mdef)); @@ -3002,12 +2942,10 @@ void mhitm_ad_slee(struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm UNUSED) { + boolean negated = mhitm_mgc_atk_negated(magr, mdef); + 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 && !mdef->msleeping && sleep_monst(mdef, rnd(10), -1)) { if (!Blind) pline("%s is put to sleep by you!", Monnam(mdef)); @@ -3015,11 +2953,8 @@ mhitm_ad_slee(struct monst *magr, struct attack *mattk, struct monst *mdef, } } else if (mdef == &g.youmonst) { /* mhitu */ - int armpro = magic_negation(mdef); - boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); - hitmsg(magr, mattk); - if (uncancelled && g.multi >= 0 && !rn2(5)) { + if (!negated && g.multi >= 0 && !rn2(5)) { if (Sleep_resistance) { monstseesu(M_SEEN_SLEEP); return; @@ -3032,10 +2967,7 @@ mhitm_ad_slee(struct monst *magr, struct attack *mattk, struct monst *mdef, } } else { /* mhitm */ - int armpro = magic_negation(mdef); - boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); - - if (!cancelled && !mdef->msleeping + if (!negated && !mdef->msleeping && sleep_monst(mdef, rnd(10), -1)) { if (g.vis && canspotmon(mdef)) { char buf[BUFSZ]; @@ -3052,14 +2984,11 @@ void mhitm_ad_slim(struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { + boolean negated = mhitm_mgc_atk_negated(magr, mdef); 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) return; /* physical damage only */ if (!rn2(4) && !slimeproof(pd)) { @@ -3080,11 +3009,8 @@ mhitm_ad_slim(struct monst *magr, struct attack *mattk, struct monst *mdef, } } else if (mdef == &g.youmonst) { /* mhitu */ - int armpro = magic_negation(mdef); - boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); - hitmsg(magr, mattk); - if (!uncancelled) + if (negated) return; if (flaming(pd)) { pline_The("slime burns away!"); @@ -3102,10 +3028,7 @@ mhitm_ad_slim(struct monst *magr, struct attack *mattk, struct monst *mdef, pline("Yuck!"); } else { /* mhitm */ - int armpro = magic_negation(mdef); - boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); - - if (cancelled) + if (negated) return; /* physical damage only */ if (!rn2(4) && !slimeproof(pd)) { if (!munslime(mdef, FALSE) && !DEADMONSTER(mdef)) { @@ -3135,13 +3058,12 @@ mhitm_ad_ench(struct monst *magr, struct attack *mattk, struct monst *mdef, /* there's no msomearmor() function, so just do damage */ } else if (mdef == &g.youmonst) { /* mhitu */ - int armpro = magic_negation(mdef); - boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + boolean negated = mhitm_mgc_atk_negated(magr, mdef); hitmsg(magr, mattk); /* uncancelled is sufficient enough; please don't make this attack less frequent */ - if (uncancelled) { + if (!negated) { struct obj *obj = some_armor(mdef); if (!obj) { @@ -3179,15 +3101,13 @@ mhitm_ad_slow( struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm UNUSED) { + boolean negated = mhitm_mgc_atk_negated(magr, mdef); + if (defended(mdef, AD_SLOW)) return; 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 && mdef->mspeed != MSLOW) { unsigned int oldspeed = mdef->mspeed; @@ -3197,18 +3117,12 @@ mhitm_ad_slow( } } else if (mdef == &g.youmonst) { /* mhitu */ - int armpro = magic_negation(mdef); - boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); - hitmsg(magr, mattk); - if (uncancelled && HFast && !rn2(4)) + if (!negated && HFast && !rn2(4)) u_slow_down(); } else { /* mhitm */ - int armpro = magic_negation(mdef); - boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); - - if (!cancelled && mdef->mspeed != MSLOW) { + if (!negated && mdef->mspeed != MSLOW) { unsigned int oldspeed = mdef->mspeed; mon_adjust_speed(mdef, -1, (struct obj *) 0); @@ -3261,22 +3175,17 @@ void mhitm_ad_poly(struct monst *magr, struct attack *mattk, struct monst *mdef, struct mhitm_data *mhm) { + boolean negated = mhitm_mgc_atk_negated(magr, mdef); + if (magr == &g.youmonst) { /* uhitm */ - int armpro = magic_negation(mdef); - /* require weaponless attack in order to honor AD_POLY; - since hero can't be cancelled, only defender's armor applies */ - boolean negated = uwep || !(rn2(10) >= 3 * armpro); - - if (!negated && mhm->damage < mdef->mhp) + /* require weaponless attack in order to honor AD_POLY */ + if (!uwep && !negated && mhm->damage < mdef->mhp) mhm->damage = mon_poly(&g.youmonst, mdef, mhm->damage); } else if (mdef == &g.youmonst) { /* mhitu */ - int armpro = magic_negation(&g.youmonst); - boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); - hitmsg(magr, mattk); - if (uncancelled + if (!negated && Maybe_Half_Phys(mhm->damage) < (Upolyd ? u.mh : u.uhp)) mhm->damage = mon_poly(magr, &g.youmonst, mhm->damage); } else { @@ -3716,11 +3625,10 @@ mhitm_ad_were( return; } else if (mdef == &g.youmonst) { /* mhitu */ - int armpro = magic_negation(mdef); - boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + boolean negated = mhitm_mgc_atk_negated(magr, mdef); hitmsg(magr, mattk); - if (uncancelled && !rn2(4) && u.ulycn == NON_PM + if (!negated && !rn2(4) && u.ulycn == NON_PM && !Protection_from_shape_changers && !defends(AD_WERE, uwep)) { urgent_pline("You feel feverish."); exercise(A_CON, FALSE);