fix github issue #1170 - trapped without a trap
Issue reported by mkuoppal: drum of earthquake triggers a sanity check warning which the fuzzer escalated to panic. Analysis by entrez. If a pit gets created next to a pool or moat or lava, liquid might flow there and replace the pit. But the drum of earthquake code assumed that the pit was still there. If there was a monster there and it wasn't levitating or flying and it wasn't killed by the liquid, it got marked as trapped even though the pit was gone. 'sanity_check' noticed. With difficulty I was able to reproduce the impossible warning before the fix, but the are a bunch of random factors at play. After the fix I can't reproduce it again, but that's not a guarantee that it's actually fixed. The analysis seems correct though and the fix is based on dealing with that. Closes #1170
This commit is contained in:
@@ -1323,6 +1323,11 @@ change [master] mind flayer, the Wizard, and the riders to bright magenta
|
||||
walking into a shopkeeper tries to pay the bill
|
||||
show billed items in a menu when paying with non-traditional menustyle
|
||||
prioritize paying shopkeeper next to you even if multiple are detected
|
||||
avoid impossible "trapped without a trap (fmon)" from 'sanity_check' when a
|
||||
drum of earthquake made a pit at a monster's spot and pit creation
|
||||
caused adjacent pool/moat/lava to flood that spot; if a non-floater,
|
||||
non-flyer monster survived that it got marked as trapped even though
|
||||
flooding deleted the trap
|
||||
|
||||
|
||||
Fixes to 3.7.0-x General Problems Exposed Via git Repository
|
||||
|
||||
25
src/dig.c
25
src/dig.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 dig.c $NHDT-Date: 1596498156 2020/08/03 23:42:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.142 $ */
|
||||
/* NetHack 3.7 dig.c $NHDT-Date: 1702206282 2023/12/10 11:04:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.204 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Michael Allison, 2012. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -747,19 +747,32 @@ digactualhole(coordxy x, coordxy y, struct monst *madeby, int ttyp)
|
||||
DISABLE_WARNING_FORMAT_NONLITERAL
|
||||
|
||||
/*
|
||||
* Called from dighole(), but also from do_break_wand()
|
||||
* in apply.c.
|
||||
* Called from dighole(); also from do_break_wand() in apply.c
|
||||
* and do_earthquake() in music.c.
|
||||
*/
|
||||
void
|
||||
liquid_flow(coordxy x, coordxy y, schar typ, struct trap *ttmp,
|
||||
const char *fillmsg)
|
||||
liquid_flow(
|
||||
coordxy x, coordxy y,
|
||||
schar typ,
|
||||
struct trap *ttmp,
|
||||
const char *fillmsg)
|
||||
{
|
||||
struct obj *objchain;
|
||||
struct monst *mon;
|
||||
boolean u_spot = u_at(x, y);
|
||||
|
||||
/* caller should have changed levl[x][y].typ to POOL, MOAT, or LAVA */
|
||||
if (!is_pool_or_lava(x, y)) {
|
||||
if (iflags.sanity_check) {
|
||||
impossible("Insane liquid_flow(%d,%d,%s,%s).", x, y,
|
||||
ttmp ? trapname(ttmp->ttyp, TRUE) : "no trap",
|
||||
fillmsg ? fillmsg : "no mesg");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (ttmp)
|
||||
(void) delfloortrap(ttmp);
|
||||
(void) delfloortrap(ttmp); /* will untrap monster is one is here */
|
||||
/* if any objects were frozen here, they're released now */
|
||||
unearth_objs(x, y);
|
||||
|
||||
|
||||
13
src/music.c
13
src/music.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 music.c $NHDT-Date: 1646688067 2022/03/07 21:21:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.77 $ */
|
||||
/* NetHack 3.7 music.c $NHDT-Date: 1702206294 2023/12/10 11:04:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.101 $ */
|
||||
/* Copyright (c) 1989 by Jean-Christophe Collet */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -337,8 +337,11 @@ do_earthquake(int force)
|
||||
wand of digging if you alter this sequence. */
|
||||
filltype = fillholetyp(x, y, FALSE);
|
||||
if (filltype != ROOM) {
|
||||
levl[x][y].typ = filltype; /* flags set via doormask */
|
||||
set_levltyp(x, y, filltype); /* levl[x][y] = filltype; */
|
||||
liquid_flow(x, y, filltype, chasm, (char *) 0);
|
||||
/* liquid_flow() deletes trap, might kill mtmp */
|
||||
if ((chasm = t_at(x, y)) == NULL)
|
||||
break; /* from switch, not loop */
|
||||
}
|
||||
|
||||
mtmp = m_at(x, y); /* (redundant?) */
|
||||
@@ -353,8 +356,8 @@ do_earthquake(int force)
|
||||
break; /* from switch, not loop */
|
||||
}
|
||||
|
||||
/* We have to check whether monsters or player
|
||||
falls in a chasm... */
|
||||
/* We have to check whether monsters or hero falls into a
|
||||
new pit.... Note: if we get here, chasm is non-Null. */
|
||||
if (mtmp) {
|
||||
if (!is_flyer(mtmp->data) && !is_clinger(mtmp->data)) {
|
||||
boolean m_already_trapped = mtmp->mtrapped;
|
||||
@@ -427,7 +430,7 @@ do_earthquake(int force)
|
||||
exercise(A_DEX, TRUE);
|
||||
else
|
||||
selftouch((Upolyd && (slithy(gy.youmonst.data)
|
||||
|| nolimbs(gy.youmonst.data)))
|
||||
|| nolimbs(gy.youmonst.data)))
|
||||
? "Shaken, you"
|
||||
: "Falling down, you");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user