]> granicus.if.org Git - nethack/commitdiff
more #adjust (#H6571)
authorPatR <rankin@nethack.org>
Tue, 5 Dec 2017 11:38:23 +0000 (03:38 -0800)
committerPatR <rankin@nethack.org>
Tue, 5 Dec 2017 11:38:23 +0000 (03:38 -0800)
Make the suggested change that only adjusting something into its own
slot be the way to collect/merge compatible stacks with it, instead
of any #adjust without a split count.  This removes the previous
special case for a count that matches the stack size.  Having to
know the exact count was not a burden on the player, but being able
to move things around without merging with other stacks makes more
sense than the original behavior or the hack to work-around that
behavior.

doc/Guidebook.mn
doc/Guidebook.tex
doc/fixes36.1
src/invent.c

index 16199ef814d830ca4d6345739cf33e79a5e48d06..3989cec93f16ee265926dbf2ce9c2f0ee26cc602 100644 (file)
@@ -1,4 +1,4 @@
-.\" $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.240 $ $NHDT-Date: 1512098127 2017/12/01 03:15:27 $
+.\" $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.241 $ $NHDT-Date: 1512473628 2017/12/05 11:33:48 $
 .ds h0 "NetHack Guidebook
 .ds h1
 .ds h2 %
@@ -930,11 +930,19 @@ being moved.
 ``#adjust'' can also be used to split a stack of objects; when
 choosing the item to adjust, enter a count prior to its letter.
 .lp ""
-When no count is given, other compatible stacks are merged with the source
-stack as it's moved to the destination.  When a split count is given, the
-only stack that might be merged is the one already in the destination.
-To move a whole stack without having other compatible ones merge with it,
-specify a ``split'' count which matches the full stack size.
+Adjusting without a count used to collect all compatible stacks when
+moving to the destination.  That behavior has been changed; to gather
+compatible stacks, ``#adjust'' a stack into its own inventory slot.
+If it has a name assigned, other stacks with the same name or with
+no name will merge provided that all their other attributes match.
+If it does not have a name, only other stacks with no name are eligible.
+In either case, otherwise compatible stacks with a different name
+will not be merged.  This contrasts with using ``#adjust'' to move
+from one slot to a different slot.  In that situation, moving (no
+count given) a compatible stack will merge if either stack has a
+name when the other doesn't and give that name to the result, while
+splitting (count given) will ignore the source stack's name when
+deciding whether to merge with the destination stack.
 .lp #annotate
 Allows you to specify one line of text to associate with the current
 dungeon level.  All levels with annotations are displayed by the
