]> granicus.if.org Git - nethack/commitdiff
fix #K3241 - potion dip drop due to pickup_burden
authorPatR <rankin@nethack.org>
Tue, 12 Jan 2021 00:19:50 +0000 (16:19 -0800)
committerPatR <rankin@nethack.org>
Tue, 12 Jan 2021 00:19:50 +0000 (16:19 -0800)
Dipping a unicorn horn to transform a potion causes that potion
to be removed from and re-inserted into inventory.  If the hero
was above 'pickup_burden' threshold prior to dipping and
removing the old potion brought encumbrance back under that,
attempting to add the new one back would drop it instead of
re-exceeding the threshold.

doc/fixes37.0
src/potion.c

index a173aff42f5ae0db6539cb62a1afe6b68793e065..9f84ee6fd74de40ab3de0a75b682eefc3a3c70d7 100644 (file)
@@ -1,4 +1,4 @@
-NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.425 $ $NHDT-Date: 1610138674 2021/01/08 20:44:34 $
+NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.426 $ $NHDT-Date: 1610410779 2021/01/12 00:19:39 $
 
 General Fixes and Modified Features
 -----------------------------------
@@ -361,6 +361,9 @@ when a pet ate a mimic corpse and tried to temporarily look like a sink it
        ended up looking like a throne (terrain type SINK == symbol S_throne)
 have dowhatdoes ('&') catch up with '?i' to describe ^A, ESC, and movement
        prefix keystrokes correctly instead of reporting "no such command"
+transforming a potion by dipping a unicorn horn into it could result in the
+       potion being dropped due to 'pickup_burden' if encumbrance was already
+       over threshold before dipping but within it after removal from invent
 
 
 Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
index d46d4da329b04388f672715fa2761feed68715a3..0cdb38e325f0e43f118ff6e079d36179741a3407 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 potion.c        $NHDT-Date: 1596498197 2020/08/03 23:43:17 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.182 $ */
+/* NetHack 3.7 potion.c        $NHDT-Date: 1610410780 2021/01/12 00:19:40 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.190 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2013. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -9,10 +9,12 @@ static long FDECL(itimeout, (long));
 static long FDECL(itimeout_incr, (long, int));
 static void NDECL(ghost_from_bottle);
 static int FDECL(drink_ok, (struct obj *));
-static boolean
-FDECL(H2Opotion_dip, (struct obj *, struct obj *, BOOLEAN_P, const char *));
+static boolean FDECL(H2Opotion_dip, (struct obj *, struct obj *,
+                                     BOOLEAN_P, const char *));
 static short FDECL(mixtype, (struct obj *, struct obj *));
 static int FDECL(dip_ok, (struct obj *));
+static void FDECL(hold_potion, (struct obj *, const char *,
+                                const char *, const char *));
 
 /* force `val' to be within valid range for intrinsic timeout value */
 static long
@@ -1916,6 +1918,28 @@ struct obj *obj;
     return GETOBJ_SUGGEST;
 }
 
+/* call hold_another_object() to deal with a transformed potion; its weight
+   won't have changed but it might require an extra slot that isn't available
+   or it might merge into some other carried stack */
+static void
+hold_potion(potobj, drop_fmt, drop_arg, hold_msg)
+struct obj *potobj;
+const char *drop_fmt, *drop_arg, *hold_msg;
+{
+    int cap = near_capacity(),
+        save_pickup_burden = flags.pickup_burden;
+
+    /* prevent a drop due to current setting of the 'pickup_burden' option */
+    if (flags.pickup_burden < cap)
+        flags.pickup_burden = cap;
+    /* remove from inventory after calculating near_capacity() */
+    obj_extract_self(potobj);
+    /* re-insert into inventory, possibly merging with compatible stack */
+    potobj = hold_another_object(potobj, drop_fmt, drop_arg, hold_msg);
+    flags.pickup_burden = save_pickup_burden;
+    return;
+}
+
 /* #dip command */
 int
 dodip()
@@ -2121,8 +2145,7 @@ dodip()
            been made in order to get the merge result for both cases;
            as a consequence, mixing while Fumbling drops the mixture */
         freeinv(obj);
-        (void) hold_another_object(obj, "You drop %s!", doname(obj),
-                                   (const char *) 0);
+        hold_potion(obj, "You drop %s!", doname(obj), (const char *) 0);
         return 1;
     }
 
@@ -2309,12 +2332,10 @@ dodip()
                 docall(&fakeobj);
             }
         }
-        obj_extract_self(singlepotion);
-        singlepotion = hold_another_object(singlepotion,
-                                           "You juggle and drop %s!",
-                                           doname(singlepotion),
-                                           (const char *) 0);
-        nhUse(singlepotion);
+        /* remove potion from inventory and re-insert it, possibly stacking
+           with compatible ones; override 'pickup_burden' while doing so */
+        hold_potion(singlepotion, "You juggle and drop %s!",
+                    doname(singlepotion), (const char *) 0);
         update_inventory();
         return 1;
     }