stone-to-flesh of wielded rocks

Wielding one or more rocks while other rocks were quivered and casting
stone-to-flesh at self wasn't subject to the "null obj after quiver
merge" panic but it did result in a combined stack of meatballs that
was neither wielded nor quivered.  Keep inventory items that turn into
meat and are wielded/alt-wep/quivered separate and still wielded/&c.
This commit is contained in:
PatR
2023-09-19 14:43:17 -07:00
parent dd05f5183e
commit e2203ef9a1
2 changed files with 17 additions and 8 deletions

View File

@@ -1240,6 +1240,8 @@ wand of probing reveals map locations in the ray path
applying a wielded, lit potion of oil to unlight it while other unlit
potion(s) of oil were quivered would trigger panic
"addinv: null obj after quiver merge otyp=N" where N is POT_OIL
casting stone-to-flesh at self turned wielded or quivered rocks into unwielded,
unquivered meatballs, merging stacks if there were some in each slot
Fixes to 3.7.0-x General Problems Exposed Via git Repository

View File

@@ -1818,8 +1818,8 @@ poly_obj(struct obj *obj, int id)
/*
* We may need to do extra adjustments for the hero if we're
* messing with the hero's inventory. The following calls are
* equivalent to calling freeinv on obj and addinv on otmp,
* while doing an in-place swap of the actual objects.
* equivalent to calling freeinv() on obj and addinv_nomerge()
* on otmp, while doing an in-place swap of the actual objects.
*/
freeinv_core(obj);
addinv_core1(otmp);
@@ -1834,9 +1834,12 @@ poly_obj(struct obj *obj, int id)
if (old_wornmask) {
boolean was_twohanded = bimanual(obj), was_twoweap = u.twoweap;
/* wearslot() returns a mask which might have multiple bits set;
narrow that down to the bit(s) currently in use */
new_wornmask = wearslot(otmp) & old_wornmask;
/* wearslot() expects us to deal with wielded/alt-wep/quivered
items in case they're not weapons; for other slots it might
return multiple bits (ring left|right); narrow that down to
the bit(s) currently in use */
new_wornmask = ((old_wornmask & W_WEAPONS) != 0L) ? old_wornmask
: (wearslot(otmp) & old_wornmask);
remove_worn_item(obj, TRUE);
/* if the new form can be worn in the same slot, make it so */
if ((new_wornmask & W_WEP) != 0L) {
@@ -2855,17 +2858,21 @@ zapyourself(struct obj *obj, boolean ordinary)
}
/*
* It is possible that we can now merge some inventory.
* Do a highly paranoid merge. Restart from the beginning
* until no merges.
* Do a highly paranoid merge. Restart from the beginning until
* no merges. Don't merge worn items (in case of stone-to-flesh
* of rocks wielded in differing weapon/alt-wep/quiver slot).
*/
do {
didmerge = FALSE;
for (otmp = gi.invent; !didmerge && otmp; otmp = otmp->nobj)
for (otmp = gi.invent; !didmerge && otmp; otmp = otmp->nobj) {
if (otmp->owornmask)
continue;
for (onxt = otmp->nobj; onxt; onxt = onxt->nobj)
if (merged(&otmp, &onxt)) {
didmerge = TRUE;
break;
}
}
} while (didmerge);
break;
}