]> granicus.if.org Git - nethack/commitdiff
fix #H6942 - dropx vs hold_another_object
authorPatR <rankin@nethack.org>
Sun, 23 Dec 2018 20:37:26 +0000 (12:37 -0800)
committerPatR <rankin@nethack.org>
Sun, 23 Dec 2018 20:37:26 +0000 (12:37 -0800)
Dropping an existing fragile item while levitating will usually
break it.  Getting a new wished-for fragile item and dropping it
because of fumbling or overfull inventory never would.

Some callers of hold_another_object() held on to its return value,
others discarded that.  That return value was unsafe if the item
was dropped and fell down a hole (or broke [after this change]).
Return Null if we can't be sure of the value, and make sure all
callers are prepared to deal with Null.

doc/fixes36.2
include/extern.h
src/artifact.c
src/do.c
src/dothrow.c
src/invent.c
src/mail.c
src/mkobj.c
src/pickup.c
src/potion.c
src/uhitm.c

index 01b2f33b753f93943e5f615f4e762b263ae2d23c..7be5fc55622928a974d92e24bfc7177462682a9e 100644 (file)
@@ -303,6 +303,7 @@ training riding skill had an off-by-one bug when counting turns riding
 message sequencing when vampire shifts to fog cloud to pass under closed door:
        when in sight, give form change message before moving to door spot
 limit carrying heavy loads from water to land
+failing to carry a wished-for item behaved differenctly from dropping one
 
 
 Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
index 78c7647da8cb855c7c1c0869eef9ce84b2d8011c..7a239f127fefbc3bddd67489f7891b7a4f9c09df 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 extern.h        $NHDT-Date: 1545383614 2018/12/21 09:13:34 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.675 $ */
+/* NetHack 3.6 extern.h        $NHDT-Date: 1545597403 2018/12/23 20:36:43 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.676 $ */
 /* Copyright (c) Steve Creps, 1988.                              */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -536,7 +536,7 @@ E void FDECL(impact_drop, (struct obj *, XCHAR_P, XCHAR_P, XCHAR_P));
 E int NDECL(dothrow);
 E int NDECL(dofire);
 E void FDECL(endmultishot, (BOOLEAN_P));
-E void FDECL(hitfloor, (struct obj *));
+E void FDECL(hitfloor, (struct obj *, BOOLEAN_P));
 E void FDECL(hurtle, (int, int, int, BOOLEAN_P));
 E void FDECL(mhurtle, (struct monst *, int, int, int));
 E boolean FDECL(throwing_weapon, (struct obj *));
index 80332f32521a8433df29636c316670a4fad3a03b..2a641b8d7a63dfb1b4a88333ce764a276b1ce8c4 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 artifact.c      $NHDT-Date: 1543745353 2018/12/02 10:09:13 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.127 $ */
+/* NetHack 3.6 artifact.c      $NHDT-Date: 1545597414 2018/12/23 20:36:54 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.128 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2013. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -1479,6 +1479,7 @@ struct obj *obj;
         }
         case ENERGY_BOOST: {
             int epboost = (u.uenmax + 1 - u.uen) / 2;
+
             if (epboost > 120)
                 epboost = 120; /* arbitrary */
             else if (epboost < 12)
@@ -1598,6 +1599,7 @@ struct obj *obj;
             otmp->owt = weight(otmp);
             otmp = hold_another_object(otmp, "Suddenly %s out.",
                                        aobjnam(otmp, "fall"), (char *) 0);
+            nhUse(otmp);
             break;
         }
         }
