fix bullwhip-induced panic
While testing some corpse/statue name manipulation changes I managed to trigger a panic during end-of-game cleanup. Using a bullwhip to snatch a wielded cockatrice corpse from a monster's inventory into the hero's inventory and being turned to stone due to lack of gloves took the corpse out of the monster's inventory but didn't place it anywhere. If no life-saving took place, it led to an "obj_is_local" panic during timer cleanup when freeing the level. This patch includes some of the stuff I've been testing rather than just the fix for the panic (which is the very last bit of the diff).
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.568 $ $NHDT-Date: 1623282330 2021/06/09 23:45:30 $
|
||||
NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.571 $ $NHDT-Date: 1623807747 2021/06/16 01:42:27 $
|
||||
|
||||
General Fixes and Modified Features
|
||||
-----------------------------------
|
||||
@@ -542,6 +542,9 @@ change attendant (healer quest) monster from lawful to neutral
|
||||
quit is not longer bound to M-q
|
||||
change default value of autopickup to off and color to on
|
||||
resurrected corpse of mon could end up with different gender from original mon
|
||||
using a bullwhip to snatch a wielded cockatrice corpse from a monster when not
|
||||
wearing gloves and without life-saving could trigger "obj_is_local"
|
||||
panic during final cleanup
|
||||
|
||||
|
||||
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
|
||||
|
||||
40
src/apply.c
40
src/apply.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 apply.c $NHDT-Date: 1621387861 2021/05/19 01:31:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.344 $ */
|
||||
/* NetHack 3.7 apply.c $NHDT-Date: 1623807747 2021/06/16 01:42:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.345 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -271,7 +271,7 @@ its_dead(int rx, int ry, int *resp)
|
||||
humanoid(mptr) ? "person" : "creature");
|
||||
what = buf;
|
||||
} else {
|
||||
what = pmname(mptr, NEUTRAL);
|
||||
what = obj_pmname(statue);
|
||||
if (!type_is_pname(mptr))
|
||||
what = The(what);
|
||||
}
|
||||
@@ -1920,6 +1920,7 @@ static void
|
||||
use_tinning_kit(struct obj *obj)
|
||||
{
|
||||
struct obj *corpse, *can;
|
||||
struct permonst *mptr;
|
||||
|
||||
/* This takes only 1 move. If this is to be changed to take many
|
||||
* moves, we've got to deal with decaying corpses...
|
||||
@@ -1934,29 +1935,28 @@ use_tinning_kit(struct obj *obj)
|
||||
You("cannot tin %s which is partly eaten.", something);
|
||||
return;
|
||||
}
|
||||
if (touch_petrifies(&mons[corpse->corpsenm]) && !Stone_resistance
|
||||
&& !uarmg) {
|
||||
mptr = &mons[corpse->corpsenm];
|
||||
if (touch_petrifies(mptr) && !Stone_resistance && !uarmg) {
|
||||
char kbuf[BUFSZ];
|
||||
const char *corpse_name = an(cxname(corpse));
|
||||
|
||||
if (poly_when_stoned(g.youmonst.data))
|
||||
You("tin %s without wearing gloves.",
|
||||
an(mons[corpse->corpsenm].pmnames[NEUTRAL]));
|
||||
else {
|
||||
if (poly_when_stoned(g.youmonst.data)) {
|
||||
You("tin %s without wearing gloves.", corpse_name);
|
||||
} else {
|
||||
pline("Tinning %s without wearing gloves is a fatal mistake...",
|
||||
an(mons[corpse->corpsenm].pmnames[NEUTRAL]));
|
||||
Sprintf(kbuf, "trying to tin %s without gloves",
|
||||
an(mons[corpse->corpsenm].pmnames[NEUTRAL]));
|
||||
corpse_name);
|
||||
Sprintf(kbuf, "trying to tin %s without gloves", corpse_name);
|
||||
}
|
||||
instapetrify(kbuf);
|
||||
}
|
||||
if (is_rider(&mons[corpse->corpsenm])) {
|
||||
if (is_rider(mptr)) {
|
||||
if (revive_corpse(corpse))
|
||||
verbalize("Yes... But War does not preserve its enemies...");
|
||||
else
|
||||
pline_The("corpse evades your grasp.");
|
||||
return;
|
||||
}
|
||||
if (mons[corpse->corpsenm].cnutrit == 0) {
|
||||
if (mptr->cnutrit == 0) {
|
||||
pline("That's too insubstantial to tin.");
|
||||
return;
|
||||
}
|
||||
@@ -2141,7 +2141,7 @@ fig_transform(anything *arg, long timeout)
|
||||
char monnambuf[BUFSZ], carriedby[BUFSZ];
|
||||
|
||||
if (!figurine) {
|
||||
debugpline0("null figurine in fig_transform()");
|
||||
impossible("null figurine in fig_transform()");
|
||||
return;
|
||||
}
|
||||
silent = (timeout != g.monstermoves); /* happened while away */
|
||||
@@ -2908,10 +2908,18 @@ use_whip(struct obj *obj)
|
||||
&& polymon(PM_STONE_GOLEM))) {
|
||||
char kbuf[BUFSZ];
|
||||
|
||||
Sprintf(kbuf, "%s corpse",
|
||||
an(mons[otmp->corpsenm].pmnames[NEUTRAL]));
|
||||
Strcpy(kbuf, (otmp->quan == 1L) ? an(onambuf)
|
||||
: onambuf);
|
||||
pline("Snatching %s is a fatal mistake.", kbuf);
|
||||
/* corpse probably has a rot timer but is now
|
||||
OBJ_FREE; end of game cleanup will panic if
|
||||
it isn't part of current level; plus it would
|
||||
be missing from bones, so put it on the floor */
|
||||
place_object(otmp, u.ux, u.uy); /* but don't stack */
|
||||
|
||||
instapetrify(kbuf);
|
||||
/* life-saved; free the corpse again */
|
||||
obj_extract_self(otmp);
|
||||
}
|
||||
(void) hold_another_object(otmp, "You drop %s!",
|
||||
doname(otmp), (const char *) 0);
|
||||
|
||||
Reference in New Issue
Block a user