fix #H7530 - corpse from corpseless monster
Migrating monster attempting to arrive on a level which is already full of monsters gets killed off. It was leaving a corpse without regard for whether it was a type of of monster which should never leave corpses. I'd prefer that it be put back on the migrating_mons list rather than be killed off, but this just suppresses impossible corpses.
This commit is contained in:
@@ -202,6 +202,9 @@ a stale gold symbol could be displayed on the status line following a switch
|
||||
to a new symset, as observed and reported for Windows RogueEpyx symset
|
||||
successfully paying for shop damage with shop credit would be followed by
|
||||
impossible "zero payment in money2mon"
|
||||
if a migrating monster was killed off because there was no room on the
|
||||
destination level, it would leave a corpse even if it was a type
|
||||
which should never leave one (demon, golem, blob, &c)
|
||||
|
||||
|
||||
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
|
||||
|
||||
26
src/dog.c
26
src/dog.c
@@ -7,6 +7,11 @@
|
||||
|
||||
STATIC_DCL int NDECL(pet_type);
|
||||
|
||||
/* cloned from mon.c; used here if mon_arrive() can't place mon */
|
||||
#define LEVEL_SPECIFIC_NOCORPSE(mdat) \
|
||||
(Is_rogue_level(&u.uz) \
|
||||
|| (level.flags.graveyard && is_undead(mdat) && rn2(3)))
|
||||
|
||||
void
|
||||
newedog(mtmp)
|
||||
struct monst *mtmp;
|
||||
@@ -79,6 +84,7 @@ boolean quietly;
|
||||
do {
|
||||
if (otmp) { /* figurine; otherwise spell */
|
||||
int mndx = otmp->corpsenm;
|
||||
|
||||
pm = &mons[mndx];
|
||||
/* activating a figurine provides one way to exceed the
|
||||
maximum number of the target critter created--unless
|
||||
@@ -294,6 +300,7 @@ struct monst *mtmp;
|
||||
boolean with_you;
|
||||
{
|
||||
struct trap *t;
|
||||
struct obj *obj;
|
||||
xchar xlocale, ylocale, xyloc, xyflags, wander;
|
||||
int num_segs;
|
||||
|
||||
@@ -417,8 +424,10 @@ boolean with_you;
|
||||
/* monster moved a bit; pick a nearby location */
|
||||
/* mnearto() deals w/stone, et al */
|
||||
char *r = in_rooms(xlocale, ylocale, 0);
|
||||
|
||||
if (r && *r) {
|
||||
coord c;
|
||||
|
||||
/* somexy() handles irregular rooms */
|
||||
if (somexy(&rooms[*r - ROOMOFFSET], &c))
|
||||
xlocale = c.x, ylocale = c.y;
|
||||
@@ -426,6 +435,7 @@ boolean with_you;
|
||||
xlocale = ylocale = 0;
|
||||
} else { /* not in a room */
|
||||
int i, j;
|
||||
|
||||
i = max(1, xlocale - wander);
|
||||
j = min(COLNO - 1, xlocale + wander);
|
||||
xlocale = rn1(j - i, i);
|
||||
@@ -446,8 +456,11 @@ boolean with_you;
|
||||
* Failed to place migrating monster,
|
||||
* probably because the level is full.
|
||||
* Dump the monster's cargo and leave the monster dead.
|
||||
*
|
||||
* TODO? Put back on migrating_mons list instead so
|
||||
* that if hero leaves this level and then returns,
|
||||
* monster will have another chance to arrive.
|
||||
*/
|
||||
struct obj *obj;
|
||||
fail_mon_placement:
|
||||
while ((obj = mtmp->minvent) != 0) {
|
||||
obj_extract_self(obj);
|
||||
@@ -462,8 +475,15 @@ fail_mon_placement:
|
||||
impossible("Can't find relocated object.");
|
||||
}
|
||||
}
|
||||
(void) mkcorpstat(CORPSE, (struct monst *) 0, mtmp->data, xlocale,
|
||||
ylocale, CORPSTAT_NONE);
|
||||
/*
|
||||
* TODO? Maybe switch to make_corpse() [won't be needed if
|
||||
* we re-migrate as suggested above], probably with new
|
||||
* CORPSTAT_NOOBJS flag to suppress dragon scales and such.
|
||||
*/
|
||||
if (!(mvitals[monsndx(mtmp->data)].mvflags & G_NOCORPSE)
|
||||
&& !LEVEL_SPECIFIC_NOCORPSE(mtmp->data))
|
||||
(void) mkcorpstat(CORPSE, mtmp, mtmp->data,
|
||||
xlocale, ylocale, CORPSTAT_NONE);
|
||||
mtmp->mx = mtmp->my = -1; /* for mongone, mon is not anywhere */
|
||||
mongone(mtmp);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ STATIC_DCL struct obj *FDECL(make_corpse, (struct monst *, unsigned));
|
||||
STATIC_DCL void FDECL(m_detach, (struct monst *, struct permonst *));
|
||||
STATIC_DCL void FDECL(lifesaved_monster, (struct monst *));
|
||||
|
||||
/* note: duplicated in dog.c */
|
||||
#define LEVEL_SPECIFIC_NOCORPSE(mdat) \
|
||||
(Is_rogue_level(&u.uz) \
|
||||
|| (level.flags.graveyard && is_undead(mdat) && rn2(3)))
|
||||
@@ -446,7 +447,8 @@ unsigned corpseflags;
|
||||
}
|
||||
/* All special cases should precede the G_NOCORPSE check */
|
||||
|
||||
if (!obj) return NULL;
|
||||
if (!obj)
|
||||
return (struct obj *) 0;
|
||||
|
||||
/* if polymorph or undead turning has killed this monster,
|
||||
prevent the same attack beam from hitting its corpse */
|
||||
|
||||
Reference in New Issue
Block a user