From: PatR Date: Mon, 16 May 2022 08:30:00 +0000 (-0700) Subject: fix github issue #764 - misplaced corpses X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6af5555215b1c1757c0c7e76f055a036dc0c6f13;p=nethack 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 --- diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 536700064..dbe8ff0bb 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -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 diff --git a/src/dog.c b/src/dog.c index e05968d90..ee8e635cc 100644 --- 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) */ diff --git a/src/mon.c b/src/mon.c index ae234d8b5..8dbd1eba7 100644 --- 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); diff --git a/src/worm.c b/src/worm.c index 188a053f9..fe8ae12b3 100644 --- a/src/worm.c +++ b/src/worm.c @@ -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 */ } /*