]> granicus.if.org Git - nethack/commitdiff
fix github issue #764 - misplaced corpses
authorPatR <rankin@nethack.org>
Mon, 16 May 2022 08:30:00 +0000 (01:30 -0700)
committerPatR <rankin@nethack.org>
Mon, 16 May 2022 08:30:00 +0000 (01:30 -0700)
Reported by jeremyhetzler and confirmed by k2:  dead monsters weren't
leaving corpses at the spot they died.

Don't set a monster's mx,my coordinates to 0,0 when taking it off the
map (unless it is migrating to another level; mx==0 is the bit of data
used to indicate that).  Corpse drop happens after that and expects
the dead monster's former map coordinates to be intact.

Fixes #764

doc/fixes3-7-0.txt
src/dog.c
src/mon.c
src/worm.c

index 536700064054c376eb29b8c04f518e10c88c466f..dbe8ff0bbf015070407cbcb6d1621cb84f6c86b1 100644 (file)
@@ -1,4 +1,4 @@
-HDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.914 $ $NHDT-Date: 1652478351 2022/05/13 21:45:51 $
+HDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.916 $ $NHDT-Date: 1652689792 2022/05/16 08:29:52 $
 
 General Fixes and Modified Features
 -----------------------------------
@@ -1213,6 +1213,8 @@ revised monster teleportation message handling could produce duplicate message
        when shopkeeper who left shop got returned to it
 recent changes in removing a dead monster from the map didn't update screen
        to show objects it dropped; they were present, just not displayed
+further changes resulted in dead monsters' corpses be placed at <0,0>;
+       reverse the part(s) that cleared stale monst->mx,my
 
 curses: 'msg_window' option wasn't functional for curses unless the binary
        also included tty support
index e05968d90aee80bd85a028fea8dca45e22f4a642..ee8e635ccd03354b40831e08e13785ea74db0994 100644 (file)
--- a/src/dog.c
+++ b/src/dog.c
@@ -1,4 +1,4 @@
-/* NetHack 3.7 dog.c   $NHDT-Date: 1652577033 2022/05/15 01:10:33 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.120 $ */
+/* NetHack 3.7 dog.c   $NHDT-Date: 1652689621 2022/05/16 08:27:01 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.121 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2011. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -602,14 +602,15 @@ mon_leave(struct monst *mtmp)
     /* if this is a long worm, handle its tail segments before mtmp itself;
        we pass possibly trundated segment count to caller via return value  */
     if (mtmp->wormno) {
-        int cnt = count_wsegs(mtmp);
+        int cnt = count_wsegs(mtmp), mx = mtmp->mx, my = mtmp->my;
 
         /* since monst->wormno is overloaded to hold the number of
            tail segments during migration, a very long worm with
            more segments than can fit in that field gets truncated */
         num_segs = min(cnt, MAX_NUM_WORMS - 1);
-        wormgone(mtmp); /* discard tail segments, take head off map */
-        /* mtmp->mx,mtmp->my is now 0,0 */
+        wormgone(mtmp);
+        /* put the head back */
+        place_monster(mtmp, mx, my);
     }
 
     return num_segs;
