From: PatR Date: Fri, 6 Mar 2020 17:24:33 +0000 (-0800) Subject: fix #H4545 - stack of scrolls of scare monster X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3f377b9405b2f2da91ee1905cbdaa9a6c820342c;p=nethack fix #H4545 - stack of scrolls of scare monster Reported 3.5 years ago. Specifying a count for pickup to pick up a subset of a stack was processed after scrolls of scare monster were handled, so a whole stack of those got picked up or crumbled to dust whether you gave a count or not. Also, if you were too encumbered to pick up the full stack, they still all crumbled or all changed state to crumble next time, then for the latter case you picked up as big a subset as you could handle. --- diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 03d81ed9c..931405864 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.118 $ $NHDT-Date: 1583315888 2020/03/04 09:58:08 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.121 $ $NHDT-Date: 1583515468 2020/03/06 17:24:28 $ General Fixes and Modified Features ----------------------------------- @@ -62,6 +62,8 @@ display wasn't updating immediately after toggling hilite_pet option randomly choosing role could lead to crash via segfault if eel bite attack caused hero to move (killed + rehumanized + crawled out of water), its grab attack could succeed even if no longer adjacent +specifying a count when picking [part of] a stack of scrolls of scare monster + ignored that count and the whole stack was affected Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/pickup.c b/src/pickup.c index f3a674de3..a8b497d8f 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pickup.c $NHDT-Date: 1581985559 2020/02/18 00:25:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.261 $ */ +/* NetHack 3.6 pickup.c $NHDT-Date: 1583515468 2020/03/06 17:24:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.263 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1570,16 +1570,32 @@ boolean telekinesis; /* not picking it up directly by hand */ || rider_corpse_revival(obj, telekinesis)) return -1; } else if (obj->otyp == SCR_SCARE_MONSTER) { - if (obj->blessed) - obj->blessed = 0; - else if (!obj->spe && !obj->cursed) + int old_wt, new_wt; + + /* process a count before altering/deleting scrolls; + tricky because being unable to lift full stack imposes an + implicit count; unliftable ones should be treated as if + the count excluded them so that they don't change state */ + if ((count = carry_count(obj, (struct obj *) 0, + count ? count : obj->quan, + FALSE, &old_wt, &new_wt)) < 1L) + return -1; /* couldn't even pick up 1, so effectively untouched */ + /* all current callers handle a new object sanely when traversing + a list; other half of a split will be left as-is and whatever + already follows 'obj' will still be processed next */ + if (count > 0L && count < obj->quan) + obj = splitobj(obj, count); + + if (obj->blessed) { + unbless(obj); + } else if (!obj->spe && !obj->cursed) { obj->spe = 1; - else { + } else { pline_The("scroll%s %s to dust as you %s %s up.", plur(obj->quan), otense(obj, "turn"), telekinesis ? "raise" : "pick", (obj->quan == 1L) ? "it" : "them"); - if (!(objects[SCR_SCARE_MONSTER].oc_name_known) - && !(objects[SCR_SCARE_MONSTER].oc_uname)) + if (!objects[SCR_SCARE_MONSTER].oc_name_known + && !objects[SCR_SCARE_MONSTER].oc_uname) docall(obj); useupf(obj, obj->quan); return 1; /* tried to pick something up and failed, but