loadstone dropping fix
Fix the reported problem of bad inventory management if the user
specified a count (with traditional menu style) when attempting to drop
part of a stack of cursed loadstones. After the "you can't drop that"
message, it tried to undo the stack split, but splitobj was changed
sometime back and the undo hack wasn't adjusted to account for the fact
that it needed to merge with the previous object instead of the next one.
The result was that it would incorrectly increment the count of the next
item instead of the original loadstone, or crash in canletgo() if the
split off stone was the last item in the list.
This prevents cursed loadstones from being split (via getobj()'s
count handling) in the first place, so there's nothing to undo later.
It still uses a similar kludge so that the "can't drop that" message can
be adjusted, but it's now a simpler kludge and I hope a more robust one.
This commit is contained in:
@@ -97,6 +97,8 @@ must be able to reach floor in order to use stethoscope on corpse or statue
|
||||
fix a few coordinate (y,y) -> (x,y) typos in apply.c, mon.c, and wizard.c
|
||||
killing a long worm on a drawbridge could produce a panic
|
||||
prevent "see it drop from your pack" when figurine monster becomes undetected
|
||||
attempting to drop a subset of a stack of multiple cursed loadstones could
|
||||
corrupt inventory or cause a crash
|
||||
|
||||
|
||||
Platform- and/or Interface-Specific Fixes
|
||||
|
||||
44
src/do.c
44
src/do.c
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)do.c 3.4 2003/04/25 */
|
||||
/* SCCS Id: @(#)do.c 3.4 2003/12/02 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -406,20 +406,18 @@ register const char *word;
|
||||
return(FALSE);
|
||||
}
|
||||
if (obj->otyp == LOADSTONE && obj->cursed) {
|
||||
if (*word)
|
||||
pline("For some reason, you cannot %s the stone%s!",
|
||||
word, plur(obj->quan));
|
||||
/* Kludge -- see invent.c */
|
||||
if (obj->corpsenm) {
|
||||
struct obj *otmp;
|
||||
|
||||
otmp = obj;
|
||||
obj = obj->nobj;
|
||||
obj->quan += otmp->quan;
|
||||
obj->owt = weight(obj);
|
||||
freeinv(otmp);
|
||||
obfree(otmp, obj);
|
||||
/* getobj() kludge sets corpsenm to user's specified count
|
||||
when refusing to split a stack of cursed loadstones */
|
||||
if (*word) {
|
||||
/* getobj() ignores a count for throwing since that is
|
||||
implicitly forced to be 1; replicate its kludge... */
|
||||
if (!strcmp(word, "throw") && obj->quan > 1L)
|
||||
obj->corpsenm = 1;
|
||||
pline("For some reason, you cannot %s%s the stone%s!",
|
||||
word, obj->corpsenm ? " any of" : "",
|
||||
plur(obj->quan));
|
||||
}
|
||||
obj->corpsenm = 0; /* reset */
|
||||
obj->bknown = 1;
|
||||
return(FALSE);
|
||||
}
|
||||
@@ -694,14 +692,20 @@ int retry;
|
||||
for (i = 0; i < n; i++) {
|
||||
otmp = pick_list[i].item.a_obj;
|
||||
cnt = pick_list[i].count;
|
||||
if (cnt < otmp->quan && !welded(otmp) &&
|
||||
(!otmp->cursed || otmp->otyp != LOADSTONE)) {
|
||||
if (cnt < otmp->quan) {
|
||||
if (welded(otmp)) {
|
||||
; /* don't split */
|
||||
} else if (otmp->otyp == LOADSTONE && otmp->cursed) {
|
||||
/* same kludge as getobj(), for canletgo()'s use */
|
||||
otmp->corpsenm = (int) cnt; /* don't split */
|
||||
} else {
|
||||
#ifndef GOLDOBJ
|
||||
if (otmp->oclass == COIN_CLASS)
|
||||
(void) splitobj(otmp, otmp->quan - cnt);
|
||||
else
|
||||
if (otmp->oclass == COIN_CLASS)
|
||||
(void) splitobj(otmp, otmp->quan - cnt);
|
||||
else
|
||||
#endif
|
||||
otmp = splitobj(otmp, cnt);
|
||||
otmp = splitobj(otmp, cnt);
|
||||
}
|
||||
}
|
||||
n_dropped += drop(otmp);
|
||||
}
|
||||
|
||||
16
src/invent.c
16
src/invent.c
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)invent.c 3.4 2003/11/18 */
|
||||
/* SCCS Id: @(#)invent.c 3.4 2003/12/02 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -1065,14 +1065,12 @@ register const char *let,*word;
|
||||
if(allowcnt == 2) { /* cnt given */
|
||||
if(cnt == 0) return (struct obj *)0;
|
||||
if(cnt != otmp->quan) {
|
||||
otmp = splitobj(otmp, cnt);
|
||||
/* Very ugly kludge necessary to prevent someone from trying
|
||||
* to drop one of several loadstones and having the loadstone
|
||||
* now be separate.
|
||||
*/
|
||||
if (!strcmp(word, "drop") &&
|
||||
otmp->otyp == LOADSTONE && otmp->cursed)
|
||||
otmp->corpsenm = otmp->invlet;
|
||||
/* don't split a stack of cursed loadstones */
|
||||
if (otmp->otyp == LOADSTONE && otmp->cursed)
|
||||
/* kludge for canletgo()'s can't-drop-this message */
|
||||
otmp->corpsenm = (int) cnt;
|
||||
else
|
||||
otmp = splitobj(otmp, cnt);
|
||||
}
|
||||
}
|
||||
return(otmp);
|
||||
|
||||
Reference in New Issue
Block a user