From fa41d5fe66d9452fdc2d33d7b8df2b9f9f9f6529 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 29 Dec 2021 19:40:23 +0200 Subject: [PATCH] Apply a wielded polearm with fire-command Wield a polearm and use 'f'ire to automatically hit with it, if there's a single valid target. With fireassist-option, will swapweapon to a polearm. This only applies if quiver is empty and autoquiver is off. --- doc/Guidebook.mn | 4 +++- doc/Guidebook.tex | 4 +++- doc/fixes37.0 | 1 + include/extern.h | 1 + src/apply.c | 23 ++++++++++++++--------- src/dothrow.c | 19 ++++++++++++++++--- 6 files changed, 38 insertions(+), 14 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index d5c846454..08cdcf8e9 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -799,6 +799,7 @@ If your wielded weapon has the throw-and-return property, your quiver is empty, and .op autoquiver is false, you will throw that wielded weapon instead of filling the quiver. +This will also automatically use a polearm if wielded. If .op fireassist is true, firing will automatically try to wield a launcher (for example, @@ -1244,7 +1245,8 @@ You can set the .op paranoid_confirmation:quit option to require a response of \f(CRyes\fP instead. .lp "#fire " -Fire ammunition from quiver, possibly autowielding a launcher. +Fire ammunition from quiver, possibly autowielding a launcher, +or hit with a wielded polearm. Default key is \(oqf\(cq. .lp "#force " Force a lock. diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 43790bd3e..d45e5ada7 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -896,6 +896,7 @@ computer pick something appropriate if {\it autoquiver\/} is true. If your wielded weapon has the throw-and-return property, your quiver is empty, and {\it autoquiver\/} is false, you will throw that wielded weapon instead of filling the quiver. +This will also automatically use a polearm if wielded. If {\it fireassist\/} is true, firing will automatically try to wield a launcher (for example, a bow or a sling) matching the ammo in the quiver; this might take multiple turns, and get interrupted by a monster. @@ -1348,7 +1349,8 @@ You can set the option to require a response of ``{\tt yes}'' instead. %.lp \item[\tb{\#fire}] -Fire ammunition from quiver, possibly autowielding a launcher. +Fire ammunition from quiver, possibly autowielding a launcher, +or hit with a wielded polearm. Default key is `{\tt f}'. %.lp \item[\tb{\#force}] diff --git a/doc/fixes37.0 b/doc/fixes37.0 index b929cbf6d..330f98cec 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -725,6 +725,7 @@ apply runmode delay to multiturn actions, not just running if a giant carrying a boulder was on ice that melted, it could be killed twice, first by drowning, then by boulder filling the resulting pool when it dropped inventory before being removed from the map +allow fire-command to automatically use a polearm, if wielding it Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 6fa48fd2e..7c6bac9c1 100644 --- a/include/extern.h +++ b/include/extern.h @@ -52,6 +52,7 @@ extern boolean catch_lit(struct obj *); extern void use_unicorn_horn(struct obj **); extern boolean tinnable(struct obj *); extern void reset_trapset(void); +extern int use_pole(struct obj *, boolean); extern void fig_transform(union any *, long); extern int unfixable_trouble_count(boolean); diff --git a/src/apply.c b/src/apply.c index f315e3921..424deb4f6 100644 --- a/src/apply.c +++ b/src/apply.c @@ -30,7 +30,6 @@ static void use_stone(struct obj *); static int set_trap(void); /* occupation callback */ static int use_whip(struct obj *); static void display_polearm_positions(int); -static int use_pole(struct obj *); static int use_cream_pie(struct obj *); static int jelly_ok(struct obj *); static int use_royal_jelly(struct obj *); @@ -3076,8 +3075,8 @@ display_polearm_positions(int state) } /* Distance attacks by pole-weapons */ -static int -use_pole(struct obj *obj) +int +use_pole(struct obj *obj, boolean autohit) { const char thump[] = "Thump! Your blow bounces harmlessly off the %s."; int res = 0, typ, max_range, min_range, glyph; @@ -3125,7 +3124,8 @@ use_pole(struct obj *obj) g.polearm_range_max = max_range; /* Prompt for a location */ - pline(where_to_hit); + if (!autohit) + pline(where_to_hit); cc.x = u.ux; cc.y = u.uy; if (!find_poleable_mon(&cc, min_range, max_range) && hitm @@ -3135,16 +3135,21 @@ use_pole(struct obj *obj) cc.x = hitm->mx; cc.y = hitm->my; } - getpos_sethilite(display_polearm_positions, get_valid_polearm_position); - if (getpos(&cc, TRUE, "the spot to hit") < 0) - return res; /* ESC; uses turn iff polearm became wielded */ + if (!autohit) { + getpos_sethilite(display_polearm_positions, get_valid_polearm_position); + if (getpos(&cc, TRUE, "the spot to hit") < 0) + return res; /* ESC; uses turn iff polearm became wielded */ + } glyph = glyph_at(cc.x, cc.y); if (distu(cc.x, cc.y) > max_range) { pline("Too far!"); return res; } else if (distu(cc.x, cc.y) < min_range) { - pline("Too close!"); + if (autohit && cc.x == u.ux && cc.y == u.uy) + pline("Don't know what to hit."); + else + pline("Too close!"); return res; } else if (!cansee(cc.x, cc.y) && !glyph_is_poleable(glyph)) { You(cant_see_spot); @@ -3948,7 +3953,7 @@ doapply(void) default: /* Pole-weapons can strike at a distance */ if (is_pole(obj)) { - res = use_pole(obj); + res = use_pole(obj, FALSE); break; } else if (is_pick(obj) || is_axe(obj)) { res = use_pick_axe(obj); diff --git a/src/dothrow.c b/src/dothrow.c index 67bdd042a..4e0ef19ed 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -417,7 +417,7 @@ find_launcher(struct obj *ammo) return (struct obj *)0; } -/* f command -- fire: throw from the quiver */ +/* f command -- fire: throw from the quiver or use wielded polearm */ int dofire(void) { @@ -445,8 +445,21 @@ dofire(void) if (!flags.autoquiver) { if (uwep && AutoReturn(uwep, uwep->owornmask)) obj = uwep; - else - You("have no ammunition readied."); + else { + /* if we're wielding a polearm, apply it */ + if (uwep && is_pole(uwep)) + return use_pole(uwep, TRUE); + else if (iflags.fireassist + && uswapwep && is_pole(uswapwep) + && !(uswapwep->cursed && uswapwep->bknown)) { + /* we have a known not-cursed polearm as swap weapon. + swap to it and retry */ + cmdq_add_ec(doswapweapon); + cmdq_add_ec(dofire); + return 0; + } else + You("have no ammunition readied."); + } } else { autoquiver(); if ((obj = uquiver) == 0)