unhiding during level change
From the newsgroup: if a pet was hiding under an object next to you
when you changed levels, it could arrive hidden at the destination if there
was something available to hide under there too, and sometimes you'd start
the new level with a hidden monster glyph at its location. I was able to
reproduce that once with current trunk code, but while trying to figure
out what is actually happening I've been unable to make it happen again.
However, it doesn't make sense for a monster to be able to remain in hiding
during the level change in the first place, so this patch prevents that.
(I'd still like to know how/why map_invisible() is sometimes getting called.
[The test character was a level 1 tourist without auto-search capability.]
I'm reasonably sure that it won't happen any more once this fix in place.)
This also brings adjacent pets out of hiding when they accompany you
during ascension or dungeon escape, but it seems that that wasn't actually
necessary. The end of game disclosure already lists such by name rather
than as "it", contrary to my expectations. (I had forgotten that end-of-
game forces true names so that blindness and hallucination don't interfere
with disclosure; obviously that ends up handling hidden monsters too.)
This commit is contained in:
@@ -263,6 +263,7 @@ try harder to keep dragged chain between ball and hero
|
||||
fireproof containers should not burn in lava
|
||||
fix invalid pointer dereference after applying a wielded cream pie
|
||||
avoid drowned in a drowning and burned by burning if life-saving is inadequate
|
||||
hidden monsters who change levels come out of hiding in the process
|
||||
|
||||
|
||||
Platform- and/or Interface-Specific Fixes
|
||||
|
||||
@@ -1247,7 +1247,7 @@ E void NDECL(dmonsfree);
|
||||
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 *));
|
||||
|
||||
12
src/dog.c
12
src/dog.c
@@ -1,4 +1,4 @@
|
||||
/* 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. */
|
||||
|
||||
@@ -604,13 +604,10 @@ boolean pets_only; /* true for ascension or final escape */
|
||||
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
|
||||
@@ -660,10 +657,7 @@ migrate_to_level(mtmp, tolev, xyloc, cc)
|
||||
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);
|
||||
|
||||
48
src/mon.c
48
src/mon.c
@@ -1,4 +1,4 @@
|
||||
/* 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. */
|
||||
|
||||
@@ -1297,7 +1297,7 @@ register struct monst *mtmp, *mtmp2;
|
||||
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
|
||||
@@ -1326,22 +1326,48 @@ register struct monst *mtmp, *mtmp2;
|
||||
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);
|
||||
}
|
||||
|
||||
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.");
|
||||
remove_monster(mx, my);
|
||||
|
||||
if (mon == fmon) {
|
||||
fmon = fmon->nmon;
|
||||
} else {
|
||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
|
||||
if (mtmp->nmon == mon) break;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user