From d07595db2c7f089ca01fc83e1196675c5f2c745a Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 6 Apr 2020 06:12:25 -0700 Subject: [PATCH] dual-wielding tweaks Reject arrows and darts as candidates for wielding two weapons at once. Make the check for being able to two-weapon when polymorphed be more robust. Instead of just testing whether the monster form's second atttack is a weapon attack and then assuming that the first one is too, test the first three to validate that at least two of those are AT_WEAP. The existing code works but seemed fragile. --- doc/fixes37.0 | 3 ++- include/mondata.h | 12 ++++++++++-- src/wield.c | 12 +++++++++--- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 1ca840cc1..93ac0cb70 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.162 $ $NHDT-Date: 1586119020 2020/04/05 20:37:00 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.163 $ $NHDT-Date: 1586178711 2020/04/06 13:11:51 $ General Fixes and Modified Features ----------------------------------- @@ -26,6 +26,7 @@ monster wielding Stormbringer or healer's Staff against another monster would heal the hero instead of the wielding monster when draining life change twoweapon feedback from "not a weapon" to "not a suitable weapon" don't allow twoweapon combat if either weapon is a bow, crossbow, or sling + [later: or arrows, bolts, and missiles (darts, shuriken, boomerangs)] drum of earthquake feedback reported various things (fountains, thrones, &c) falling into a chasm but they remained intact because trap creation had been changed to not clobber such things (so couldn't make pits) diff --git a/include/mondata.h b/include/mondata.h index 3e12c2e70..abff12a2c 100644 --- a/include/mondata.h +++ b/include/mondata.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 mondata.h $NHDT-Date: 1576626512 2019/12/17 23:48:32 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.39 $ */ +/* NetHack 3.6 mondata.h $NHDT-Date: 1586178708 2020/04/06 13:11:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.43 $ */ /* Copyright (c) 1989 Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ @@ -140,7 +140,15 @@ #define strongmonst(ptr) (((ptr)->mflags2 & M2_STRONG) != 0L) #define can_breathe(ptr) attacktype(ptr, AT_BREA) #define cantwield(ptr) (nohands(ptr) || verysmall(ptr)) -#define could_twoweap(ptr) ((ptr)->mattk[1].aatyp == AT_WEAP) +/* Does this type of monster have multiple weapon attacks? If so, + hero poly'd into this form can use two-weapon combat. It used + to just check mattk[1] and assume mattk[0], which was suitable + for mons[] at the time but somewhat fragile. This is more robust + without going to the extreme of checking all six slots. */ +#define could_twoweap(ptr) \ + (( ((ptr)->mattk[0].aatyp == AT_WEAP) \ + + ((ptr)->mattk[1].aatyp == AT_WEAP) \ + + ((ptr)->mattk[2].aatyp == AT_WEAP) ) > 1) #define cantweararm(ptr) (breakarm(ptr) || sliparm(ptr)) #define throws_rocks(ptr) (((ptr)->mflags2 & M2_ROCKTHROW) != 0L) #define type_is_pname(ptr) (((ptr)->mflags2 & M2_PNAME) != 0L) diff --git a/src/wield.c b/src/wield.c index 01e7fde95..4ea53ca26 100644 --- a/src/wield.c +++ b/src/wield.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 wield.c $NHDT-Date: 1578190903 2020/01/05 02:21:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.72 $ */ +/* NetHack 3.6 wield.c $NHDT-Date: 1586178709 2020/04/06 13:11:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.75 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -662,9 +662,15 @@ can_twoweapon() { struct obj *otmp; - /* to dual-wield, must be a weapon-tool or a weapon other than a bow */ + /* to dual-wield, obj must be a weapon or a weapon-tool, and not + a bow or arrow or missile (dart, shuriken, boomerang), matching + the sorts of weapons which yield "you begin bashing" when used + for melee; we don't bother including polearms here because + they'll be rejected as two-weapon because they're two-handed */ #define TWOWEAPOK(obj) \ - (((obj)->oclass == WEAPON_CLASS) ? !is_launcher(obj) : is_weptool(obj)) + (((obj)->oclass == WEAPON_CLASS) \ + ? !(is_launcher(obj) ||is_ammo(obj) || is_missile(obj)) \ + : is_weptool(obj)) if (!could_twoweap(g.youmonst.data)) { if (Upolyd)