]> granicus.if.org Git - nethack/commitdiff
More monster location sanity checks
authorPasi Kallinen <paxed@alt.org>
Mon, 19 Nov 2018 20:38:10 +0000 (22:38 +0200)
committerPasi Kallinen <paxed@alt.org>
Mon, 19 Nov 2018 20:38:16 +0000 (22:38 +0200)
Placing a monster over already existing one will now complain.
Define EXTRA_SANITY_CHECKS to check monster removal too.

include/rm.h
src/mail.c
src/mhitm.c
src/save.c
src/steed.c
src/worm.c

index 7fd41c47cd8da90df432726c0514e5a6c3c837d9..93362d67bd4c36116e00145c7b31a0877a546628 100644 (file)
@@ -629,8 +629,19 @@ extern dlevel_t level; /* structure describing the current level */
 #define MON_BURIED_AT(x, y)                     \
     (level.monsters[x][y] != (struct monst *) 0 \
      && (level.monsters[x][y])->mburied)
+#if EXTRA_SANITY_CHECKS
+#define place_worm_seg(m, x, y) do { \
+    if (level.monsters[x][y] && level.monsters[x][y] != m) impossible("place_worm_seg over mon"); \
+    level.monsters[x][y] = m; \
+    } while(0)
+#define remove_monster(x, y) do { \
+    if (!level.monsters[x][y]) impossible("no monster to remove"); \
+    level.monsters[x][y] = (struct monst *) 0; \
+    } while(0)
+#else
 #define place_worm_seg(m, x, y) level.monsters[x][y] = m
 #define remove_monster(x, y) level.monsters[x][y] = (struct monst *) 0
+#endif
 #define m_at(x, y) (MON_AT(x, y) ? level.monsters[x][y] : (struct monst *) 0)
 #define m_buried_at(x, y) \
     (MON_BURIED_AT(x, y) ? level.monsters[x][y] : (struct monst *) 0)
index 6427cf8cd834f81aed0fcb1871e3def88cf3d24c..8e3eec8f7ad4824487829be9ade846baabf9a10a 100644 (file)
@@ -336,19 +336,21 @@ register int tx, ty; /* destination of mail daemon */
         else if (fx == u.ux && fy == u.uy)
             verbalize("Excuse me.");
 
+        if (mon)
+            remove_monster(fx, fy);
         place_monster(md, fx, fy); /* put md down */
         newsym(fx, fy);            /* see it */
         flush_screen(0);           /* make sure md shows up */
         delay_output();            /* wait a little bit */
 
         /* Remove md from the dungeon.  Restore original mon, if necessary. */
+        remove_monster(fx, fy);
         if (mon) {
             if ((mon->mx != fx) || (mon->my != fy))
                 place_worm_seg(mon, fx, fy);
             else
                 place_monster(mon, fx, fy);
-        } else
-            remove_monster(fx, fy);
+        }
         newsym(fx, fy);
     }
 
@@ -357,9 +359,11 @@ register int tx, ty; /* destination of mail daemon */
      * very unlikely).  If one exists, then have the md leave in disgust.
      */
     if ((mon = m_at(fx, fy)) != 0) {
+        remove_monster(fx, fy);
         place_monster(md, fx, fy); /* display md with text below */
         newsym(fx, fy);
         verbalize("This place's too crowded.  I'm outta here.");
+        remove_monster(fx, fy);
 
         if ((mon->mx != fx) || (mon->my != fy)) /* put mon back */
             place_worm_seg(mon, fx, fy);
index ba322a8caeea3ab972b685f129538d4d98b8531a..774e9a56e6bf23e70b1d3f09febfb8f861018900 100644 (file)
@@ -725,6 +725,7 @@ register struct attack *mattk;
      *  but don't leave it on the screen.  Move the aggressor to the
      *  defender's position.
      */
+    remove_monster(dx, dy);
     remove_monster(ax, ay);
     place_monster(magr, dx, dy);
     newsym(ax, ay); /* erase old position */
index d7827fcfd8b487ea092eab489b3a7c854fd47315..bca03c49ec86d0ca9cb7c52ad29bb1312ddbb340 100644 (file)
@@ -536,6 +536,11 @@ skip_lots:
     saveobjchn(fd, level.buriedobjlist, mode);
     saveobjchn(fd, billobjs, mode);
     if (release_data(mode)) {
+        int x,y;
+
+        for (y = 0; y < ROWNO; y++)
+            for (x = 0; x < COLNO; x++)
+                level.monsters[x][y] = 0;
         fmon = 0;
         ftrap = 0;
         fobj = 0;
index 6b940c26e92230ac3a15792d36610bb307d2b34c..61f252a4c73ba516a1389e6ce1ed15b220459c5d 100644 (file)
@@ -704,6 +704,8 @@ int x, y;
                    (mon == u.usteed) ? "steed" : "defunct monster");
         return;
     }
+    if (level.monsters[x][y])
+        impossible("placing monster over another?");
     mon->mx = x, mon->my = y;
     level.monsters[x][y] = mon;
 }
index b2bf598dc59748afaaf075b7b82531ce5911e978..4e9d144b1fcb55ba7be32a65b543d5b3c6f4ae6d 100644 (file)
@@ -383,6 +383,7 @@ struct obj *weap;
 
     /* Sometimes the tail end dies. */
     if (!new_worm) {
+        place_worm_seg(worm, x, y); /* place the "head" segment back */
         if (context.mon_moving) {
             if (canspotmon(worm))
                 pline("Part of %s tail has been cut off.",