diff --git a/doc/fixes34.3 b/doc/fixes34.3 index 6ceb3dea0..f3631b89e 100644 --- a/doc/fixes34.3 +++ b/doc/fixes34.3 @@ -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 diff --git a/src/do.c b/src/do.c index 80ea45811..c0f175663 100644 --- a/src/do.c +++ b/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); } diff --git a/src/invent.c b/src/invent.c index ceb632f3e..e6d359674 100644 --- a/src/invent.c +++ b/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);