From 66dc16b61ff903fcb4972312e73d1d3624a5faf0 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 14 Jul 2022 16:13:47 -0700 Subject: [PATCH] gulpmm "placing over itself" Reported direclty to devteam by a hardfought player: |placing tame fire vortex <56,18> over itself at <56,18>, [...] An old map fixup when an engulfer and its victim temporarily share the same map location got impacted by changes made a month or two back for removing dead or migrated monsters from the map. The old fixup (for putting the engulfer back after removing the victim also removed it) was no longer needed and using it resulted in a warning from place_monster() about putting a monster on top of itself. --- doc/fixes3-7-0.txt | 2 ++ src/mhitm.c | 37 ++++++++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 8aee6bfdd..747f42ed0 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1300,6 +1300,8 @@ save files created with SCORE_ON_BOTL disabled were erroneously being rejected avoid "It suddenly appears!" if a monster with the STRAT_APPEARMSG attribute is seen to teleport away then not seen at its destination avoid boulder-on/in-water sanity_check warnings on the Plane of Water +when one monster swallowed/engulfed another and killed it, impossible + "placing over itself ..." could be given by place_monster() curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/src/mhitm.c b/src/mhitm.c index 613e5ee0d..ca6bf05c1 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -748,8 +748,10 @@ engulf_target(struct monst *magr, struct monst *mdef) /* Returns the same values as mattackm(). */ static int -gulpmm(register struct monst *magr, register struct monst *mdef, - register struct attack *mattk) +gulpmm( + struct monst *magr, + struct monst *mdef, + struct attack *mattk) { coordxy ax, ay, dx, dy; int status; @@ -810,14 +812,31 @@ gulpmm(register struct monst *magr, register struct monst *mdef, ; /* both died -- do nothing */ } else if (status & MM_DEF_DIED) { /* defender died */ /* - * Note: remove_monster() was called in relmon(), wiping out - * magr from level.monsters[mdef->mx][mdef->my]. We need to - * put it back and display it. -kd + * Note: mdamagem() -> monkilled() -> mondead() -> m_detach() + * -> relmon() used to call remove_monster() for the dead + * monster even when it wasn't the one on the map, so we + * needed to put magr back after mdef was killed and removed + * from their shared spot. But now [3.7] relmon() calls + * mon_leaving_level() and that checks whether the monster at + * dying monster's coordinates is that dying monster and only + * removes it when they match. So magr is still at mdef's + * former spot these days. + * + * We still potentially do one fixup: if the gulp targetted + * an inhospitable location, magr will return to its previous + * spot instead of staying. */ - if (!goodpos(dx, dy, magr, MM_IGNOREWATER)) - dx = ax, dy = ay; - place_monster(magr, dx, dy); - newsym(dx, dy); + if (!goodpos(dx, dy, magr, MM_IGNOREWATER)) { + if (m_at(dx, dy) == magr) { + remove_monster(dx, dy); + newsym(dx, dy); + } + dx = ax, dy = ay; /* magr's spot at start of the attack */ + } + if (m_at(dx, dy) != magr) { + place_monster(magr, dx, dy); + newsym(dx, dy); + } /* aggressor moves to and might encounter trouble there */ if (minliquid(magr) || (t_at(dx, dy)