]> granicus.if.org Git - nethack/commitdiff
#adjust enhancement - splitting stacks
authornethack.rankin <nethack.rankin>
Sat, 6 Nov 2004 02:42:41 +0000 (02:42 +0000)
committernethack.rankin <nethack.rankin>
Sat, 6 Nov 2004 02:42:41 +0000 (02:42 +0000)
     Allow the #adjust command to be used to split an inventory stack
as well as for moving things to specific slot letters.  Splitting is
accomplished by specifying a count along with the letter of the stack to
operate on, similar to when dropping a stack with 'd'.  The comment above
doorganize() has more details.

     This change will make it possible for users to split stacks of cursed
loadstones which they couldn't easily do before, but I don't see anything
wrong with that.  It was always possible to have multiple stacks of load-
stones by starting with ones that had different curse/bless status, so this
hasn't introduced a totally new situation.  On the other hand, I haven't
tested this with the GOLDOBJ configuration and am not sure whether there is
any need to prevent gold from being split there.  The getobj() call doesn't
specify COIN_CLASS so perhaps it's irrelevant (unless it ought to be
changed the other direction by adding that to intentionally allow gold to
be split?).

doc/Guidebook.mn
doc/Guidebook.tex
doc/fixes34.4
src/invent.c

index 5b11d201ea0eab32aa6dd90de3cf76be2d23a0e7..982a2ed3c6efab3076e87bf397d443c81ec70d12 100644 (file)
@@ -675,6 +675,12 @@ compiled with.
 Adjust inventory letters (most useful when the
 .op fixinv
 option is ``on'').
+This command allows you to move an item from one particular inventory
+slot to another so that it has a letter which is more meaningful for you
+or that it will appear in a particular location when inventory listings
+are displayed.
+``#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 #chat
 Talk to someone.
 .lp #conduct
index 96e384422aa0c6f687376a9ad1f9bc75f8a52421..c411981d4e71a9cc2a3b160d1203a6e0e3c622d2 100644 (file)
@@ -27,7 +27,7 @@
 \begin{document}
 %
 % input file: guidebook.mn
-% $Revision: 1.85 $ $Date: 2004/10/28 01:48:52 $
+% $Revision: 1.86 $ $Date: 2004/10/30 01:44:12 $
 %
 %.ds h0 "
 %.ds h1 %.ds h2 \%
@@ -894,6 +894,12 @@ the game was compiled with.
 Adjust inventory letters (most useful when the
 {\it fixinv\/}
 option is ``on'').
