more abandoned migrations when entering endgame

The earlier commit just removed monsters from migrating_mons and left
them orphaned.  Also it ignored migrating objects.

Actually release the monsters that can no longer arrive at their
migration destinations.  Release their inventories too.

Release objects that can no longer arrive at migration destinations.
This commit is contained in:
PatR
2022-08-05 16:55:05 -07:00
parent 7a3c11ec6b
commit a84025c36c
3 changed files with 37 additions and 11 deletions

View File

@@ -600,7 +600,7 @@ extern void mon_arrive(struct monst *, int);
extern void mon_catchup_elapsed_time(struct monst *, long);
extern void keepdogs(boolean);
extern void migrate_to_level(struct monst *, coordxy, coordxy, coord *);
extern void discard_migrating_mons(void);
extern void discard_migrations(void);
extern int dogfood(struct monst *, struct obj *);
extern boolean tamedog(struct monst *, struct obj *);
extern void abuse_dog(struct monst *);

View File

@@ -1463,8 +1463,8 @@ goto_level(
/* mark #overview data for all dungeon branches as uninteresting */
for (l_idx = 0; l_idx < g.n_dgns; ++l_idx)
remdun_mapseen(l_idx);
/* get rid of monsters scheduled to migrate to discarded levels */
discard_migrating_mons();
/* get rid of mons & objs scheduled to migrate to discarded levels */
discard_migrations();
}
if (Is_rogue_level(newlevel) || Is_rogue_level(&u.uz))

View File

@@ -845,23 +845,49 @@ migrate_to_level(
/* when entering the endgame, levels from the dungeon and its branches are
discarded because they can't be reached again; do the same for monsters
scheduled to migrate to those levels */
and objects scheduled to migrate to those levels */
void
discard_migrating_mons(void)
discard_migrations(void)
{
struct monst *mtmp, **mprev;
d_level mdest;
struct obj *otmp, **oprev;
d_level dest;
for (mprev = &g.migrating_mons; (mtmp = *mprev) != 0; ) {
mdest.dnum = mtmp->mux;
mdest.dlevel = mtmp->muy;
dest.dnum = mtmp->mux;
dest.dlevel = mtmp->muy;
/* the Wizard is kept regardless of location so that he is
ready to be brought back; nothing should be scheduled to
migrate to the endgame but if we find such, we'll keep it */
if (!mtmp->iswiz && !In_endgame(&mdest))
*mprev = mtmp->nmon; /* remove mtmp from migrating_mons */
else
if (mtmp->iswiz || In_endgame(&dest)) {
mprev = &mtmp->nmon; /* keep mtmp on migrating_mons */
} else {
*mprev = mtmp->nmon; /* remove mtmp from migrating_mons */
mtmp->nmon = 0;
discard_minvent(mtmp, FALSE);
/* bypass mongone() and its call to m_detach() plus dmonsfree() */
dealloc_monst(mtmp);
}
}
/* objects get similar treatment */
for (oprev = &g.migrating_objs; (otmp = *oprev) != 0; ) {
dest.dnum = otmp->ox;
dest.dlevel = otmp->oy;
/* there is no special case like the Wizard (certainly not the
Amulet; the hero has to be carrying it to enter the endgame
which triggers the call to this routine); again we don't
expect any objects to be migrating to the endgame but will
keep any we find so that they could be delivered */
if (In_endgame(&dest)) {
oprev = &otmp->nobj; /* keep otmp on migrating_objs */
} else {
/* bypass obj_extract_self() */
*oprev = otmp->nobj; /* remove otmp from migrating_objs */
otmp->nobj = 0;
otmp->where = OBJ_FREE;
obfree(otmp, (struct obj *) 0); /* releases any contents too */
}
}
}