diff --git a/doc/fixes37.0 b/doc/fixes37.0 index f402c999e..66be2e7f8 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.43 $ $NHDT-Date: 1578137629 2020/01/04 11:33:49 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.49 $ $NHDT-Date: 1578190894 2020/01/05 02:21:34 $ General Fixes and Modified Features ----------------------------------- @@ -27,6 +27,7 @@ fix accessing mons[-1] when monster figures out if a tin cures stoning 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 Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/objnam.c b/src/objnam.c index 6da47e52d..fe5f2442a 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 objnam.c $NHDT-Date: 1576638500 2019/12/18 03:08:20 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.257 $ */ +/* NetHack 3.7 objnam.c $NHDT-Date: 1578190895 2020/01/05 02:21:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.279 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1174,7 +1174,18 @@ unsigned doname_flags; } if ((obj->owornmask & W_WEP) && !g.mrg_to_wielded) { - if (obj->quan != 1L) { + boolean twoweap_primary = (obj == uwep && u.twoweap); + + /* use alternate phrasing for non-weapons and for wielded ammo + (arrows, bolts), or missiles (darts, shuriken, boomerangs) + except when those are being actively dual-wielded where the + regular phrasing will list them as "in right hand" to + contrast with secondary weapon's "in left hand" */ + if ((obj->quan != 1L + || ((obj->oclass == WEAPON_CLASS) + ? (is_ammo(obj) || is_missile(obj)) + : !is_weptool(obj))) + && !twoweap_primary) { Strcat(bp, " (wielded)"); } else { const char *hand_s = body_part(HAND); @@ -1183,10 +1194,13 @@ unsigned doname_flags; hand_s = makeplural(hand_s); /* note: Sting's glow message, if added, will insert text in front of "(weapon in hand)"'s closing paren */ - Sprintf(eos(bp), " (%sweapon in %s)", - (obj->otyp == AKLYS) ? "tethered " : "", hand_s); + Sprintf(eos(bp), " (%s%s in %s%s)", + twoweap_primary ? "wielded" : "weapon", + (obj->otyp == AKLYS) ? "tethered " : "", + twoweap_primary ? "right " : "", hand_s); - if (g.warn_obj_cnt && obj == uwep && (EWarn_of_mon & W_WEP) != 0L) { + if (g.warn_obj_cnt && obj == uwep + && (EWarn_of_mon & W_WEP) != 0L) { if (!Blind) /* we know bp[] ends with ')'; overwrite that */ Sprintf(eos(bp) - 1, ", %s %s)", glow_verb(g.warn_obj_cnt, TRUE), @@ -1196,9 +1210,11 @@ unsigned doname_flags; } if (obj->owornmask & W_SWAPWEP) { if (u.twoweap) - Sprintf(eos(bp), " (wielded in other %s)", body_part(HAND)); + Sprintf(eos(bp), " (wielded in left %s)", body_part(HAND)); else - Strcat(bp, " (alternate weapon; not wielded)"); + /* TODO: rephrase this when obj isn't a weapon or weptool */ + Sprintf(eos(bp), " (alternate weapon%s; not wielded)", + plur(obj->quan)); } if (obj->owornmask & W_QUIVER) { switch (obj->oclass) { diff --git a/src/wield.c b/src/wield.c index 219f65edc..c99ee9c7b 100644 --- a/src/wield.c +++ b/src/wield.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 wield.c $NHDT-Date: 1577186790 2019/12/24 11:26:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.69 $ */ +/* NetHack 3.6 wield.c $NHDT-Date: 1578190903 2020/01/05 02:21:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.72 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -659,32 +659,41 @@ can_twoweapon() { struct obj *otmp; -#define NOT_WEAPON(obj) (!is_weptool(obj) && obj->oclass != WEAPON_CLASS) + /* to dual-wield, must be a weapon-tool or a weapon other than a bow */ +#define TWOWEAPOK(obj) \ + (((obj)->oclass == WEAPON_CLASS) ? !is_launcher(obj) : is_weptool(obj)) + if (!could_twoweap(g.youmonst.data)) { if (Upolyd) You_cant("use two weapons in your current form."); else pline("%s aren't able to use two weapons at once.", - makeplural((flags.female && g.urole.name.f) ? g.urole.name.f - : g.urole.name.m)); - } else if (!uwep || !uswapwep) - Your("%s%s%s empty.", uwep ? "left " : uswapwep ? "right " : "", - body_part(HAND), (!uwep && !uswapwep) ? "s are" : " is"); - else if (NOT_WEAPON(uwep) || NOT_WEAPON(uswapwep)) { - otmp = NOT_WEAPON(uwep) ? uwep : uswapwep; - pline("%s %s.", Yname2(otmp), - is_plural(otmp) ? "aren't suitable weapons" - : "isn't a suitable weapon"); + makeplural((flags.female && g.urole.name.f) + ? g.urole.name.f : g.urole.name.m)); + } else if (!uwep || !uswapwep) { + const char *hand_s = body_part(HAND); + + if (!uwep && !uswapwep) + hand_s = makeplural(hand_s); + /* "your hands are empty" or "your {left|right} hand is empty" */ + Your("%s%s %s empty.", uwep ? "left " : uswapwep ? "right " : "", + hand_s, vtense(hand_s, "are")); + } else if (!TWOWEAPOK(uwep) || !TWOWEAPOK(uswapwep)) { + otmp = !TWOWEAPOK(uwep) ? uwep : uswapwep; + pline("%s %s suitable %s weapon%s.", Yname2(otmp), + is_plural(otmp) ? "aren't" : "isn't a", + (otmp == uwep) ? "primary" : "secondary", + plur(otmp->quan)); } else if (bimanual(uwep) || bimanual(uswapwep)) { otmp = bimanual(uwep) ? uwep : uswapwep; pline("%s isn't one-handed.", Yname2(otmp)); - } else if (uarms) + } else if (uarms) { You_cant("use two weapons while wearing a shield."); - else if (uswapwep->oartifact) + } else if (uswapwep->oartifact) { pline("%s being held second to another weapon!", Yobjnam2(uswapwep, "resist")); - else if (uswapwep->otyp == CORPSE && cant_wield_corpse(uswapwep)) { - /* [Note: NOT_WEAPON() check prevents ever getting here...] */ + } else if (uswapwep->otyp == CORPSE && cant_wield_corpse(uswapwep)) { + /* [Note: !TWOWEAPOK() check prevents ever getting here...] */ ; /* must be life-saved to reach here; return FALSE */ } else if (Glib || uswapwep->cursed) { if (!Glib)