diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 8b766ebb2..8c3b51b2e 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -634,6 +634,11 @@ if a Rider or displacer beast swapped places with a single-segment long worm the segment co-located with the head wasn't moved with that head; if sanity_checking was enabled a warning could be triggered: mon (000000) at seg location is not worm (123abc) +blessed scroll of remove curse read while confused blesses or curses any + uncursed items in inventory, but if hero was dual-wielding and the + scroll cursed the secondary weapon, that would be dropped and further + object traversal would process items on the floor at hero's spot + instead of the rest of inventory Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/read.c b/src/read.c index 2d8c4ecba..2f69fa985 100644 --- a/src/read.c +++ b/src/read.c @@ -1310,12 +1310,13 @@ seffect_scare_monster(struct obj **sobjp) static void seffect_remove_curse(struct obj **sobjp) { - struct obj *sobj = *sobjp; + struct obj *sobj = *sobjp; /* scroll or fake spellbook */ int otyp = sobj->otyp; boolean sblessed = sobj->blessed; boolean scursed = sobj->cursed; boolean confused = (Confusion != 0); - register struct obj *obj; + register struct obj *obj, *nxto; + long wornmask; You_feel(!Hallucination ? (!confused ? "like someone is helping you." @@ -1326,9 +1327,14 @@ seffect_remove_curse(struct obj **sobjp) if (scursed) { pline_The("scroll disintegrates."); } else { - for (obj = g.invent; obj; obj = obj->nobj) { - long wornmask; - + /* 3.7: this used to use a straight + for (obj = invent; obj; obj = obj->nobj) {} + traversal, but for the confused case, secondary weapon might + become cursed and be dropped, moving it from the invent chain + to the floor chain at hero's spot, so we have to remember the + next object prior to processing the current one */ + for (obj = g.invent; obj; obj = nxto) { + nxto = obj->nobj; /* gold isn't subject to cursing and blessing */ if (obj->oclass == COIN_CLASS) continue;