]> granicus.if.org Git - nethack/commitdiff
kicking off edge of map
authornethack.rankin <nethack.rankin>
Sat, 27 Jan 2007 04:33:16 +0000 (04:33 +0000)
committernethack.rankin <nethack.rankin>
Sat, 27 Jan 2007 04:33:16 +0000 (04:33 +0000)
     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.

doc/fixes34.4
src/display.c
src/dokick.c

index db8d50b0a01c43b844dadd06e5ed268d9a41437b..8d834711763e80fb13e7305fb74cd4fccc66cc70 100644 (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
 can't throw if poly'd into form which lacks hands
 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
index 95ddb5a2162ce551a32a28d076525fd33693991d..9a2686f3c7e9f3acb4fa5949b3e625f063ae5c1c 100644 (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 */
 /* and Dave Cohrs, 1990.                                         */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -502,16 +502,18 @@ void
 feel_location(x, y)
     xchar x, y;
 {
-    struct rm *lev = &(levl[x][y]);
+    struct rm *lev;
     struct obj *boulder;
     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
      * 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
      * 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. */
     if (Underwater && !Is_waterlevel(&u.uz) && ! is_pool(x,y))
index 7790b5b358714c4165e3b4624171888594806c41..33fe8ae5a0b073ffd6ac402d74f28158eccd5ec2 100644 (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. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -8,7 +8,7 @@
 #define martial()      (martial_bonus() || is_bigfoot(youmonst.data) || \
                (uarmf && uarmf->otyp == KICKING_BOOTS))
 
-static NEARDATA struct rm *maploc;
+static NEARDATA struct rm *maploc, nowhere;
 static NEARDATA const char *gate_str;
 
 extern boolean notonhead;      /* for long worms */
@@ -603,6 +603,7 @@ char *buf;
        const char *what;
 
        if (kickobj) what = killer_xname(kickobj);
+       if (maploc == &nowhere) what = "nothing";
        else if (IS_DOOR(maploc->typ)) what = "a door";
        else if (IS_TREE(maploc->typ)) what = "a tree";
        else if (IS_STWALL(maploc->typ)) what = "a wall";
@@ -739,6 +740,10 @@ dokick()
        wake_nearby();
        u_wipe_engr(2);
 
+       if (!isok(x, y)) {
+           maploc = &nowhere;
+           goto ouch;
+       }
        maploc = &levl[x][y];
 
        /* The next five tests should stay in    */
@@ -1012,12 +1017,14 @@ ouch:
                    pline("Ouch!  That hurts!");
                    exercise(A_DEX, FALSE);
                    exercise(A_STR, FALSE);
-                   if (Blind) feel_location(x,y); /* we know we hit it */
-                   if (is_drawbridge_wall(x,y) >= 0) {
-                       pline_The("drawbridge is unaffected.");
-                       /* update maploc to refer to the drawbridge */
-                       (void) find_drawbridge(&x,&y);
-                       maploc = &levl[x][y];
+                   if (isok(x, y)) {
+                       if (Blind) feel_location(x,y); /* we know we hit it */
+                       if (is_drawbridge_wall(x,y) >= 0) {
+                           pline_The("drawbridge is unaffected.");
+                           /* update maploc to refer to the drawbridge */
+                           (void) find_drawbridge(&x,&y);
+                           maploc = &levl[x][y];
+                       }
                    }
                    if(!rn2(3)) set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
                    dmg = rnd(ACURR(A_CON) > 15 ? 3 : 5);