]> granicus.if.org Git - nethack/commitdiff
Fix freeing monsters not on map
authorPasi Kallinen <paxed@alt.org>
Sat, 17 Nov 2018 17:26:49 +0000 (19:26 +0200)
committerPasi Kallinen <paxed@alt.org>
Mon, 19 Nov 2018 19:16:46 +0000 (21:16 +0200)
Sometimes we free the monster data, but the monster is not on the
map - usually this happens if the map is full of monsters and a new one
is migrated on the level.

Make m_detach check the monster x coordinate, so it knows not to touch the map
if the monster isn't on it.

src/dog.c
src/mail.c
src/mon.c

index e5767103a8a51e31ef39fb82c0905167f42e1dae..71a4ea289ff9efddda41ad1d2de6d528d7d61a44 100644 (file)
--- a/src/dog.c
+++ b/src/dog.c
@@ -464,6 +464,7 @@ fail_mon_placement:
             }
             (void) mkcorpstat(CORPSE, (struct monst *) 0, mtmp->data, xlocale,
                               ylocale, CORPSTAT_NONE);
+            mtmp->mx = mtmp->my = -1; /* for mongone, mon is not anywhere */
             mongone(mtmp);
         }
     }
index 3f47e3a55adc23bb8d0e6455ec804f899976c9e8..6427cf8cd834f81aed0fcb1871e3def88cf3d24c 100644 (file)
@@ -418,7 +418,8 @@ struct mail_info *info;
 
 /* zip back to starting location */
 go_back:
-    (void) md_rush(md, start.x, start.y);
+    if (!md_rush(md, start.x, start.y))
+        md->mx = md->my = -1; /* for mongone, md is not on map */
     mongone(md);
 /* deliver some classes of messages even if no daemon ever shows up */
 give_up:
index 079321f41b751883dad64198771a62a71aae912b..7340e1ad6a40a657e16bdb849bd54f6cb52e8feb 100644 (file)
--- a/src/mon.c
+++ b/src/mon.c
@@ -1745,6 +1745,8 @@ m_detach(mtmp, mptr)
 struct monst *mtmp;
 struct permonst *mptr; /* reflects mtmp->data _prior_ to mtmp's death */
 {
+    boolean onmap = (mtmp->mx > -1);
+
     if (mtmp == context.polearm.hitmon)
         context.polearm.hitmon = 0;
     if (mtmp->mleashed)
@@ -1753,14 +1755,21 @@ struct permonst *mptr; /* reflects mtmp->data _prior_ to mtmp's death */
     mtmp->mtrapped = 0;
     mtmp->mhp = 0; /* simplify some tests: force mhp to 0 */
     relobj(mtmp, 0, FALSE);
-    remove_monster(mtmp->mx, mtmp->my);
+    if (onmap) {
+        if (mtmp->wormno)
+            remove_worm(mtmp);
+        else
+            remove_monster(mtmp->mx, mtmp->my);
+    }
     if (emits_light(mptr))
         del_light_source(LS_MONSTER, monst_to_any(mtmp));
     if (mtmp->m_ap_type)
         seemimic(mtmp);
-    newsym(mtmp->mx, mtmp->my);
+    if (onmap)
+        newsym(mtmp->mx, mtmp->my);
     unstuck(mtmp);
-    fill_pit(mtmp->mx, mtmp->my);
+    if (onmap)
+        fill_pit(mtmp->mx, mtmp->my);
 
     if (mtmp->isshk)
         shkgone(mtmp);