#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?).
This commit is contained in:
nethack.rankin
2004-11-06 02:42:41 +00:00
parent 0a9b85159e
commit 88dad9386b
4 changed files with 105 additions and 19 deletions

View 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

View 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.

View 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

View 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:";
obj = otmp;
otmp = otmp->nobj;
extract_nobj(obj, &invent);
} else {
if (otmp->invlet == let) {
adj_type = "Swapping:";
otmp->invlet = obj->invlet;
}
otmp = otmp->nobj;
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;
extract_nobj(obj, &invent);
} 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);
}