Reported directly to devteam, zapping wand of undead turning at a
shopkeeper's corpse would cause a crash. 'Traits' to fully recreate
the shk were attached to the corpse, but the temporary monster
created on the map intended to be relaced by the shk didn't have any
eshk struct, and the sequence replmon() -> replshk() -> inhishop()
attempted to access mtmp->mextra->eshk when trying to reattach the
shk to his/her shop. No other mextra structs involve pointer fixups,
so pets, priests, vault guards don't need extra handling.
I tested four cases. #1 and #3 had no shop bill at the time; I'm not
sure about #2. These all worked.
1) shk killed inside shop, resurrected there;
2) killed outside shop on the shop level, resurrected there;
3) killed inside his shop, corpse carried to different level before
being resurrected;
4) killed and resurrected on different level from shop after hero
stole something (teleported out of shop with unpaid item)--shk
left shop to chase hero and followed him/her up some stairs.
at self to prevent turning into slime was not properly killed off;
it wouldn't benefit from an amulet of life saving and would trigger
impossible "dmonsfree: N removed doesn't match M pending"
+resurrecting a shopkeeper corpse caused crash (replmon -> replshk -> inhishop
+ -> no eshk data for temporary monster being replaced with revived shk)
Fixes to Post-3.6.0 Problems that Were Exposed Via git Respository
-/* NetHack 3.6 zap.c $NHDT-Date: 1462663451 2016/05/07 23:24:11 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.252 $ */
+/* NetHack 3.6 zap.c $NHDT-Date: 1463533826 2016/05/18 01:10:26 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.255 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
mtmp2->mblinded = 0;
mtmp2->mstun = 0;
mtmp2->mconf = 0;
+ /* when traits are for a shopeekper, dummy monster 'mtmp' won't
+ have necessary eshk data for replmon() -> replshk() */
+ if (mtmp2->isshk) {
+ neweshk(mtmp);
+ *ESHK(mtmp) = *ESHK(mtmp2);
+ if (ESHK(mtmp2)->bill_p != 0
+ && ESHK(mtmp2)->bill_p != (struct bill_x *) -1000)
+ ESHK(mtmp)->bill_p = &(ESHK(mtmp)->bill[0]);
+ mtmp->isshk = 1;
+ }
replmon(mtmp, mtmp2);
newsym(mtmp2->mx, mtmp2->my); /* Might now be invisible */