From: Pasi Kallinen Date: Wed, 4 Oct 2017 19:01:03 +0000 (+0300) Subject: Cleaver can hit three monsters with one swing X-Git-Tag: NetHack-3.6.1_RC01~321^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=856034d58504da93cd82ee5bd4c8b06ccb641376;p=nethack Cleaver can hit three monsters with one swing When hitting a monster with the Cleaver, you swing it in an arc, possibly hitting the monsters to the left and right of the targeted monster. Based on code by Fredrik Ljungdahl --- diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 2e29869c5..05e62c36d 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -354,6 +354,7 @@ wielding Trollsbane prevents trolls from reviving wielding Demonbane prevents demons summoning friends wielding Dragonbane confers reflection wielding Ogresmasher grants 25 constitution +Cleaver can hit three monsters with one swing Elbereth must now be on a square by itself to function Elbereth now erodes based on attacks by the player, not monsters scared novels are made of paper, not gold diff --git a/src/uhitm.c b/src/uhitm.c index 0fcf8445c..b4d272187 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -8,6 +8,7 @@ STATIC_DCL boolean FDECL(known_hitum, (struct monst *, struct obj *, int *, int, int, struct attack *, int)); STATIC_DCL boolean FDECL(theft_petrifies, (struct obj *)); STATIC_DCL void FDECL(steal_it, (struct monst *, struct attack *)); +STATIC_DCL boolean FDECL(hitum_cleave, (struct monst *, struct attack *)); STATIC_DCL boolean FDECL(hitum, (struct monst *, struct attack *)); STATIC_DCL boolean FDECL(hmon_hitmon, (struct monst *, struct obj *, int, int)); @@ -489,6 +490,63 @@ int dieroll; return malive; } +/* hit the monster next to you and the monsters to the left and right of it */ +STATIC_OVL boolean +hitum_cleave(mon, uattk) +struct monst *mon; +struct attack *uattk; +{ + int i = 0; + int x = u.ux; + int y = u.uy; + int count = 3; + boolean malive = TRUE; + struct monst *mtmp; + + /* find the direction we're swinging */ + while (i < 8) { + if (xdir[i] == u.dx && ydir[i] == u.dy) + break; + i++; + } + + if (i == 8) { + impossible("hitum_cleave: failed to find target monster?"); + return TRUE; + } + i = (i + 2) % 8; + + /* swing from right to left */ + while (count-- && uwep) { + boolean result; + int tmp, dieroll, mhit, attknum, armorpenalty; + + if (!i) + i = 7; + else + i--; + + mtmp = NULL; + if (isok(x + xdir[i], y + ydir[i])) + mtmp = m_at(x + xdir[i], y + ydir[i]); + if (!mtmp) + continue; + + + tmp = find_roll_to_hit(mtmp, uattk->aatyp, uwep, + &attknum, &armorpenalty); + dieroll = rnd(20); + mhit = (tmp > dieroll); + result = known_hitum(mtmp, uwep, &mhit, tmp, armorpenalty, + uattk, dieroll); + (void) passive(mtmp, mhit, DEADMONSTER(mtmp), AT_WEAP, !uwep); + if (mon == mtmp) + malive = result; + } + + return malive; +} + /* hit target monster; returns TRUE if it still lives */ STATIC_OVL boolean hitum(mon, uattk) @@ -503,6 +561,10 @@ struct attack *uattk; int dieroll = rnd(20); int mhit = (tmp > dieroll || u.uswallow); + if (uwep && uwep->oartifact == ART_CLEAVER + && !u.uswallow && !u.ustuck && !NODIAG(u.umonnum)) + return hitum_cleave(mon, uattk); + if (tmp > dieroll) exercise(A_DEX, TRUE); malive = known_hitum(mon, uwep, &mhit, tmp, armorpenalty, uattk, dieroll);