kicking off edge of map

From a bug report:  if you
were at one of the map edges and kicked away from map center while blind,
you'd get impossible("show_glyph: bad pos ...").  That was due to calling
feel_location() for the out of bounds location, which occurred after the
kick code had made use of invalid data so other problems might occur too.

     Now you kick "nothing" as if it was something (hence possibly wounding
your leg, taking some damage, potentially dying).  I didn't want to try to
classify the surrounding terrain as rock or air or whatever, and the thing
being kicked only shows up if the kick is fatal.
This commit is contained in:
nethack.rankin
2007-01-27 04:33:16 +00:00
parent c36712aabe
commit e2fffafb7c
3 changed files with 22 additions and 11 deletions

View File

@@ -295,6 +295,8 @@ statues that "come to life" when trap activates shouldn't start out sleeping
shopkeepers and priests wouldn't step on graves put in their rooms by bones shopkeepers and priests wouldn't step on graves put in their rooms by bones
can't throw if poly'd into form which lacks hands can't throw if poly'd into form which lacks hands
can't eat an artifact you're unable to touch can't eat an artifact you're unable to touch
attempting to kick beyond map edge performed an out of array bounds memory
access; symptom seen was "show_glyph: bad pos" warning when blind
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)display.c 3.5 2007/01/17 */ /* SCCS Id: @(#)display.c 3.5 2007/01/26 */
/* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */ /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */
/* and Dave Cohrs, 1990. */ /* and Dave Cohrs, 1990. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -502,16 +502,18 @@ void
feel_location(x, y) feel_location(x, y)
xchar x, y; xchar x, y;
{ {
struct rm *lev = &(levl[x][y]); struct rm *lev;
struct obj *boulder; struct obj *boulder;
register struct monst *mon; register struct monst *mon;
if (!isok(x, y)) return;
lev = &(levl[x][y]);
/* If the hero's memory of an invisible monster is accurate, we want to keep /* If the hero's memory of an invisible monster is accurate, we want to keep
* him from detecting the same monster over and over again on each turn. * him from detecting the same monster over and over again on each turn.
* We must return (so we don't erase the monster). (We must also, in the * We must return (so we don't erase the monster). (We must also, in the
* search function, be sure to skip over previously detected 'I's.) * search function, be sure to skip over previously detected 'I's.)
*/ */
if (glyph_is_invisible(levl[x][y].glyph) && m_at(x,y)) return; if (glyph_is_invisible(lev->glyph) && m_at(x,y)) return;
/* The hero can't feel non pool locations while under water. */ /* The hero can't feel non pool locations while under water. */
if (Underwater && !Is_waterlevel(&u.uz) && ! is_pool(x,y)) if (Underwater && !Is_waterlevel(&u.uz) && ! is_pool(x,y))

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)dokick.c 3.5 2007/01/02 */ /* SCCS Id: @(#)dokick.c 3.5 2007/01/26 */
/* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */ /* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -8,7 +8,7 @@
#define martial() (martial_bonus() || is_bigfoot(youmonst.data) || \ #define martial() (martial_bonus() || is_bigfoot(youmonst.data) || \
(uarmf && uarmf->otyp == KICKING_BOOTS)) (uarmf && uarmf->otyp == KICKING_BOOTS))
static NEARDATA struct rm *maploc; static NEARDATA struct rm *maploc, nowhere;
static NEARDATA const char *gate_str; static NEARDATA const char *gate_str;
extern boolean notonhead; /* for long worms */ extern boolean notonhead; /* for long worms */
@@ -603,6 +603,7 @@ char *buf;
const char *what; const char *what;
if (kickobj) what = killer_xname(kickobj); if (kickobj) what = killer_xname(kickobj);
if (maploc == &nowhere) what = "nothing";
else if (IS_DOOR(maploc->typ)) what = "a door"; else if (IS_DOOR(maploc->typ)) what = "a door";
else if (IS_TREE(maploc->typ)) what = "a tree"; else if (IS_TREE(maploc->typ)) what = "a tree";
else if (IS_STWALL(maploc->typ)) what = "a wall"; else if (IS_STWALL(maploc->typ)) what = "a wall";
@@ -739,6 +740,10 @@ dokick()
wake_nearby(); wake_nearby();
u_wipe_engr(2); u_wipe_engr(2);
if (!isok(x, y)) {
maploc = &nowhere;
goto ouch;
}
maploc = &levl[x][y]; maploc = &levl[x][y];
/* The next five tests should stay in */ /* The next five tests should stay in */
@@ -1012,12 +1017,14 @@ ouch:
pline("Ouch! That hurts!"); pline("Ouch! That hurts!");
exercise(A_DEX, FALSE); exercise(A_DEX, FALSE);
exercise(A_STR, FALSE); exercise(A_STR, FALSE);
if (Blind) feel_location(x,y); /* we know we hit it */ if (isok(x, y)) {
if (is_drawbridge_wall(x,y) >= 0) { if (Blind) feel_location(x,y); /* we know we hit it */
pline_The("drawbridge is unaffected."); if (is_drawbridge_wall(x,y) >= 0) {
/* update maploc to refer to the drawbridge */ pline_The("drawbridge is unaffected.");
(void) find_drawbridge(&x,&y); /* update maploc to refer to the drawbridge */
maploc = &levl[x][y]; (void) find_drawbridge(&x,&y);
maploc = &levl[x][y];
}
} }
if(!rn2(3)) set_wounded_legs(RIGHT_SIDE, 5 + rnd(5)); if(!rn2(3)) set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
dmg = rnd(ACURR(A_CON) > 15 ? 3 : 5); dmg = rnd(ACURR(A_CON) > 15 ? 3 : 5);