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.
This commit is contained in:
PatR
2021-10-03 14:15:02 -07:00
parent 5a652b0478
commit c3e5aaf8ba
2 changed files with 15 additions and 2 deletions

View File

@@ -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

View File

@@ -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 */