@@ -1621,7 +1623,7 @@ struct obj *obj;
         }
 
         if ((eprop & ~W_ARTI) || iprop) {
       nothing_special:
+ nothing_special:
             /* you had the property from some other source too */
             if (carried(obj))
                 You_feel("a surge of power, but nothing seems to happen.");
@@ -1975,7 +1977,7 @@ boolean loseit;    /* whether to drop it if hero can longer touch it */
     if (loseit && obj) {
         if (Levitation) {
             freeinv(obj);
-            hitfloor(obj);
+            hitfloor(obj, TRUE);
         } else {
             /* dropx gives a message iff item lands on an altar */
             if (!IS_ALTAR(levl[u.ux][u.uy].typ))
index 3438a44b1eebec9f74e352e04af15298887a725f..b05339df4d419ae87a82feeb46d69340860144aa 100644 (file)
--- a/src/do.c
+++ b/src/do.c
@@ -1,4 +1,4 @@
-/* NetHack 3.6 do.c    $NHDT-Date: 1545043771 2018/12/17 10:49:31 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.181 $ */
+/* NetHack 3.6 do.c    $NHDT-Date: 1545597418 2018/12/23 20:36:58 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.182 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Derek S. Ray, 2015. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -612,7 +612,7 @@ register struct obj *obj;
             if (obj->oclass == COIN_CLASS)
                 context.botl = 1;
             freeinv(obj);
-            hitfloor(obj);
+            hitfloor(obj, TRUE);
             if (levhack)
                 float_down(I_SPECIAL | TIMEOUT, W_ARTI | W_ART);
             return 1;
index b3a2f8ba4891726026f3727ea42196b31714de64..de1afca9c225fec05261824d9992e273ec08b41c 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 dothrow.c       $NHDT-Date: 1545044705 2018/12/17 11:05:05 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.154 $ */
+/* NetHack 3.6 dothrow.c       $NHDT-Date: 1545597420 2018/12/23 20:37:00 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.155 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2013. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -415,21 +415,21 @@ boolean verbose;
     }
 }
 
-/*
- * Object hits floor at hero's feet.  Called from drop() and throwit().
- */
+/* Object hits floor at hero's feet.
+   Called from drop(), throwit(), hold_another_object(). */
 void
-hitfloor(obj)
-register struct obj *obj;
+hitfloor(obj, verbosely)
+struct obj *obj;
+boolean verbosely; /* usually True; False if caller has given drop message */
 {
-    if (IS_SOFT(levl[u.ux][u.uy].typ) || u.uinwater) {
+    if (IS_SOFT(levl[u.ux][u.uy].typ) || u.uinwater || u.uswallow) {
         dropy(obj);
         return;
     }
     if (IS_ALTAR(levl[u.ux][u.uy].typ))
         doaltarobj(obj);
-    else
-        pline("%s hit%s the %s.", Doname2(obj), (obj->quan == 1L) ? "s" : "",
+    else if (verbosely)
+        pline("%s %s the %s.", Doname2(obj), otense(obj, "hit"),
               surface(u.ux, u.uy));
 
     if (hero_breaks(obj, u.ux, u.uy, TRUE))
@@ -1047,7 +1047,7 @@ boolean hitsroof;
             done(STONING);
             return obj ? TRUE : FALSE;
         }
-        hitfloor(obj);
+        hitfloor(obj, TRUE);
         thrownobj = 0;
         losehp(Maybe_Half_Phys(dmg), "falling object", KILLED_BY_AN);
     }
@@ -1168,7 +1168,7 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
                for dealing with cursed saddle:  throw holy water > */
             potionhit(u.usteed, obj, POTHIT_HERO_THROW);
         } else {
-            hitfloor(obj);
+            hitfloor(obj, TRUE);
         }
         thrownobj = (struct obj *) 0;
         return;
index 93939ad86906b674aaae77ac6646ba59275bc51b..62ec7040158b143afec3b2e3b4c93d3315a4bb31 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 invent.c        $NHDT-Date: 1545043772 2018/12/17 10:49:32 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.244 $ */
+/* NetHack 3.6 invent.c        $NHDT-Date: 1545597422 2018/12/23 20:37:02 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.245 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Derek S. Ray, 2015. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -975,9 +975,9 @@ const char *drop_fmt, *drop_arg, *hold_msg;
         }
     }
     if (Fumbling) {
-        if (drop_fmt)
-            pline(drop_fmt, drop_arg);
-        dropy(obj);
+        obj->nomerge = 1;
+        obj = addinv(obj); /* dropping expects obj to be in invent */
+        goto drop_it;
     } else {
         long oquan = obj->quan;
         int prev_encumbr = near_capacity(); /* before addinv() */
@@ -994,12 +994,10 @@ const char *drop_fmt, *drop_arg, *hold_msg;
         obj = addinv(obj);
         if (inv_cnt(FALSE) > 52 || ((obj->otyp != LOADSTONE || !obj->cursed)
                                     && near_capacity() > prev_encumbr)) {
-            if (drop_fmt)
-                pline(drop_fmt, drop_arg);
             /* undo any merge which took place */
             if (obj->quan > oquan)
                 obj = splitobj(obj, oquan);
-            dropx(obj);
+            goto drop_it;
         } else {
             if (flags.autoquiver && !uquiver && !obj->owornmask
                 && (is_missile(obj) || ammo_and_launcher(obj, uwep)
@@ -1010,6 +1008,18 @@ const char *drop_fmt, *drop_arg, *hold_msg;
         }
     }
     return obj;
+
+ drop_it:
+    if (drop_fmt)
+        pline(drop_fmt, drop_arg);
+    obj->nomerge = 0;
+    if (can_reach_floor(TRUE)) {
+        dropx(obj);
+    } else {
+        freeinv(obj);
+        hitfloor(obj, FALSE);
+    }
+    return (struct obj *) 0; /* might be gone */
 }
 
 /* useup() all of an item regardless of its quantity */
index b3f8e97c6a92201104106a88b8513f69a89ff030..63142ad517bee4125463259767e0f65bbb6dc5c4 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 mail.c  $NHDT-Date: 1542765359 2018/11/21 01:55:59 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.37 $ */
+/* NetHack 3.6 mail.c  $NHDT-Date: 1545597424 2018/12/23 20:37:04 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.39 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Pasi Kallinen, 2018. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -186,7 +186,7 @@ coord *startp;
      */
     lax = 0; /* be picky */
     max_distance = -1;
-retry:
+ retry:
     for (row = 0; row < ROWNO; row++) {
         if (viz_rmin[row] < viz_rmax[row]) {
             /* There are valid positions on this row. */
@@ -418,15 +418,17 @@ struct mail_info *info;
         display_nhwindow(WIN_MESSAGE, FALSE);
         obj = hold_another_object(obj, "Oops!", (const char *) 0,
                                   (const char *) 0);
+        nhUse(obj);
     }
 
-/* zip back to starting location */
-go_back:
+ go_back:
+    /* zip back to starting location */
     if (!md_rush(md, start.x, start.y))
         md->mx = md->my = 0; /* for mongone, md is not on map */
     mongone(md);
-/* deliver some classes of messages even if no daemon ever shows up */
-give_up:
+
+ give_up:
+    /* deliver some classes of messages even if no daemon ever shows up */
     if (!message_seen && info->message_typ == MSG_OTHER)
         pline("Hark!  \"%s.\"", info->display_txt);
 }
@@ -609,7 +611,7 @@ boolean adminmsg;
     else
         unlink(mailbox);
     return;
-bail:
+ bail:
     /* bail out _professionally_ */
     if (!adminmsg)
         pline("It appears to be all gibberish.");
index 9a0ec48f2a99a81752a6bdc48dccc7ede62df16d..50140fe1fb23ed7efb5a509b2f72ae03c7346706 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 mkobj.c $NHDT-Date: 1542798624 2018/11/21 11:10:24 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.136 $ */
+/* NetHack 3.6 mkobj.c $NHDT-Date: 1545597425 2018/12/23 20:37:05 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.137 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Derek S. Ray, 2015. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -2168,18 +2168,21 @@ boolean tipping; /* caller emptying entire contents; affects shop handling */
            being included in its formatted name during next message */
         iflags.suppress_price++;
         if (!tipping) {
-            obj = hold_another_object(
-                obj, u.uswallow ? "Oops!  %s out of your reach!"
-                                : (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
-                                   || levl[u.ux][u.uy].typ < IRONBARS
-                                   || levl[u.ux][u.uy].typ >= ICE)
-                                      ? "Oops!  %s away from you!"
-                                      : "Oops!  %s to the floor!",
-                The(aobjnam(obj, "slip")), (const char *) 0);
+            obj = hold_another_object(obj,
+                                      u.uswallow
+                                        ? "Oops!  %s out of your reach!"
+                                        : (Is_airlevel(&u.uz)
+                                           || Is_waterlevel(&u.uz)
+                                           || levl[u.ux][u.uy].typ < IRONBARS
+                                           || levl[u.ux][u.uy].typ >= ICE)
+                                          ? "Oops!  %s away from you!"
+                                          : "Oops!  %s to the floor!",
+                                      The(aobjnam(obj, "slip")), (char *) 0);
+            nhUse(obj);
         } else {
             /* assumes this is taking place at hero's location */
             if (!can_reach_floor(TRUE)) {
-                hitfloor(obj); /* does altar check, message, drop */
+                hitfloor(obj, TRUE); /* does altar check, message, drop */
             } else {
                 if (IS_ALTAR(levl[u.ux][u.uy].typ))
                     doaltarobj(obj); /* does its own drop message */
index 65a541d1228510024e72a9f39b40c265fd82cac0..a8b611454527cbaa4508e96ff9426167947d0d2a 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 pickup.c        $NHDT-Date: 1543188989 2018/11/25 23:36:29 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.220 $ */
+/* NetHack 3.6 pickup.c        $NHDT-Date: 1545597427 2018/12/23 20:37:07 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.221 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2012. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -2023,6 +2023,7 @@ boolean *prev_loot;
             }
             otmp = hold_another_object(otmp, "You drop %s!", doname(otmp),
                                        (const char *) 0);
+            nhUse(otmp);
             timepassed = rnd(3);
             if (prev_loot)
                 *prev_loot = TRUE;
@@ -3188,7 +3189,7 @@ struct obj *box; /* or bag */
 
             if (highdrop) {
                 /* might break or fall down stairs; handles altars itself */
-                hitfloor(otmp);
+                hitfloor(otmp, TRUE);
             } else {
                 if (altarizing) {
                     doaltarobj(otmp);
index a6bf5f656646121fcfbe630c780874c9e22c98ac..482321692d1d634fd1d5d0481e5d6b311fb530bb 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 potion.c        $NHDT-Date: 1545182147 2018/12/19 01:15:47 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.156 $ */
+/* NetHack 3.6 potion.c        $NHDT-Date: 1545597429 2018/12/23 20:37:09 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.157 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2013. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -2237,6 +2237,7 @@ more_dips:
         singlepotion =
             hold_another_object(singlepotion, "You juggle and drop %s!",
                                 doname(singlepotion), (const char *) 0);
+        nhUse(singlepotion);
         update_inventory();
         return 1;
     }
index 01c4235931264ebf97b175bce929c86f62dd3582..fa50677dc67300e7179f1e40cfc1d5442df44aea 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 uhitm.c $NHDT-Date: 1544840256 2018/12/15 02:17:36 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.196 $ */
+/* NetHack 3.6 uhitm.c $NHDT-Date: 1545597432 2018/12/23 20:37:12 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.197 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2012. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -1546,7 +1546,8 @@ struct attack *mattk;
         /* give the object to the character */
         otmp = hold_another_object(otmp, "You snatched but dropped %s.",
                                    doname(otmp), "You steal: ");
-        if (otmp->where != OBJ_INVENT)
+        /* might have dropped otmp, and it might have broken or left level */
+        if (!otmp || otmp->where != OBJ_INVENT)
             continue;
         if (theft_petrifies(otmp))
             break; /* stop thieving even though hero survived */