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
+2
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 applying a wielded, lit potion of oil to unlight it while other unlit
potion(s) of oil were quivered would trigger panic potion(s) of oil were quivered would trigger panic
"addinv: null obj after quiver merge otyp=N" where N is POT_OIL "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 Fixes to 3.7.0-x General Problems Exposed Via git Repository
+15 -8
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 * We may need to do extra adjustments for the hero if we're
* messing with the hero's inventory. The following calls are * messing with the hero's inventory. The following calls are
* equivalent to calling freeinv on obj and addinv on otmp, * equivalent to calling freeinv() on obj and addinv_nomerge()
* while doing an in-place swap of the actual objects. * on otmp, while doing an in-place swap of the actual objects.
*/ */
freeinv_core(obj); freeinv_core(obj);
addinv_core1(otmp); addinv_core1(otmp);
@@ -1834,9 +1834,12 @@ poly_obj(struct obj *obj, int id)
if (old_wornmask) { if (old_wornmask) {
boolean was_twohanded = bimanual(obj), was_twoweap = u.twoweap; boolean was_twohanded = bimanual(obj), was_twoweap = u.twoweap;
/* wearslot() returns a mask which might have multiple bits set; /* wearslot() expects us to deal with wielded/alt-wep/quivered
narrow that down to the bit(s) currently in use */ items in case they're not weapons; for other slots it might
new_wornmask = wearslot(otmp) & old_wornmask; 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); remove_worn_item(obj, TRUE);
/* if the new form can be worn in the same slot, make it so */ /* if the new form can be worn in the same slot, make it so */
if ((new_wornmask & W_WEP) != 0L) { 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. * It is possible that we can now merge some inventory.
* Do a highly paranoid merge. Restart from the beginning * Do a highly paranoid merge. Restart from the beginning until
* until no merges. * no merges. Don't merge worn items (in case of stone-to-flesh
* of rocks wielded in differing weapon/alt-wep/quiver slot).
*/ */
do { do {
didmerge = FALSE; 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) for (onxt = otmp->nobj; onxt; onxt = onxt->nobj)
if (merged(&otmp, &onxt)) { if (merged(&otmp, &onxt)) {
didmerge = TRUE; didmerge = TRUE;
break; break;
} }
}
} while (didmerge); } while (didmerge);
break; break;
} }