fix github issue #764 - misplaced corpses

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
This commit is contained in:
PatR
2022-05-16 01:30:00 -07:00
parent c8ceeac24e
commit 6af5555215
4 changed files with 23 additions and 24 deletions
+3 -1
View 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 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 when shopkeeper who left shop got returned to it
recent changes in removing a dead monster from the map didn't update screen 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 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 curses: 'msg_window' option wasn't functional for curses unless the binary
also included tty support also included tty support
+9 -8
View File
@@ -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) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */ /* 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; /* if this is a long worm, handle its tail segments before mtmp itself;
we pass possibly trundated segment count to caller via return value */ we pass possibly trundated segment count to caller via return value */
if (mtmp->wormno) { 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 /* since monst->wormno is overloaded to hold the number of
tail segments during migration, a very long worm with tail segments during migration, a very long worm with
more segments than can fit in that field gets truncated */ more segments than can fit in that field gets truncated */
num_segs = min(cnt, MAX_NUM_WORMS - 1); num_segs = min(cnt, MAX_NUM_WORMS - 1);
wormgone(mtmp); /* discard tail segments, take head off map */ wormgone(mtmp);
/* mtmp->mx,mtmp->my is now 0,0 */ /* put the head back */
place_monster(mtmp, mx, my);
} }
return num_segs; return num_segs;
@@ -691,7 +692,8 @@ keepdogs(
/* prepare to take mtmp off the map */ /* prepare to take mtmp off the map */
num_segs = mon_leave(mtmp); num_segs = mon_leave(mtmp);
/* take off map and move mtmp from fmon list to mydogs */ /* 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->wormno = num_segs;
mtmp->mlstmv = g.moves; mtmp->mlstmv = g.moves;
} else if (mtmp->iswiz) { } else if (mtmp->iswiz) {
@@ -728,7 +730,7 @@ migrate_to_level(
/* prepare to take mtmp off the map */ /* prepare to take mtmp off the map */
num_segs = mon_leave(mtmp); num_segs = mon_leave(mtmp);
/* take off map and move mtmp from fmon list to migrating_mons */ /* 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; mtmp->mstate |= MON_MIGRATING;
new_lev.dnum = ledger_to_dnum((xchar) tolev); new_lev.dnum = ledger_to_dnum((xchar) tolev);
@@ -748,8 +750,7 @@ migrate_to_level(
mtmp->mtrack[0].y = xyflags; mtmp->mtrack[0].y = xyflags;
mtmp->mux = new_lev.dnum; mtmp->mux = new_lev.dnum;
mtmp->muy = new_lev.dlevel; mtmp->muy = new_lev.dlevel;
mtmp->mx = mtmp->my = 0; /* this implies migration (note: already done mtmp->mx = mtmp->my = 0; /* mx==0 implies migating */
* by relmon() -> mon_leaving_level() above) */
/* don't extinguish a mobile light; it still exists but has changed /* 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) */ from local (monst->mx > 0) to global (mx==0, not on this level) */
+9 -11
View File
@@ -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) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */ /*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -2310,7 +2310,7 @@ static void
mon_leaving_level(struct monst *mon) mon_leaving_level(struct monst *mon)
{ {
int mx = mon->mx, my = mon->my; 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 */ /* to prevent an infinite relobj-flooreffects-hmon-killed loop */
mon->mtrapped = 0; mon->mtrapped = 0;
@@ -2323,9 +2323,10 @@ mon_leaving_level(struct monst *mon)
else else
remove_monster(mx, my); remove_monster(mx, my);
mon->mx = mon->my = 0; /* off normal map; if caller wants to use #if 0 /* mustn't do this; too many places assume that the stale
* mon's coordinates after this, it must monst->mx,my values are still valid */
* save those before calling us */ mon->mx = mon->my = 0; /* off normal map */
#endif
} }
if (onmap) { if (onmap) {
mon->mundetected = 0; /* for migration; doesn't matter for death */ mon->mundetected = 0; /* for migration; doesn't matter for death */
@@ -2386,13 +2387,9 @@ m_detach(
leaddead(); leaddead();
if (mtmp->m_id == g.stealmid) if (mtmp->m_id == g.stealmid)
thiefdead(); thiefdead();
/* release (drop onto map) all objects carried by mtmp; first, /* release (drop onto map) all objects carried by mtmp; assumes that
temporarily restore mtmp's internal location (without actually mtmp->mx,my contains the appropriate location */
putting it back on the map) because relobj() relies on that but
mon_leaving_level() just cleared that */
mtmp->mx = mx, mtmp->my = my;
relobj(mtmp, 1, FALSE); /* drop mtmp->minvent, then issue newsym(mx,my) */ relobj(mtmp, 1, FALSE); /* drop mtmp->minvent, then issue newsym(mx,my) */
mtmp->mx = mtmp->my = 0;
if (mtmp->isshk) if (mtmp->isshk)
shkgone(mtmp); shkgone(mtmp);
@@ -2756,6 +2753,7 @@ mondied(register struct monst* mdef)
if (!DEADMONSTER(mdef)) if (!DEADMONSTER(mdef))
return; /* lifesaved */ return; /* lifesaved */
/* this assumes that the dead monster's map coordinates remain accurate */
if (corpse_chance(mdef, (struct monst *) 0, FALSE) if (corpse_chance(mdef, (struct monst *) 0, FALSE)
&& (accessible(mdef->mx, mdef->my) || is_pool(mdef->mx, mdef->my))) && (accessible(mdef->mx, mdef->my) || is_pool(mdef->mx, mdef->my)))
(void) make_corpse(mdef, CORPSTAT_NONE); (void) make_corpse(mdef, CORPSTAT_NONE);
+2 -4
View 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) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2009. */ /*-Copyright (c) Robert Patrick Rankin, 2009. */
/* NetHack may be freely redistributed. See license for details. */ /* 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.) * the hidden tail segment which is co-located with the head.)
*/ */
toss_wsegs(wtails[wnum], TRUE); 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; wheads[wnum] = wtails[wnum] = (struct wseg *) 0;
wgrowtime[wnum] = 0L; wgrowtime[wnum] = 0L;
@@ -328,7 +326,7 @@ wormgone(struct monst *worm)
with MCORPSENM()==PM_LONG_WORM so that the same zap won't trigger with MCORPSENM()==PM_LONG_WORM so that the same zap won't trigger
another polymorph if it hits the new tail */ another polymorph if it hits the new tail */
if (worm->data == &mons[PM_LONG_WORM] && has_mcorpsenm(worm)) 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 */
} }
/* /*