From c3e5aaf8ba4c473f38a69eecea9d74977357ffdd Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 3 Oct 2021 14:15:02 -0700 Subject: [PATCH] displacer monster vs long worm Reported directly to devteam: monster vs monster location swapping didn't handle single-segment long worms properly. Multi-segment worms are disallowed but a worm with no visible segments (which actually has 1 segment at the head's location) are allowed and the segment wasn't being moved with the core monster and could trigger warnings if sanity checking is enabled. The next time that the worm moved, it got itself back in synch. I couldn't reproduce the warning but mdisplacem() clearly assumed that a long worm reporting 0 segments didn't have any so wasn't attempting to handle the hidden one. --- doc/fixes37.0 | 4 ++++ src/mhitm.c | 13 +++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index b2d17af47..8b766ebb2 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -630,6 +630,10 @@ obj->o_id might be set to invalid value 0 when a partly used up stack had a dummy copy added to a shop's bill or when a bones file was loaded (in theory that could happen on any system but in practice it could only happen on a configuration that uses 16-bit ints) +if a Rider or displacer beast swapped places with a single-segment long worm + the segment co-located with the head wasn't moved with that head; + if sanity_checking was enabled a warning could be triggered: + mon (000000) at seg location is not worm (123abc) Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/mhitm.c b/src/mhitm.c index 4f09298f9..11787acad 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -243,13 +243,22 @@ mdisplacem(register struct monst *magr, register struct monst *mdef, } remove_monster(fx, fy); /* pick up from orig position */ - remove_monster(tx, ty); + if (mdef->wormno) + remove_worm(mdef); + else + remove_monster(tx, ty); place_monster(magr, tx, ty); /* put down at target spot */ place_monster(mdef, fx, fy); + if (mdef->wormno) /* now put down tail */ + place_worm_tail_randomly(mdef, fx, fy); + /* either creature might move into or out of a poison gas cloud */ + update_monster_region(magr); + update_monster_region(mdef); + if (g.vis && !quietly) pline("%s moves %s out of %s way!", Monnam(magr), mon_nam(mdef), is_rider(pa) ? "the" : mhis(magr)); - newsym(fx, fy); /* see it */ + newsym(fx, fy); /* see it */ newsym(tx, ty); /* all happen */ flush_screen(0); /* make sure it shows up */