From f6e70bbc585065b441a1f8e16f825baba09091b6 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 28 Nov 2023 01:15:04 -0800 Subject: [PATCH] two-weapon combat on/off via inventory item action When testing 'm )' I noticed that weapon and alternate weapon weren't offering the chance to toggle two-weapon mode. When already on, providing it as a choice to toggle it off is simple, but when at is off that isn't the case. There are lots of reasons why attempting to toggle it on might fail and it is silly to offer as a choice if failure is sure to occur. This tries to filter out the majority of reasons why the player can't toggle it on when deciding whether to include 'X' as a choice. --- doc/fixes3-7-0.txt | 1 + src/invent.c | 28 ++++++++++++++++++++++++++++ src/wield.c | 2 +- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index f2d29c1a6..a9d16bc2f 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1752,6 +1752,7 @@ when using 'm #overview' to annotate a level other than current the one, when using 'm #overview' in the endgame, don't include non-endgame levels when a tethered aklys gets caught in a web, make sure it doesn't return and that the display of the tether gets cleaned up +add 'X' as a potential context-sensitive item-action for uwep and uswapwep Fixes to 3.7.0-x Platform and/or Interface Problems Exposed Via git Repository diff --git a/src/invent.c b/src/invent.c index 5cae0e56c..ceca0936d 100644 --- a/src/invent.c +++ b/src/invent.c @@ -2827,6 +2827,7 @@ enum item_action_actions { IA_WIELD_OBJ, IA_WEAR_OBJ, IA_SWAPWEAPON, + IA_TWOWEAPON, IA_ZAP_OBJ, IA_WHATIS_OBJ, /* '/' specify inventory object */ }; @@ -3044,6 +3045,9 @@ itemactions_pushkeys(struct obj *otmp, int act) case IA_SWAPWEAPON: cmdq_add_ec(CQ_CANNED, doswapweapon); break; + case IA_TWOWEAPON: + cmdq_add_ec(CQ_CANNED, dotwoweapon); + break; case IA_ZAP_OBJ: cmdq_add_ec(CQ_CANNED, dozap); cmdq_add_key(CQ_CANNED, otmp->invlet); @@ -3339,6 +3343,30 @@ itemactions(struct obj *otmp) else if (otmp == uswapwep) ia_addmenu(win, IA_SWAPWEAPON, 'x', "Swap this with your main weapon"); + /* this is based on TWOWEAPOK() in wield.c; we don't call can_two_weapon() + because it is very verbose; attempting to two-weapon might be rejected + but we screen out most reasons for rejection before offering it as a + choice */ +#define MAYBETWOWEAPON(obj) \ + ((((obj)->oclass == WEAPON_CLASS) \ + ? !(is_launcher(obj) || is_ammo(obj) || is_missile(obj)) \ + : is_weptool(obj)) \ + && !bimanual(obj)) + + /* X: Toggle two-weapon mode on or off */ + if ((otmp == uwep || otmp == uswapwep) + /* if already two-weaponing, no special checks needed to toggle off */ + && (u.twoweap + /* but if not, try to filter most "you can't do that" here */ + || (could_twoweap(gy.youmonst.data) && !uarms + && uwep && MAYBETWOWEAPON(uwep) + && uswapwep && MAYBETWOWEAPON(uswapwep)))) { + Sprintf(buf, "Toggle two-weapon combat %s", u.twoweap ? "off" : "on"); + ia_addmenu(win, IA_TWOWEAPON, 'X', buf); + } + +#undef MAYBETWOWEAPON + /* z: Zap wand */ if (otmp->oclass == WAND_CLASS) ia_addmenu(win, IA_ZAP_OBJ, 'z', "Zap this wand to release its magic"); diff --git a/src/wield.c b/src/wield.c index 36fa73636..1e69f1deb 100644 --- a/src/wield.c +++ b/src/wield.c @@ -73,7 +73,7 @@ static int wield_ok(struct obj *); empty hands and two-handed weapons have to be handled separately */ #define TWOWEAPOK(obj) \ (((obj)->oclass == WEAPON_CLASS) \ - ? !(is_launcher(obj) ||is_ammo(obj) || is_missile(obj)) \ + ? !(is_launcher(obj) || is_ammo(obj) || is_missile(obj)) \ : is_weptool(obj)) static const char