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 *);
/* 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 */
+ }
}
}