fix #K3503 - boulder-carrying monster killed twice

A giant that is carrying a boulder and standing on ice who drowns when
the ice gets melted could die a second time if the resulting pool gets
plugged by the boulder.  It results in an impossible from dmonsfree()
about bookkeeping inconsistency when dead monsters are removed at the
end of the turn.  The fuzzer escalates that to a panic.
This commit is contained in:
PatR
2021-12-26 09:44:10 -08:00
parent 80a61c6e67
commit 9daefde0c4
2 changed files with 12 additions and 1 deletions

View File

@@ -722,6 +722,9 @@ attack feedback when using a bullwhip said "swing"; change to "lash"
attack feedback for monster using polearm when adjacent said "thrust"; change
to "bash"
apply runmode delay to multiturn actions, not just running
if a giant carrying a boulder was on ice that melted, it could be killed
twice, first by drowning, then by boulder filling the resulting pool
when it dropped inventory before being removed from the map
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository

View File

@@ -66,7 +66,15 @@ boulder_hits_pool(struct obj *otmp, int rx, int ry, boolean pushing)
} else
levl[rx][ry].typ = ROOM, levl[rx][ry].flags = 0;
if ((mtmp = m_at(rx, ry)) != 0)
/* 3.7: normally DEADMONSTER() is used when traversing the fmon
list--dead monsters usually aren't still at specific map
locations; however, if ice melts causing a giant to drown,
that giant would still be on the map when it drops inventory;
if it was carrying a boulder which now fills the pool, 'mtmp'
will be dead here; killing it again would yield impossible
"dmonsfree: N removed doesn't match N+1 pending" when other
monsters have finished their current turn */
if ((mtmp = m_at(rx, ry)) != 0 && !DEADMONSTER(mtmp))
mondied(mtmp);
if (ttmp)