diff --git a/include/extern.h b/include/extern.h index f4d5c0fcf..b72d73296 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2790,6 +2790,7 @@ E void FDECL(mhitm_ad_ston, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_were, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_heal, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_stun, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_legs, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E boolean FDECL(do_stone_u, (struct monst *)); E void FDECL(do_stone_mon, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); diff --git a/src/mhitm.c b/src/mhitm.c index decb034b8..b892e56c3 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -955,11 +955,10 @@ int dieroll; return mhm.hitflags; break; case AD_LEGS: - if (magr->mcan) { - mhm.damage = 0; - break; - } - goto physical; + mhitm_ad_legs(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; + break; case AD_WERE: mhitm_ad_were(magr, mattk, mdef, &mhm); if (mhm.done) diff --git a/src/mhitu.c b/src/mhitu.c index a67f78e38..030c98ee9 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1073,46 +1073,11 @@ register struct attack *mattk; if (mhm.done) return mhm.hitflags; break; - case AD_LEGS: { - long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; - const char *sidestr = (side == RIGHT_SIDE) ? "right" : "left", - *Monst_name = Monnam(mtmp), *leg = body_part(LEG); - - /* This case is too obvious to ignore, but Nethack is not in - * general very good at considering height--most short monsters - * still _can_ attack you when you're flying or mounted. - */ - if ((u.usteed || Levitation || Flying) && !is_flyer(mtmp->data)) { - pline("%s tries to reach your %s %s!", Monst_name, sidestr, leg); - mhm.damage = 0; - } else if (mtmp->mcan) { - pline("%s nuzzles against your %s %s!", Monnam(mtmp), - sidestr, leg); - mhm.damage = 0; - } else { - if (uarmf) { - if (rn2(2) && (uarmf->otyp == LOW_BOOTS - || uarmf->otyp == IRON_SHOES)) { - pline("%s pricks the exposed part of your %s %s!", - Monst_name, sidestr, leg); - } else if (!rn2(5)) { - pline("%s pricks through your %s boot!", Monst_name, - sidestr); - } else { - pline("%s scratches your %s boot!", Monst_name, - sidestr); - mhm.damage = 0; - break; - } - } else - pline("%s pricks your %s %s!", Monst_name, sidestr, leg); - - set_wounded_legs(side, rnd(60 - ACURR(A_DEX))); - exercise(A_STR, FALSE); - exercise(A_DEX, FALSE); - } + case AD_LEGS: + mhitm_ad_legs(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; - } case AD_STON: mhitm_ad_ston(mtmp, mattk, &g.youmonst, &mhm); if (mhm.done) diff --git a/src/uhitm.c b/src/uhitm.c index 7824e6ac2..9c33c959a 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -3810,6 +3810,80 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_legs(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 */ +#if 0 + if (u.ucancelled) { + mhm->damage = 0; + return; + } +#endif + mhitm_ad_phys(magr, mattk, mdef, mhm); + if (mhm->done) + return; + } else if (mdef == &g.youmonst) { + /* mhitu */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + + long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; + const char *sidestr = (side == RIGHT_SIDE) ? "right" : "left", + *Monst_name = Monnam(magr), *leg = body_part(LEG); + + /* This case is too obvious to ignore, but Nethack is not in + * general very good at considering height--most short monsters + * still _can_ attack you when you're flying or mounted. + */ + if ((u.usteed || Levitation || Flying) && !is_flyer(magr->data)) { + pline("%s tries to reach your %s %s!", Monst_name, sidestr, leg); + mhm->damage = 0; + } else if (magr->mcan) { + pline("%s nuzzles against your %s %s!", Monnam(magr), + sidestr, leg); + mhm->damage = 0; + } else { + if (uarmf) { + if (rn2(2) && (uarmf->otyp == LOW_BOOTS + || uarmf->otyp == IRON_SHOES)) { + pline("%s pricks the exposed part of your %s %s!", + Monst_name, sidestr, leg); + } else if (!rn2(5)) { + pline("%s pricks through your %s boot!", Monst_name, + sidestr); + } else { + pline("%s scratches your %s boot!", Monst_name, + sidestr); + mhm->damage = 0; + return; + } + } else + pline("%s pricks your %s %s!", Monst_name, sidestr, leg); + + set_wounded_legs(side, rnd(60 - ACURR(A_DEX))); + exercise(A_STR, FALSE); + exercise(A_DEX, FALSE); + } + } else { + /* mhitm */ + if (magr->mcan) { + mhm->damage = 0; + return; + } + mhitm_ad_phys(magr, mattk, mdef, mhm); + if (mhm->done) + return; + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return - replace "return" with mhm->done = TRUE @@ -3877,13 +3951,10 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_LEGS: -#if 0 - if (u.ucancelled) { - mhm.damage = 0; - break; - } -#endif - goto physical; + mhitm_ad_legs(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; + break; case AD_WERE: mhitm_ad_were(&g.youmonst, mattk, mdef, &mhm); if (mhm.done)