]> granicus.if.org Git - nethack/commitdiff
Cleaver can hit three monsters with one swing
authorPasi Kallinen <paxed@alt.org>
Wed, 4 Oct 2017 19:01:03 +0000 (22:01 +0300)
committerPasi Kallinen <paxed@alt.org>
Wed, 4 Oct 2017 19:01:28 +0000 (22:01 +0300)
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

doc/fixes36.1
src/uhitm.c

index 2e29869c50e87eac521ffe5639dc5a9be98b3afe..05e62c36d5802d014fc07e0ebe58ddecce6ba30f 100644 (file)
@@ -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
index 0fcf8445c4ed16768f81020f95d32a65a22bdaf2..b4d2721879dd37a1a475be502f01fe45cc9c21b7 100644 (file)
@@ -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);