fix #H7155 - polearm can reveal hidden monster

The code to choose a likely target when applying a polearm was
basing its decision on visible spots which contained monsters,
so could expose the location of a hidden monster if there was
only one such spot within polearm range.  Not mentioned in the
report:  it also wouldn't pick remembered, unseen monster unless
there was a monster still at that spot.

I've changed it to choose candidate location based on the glyphs
shown rather than on the presence of monsters.
This commit is contained in:
PatR
2018-05-19 15:46:09 -07:00
parent 98099863ff
commit b17c6d0b54
2 changed files with 38 additions and 17 deletions

View File

@@ -17,6 +17,7 @@ numeric hilite_status values didn't allow negative numbers (needed for AC);
permanent inventory window was updated too soon when a scroll of charging
was used to [re]charge an item, not reflecting the item's change(s)
for starting inventory, don't give an orc hero lembas wafers or cram rations
targetting with a polearm could give away location of hidden monster
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 apply.c $NHDT-Date: 1519598527 2018/02/25 22:42:07 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.243 $ */
/* NetHack 3.6 apply.c $NHDT-Date: 1526769961 2018/05/19 22:46:01 $ $NHDT-Branch: NetHack-3.6.2 $:$NHDT-Revision: 1.246 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
@@ -2865,21 +2865,41 @@ coord *pos;
int min_range, max_range;
{
struct monst *mtmp;
struct monst *selmon = (struct monst *) 0;
coord mpos;
boolean impaired;
int x, y, lo_x, hi_x, lo_y, hi_y, rt, glyph;
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
if (mtmp && !DEADMONSTER(mtmp) && !mtmp->mtame
&& cansee(mtmp->mx, mtmp->my)
&& distu(mtmp->mx, mtmp->my) <= max_range
&& distu(mtmp->mx, mtmp->my) >= min_range) {
if (selmon)
return FALSE;
selmon = mtmp;
if (Blind)
return FALSE; /* must be able to see target location */
impaired = (Confusion || Stunned || Hallucination);
mpos.x = mpos.y = 0; /* no candidate location yet */
rt = isqrt(max_range);
lo_x = max(u.ux - rt, 1), hi_x = min(u.ux + rt, COLNO - 1);
lo_y = max(u.uy - rt, 0), hi_y = min(u.uy + rt, ROWNO - 1);
for (x = lo_x; x <= hi_x; ++x) {
for (y = lo_y; y <= hi_y; ++y) {
if (distu(x, y) < min_range || distu(x, y) > max_range
|| !isok(x, y) || !cansee(x, y))
continue;
glyph = glyph_at(x, y);
if (!impaired
&& glyph_is_monster(glyph)
&& (mtmp = m_at(x, y)) != 0
&& (mtmp->mtame || (mtmp->mpeaceful && flags.confirm)))
continue;
if (glyph_is_monster(glyph)
|| glyph_is_warning(glyph)
|| glyph_is_invisible(glyph)
|| (glyph_is_statue(glyph) && impaired)) {
if (mpos.x)
return FALSE; /* more than one candidate location */
mpos.x = x, mpos.y = y;
}
}
if (!selmon)
return FALSE;
pos->x = selmon->mx;
pos->y = selmon->my;
}
if (!mpos.x)
return FALSE; /* no candidate location */
*pos = mpos;
return TRUE;
}
@@ -2887,8 +2907,8 @@ static int polearm_range_min = -1;
static int polearm_range_max = -1;
STATIC_OVL boolean
get_valid_polearm_position(x,y)
int x,y;
get_valid_polearm_position(x, y)
int x, y;
{
return (isok(x, y) && ACCESSIBLE(levl[x][y].typ)
&& distu(x, y) >= polearm_range_min
@@ -2998,7 +3018,7 @@ struct obj *obj;
return res;
}
context.polearm.hitmon = NULL;
context.polearm.hitmon = (struct monst *) 0;
/* Attack the monster there */
bhitpos = cc;
if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != (struct monst *) 0) {