Don't switch away from polearm if monster in range

Using 'f', if hero is wielding a polearm, and a monster is in range,
don't switch away even if we do have ammo in quiver and a launcher
in the inventory.
This commit is contained in:
Pasi Kallinen
2024-12-08 22:18:27 +02:00
parent dafd854993
commit 57abae29e8
3 changed files with 65 additions and 27 deletions

View File

@@ -126,6 +126,7 @@ extern void use_unicorn_horn(struct obj **);
extern boolean tinnable(struct obj *) NONNULLPTRS;
extern void reset_trapset(void);
extern int use_whip(struct obj *) NONNULLPTRS;
extern boolean could_pole_mon(void);
extern int use_pole(struct obj *, boolean) NONNULLPTRS;
extern void fig_transform(union any *, long) NONNULLARG1;
extern int unfixable_trouble_count(boolean);

View File

@@ -32,6 +32,7 @@ staticfn int touchstone_ok(struct obj *);
staticfn int use_stone(struct obj *);
staticfn int set_trap(void); /* occupation callback */
staticfn void display_polearm_positions(boolean);
staticfn void calc_pole_range(int *, int *);
staticfn int use_cream_pie(struct obj *);
staticfn int jelly_ok(struct obj *);
staticfn int use_royal_jelly(struct obj **);
@@ -3341,12 +3342,71 @@ display_polearm_positions(boolean on_off)
}
}
/*
* Calculate allowable range (pole's reach is always 2 steps):
* unskilled and basic: orthogonal direction, 4..4;
* skilled: as basic, plus knight's jump position, 4..5;
* expert: as skilled, plus diagonal, 4..8.
* ...9...
* .85458.
* .52125.
* 9410149
* .52125.
* .85458.
* ...9...
* (Note: no roles in NetHack can become expert or better
* for polearm skill; Yeoman in slash'em can become expert.)
*/
staticfn void
calc_pole_range(int *min_range, int *max_range)
{
int typ = uwep_skill_type();
*min_range = 4;
if (typ == P_NONE || P_SKILL(typ) <= P_BASIC)
*max_range = 4;
else if (P_SKILL(typ) == P_SKILLED)
*max_range = 5;
else
*max_range = 8; /* (P_SKILL(typ) >= P_EXPERT) */
gp.polearm_range_min = *min_range;
gp.polearm_range_max = *max_range;
}
/* return TRUE if hero is wielding a polearm and there's
at least one monster they could hit with it */
boolean
could_pole_mon(void)
{
int min_range, max_range;
coord cc;
struct monst *hitm = svc.context.polearm.hitmon;
if (!uwep || !is_pole(uwep))
return FALSE;
calc_pole_range(&min_range, &max_range);
cc.x = u.ux;
cc.y = u.uy;
if (!find_poleable_mon(&cc, min_range, max_range)) {
if (hitm && !DEADMONSTER(hitm) && sensemon(hitm)
&& mdistu(hitm) <= max_range && mdistu(hitm) >= min_range)
return TRUE;
} else {
return TRUE;
}
return FALSE;
}
/* Distance attacks by pole-weapons */
int
use_pole(struct obj *obj, boolean autohit)
{
const char thump[] = "Thump! Your blow bounces harmlessly off the %s.";
int res = ECMD_OK, typ, max_range, min_range, glyph;
int res = ECMD_OK, max_range, min_range, glyph;
coord cc;
struct monst *mtmp;
struct monst *hitm = svc.context.polearm.hitmon;
@@ -3366,32 +3426,7 @@ use_pole(struct obj *obj, boolean autohit)
}
/* assert(obj == uwep); */
/*
* Calculate allowable range (pole's reach is always 2 steps):
* unskilled and basic: orthogonal direction, 4..4;
* skilled: as basic, plus knight's jump position, 4..5;
* expert: as skilled, plus diagonal, 4..8.
* ...9...
* .85458.
* .52125.
* 9410149
* .52125.
* .85458.
* ...9...
* (Note: no roles in NetHack can become expert or better
* for polearm skill; Yeoman in slash'em can become expert.)
*/
min_range = 4;
typ = uwep_skill_type();
if (typ == P_NONE || P_SKILL(typ) <= P_BASIC)
max_range = 4;
else if (P_SKILL(typ) == P_SKILLED)
max_range = 5;
else
max_range = 8; /* (P_SKILL(typ) >= P_EXPERT) */
gp.polearm_range_min = min_range;
gp.polearm_range_max = max_range;
calc_pole_range(&min_range, &max_range);
/* Prompt for a location */
if (!autohit)

View File

@@ -553,6 +553,8 @@ dofire(void)
if (uquiver && is_ammo(uquiver) && iflags.fireassist) {
struct obj *olauncher;
if (uwep && is_pole(uwep) && could_pole_mon())
return use_pole(uwep, TRUE);
/* Try to find a launcher */
if (ammo_and_launcher(uquiver, uwep)) {
obj = uquiver;