fix #H7015 - explosion chain reaction bug

The fix to prevent "crushed by a gas spore's explosion" set killer.name
to an empty string after a gas spore explosion finished, but that made
nested explosions end up with empty killer.name after the innermost
call completed.  explode() shouldn't have been hanging on to a pointer
to a global value that is subject to change while it executes.  Making
a local copy of the current value at the time explode() is called will
solve that (I hope...).

Simply reverting the reset of killer.name wouldn't have been correct.
The innermost explosion would still be clobbering killer.name for any
outer MON_EXPLODE explosions in progress.  When the only exploding
monster is gas spore, that wouldn't be noticeable.  But having other
types of exploding monsters and a chain reaction which affected more
than one type would have exposed that bug.  I think this fixes both
aspects of this problem but don't have a second type of exploding
monster to verify the second part.
This commit is contained in:
PatR
2018-03-30 17:05:23 -07:00
parent 4eab7b140c
commit c058826995
2 changed files with 14 additions and 3 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 explode.c $NHDT-Date: 1513297345 2017/12/15 00:22:25 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.55 $ */
/* NetHack 3.6 explode.c $NHDT-Date: 1522454717 2018/03/31 00:05:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.56 $ */
/* Copyright (C) 1990 by Ken Arromdee */
/* NetHack may be freely redistributed. See license for details. */
@@ -44,7 +44,7 @@ int expltype;
boolean shopdamage = FALSE, generic = FALSE, physical_dmg = FALSE,
do_hallu = FALSE, inside_engulfer, grabbed, grabbing;
coord grabxy;
char hallu_buf[BUFSZ];
char hallu_buf[BUFSZ], killr_buf[BUFSZ];
short exploding_wand_typ = 0;
if (olet == WAND_CLASS) { /* retributive strike */
@@ -114,7 +114,9 @@ int expltype;
*/
if (olet == MON_EXPLODE) {
str = killer.name;
/* when explode() is called recursively, killer.name might change so
we need to retain a copy of the current value for this explosion */
str = strcpy(killr_buf, killer.name);
do_hallu = (Hallucination
&& (strstri(str, "'s explosion")
|| strstri(str, "s' explosion")));