index e776b02d0ef6a5f8e5bb3d0395e419e52f489dd0..ea948813b32e2b11fc1d7aa5ea5247ba2ba5f25c 100644 (file)
@@ -1110,11 +1110,19 @@ being moved.
 ``{\tt \#adjust}'' can also be used to split a stack of objects; when
 choosing the item to adjust, enter a count prior to its letter.\\
 %.lp ""
-When no count is given, other compatible stacks are merged with the source
-stack as it's moved to the destination.  When a split count is given, the
-only stack that might be merged is the one already in the destination.
-To move a whole stack without having other compatible ones merge with it,
-specify a ``split'' count which matches the full stack size.
+Adjusting without a count used to collect all compatible stacks when
+moving to the destination.  That behavior has been changed; to gather
+compatible stacks, ``{\tt \#adjust}'' a stack into its own inventory slot.
+If it has a name assigned, other stacks with the same name or with
+no name will merge provided that all their other attributes match.
+If it does not have a name, only other stacks with no name are eligible.
+In either case, otherwise compatible stacks with a different name
+will not be merged.  This contrasts with using ``{\tt \#adjust}'' to move
+from one slot to a different slot.  In that situation, moving (no
+count given) a compatible stack will merge if either stack has a
+name when the other doesn't and give that name to the result, while
+splitting (count given) will ignore the source stack's name when
+deciding whether to merge with the destination stack.
 %.lp
 \item[\tb{\#annotate}]
 Allows you to specify one line of text to associate with the current
index 4e1d79c763fed5ccc8a98ef9b859e2c4ddcacb2b..8b27ef9999fe44414c1c2832951d178d809cd05f 100644 (file)
@@ -720,9 +720,9 @@ Master Key of Thievery always finds door and chest traps if used to lock or
 "Elbereth" now erodes based on attacks by the player, not monsters scared
 option herecmd_menu to make a mouse click on your character pop up
        a context menu, and extended command #herecmdmenu to do the same
-for #adjust, specifying a split count which matches an inventory slot's full
-       size will move or swap that stack without combining other compatible
-       stacks (except for the one in the destination slot, if applicable)
+change #adjust's behavior when collecting compatible stacks; that used to
+       occur for any #adjust which lacked a split count, now it only happens
+       when 'adjusting' into a stack's own inventory slot
 
 
 Platform- and/or Interface-Specific New Features
index 4a8a68815b8f42118c475a505ceeadb157418176..89d823eec305a7091cb1e6473b59f378f8159a1e 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 invent.c        $NHDT-Date: 1512096431 2017/12/01 02:47:11 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.222 $ */
+/* NetHack 3.6 invent.c        $NHDT-Date: 1512473628 2017/12/05 11:33:48 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.223 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -1472,9 +1472,6 @@ redo_menu:
             else if (otmp->otyp == LOADSTONE && otmp->cursed)
                 /* kludge for canletgo()'s can't-drop-this message */
                 otmp->corpsenm = (int) cnt;
-        } else if (!strcmp(word, "adjust")) {
-            /* specifying stack's full count means something to #adjust */
-            otmp->nomerge = 1;
         }
     }
     return otmp;
@@ -3539,10 +3536,18 @@ reassign()
  *      then a 'to' slot for its destination.  Open slots and those
  *      filled by compatible stacks are listed as likely candidates
  *      but user can pick any inventory letter (including 'from').
- *      All compatible items found are gathered into the 'from'
- *      stack as it is moved.  If the 'to' slot isn't empty and
- *      doesn't merge, then its stack is swapped to the 'from' slot.
  *
+ *  to == from, 'from' has a name
+ *      All compatible items (same name or no name) are gathered
+ *      into the 'from' stack.  No count is allowed.
+ *  to == from, 'from' does not have a name
+ *      All compatible items without a name are gathered into the
+ *      'from' stack.  No count is allowed.  Compatible stacks with
+ *      names are left as-is.
+ *  to != from, no count
+ *      Move 'from' to 'to'.  If 'to' is not empty, merge 'from'
+ *      into it if possible, otherwise swap it with the 'from' slot.
+ *  to != from, count given
  *      If the user specifies a count when choosing the 'from' slot,
  *      and that count is less than the full size of the stack,
  *      then the stack will be split.  The 'count' portion is moved
@@ -3552,10 +3557,19 @@ reassign()
  *      will be moved to an open slot; if there isn't any open slot
  *      available, the adjustment attempt fails.
  *
- *      Splitting has one special case:  if 'to' slot is non-empty
- *      and is compatible with 'from' in all respects except for
- *      user-assigned names, the 'count' portion being moved is
- *      effectively renamed so that it will merge with 'to' stack.
+ *      To minimize merging for 'from == to', unnamed stacks will
+ *      merge with named 'from' but named ones won't merge with
+ *      unnamed 'from'.  Otherwise attempting to collect all unnamed
+ *      stacks would lump the first compatible named stack with them
+ *      and give them its name.
+ *
+ *      To maximize merging for 'from != to', compatible stacks will
+ *      merge when either lacks a name (or they already have the same
+ *      name).  When no count is given and one stack has a name and
+ *      the other doesn't, the merged result will have that name.
+ *      However, when splitting results in a merger, the name of the
+ *      destination overrides that of the source, even if destination
+ *      is unnamed and source is named.
  */
 int
 doorganize() /* inventory organizer by Del Lamb */
@@ -3569,8 +3583,9 @@ doorganize() /* inventory organizer by Del Lamb */
     char lets[1 + 52 + 1 + 1]; /* room for '$a-zA-Z#\0' */
     char qbuf[QBUFSZ];
     char allowall[4]; /* { ALLOW_COUNT, ALL_CLASSES, 0, 0 } */
+    char *objname, *otmpname;
     const char *adj_type;
-    boolean ever_mind = FALSE, dont_collect = FALSE;
+    boolean ever_mind = FALSE, collect;
 
     if (!invent) {
         You("aren't carrying anything to adjust.");
@@ -3602,19 +3617,12 @@ doorganize() /* inventory organizer by Del Lamb */
 
     /* figure out whether user gave a split count to getobj() */
     splitting = bumped = 0;
-    if (obj->nomerge) {
-        /* player specified full count; no split occurred and we'll
-           avoid collecting compatible stacks when moving this one */
-        obj->nomerge = 0;
-        dont_collect = TRUE;
-    } else {
-        for (otmp = invent; otmp; otmp = otmp->nobj)
-            if (otmp->nobj == obj) { /* knowledge of splitobj() operation */
-                if (otmp->invlet == obj->invlet)
-                    splitting = otmp;
-                break;
-            }
-    }
+    for (otmp = invent; otmp; otmp = otmp->nobj)
+        if (otmp->nobj == obj) { /* knowledge of splitobj() operation */
+            if (otmp->invlet == obj->invlet)
+                splitting = otmp;
+            break;
+        }
 
     /* initialize the list with all lower and upper case letters */
     lets[GOLD_INDX] = (obj->oclass == COIN_CLASS) ? GOLD_SYM : ' ';
@@ -3668,7 +3676,7 @@ doorganize() /* inventory organizer by Del Lamb */
             /* adjusting to same slot is meaningful since all
                compatible stacks get collected along the way,
                but splitting to same slot is not */
-            || ((splitting || dont_collect) && let == obj->invlet)) {
+            || (splitting && let == obj->invlet)) {
         noadjust:
             if (splitting)
                 (void) merged(&splitting, &obj);
@@ -3691,8 +3699,9 @@ doorganize() /* inventory organizer by Del Lamb */
         pline("Select an inventory slot letter."); /* else try again */
     }
 
+    collect = (let == obj->invlet);
     /* change the inventory and print the resulting item */
-    adj_type = !splitting ? "Moving:" : "Splitting:";
+    adj_type = collect ? "Collecting" : !splitting ? "Moving:" : "Splitting:";
 
     /*
      * don't use freeinv/addinv to avoid double-touching artifacts,
@@ -3701,45 +3710,52 @@ doorganize() /* inventory organizer by Del Lamb */
     extract_nobj(obj, &invent);
 
     for (otmp = invent; otmp;) {
-        if (!splitting && !dont_collect) {
-            if (merged(&otmp, &obj)) {
+        /* it's tempting to pull this outside the loop, but merged() could
+           free ONAME(obj) [via obfree()] and replace it with ONAME(otmp) */
+        objname = has_oname(obj) ? ONAME(obj) : (char *) 0;
+
+        if (collect) {
+            /* Collecting: #adjust an inventory stack into its same slot;
+               keep it there and merge other compatible stacks into it.
+               Traditional inventory behavior is to merge unnamed stacks
+               with compatible named ones; we only want that if it is
+               the 'from' stack (obj) with a name and candidate (otmp)
+               without one, not unnamed 'from' with named candidate. */
+            otmpname = has_oname(otmp) ? ONAME(otmp) : (char *) 0;
+            if ((!otmpname || (objname && !strcmp(objname, otmpname)))
+                && merged(&otmp, &obj)) {
                 adj_type = "Merging:";
                 obj = otmp;
                 otmp = otmp->nobj;
                 extract_nobj(obj, &invent);
                 continue; /* otmp has already been updated */
-            } else if (otmp->invlet == let) {
+            }
+        } else if (otmp->invlet == let) {
+            /* Moving or splitting: don't merge extra compatible stacks.
+               Found 'otmp' in destination slot; merge if compatible,
+               otherwise bump whatever is there to an open slot. */
+            if (!splitting) {
                 adj_type = "Swapping:";
                 otmp->invlet = obj->invlet;
-            }
-        } else {
-            /* splitting: don't merge extra compatible stacks;
-               if destination is compatible, do merge with it,
-               otherwise bump whatever is there to an open slot */
-            if (otmp->invlet == let) {
-                int olth = 0;
-
-                if (has_oname(obj))
-                    olth = strlen(ONAME(obj));
-                /* ugly hack:  if these objects aren't going to merge
-                   solely because they have conflicting user-assigned
-                   names, strip off the name of the one being moved */
-                if (olth && !obj->oartifact && !mergable(otmp, obj)) {
-                    char *holdname = ONAME(obj);
-
+            } else {
+                /* strip 'from' name if it has one */
+                if (objname && !obj->oartifact)
                     ONAME(obj) = (char *) 0;
-                    /* restore name iff merging is still not possible */
-                    if (!mergable(otmp, obj)) {
-                        ONAME(obj) = holdname;
-                        holdname = (char *) 0;
-                    } else
-                        free((genericptr_t) holdname);
+                if (!mergable(otmp, obj)) {
+                    /* won't merge; put 'from' name back */
+                    if (objname)
+                        ONAME(obj) = objname;
+                } else {
+                    /* will merge; discard 'from' name */
+                    if (objname)
+                        free((genericptr_t) objname), objname = 0;
                 }
 
                 if (merged(&otmp, &obj)) {
+                    adj_type = "Splitting and merging:";
                     obj = otmp;
                     extract_nobj(obj, &invent);
-                } else if (inv_cnt(FALSE) >= 52 && !dont_collect) {
+                } else if (inv_cnt(FALSE) >= 52) {
                     (void) merged(&splitting, &obj); /* undo split */
                     /* "knapsack cannot accommodate any more items" */
                     Your("pack is too full.");
@@ -3748,9 +3764,9 @@ doorganize() /* inventory organizer by Del Lamb */
                     bumped = otmp;
                     extract_nobj(bumped, &invent);
                 }
-                break;
-            } /* found 'to' slot */
-        }     /* splitting */
+            } /* moving vs splitting */
+            break; /* not collecting and found 'to' slot */
+        } /* collect */
         otmp = otmp->nobj;
     }