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
|
to a new symset, as observed and reported for Windows RogueEpyx symset
|
||||||
successfully paying for shop damage with shop credit would be followed by
|
successfully paying for shop damage with shop credit would be followed by
|
||||||
impossible "zero payment in money2mon"
|
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
|
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
|
||||||
|
|||||||
@@ -7,6 +7,11 @@
|
|||||||
|
|
||||||
STATIC_DCL int NDECL(pet_type);
|
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
|
void
|
||||||
newedog(mtmp)
|
newedog(mtmp)
|
||||||
struct monst *mtmp;
|
struct monst *mtmp;
|
||||||
@@ -79,6 +84,7 @@ boolean quietly;
|
|||||||
do {
|
do {
|
||||||
if (otmp) { /* figurine; otherwise spell */
|
if (otmp) { /* figurine; otherwise spell */
|
||||||
int mndx = otmp->corpsenm;
|
int mndx = otmp->corpsenm;
|
||||||
|
|
||||||
pm = &mons[mndx];
|
pm = &mons[mndx];
|
||||||
/* activating a figurine provides one way to exceed the
|
/* activating a figurine provides one way to exceed the
|
||||||
maximum number of the target critter created--unless
|
maximum number of the target critter created--unless
|
||||||
@@ -294,6 +300,7 @@ struct monst *mtmp;
|
|||||||
boolean with_you;
|
boolean with_you;
|
||||||
{
|
{
|
||||||
struct trap *t;
|
struct trap *t;
|
||||||
|
struct obj *obj;
|
||||||
xchar xlocale, ylocale, xyloc, xyflags, wander;
|
xchar xlocale, ylocale, xyloc, xyflags, wander;
|
||||||
int num_segs;
|
int num_segs;
|
||||||
|
|
||||||
@@ -417,8 +424,10 @@ boolean with_you;
|
|||||||
/* monster moved a bit; pick a nearby location */
|
/* monster moved a bit; pick a nearby location */
|
||||||
/* mnearto() deals w/stone, et al */
|
/* mnearto() deals w/stone, et al */
|
||||||
char *r = in_rooms(xlocale, ylocale, 0);
|
char *r = in_rooms(xlocale, ylocale, 0);
|
||||||
|
|
||||||
if (r && *r) {
|
if (r && *r) {
|
||||||
coord c;
|
coord c;
|
||||||
|
|
||||||
/* somexy() handles irregular rooms */
|
/* somexy() handles irregular rooms */
|
||||||
if (somexy(&rooms[*r - ROOMOFFSET], &c))
|
if (somexy(&rooms[*r - ROOMOFFSET], &c))
|
||||||
xlocale = c.x, ylocale = c.y;
|
xlocale = c.x, ylocale = c.y;
|
||||||
@@ -426,6 +435,7 @@ boolean with_you;
|
|||||||
xlocale = ylocale = 0;
|
xlocale = ylocale = 0;
|
||||||
} else { /* not in a room */
|
} else { /* not in a room */
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
i = max(1, xlocale - wander);
|
i = max(1, xlocale - wander);
|
||||||
j = min(COLNO - 1, xlocale + wander);
|
j = min(COLNO - 1, xlocale + wander);
|
||||||
xlocale = rn1(j - i, i);
|
xlocale = rn1(j - i, i);
|
||||||
@@ -446,8 +456,11 @@ boolean with_you;
|
|||||||
* Failed to place migrating monster,
|
* Failed to place migrating monster,
|
||||||
* probably because the level is full.
|
* probably because the level is full.
|
||||||
* Dump the monster's cargo and leave the monster dead.
|
* 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:
|
fail_mon_placement:
|
||||||
while ((obj = mtmp->minvent) != 0) {
|
while ((obj = mtmp->minvent) != 0) {
|
||||||
obj_extract_self(obj);
|
obj_extract_self(obj);
|
||||||
@@ -462,8 +475,15 @@ fail_mon_placement:
|
|||||||
impossible("Can't find relocated object.");
|
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 */
|
mtmp->mx = mtmp->my = -1; /* for mongone, mon is not anywhere */
|
||||||
mongone(mtmp);
|
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(m_detach, (struct monst *, struct permonst *));
|
||||||
STATIC_DCL void FDECL(lifesaved_monster, (struct monst *));
|
STATIC_DCL void FDECL(lifesaved_monster, (struct monst *));
|
||||||
|
|
||||||
|
/* note: duplicated in dog.c */
|
||||||
#define LEVEL_SPECIFIC_NOCORPSE(mdat) \
|
#define LEVEL_SPECIFIC_NOCORPSE(mdat) \
|
||||||
(Is_rogue_level(&u.uz) \
|
(Is_rogue_level(&u.uz) \
|
||||||
|| (level.flags.graveyard && is_undead(mdat) && rn2(3)))
|
|| (level.flags.graveyard && is_undead(mdat) && rn2(3)))
|
||||||
@@ -446,7 +447,8 @@ unsigned corpseflags;
|
|||||||
}
|
}
|
||||||
/* All special cases should precede the G_NOCORPSE check */
|
/* 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,
|
/* if polymorph or undead turning has killed this monster,
|
||||||
prevent the same attack beam from hitting its corpse */
|
prevent the same attack beam from hitting its corpse */
|
||||||
|
|||||||
Reference in New Issue
Block a user