E int FDECL(mcalcmove, (struct monst*));
E void NDECL(mcalcdistress);
E void FDECL(replmon, (struct monst *,struct monst *));
-E void FDECL(relmon, (struct monst *));
+E void FDECL(relmon, (struct monst *,struct monst **));
E struct obj *FDECL(mlifesaver, (struct monst *));
E boolean FDECL(corpse_chance,(struct monst *,struct monst *,BOOLEAN_P));
E void FDECL(mondead, (struct monst *));
-/* SCCS Id: @(#)dog.c 3.5 2006/06/11 */
+/* SCCS Id: @(#)dog.c 3.5 2006/10/20 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
obj->no_charge = 0;
}
- relmon(mtmp);
- newsym(mtmp->mx,mtmp->my);
+ relmon(mtmp, &mydogs); /* move it from map to mydogs */
mtmp->mx = mtmp->my = 0; /* avoid mnexto()/MON_AT() problem */
mtmp->wormno = num_segs;
mtmp->mlstmv = monstermoves;
- mtmp->nmon = mydogs;
- mydogs = mtmp;
} else if (mtmp->iswiz) {
/* we want to be able to find him when his next resurrection
chance comes up, but have him resume his present location
mtmp->mtame--;
m_unleash(mtmp, TRUE);
}
- relmon(mtmp);
- mtmp->nmon = migrating_mons;
- migrating_mons = mtmp;
- newsym(mtmp->mx,mtmp->my);
+ relmon(mtmp, &migrating_mons); /* move it from map to migrating_mons */
new_lev.dnum = ledger_to_dnum((xchar)tolev);
new_lev.dlevel = ledger_to_dlev((xchar)tolev);
-/* SCCS Id: @(#)mon.c 3.5 2006/09/06 */
+/* SCCS Id: @(#)mon.c 3.5 2006/10/20 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
mtmp->minvent = 0;
/* remove the old monster from the map and from `fmon' list */
- relmon(mtmp);
+ relmon(mtmp, (struct monst **)0);
/* finish adding its replacement */
#ifdef STEED
dealloc_monst(mtmp);
}
-/* release mon from display and monster list */
+/* release mon from the display and the map's monster list,
+ maybe transfer it to one of the other monster lists */
void
-relmon(mon)
+relmon(mon, monst_list)
register struct monst *mon;
+struct monst **monst_list; /* &migrating_mons or &mydogs or null */
{
register struct monst *mtmp;
+ boolean unhide = (monst_list != 0);
+ int mx = mon->mx, my = mon->my;
- if (fmon == (struct monst *)0) panic ("relmon: no fmon available.");
+ if (!fmon) panic("relmon: no fmon available.");
- remove_monster(mon->mx, mon->my);
+ if (unhide) {
+ /* can't remain hidden across level changes (exception: wizard
+ clone can continue imitating some other monster form); also,
+ might be imitating a boulder so need line-of-sight unblocking */
+ mon->mundetected = 0;
+ if (mon->m_ap_type && mon->m_ap_type != M_AP_MONSTER)
+ seemimic(mon);
+ }
+
+ remove_monster(mx, my);
+
+ if (mon == fmon) {
+ fmon = fmon->nmon;
+ } else {
+ for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
+ if (mtmp->nmon == mon) break;
- if(mon == fmon) fmon = fmon->nmon;
- else {
- for(mtmp = fmon; mtmp && mtmp->nmon != mon; mtmp = mtmp->nmon) ;
- if(mtmp) mtmp->nmon = mon->nmon;
- else panic("relmon: mon not in list.");
+ if (mtmp) mtmp->nmon = mon->nmon;
+ else panic("relmon: mon not in list.");
+ }
+
+ if (unhide) {
+ newsym(mx, my);
+ /* insert into mydogs or migrating_mons */
+ mon->nmon = *monst_list;
+ *monst_list = mon;
+ } else {
+ /* orphan has no next monster */
+ mon->nmon = 0;
}
}