sequencing issue: dismounting from dying steed
Reported by entrez: if a trap killed hero's steed and dismounting
was fatal for the hero (probably by falling onto the same trap),
impossible "dmonsfree: 1 removed doesn't match 0 pending" warning
occurred during game-over cleanup.
Move the dismount calls in mondead() and mongone() from before their
m_detach() call to the end of m_detach() itself. This led to a
cascade of problems and attempted fixes until finally zeroing in on
place_monster()'s sanity checks and dismount_steed()'s attempts to
work-around one of them.
This reverts the convoluted hack from four years ago in commit
be327d9822 and deals with the issue in
a simpler way. After that, the new dismount_steed() placement at
end of m_detach() works cleanly.
This commit is contained in:
17
src/steed.c
17
src/steed.c
@@ -660,19 +660,12 @@ dismount_steed(
|
||||
/* still no spot; last resort is any spot within bounds */
|
||||
(void) enexto(&steedcc, u.ux, u.uy, &mons[PM_GHOST]);
|
||||
}
|
||||
if (!m_at(steedcc.x, steedcc.y)) {
|
||||
if (mtmp->mhp < 1) /* make sure it isn't negative so that */
|
||||
mtmp->mhp = 0; /* ++mhp produces a positive value */
|
||||
mtmp->mhp++; /* force at least one hit point, possibly resurrecting
|
||||
* to avoid impossible("placing defunct monst on map") */
|
||||
place_monster(mtmp, steedcc.x, steedcc.y);
|
||||
mtmp->mhp--; /* take the extra hit point away: cancel resurrection
|
||||
* if former steed has died */
|
||||
} else {
|
||||
impossible("Dismounting: can't place former steed on map.");
|
||||
}
|
||||
|
||||
if (!DEADMONSTER(mtmp)) {
|
||||
gi.in_steed_dismounting++;
|
||||
place_monster(mtmp, steedcc.x, steedcc.y);
|
||||
gi.in_steed_dismounting--;
|
||||
|
||||
/* if for bones, there's no reason to place the hero;
|
||||
we want to make room for potential ghost, so move steed */
|
||||
if (reason == DISMOUNT_BONES) {
|
||||
@@ -855,7 +848,7 @@ place_monster(struct monst* mon, int x, int y)
|
||||
minimal_monnam(mon, TRUE), x, y, mon->mstate, buf);
|
||||
x = y = 0;
|
||||
}
|
||||
if (mon == u.usteed
|
||||
if ((mon == u.usteed && !gi.in_steed_dismounting)
|
||||
/* special case is for convoluted vault guard handling */
|
||||
|| (DEADMONSTER(mon) && !(mon->isgd && x == 0 && y == 0))) {
|
||||
describe_level(buf, 0);
|
||||
|
||||
Reference in New Issue
Block a user