iterating gi.invent (github issue #1315)
GitHub issue #1315 points out that it is possible for a downstream function to change an object's nobj field to point to a completely different chain. The cited example by @vultur-cadens was: for (obj = gi.invent; obj; obj = obj->nobj) if (obj->oclass != COIN_CLASS && !obj->cursed && !rn2(5)) { curse(obj); ++buc_changed; } curse() drops the weapon with drop_uswapwep(), which calls dropx(), which calls dropy(), which calls dropz(), which calls place_object(). place_object alters the nobj pointer, to point to the floor chain: otmp->nobj = fobj; fobj = otmp; The result was that the next loop iteration was then using floor objects from the floor chain. This alters several for-loops to use a more consistent approach, particularly when the obj is being handed off to a function, where a downstream function might, or might not, alter the nobj field. References: https://github.com/NetHack/NetHack/issues/1315 https://www.reddit.com/r/nethack/comments/1gkc9ub/even_if_you_drop_an_item_before_drinking_from_the/
This commit is contained in:
@@ -2382,7 +2382,7 @@ litroom(
|
||||
boolean on, /* True: make nearby area lit; False: cursed scroll */
|
||||
struct obj *obj) /* scroll, spellbook (for spell), or wand of light */
|
||||
{
|
||||
struct obj *otmp;
|
||||
struct obj *otmp, *nextobj;
|
||||
boolean blessed_effect = (obj && obj->oclass == SCROLL_CLASS
|
||||
&& obj->blessed);
|
||||
boolean no_op = (u.uswallow || Underwater || Is_waterlevel(&u.uz));
|
||||
@@ -2400,7 +2400,8 @@ litroom(
|
||||
* Shouldn't this affect all lit objects in the area of effect
|
||||
* rather than just those carried by the hero?
|
||||
*/
|
||||
for (otmp = gi.invent; otmp; otmp = otmp->nobj) {
|
||||
for (otmp = gi.invent; otmp; otmp = nextobj) {
|
||||
nextobj = otmp->nobj;
|
||||
if (otmp->lamplit) {
|
||||
if (!artifact_light(otmp))
|
||||
(void) snuff_lit(otmp);
|
||||
@@ -2431,7 +2432,8 @@ litroom(
|
||||
} else { /* on */
|
||||
if (blessed_effect) {
|
||||
/* might bless artifact lights; no effect on ordinary lights */
|
||||
for (otmp = gi.invent; otmp; otmp = otmp->nobj) {
|
||||
for (otmp = gi.invent; otmp; otmp = nextobj) {
|
||||
nextobj = otmp->nobj;
|
||||
if (otmp->lamplit && artifact_light(otmp))
|
||||
/* wielded Sunsword or worn gold dragon scales/mail;
|
||||
maybe raise its BUC state if not already blessed */
|
||||
|
||||
Reference in New Issue
Block a user