]> granicus.if.org Git - nethack/commitdiff
fix #K3603 - multiple stacks of gold in container
authorPatR <rankin@nethack.org>
Thu, 2 Jun 2022 21:44:30 +0000 (14:44 -0700)
committerPatR <rankin@nethack.org>
Thu, 2 Jun 2022 21:44:30 +0000 (14:44 -0700)
When taking stuff out of a container, specifying a subset count for
an item and getting the pickup_burden prompt, answering 'q' undid the
subset split but answering 'n' did not.  If the item in question was
a stack of gold, the container would end up with two stacks.  That
action could be repeated as long as any of the stacks was big enough
to trigger pickup_burden confirmation so an arbitrary number of gold
stacks could be produced.  (Eventually they would be too small for a
subset to cause an increase in encumbrance, or possibly all reduced
to just one gold piece, then no more stacks could be created.)

Situation occurred for all menustyles; traditional and via-menu needed
separate fixes.  It didn't occur for pickup off the floor.

Report was for 3.6.6 but the bug was still present in dev version.

doc/fixes3-7-0.txt
src/invent.c
src/pickup.c

index e48455bedb6c5ee4bb2a97e9e259756d75bfaec8..e90b77e8f56f51d8408bd7b601ea1b19a313a830 100644 (file)
@@ -1,4 +1,4 @@
-HDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.917 $ $NHDT-Date: 1652719274 2022/05/16 16:41:14 $
+HDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.933 $ $NHDT-Date: 1654205933 2022/06/02 21:38:53 $
 
 General Fixes and Modified Features
 -----------------------------------
@@ -911,11 +911,10 @@ using a marker to write "novel" or "paperback book" on a known blank spellbook
        was producing a randomly chosen Pratchett novel; make it fail instead
 when a monster killed a pudding and it left a glob, that glob might not be
        displayed on the map (wasn't an issue for killed-by-hero case)
-lua's garbage collection doesn't like the way nethack is trying to use it and
-       issues a pair of warnings each time the relevant code gets run; they
-       were vanishing into a bit bucket but now they will be displayed when
-       running in wizard mode; we need to fix the usage rather than just
-       hide the feedback
+if player gave a subset count when removing an item from a container, then got
+       the pickup_burden prompt and declined to continue, the item remained
+       split rather be recombined, making it possible to create multiple
+       stacks of gold inside a container
 
 
 Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
@@ -1229,6 +1228,8 @@ for menustyle:Full, fix the combination of 'A' auto-pick all plus 'P' just
 for menustyle:Traditional, fix 'P' for just picked up items in inventory when
        filtering what items to put into a container
 restrict stunning effect to is_xport trap types
+lua's garbage collection didn't like the way nethack was trying to use it and
+       issued a pair of warnings each time the relevant code got run
 
 curses: 'msg_window' option wasn't functional for curses unless the binary
        also included tty support
index 75133d650a5c668fc41e810235b47092a0c0b5ce..d5e78817beae45b43e6bc787e395d27f782a97a3 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 invent.c        $NHDT-Date: 1652861830 2022/05/18 08:17:10 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.389 $ */
+/* NetHack 3.7 invent.c        $NHDT-Date: 1654205933 2022/06/02 21:38:53 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.391 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Derek S. Ray, 2015. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -2205,16 +2205,17 @@ askchain(
             /*FALLTHRU*/
         case 'y':
             tmp = (*fn)(otmp);
-            if (tmp < 0) {
+            if (tmp <= 0) {
                 if (container_gone(fn)) {
                     /* otmp caused magic bag to explode;
                        both are now gone */
                     otmp = 0; /* and return */
                 } else if (otmp && otmp != otmpo) {
                     /* split occurred, merge again */
-                    (void) merged(&otmpo, &otmp);
+                    (void) unsplitobj(otmp);
                 }
-                goto ret;
+                if (tmp < 0)
+                    goto ret;
             }
             cnt += tmp;
             if (--mx == 0)
index 0882d618dbb147973e1eff3791ed2e326e6a3fde..125f215911f88b418f696e4a6bb0508b23534687 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 pickup.c        $NHDT-Date: 1608673693 2020/12/22 21:48:13 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.273 $ */
+/* NetHack 3.7 pickup.c        $NHDT-Date: 1654205934 2022/06/02 21:38:54 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.308 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2012. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -1526,10 +1526,11 @@ carry_count(struct obj *obj,            /* object to pick up... */
 /* determine whether character is able and player is willing to carry `obj' */
 static
 int
-lift_object(struct obj *obj,       /* object to pick up... */
-            struct obj *container, /* ...bag it's coming out of */
-            long *cnt_p,
-            boolean telekinesis)
+lift_object(
+    struct obj *obj,       /* object to pick up... */
+    struct obj *container, /* ...bag it's coming out of */
+    long *cnt_p,
+    boolean telekinesis)
 {
     int result, old_wt, new_wt, prev_encumbr, next_encumbr;
 
@@ -1621,8 +1622,10 @@ lift_object(struct obj *obj,       /* object to pick up... */
  * up, 1 if otherwise.
  */
 int
-pickup_object(struct obj *obj, long count,
-              boolean telekinesis) /* not picking it up directly by hand */
+pickup_object(
+    struct obj *obj,
+    long count,
+    boolean telekinesis) /* not picking it up directly by hand */
 {
     int res, nearload;
 
@@ -3119,16 +3122,17 @@ menu_loot(int retry, boolean put_in)
                     /* special split case also handled by askchain() */
                 }
                 res = put_in ? in_container(otmp) : out_container(otmp);
-                if (res < 0) {
+                if (res <= 0) {
                     if (!g.current_container) {
                         /* otmp caused current_container to explode;
                            both are now gone */
                         otmp = 0; /* and break loop */
                     } else if (otmp && otmp != pick_list[i].item.a_obj) {
                         /* split occurred, merge again */
-                        (void) merged(&pick_list[i].item.a_obj, &otmp);
+                        (void) unsplitobj(otmp);
                     }
-                    break;
+                    if (res < 0)
+                        break;
                 }
             }
             free((genericptr_t) pick_list);
@@ -3138,8 +3142,13 @@ menu_loot(int retry, boolean put_in)
 }
 
 static char
-in_or_out_menu(const char *prompt, struct obj *obj, boolean outokay,
-               boolean inokay, boolean alreadyused, boolean more_containers)
+in_or_out_menu(
+    const char *prompt,
+    struct obj *obj,
+    boolean outokay,     /* can take out */
+    boolean inokay,      /* can put in */
+    boolean alreadyused, /* controls phrasing of the decline choice */
+    boolean more_containers)
 {
     /* underscore is not a choice; it's used to skip element [0] */
     static const char lootchars[] = "_:oibrsnq", abc_chars[] = "_:abcdenq";