+This command allows you to move an item from one particular inventory
+slot to another so that it has a letter which is more meaningful for you
+or that it will appear in a particular location when inventory listings
+are displayed.
+``{\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
 \item[\tb{\#chat}]
 Talk to someone.
index 7e779e615c4c252c63f949d5741d475aa6ccd1c5..6ce1297506e5012aeac174bfac2dac22e856a13e 100644 (file)
@@ -79,6 +79,7 @@ when you're teetering on the edge of a pit you can use '>' to enter the pit
 when asked for a direction, a response of '?' yields help and then asks again
 when adding an item to inventory, try to stack it with the quiver slot
        before trying against other carried objects
+#adjust can be used to split an inventory stack
 
 
 Platform- and/or Interface-Specific New Features
index e808c519b50ce050baa11216f859d72a2a4b8edf..d8b01f111534d832f6c2e5cc0b7524bc0ff96f1d 100644 (file)
@@ -2616,16 +2616,30 @@ reassign()
  *     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.
+ *
+ *     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
+ *     to the destination, and the only candidate for merging with
+ *     it is the stack already at the 'to' slot, if any.  When the
+ *     destination is non-empty but won't merge, whatever is there
+ *     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.
  */
 int
 doorganize()   /* inventory organizer by Del Lamb */
 {
-       struct obj *obj, *otmp;
+       struct obj *obj, *otmp, *splitting, *bumped;
        register int ix, cur;
        register char let;
        char alphabet[52+1], buf[52+1];
        char qbuf[QBUFSZ];
-       char allowall[2];
+       char allowall[3];       /* { ALLOW_COUNT, ALL_CLASSES, 0 } */
        const char *adj_type;
 
        if (!invent) {
@@ -2636,16 +2650,26 @@ doorganize()    /* inventory organizer by Del Lamb */
 
        if (!flags.invlet_constant) reassign();
        /* get object the user wants to organize (the 'from' slot) */
-       allowall[0] = ALL_CLASSES; allowall[1] = '\0';
+       allowall[0] = ALLOW_COUNT;
+       allowall[1] = ALL_CLASSES;
+       allowall[2] = '\0';
        if (!(obj = getobj(allowall,"adjust"))) return(0);
 
+       /* figure out whether user gave a split count to getobj() */
+       splitting = bumped = 0;
+       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 */
        for (ix = 0, let = 'a';  let <= 'z'; ) alphabet[ix++] = let++;
        for (let = 'A'; let <= 'Z'; ) alphabet[ix++] = let++;
        alphabet[ix] = '\0';
        /* for floating inv letters, truncate list after the first open slot */
        if (!flags.invlet_constant && (ix = inv_cnt()) < 52)
-           alphabet[ix + 1] = '\0';
+           alphabet[ix + (splitting ? 0 : 1)] = '\0';
 
        /* blank out all the letters currently in use in the inventory */
        /* except those that will be merged with the selected object   */
@@ -2667,7 +2691,12 @@ doorganize()     /* inventory organizer by Del Lamb */
        Sprintf(qbuf, "Adjust letter to what [%s]?", buf);
        for (;;) {
            let = yn_function(qbuf, (char *)0, '\0');
-           if (index(quitchars, let)) {
+           if (index(quitchars, let) ||
+                   /* adjusting to same slot is meaningful since all
+                      compatible stacks get collected along the way,
+                      but splitting to same slot is not */
+                   (splitting && let == obj->invlet)) {
+               if (splitting) (void) merged(&splitting, &obj);
                pline(Never_mind);
                return 0;
            }
@@ -2676,7 +2705,7 @@ doorganize()      /* inventory organizer by Del Lamb */
        }
 
        /* change the inventory and print the resulting item */
-       adj_type = "Moving:";
+       adj_type = !splitting ? "Moving:" : "Splitting:";
 
        /*
         * don't use freeinv/addinv to avoid double-touching artifacts,
@@ -2684,19 +2713,51 @@ doorganize()    /* inventory organizer by Del Lamb */
         */
        extract_nobj(obj, &invent);
 
-       for (otmp = invent; otmp;)
-               if (merged(&otmp,&obj)) {
-                       adj_type = "Merging:";
+       for (otmp = invent; otmp; ) {
+           if (!splitting) {
+               if (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) {
+                   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 = obj->onamelth;
+
+                   /* 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)) {
+                       obj->onamelth = 0;
+                       /* restore name iff merging is still not possible */
+                       if (!mergable(otmp, obj)) obj->onamelth = olth;
+                   }
+
+                   if (merged(&otmp, &obj)) {
                        obj = otmp;
-                       otmp = otmp->nobj;
                        extract_nobj(obj, &invent);
-               } else {
-                       if (otmp->invlet == let) {
-                               adj_type = "Swapping:";
-                               otmp->invlet = obj->invlet;
-                       }
-                       otmp = otmp->nobj;
-               }
+                   } else if (inv_cnt() >= 52) {
+                       (void) merged(&splitting, &obj);    /* undo split */
+                       /* "knapsack cannot accommodate any more items" */
+                       Your("pack is too full.");
+                       return 0;
+                   } else {
+                       bumped = otmp;
+                       extract_nobj(bumped, &invent);
+                   }
+                   break;
+               } /* found 'to' slot */
+           } /* splitting */
+           otmp = otmp->nobj;
+       }
 
        /* inline addinv; insert loose object at beginning of inventory */
        obj->invlet = let;
@@ -2704,8 +2765,20 @@ doorganize()     /* inventory organizer by Del Lamb */
        obj->where = OBJ_INVENT;
        invent = obj;
        reorder_invent();
-
+       if (bumped) {
+           /* splitting the 'from' stack is causing an incompatible
+              stack in the 'to' slot to be moved into an open one;
+              we need to do another inline insertion to inventory */
+           assigninvlet(bumped);
+           bumped->nobj = invent;
+           bumped->where = OBJ_INVENT;
+           invent = bumped;
+           reorder_invent();
+       }
+
+       /* messages deferred until inventory has been fully reestablished */
        prinv(adj_type, obj, 0L);
+       if (bumped) prinv("Moving:", bumped, 0L);
        update_inventory();
        return(0);
 }