diff --git a/include/extern.h b/include/extern.h index 96fa68f13..43488aa24 100644 --- a/include/extern.h +++ b/include/extern.h @@ -600,6 +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 int dogfood(struct monst *, struct obj *); extern boolean tamedog(struct monst *, struct obj *); extern void abuse_dog(struct monst *); diff --git a/src/do.c b/src/do.c index 8bb2aab5b..5daeecbd5 100644 --- a/src/do.c +++ b/src/do.c @@ -1463,6 +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(); } if (Is_rogue_level(newlevel) || Is_rogue_level(&u.uz)) diff --git a/src/dog.c b/src/dog.c index 064cbd1a5..a984f03db 100644 --- a/src/dog.c +++ b/src/dog.c @@ -843,6 +843,28 @@ migrate_to_level( vision_recalc(0); } +/* 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 */ +void +discard_migrating_mons(void) +{ + struct monst *mtmp, **mprev; + d_level mdest; + + for (mprev = &g.migrating_mons; (mtmp = *mprev) != 0; ) { + mdest.dnum = mtmp->mux; + mdest.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 + mprev = &mtmp->nmon; /* keep mtmp on migrating_mons */ + } +} + /* return quality of food; the lower the better */ /* fungi will eat even tainted food */ int