From: nethack.rankin Date: Sat, 6 Nov 2004 02:42:41 +0000 (+0000) Subject: #adjust enhancement - splitting stacks X-Git-Tag: MOVE2GIT~1406 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=88dad9386bf11689c6ee67149dd1597987ded276;p=nethack #adjust enhancement - splitting stacks 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?). --- diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 5b11d201e..982a2ed3c 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -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 diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 96e384422..c411981d4 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -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. diff --git a/doc/fixes34.4 b/doc/fixes34.4 index 7e779e615..6ce129750 100644 --- a/doc/fixes34.4 +++ b/doc/fixes34.4 @@ -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 diff --git a/src/invent.c b/src/invent.c index e808c519b..d8b01f111 100644 --- a/src/invent.c +++ b/src/invent.c @@ -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); }