]> granicus.if.org Git - nethack/commitdiff
engraving with empty wand
authornethack.rankin <nethack.rankin>
Sat, 27 Jan 2007 05:50:10 +0000 (05:50 +0000)
committernethack.rankin <nethack.rankin>
Sat, 27 Jan 2007 05:50:10 +0000 (05:50 +0000)
     From a bug report:  if you
attempted to engrave with an empty wand while levitating, it wouldn't use
a turn unless you successfully wrested an extra charge out of the wand.
So you could always get such charge in a single elapsed turn of game time
if you didn't care about zapping in any particular direction; extremely
useful for wishing.

     Noticed when checking this:  when you did wrest the extra charge,
the engraving code accessed freed memory for the wand after it had been
used up.

     Lastly, wands producing certain effects always become discovered,
even when you don't yet know what they look like.  (This part of the patch
is trunk-only since it utilizes the routine which fixes similar case for
zapping.)

doc/fixes34.4
include/extern.h
src/engrave.c
src/zap.c

index 8d834711763e80fb13e7305fb74cd4fccc66cc70..c81ea39519fa3d21d4bfe010ca56e760748c5c25 100644 (file)
@@ -297,6 +297,9 @@ 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
+attempting to engrave with an empty wand should use a turn even when hero is
+       levitating--trying and failing to wrest a charge takes time
+don't access freed memory after engraving "wrests one last charnge" from wand
 
 
 Platform- and/or Interface-Specific Fixes
index 1fac63df43ae53c6f7a6db0639cd7b011f6cd323..9a5703eba3ed93209f68954c0d7a5b37e75d211a 100644 (file)
@@ -2578,6 +2578,7 @@ E int FDECL(dowrite, (struct obj *));
 
 /* ### zap.c ### */
 
+E void FDECL(learnwand, (struct obj *));
 E int FDECL(bhitm, (struct monst *,struct obj *));
 E void FDECL(probe_monster, (struct monst *));
 E boolean FDECL(get_obj_location, (struct obj *,xchar *,xchar *,int));
index c8b9190274a17842a4f5feba3ed3ec6cb69b8cb9..a02320ca1bb064a9845c75339a9d3b7583322a3b 100644 (file)
@@ -1,4 +1,4 @@
-/*     SCCS Id: @(#)engrave.c  3.5     2006/12/06      */
+/*     SCCS Id: @(#)engrave.c  3.5     2007/01/26      */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -618,7 +618,7 @@ doengrave()
                        return 1;
                    }
                    zapwand = TRUE;
-                   if (Levitation) ptext = FALSE;
+                   if (!can_reach_floor(TRUE)) ptext = FALSE;
 
                    switch (otmp->otyp) {
                    /* DUST wands */
@@ -771,11 +771,12 @@ doengrave()
                    /* type = MARK wands */
                    /* type = ENGR_BLOOD wands */
                    }
-               } else /* end if zappable */
-                   if (!can_reach_floor(TRUE)) {
-                       cant_reach_floor(u.ux, u.uy, FALSE, TRUE);
-                       return(0);
-                   }
+               } else { /* end if zappable */
+                   /* failing to wrest one last charge takes time */
+                   ptext = FALSE;      /* use "early exit" below, return 1 */
+                   /* cancelled wand turns to dust unless hero can't write */
+                   if (otmp->spe < 0 && can_reach_floor(TRUE)) zapwand = TRUE;
+               }
                break;
 
            case WEAPON_CLASS:
@@ -855,8 +856,8 @@ doengrave()
 
        /* Identify stylus */
        if (doknown) {
-           makeknown(otmp->otyp);
-           more_experienced(0,10);
+           learnwand(otmp);
+           if (objects[otmp->otyp].oc_name_known) more_experienced(0, 10);
        }
 
        if (teleengr) {
@@ -884,11 +885,12 @@ doengrave()
      "are not going to get anywhere trying to write in the %s with your dust.",
                    is_ice(u.ux,u.uy) ? "frost" : "dust");
            useup(otmp);
+           otmp = 0;   /* wand is now gone */
            ptext = FALSE;
        }
 
        if (!ptext) {           /* Early exit for some implements. */
-           if (otmp->oclass == WAND_CLASS && !can_reach_floor(TRUE))
+           if (otmp && otmp->oclass == WAND_CLASS && !can_reach_floor(TRUE))
                cant_reach_floor(u.ux, u.uy, FALSE, TRUE);
            return(1);
        }
index c025c289143587a25cdc50da5ec398cc52814704..fc9bd24721f9bd4f028711f0a0034b243235a767 100644 (file)
--- a/src/zap.c
+++ b/src/zap.c
@@ -19,7 +19,6 @@ extern boolean notonhead;     /* for long worms */
 /* kludge to use mondied instead of killed */
 extern boolean m_using;
 
-STATIC_DCL void FDECL(learnwand, (struct obj *));
 STATIC_DCL void FDECL(polyuse, (struct obj *,int,int));
 STATIC_DCL void FDECL(create_polymon, (struct obj *,int));
 STATIC_DCL boolean FDECL(zap_updown, (struct obj *));
@@ -117,7 +116,7 @@ const char * const flash_types[] = {        /* also used in buzzmu(mcastu.c) */
  */
 
 /* wand discovery gets special handling when hero is blinded */
-STATIC_OVL void
+void
 learnwand(obj)
 struct obj *obj;
 {