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 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) 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 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 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) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -2865,21 +2865,41 @@ coord *pos;
int min_range, max_range; int min_range, max_range;
{ {
struct monst *mtmp; 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 (Blind)
if (mtmp && !DEADMONSTER(mtmp) && !mtmp->mtame return FALSE; /* must be able to see target location */
&& cansee(mtmp->mx, mtmp->my) impaired = (Confusion || Stunned || Hallucination);
&& distu(mtmp->mx, mtmp->my) <= max_range mpos.x = mpos.y = 0; /* no candidate location yet */
&& distu(mtmp->mx, mtmp->my) >= min_range) { rt = isqrt(max_range);
if (selmon) lo_x = max(u.ux - rt, 1), hi_x = min(u.ux + rt, COLNO - 1);
return FALSE; lo_y = max(u.uy - rt, 0), hi_y = min(u.uy + rt, ROWNO - 1);
selmon = mtmp; 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; if (!mpos.x)
pos->x = selmon->mx; return FALSE; /* no candidate location */
pos->y = selmon->my; *pos = mpos;
return TRUE; return TRUE;
} }
@@ -2887,8 +2907,8 @@ static int polearm_range_min = -1;
static int polearm_range_max = -1; static int polearm_range_max = -1;
STATIC_OVL boolean STATIC_OVL boolean
get_valid_polearm_position(x,y) get_valid_polearm_position(x, y)
int x,y; int x, y;
{ {
return (isok(x, y) && ACCESSIBLE(levl[x][y].typ) return (isok(x, y) && ACCESSIBLE(levl[x][y].typ)
&& distu(x, y) >= polearm_range_min && distu(x, y) >= polearm_range_min
@@ -2998,7 +3018,7 @@ struct obj *obj;
return res; return res;
} }
context.polearm.hitmon = NULL; context.polearm.hitmon = (struct monst *) 0;
/* Attack the monster there */ /* Attack the monster there */
bhitpos = cc; bhitpos = cc;
if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != (struct monst *) 0) { if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != (struct monst *) 0) {