@@ -691,7 +692,8 @@ keepdogs(
             /* prepare to take mtmp off the map */
             num_segs = mon_leave(mtmp);
             /* take off map and move mtmp from fmon list to mydogs */
-            relmon(mtmp, &g.mydogs); /* mtmp->mx,my get changed to 0,0 */
+            relmon(mtmp, &g.mydogs); /* mtmp->mx,my retain current value */
+            mtmp->mx = mtmp->my = 0; /* mx==0 implies migating */
             mtmp->wormno = num_segs;
             mtmp->mlstmv = g.moves;
         } else if (mtmp->iswiz) {
@@ -728,7 +730,7 @@ migrate_to_level(
     /* prepare to take mtmp off the map */
     num_segs = mon_leave(mtmp);
     /* take off map and move mtmp from fmon list to migrating_mons */
-    relmon(mtmp, &g.migrating_mons); /* mtmp->mx,my get changed to 0,0 */
+    relmon(mtmp, &g.migrating_mons); /* mtmp->mx,my retain their value */
     mtmp->mstate |= MON_MIGRATING;
 
     new_lev.dnum = ledger_to_dnum((xchar) tolev);
@@ -748,8 +750,7 @@ migrate_to_level(
     mtmp->mtrack[0].y = xyflags;
     mtmp->mux = new_lev.dnum;
     mtmp->muy = new_lev.dlevel;
-    mtmp->mx = mtmp->my = 0; /* this implies migration (note: already done
-                              * by relmon() -> mon_leaving_level() above) */
+    mtmp->mx = mtmp->my = 0; /* mx==0 implies migating */
 
     /* don't extinguish a mobile light; it still exists but has changed
        from local (monst->mx > 0) to global (mx==0, not on this level) */
index ae234d8b500aeefd701208ed03c319d6a13d3e86..8dbd1eba7bab42950c42dd60157e46ae22f99cc4 100644 (file)
--- a/src/mon.c
+++ b/src/mon.c
@@ -1,4 +1,4 @@
-/* NetHack 3.7 mon.c   $NHDT-Date: 1652478356 2022/05/13 21:45:56 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.426 $ */
+/* NetHack 3.7 mon.c   $NHDT-Date: 1652689648 2022/05/16 08:27:28 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.428 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Derek S. Ray, 2015. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -2310,7 +2310,7 @@ static void
 mon_leaving_level(struct monst *mon)
 {
     int mx = mon->mx, my = mon->my;
-    boolean onmap = (mx > 0 && mon != u.usteed);
+    boolean onmap = (isok(mx, my) && g.level.monsters[mx][my] == mon);
 
     /* to prevent an infinite relobj-flooreffects-hmon-killed loop */
     mon->mtrapped = 0;
@@ -2323,9 +2323,10 @@ mon_leaving_level(struct monst *mon)
         else
             remove_monster(mx, my);
 
-        mon->mx = mon->my = 0; /* off normal map; if caller wants to use
-                                * mon's coordinates after this, it must
-                                * save those before calling us */
+#if 0   /* mustn't do this; too many places assume that the stale
+           monst->mx,my values are still valid */
+        mon->mx = mon->my = 0; /* off normal map */
+#endif
     }
     if (onmap) {
         mon->mundetected = 0; /* for migration; doesn't matter for death */
@@ -2386,13 +2387,9 @@ m_detach(
         leaddead();
     if (mtmp->m_id == g.stealmid)
         thiefdead();
-    /* release (drop onto map) all objects carried by mtmp; first,
-       temporarily restore mtmp's internal location (without actually
-       putting it back on the map) because relobj() relies on that but
-       mon_leaving_level() just cleared that */
-    mtmp->mx = mx, mtmp->my = my;
+    /* release (drop onto map) all objects carried by mtmp; assumes that
+       mtmp->mx,my contains the appropriate location */
     relobj(mtmp, 1, FALSE); /* drop mtmp->minvent, then issue newsym(mx,my) */
-    mtmp->mx = mtmp->my = 0;
 
     if (mtmp->isshk)
         shkgone(mtmp);
@@ -2756,6 +2753,7 @@ mondied(register struct monst* mdef)
     if (!DEADMONSTER(mdef))
         return; /* lifesaved */
 
+    /* this assumes that the dead monster's map coordinates remain accurate */
     if (corpse_chance(mdef, (struct monst *) 0, FALSE)
         && (accessible(mdef->mx, mdef->my) || is_pool(mdef->mx, mdef->my)))
         (void) make_corpse(mdef, CORPSTAT_NONE);
index 188a053f9b526a87859fe4f6c68b3d93a7ab5a5a..fe8ae12b33d75717d54e34f0ae1ddf7433c0fe8e 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.7 worm.c  $NHDT-Date: 1652577033 2022/05/15 01:10:33 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.55 $ */
+/* NetHack 3.7 worm.c  $NHDT-Date: 1652689653 2022/05/16 08:27:33 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.56 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2009. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -317,8 +317,6 @@ wormgone(struct monst *worm)
      *  the hidden tail segment which is co-located with the head.)
      */
     toss_wsegs(wtails[wnum], TRUE);
-    worm->mx = worm->my = 0; /* 'worm' is no longer on map but has not
-                              * been killed off; caller might put it back */
 
     wheads[wnum] = wtails[wnum] = (struct wseg *) 0;
     wgrowtime[wnum] = 0L;
@@ -328,7 +326,7 @@ wormgone(struct monst *worm)
        with MCORPSENM()==PM_LONG_WORM so that the same zap won't trigger
        another polymorph if it hits the new tail */
     if (worm->data == &mons[PM_LONG_WORM] && has_mcorpsenm(worm))
-        MCORPSENM(worm) = NON_PM; /* not polymorph-proof */
+        MCORPSENM(worm) = NON_PM; /* no longer polymorph-proof */
 }
 
 /*