]> granicus.if.org Git - nethack/commitdiff
Put monsters into limbo if they cannot be placed
authorPasi Kallinen <paxed@alt.org>
Sun, 11 Oct 2015 15:52:24 +0000 (18:52 +0300)
committerPasi Kallinen <paxed@alt.org>
Sun, 11 Oct 2015 15:52:27 +0000 (18:52 +0300)
Whenever mnearto tries to displace a monster from underneath
another, and the displaced one cannot be placed anywhere,
make it drop special objects and put it into migration, with
the current level as the target.

This should be a good enough stopgap measure - it's not going
to happen unless the level is (nearly) full of monsters.

And it seems to cure a near-impossible-to-track data corruption,
with monster list pointing to garbage.

src/mon.c

index f257e7f3175e33b0012005c834b1e581a60f3e62..44f4c48ae02062905c65c5f4e976eb7465ff64d7 100644 (file)
--- a/src/mon.c
+++ b/src/mon.c
@@ -2342,13 +2342,15 @@ boolean move_other; /* make sure mtmp gets to x, y! so move m_at(x, y) */
         xchar oldx = othermon->mx, oldy = othermon->my;
 
         othermon->mx = othermon->my = 0;
-        if (!mnearto(othermon, x, y, FALSE)) {
+        (void) mnearto(othermon, x, y, FALSE);
+        if (othermon->mx == 0 && othermon->my == 0) {
+            /* reloc failed, dump monster into "limbo"
+               (aka migrate to current level) */
             othermon->mx = oldx;
             othermon->my = oldy;
-            return FALSE;
+            mdrop_special_objs(othermon);
+            migrate_to_level(othermon, ledger_no(&u.uz), MIGR_APPROX_XY, NULL);
         }
-        if (othermon->mx != x || othermon->my != y)
-            return TRUE;
     }
 
     return FALSE;