fix #H7591 - migrating monsters vs full levels

During level change, when a monster from mydogs (monsters accompaying
hero, usually pets) couldn't be placed because the level was full, it
was set to migrate to that level (in order to get another chance to
arrive if hero left and returned).  The code sequence
 mon_arrive()-> mnexto()-> m_into_limbo()-> migrate_to_level()-> relmon()
tried to remove the monster from the map, but it wasn't necessarily on
the map (depending upon whether it couldn't arrive at all, or arrived
at the hero's spot and couldn't be moved out of the hero's way).  The
EXTRA_SANITY_CHECKS for remove_monster() issued impossible "no monster
to remove".  relmon() now checks whether monster is already off the map.

While investigating that, I discovered that pets set to re-migrate
to the same level to try again on hero's next visit didn't work at all.
migrating_mons gets processed after mydogs so moving something from
the latter to the former after arrival failure just resulted in
immediate second failure when the more general list was handled during
the hero's current arrival.  And failure to arrive from migrating_mons
would kill the monster instead of scheduling another attempt.

The sanest fix for that turned out to be to have all monsters who
can't arrive be put back on the migrating_mons list to try again upon
hero's next visit.  Pets still fail twice but are no longer discarded
during the second time, and now do arrive when hero leaves and comes
back provided he or she has opened up some space before leaving.  If
there's still no space on the next visit, monsters who can't arrive
then are scheduled to try again on the visit after that.

Recent fix for invalid corpses becomes moot.  Monsters aren't killed
during arrival failure so there are no resulting corpses to deal with.
This commit is contained in:
PatR
2018-11-24 01:45:09 -08:00
parent 531ccca7d9
commit cc5bb44a9a
5 changed files with 70 additions and 77 deletions

View File

@@ -205,6 +205,17 @@ successfully paying for shop damage with shop credit would be followed by
if a migrating monster was killed off because there was no room on the
destination level, it would leave a corpse even if it was a type
which should never leave one (demon, golem, blob, &c)
monsters accompanying hero during level change (usually pets) who failed to
arrive and tried to re-migrate were being removed from the map after
already having been removed [impossible "no monster to remove" if
compiled with EXTRA_SANITY_CHECKS enabled] during migration handling
monsters accompanying hero during level change (usually pets) who failed to
arrive and tried to re-migrate (for hero's next visit to the level)
ended up being killed because the migration attempt happened right
away (same visit by hero, so level still full) and they weren't
accompanying hero on the second attempt
fix for above (all failed arrivals will re-migrate) makes the earlier fix (for
invalid corpse being left by monst killed upon migration failure) moot
end of game while carrying Schroedinger's Box would reveal cat-or-corpse
for inventory disclosure or put that info into dumplog, but not both
attempting to untrap an adjacent trap while on the edge of--not in--a pit