recursive spoteffects (trunk only)
Attempt to fix a buglist item: if hero poly'd into iron golem form
enters a pool of water and drowning triggers reversion to human/whatever
form due to water damage, he will fall into that pool again, crawl or
teleport out, then redundantly crawl or teleport out for the initial entry.
[ spoteffects -> drown -> losehp -> rehumanize -> polyman -> spoteffects
-> drown ]
I don't have a lot of confidence in this fix. It does handle the
reported problem, and hasn't broken a couple of earlier tricky cases
(ice melting to water, land mine turning into a pit). But drown() and
lava_effects() seem to leave a trail of special case handling wherever
they appear so they--or spoteffects, or both--ought to be redone somehow.
This commit is contained in:
@@ -143,6 +143,8 @@ don't give attribute adjustment messages ("you feel wise") unless the current
|
||||
meditating monsters stop meditating when affected by something which wakes
|
||||
sleeping mosnters
|
||||
monsters capable of hiding can't do so when trapped or while holding you
|
||||
limit recursive calls to spoteffects (poly'd hero fell into water, reverted
|
||||
to human because of it, fell into same water, then crawled out twice)
|
||||
|
||||
|
||||
Platform- and/or Interface-Specific Fixes
|
||||
|
||||
38
src/hack.c
38
src/hack.c
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)hack.c 3.5 2006/04/10 */
|
||||
/* SCCS Id: @(#)hack.c 3.5 2006/05/31 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -1504,10 +1504,28 @@ void
|
||||
spoteffects(pick)
|
||||
boolean pick;
|
||||
{
|
||||
static int inspoteffects = 0;
|
||||
static coord spotloc;
|
||||
static int spotterrain;
|
||||
static struct trap *spottrap = (struct trap *)0;
|
||||
static unsigned spottraptyp = NO_TRAP;
|
||||
struct trap *trap = t_at(u.ux, u.uy);
|
||||
register struct monst *mtmp;
|
||||
|
||||
|
||||
/* prevent recursion from affecting the hero all over again
|
||||
[hero poly'd to iron golem enters water here, drown() inflicts
|
||||
damage that triggers rehumanize() which calls spoteffects()...] */
|
||||
if (inspoteffects && u.ux == spotloc.x && u.uy == spotloc.y &&
|
||||
/* except when reason is transformed terrain (ice -> water) */
|
||||
spotterrain == levl[u.ux][u.uy].typ &&
|
||||
/* or transformed trap (land mine -> pit) */
|
||||
(!spottrap || !trap || trap->ttyp == spottraptyp))
|
||||
return;
|
||||
|
||||
++inspoteffects;
|
||||
spotterrain = levl[u.ux][u.uy].typ;
|
||||
spotloc.x = u.ux, spotloc.y = u.uy;
|
||||
|
||||
if(u.uinwater) {
|
||||
int was_underwater;
|
||||
|
||||
@@ -1552,10 +1570,13 @@ stillinwater:;
|
||||
pick = FALSE;
|
||||
} else
|
||||
#endif
|
||||
/* drown(),lava_effects() return true if hero changes
|
||||
location while surviving the problem */
|
||||
if (is_lava(u.ux, u.uy)) {
|
||||
if (lava_effects()) return;
|
||||
} else if (!Wwalking && drown())
|
||||
return;
|
||||
if (lava_effects()) goto spotdone;
|
||||
} else if (!Wwalking) {
|
||||
if (drown()) goto spotdone;
|
||||
}
|
||||
}
|
||||
}
|
||||
check_special_room(FALSE);
|
||||
@@ -1564,7 +1585,6 @@ stillinwater:;
|
||||
dosinkfall();
|
||||
#endif
|
||||
if (!in_steed_dismounting) { /* if dismounting, we'll check again later */
|
||||
struct trap *trap = t_at(u.ux, u.uy);
|
||||
boolean pit;
|
||||
|
||||
/*
|
||||
@@ -1646,6 +1666,12 @@ stillinwater:;
|
||||
}
|
||||
mnexto(mtmp); /* have to move the monster */
|
||||
}
|
||||
spotdone:
|
||||
if (!--inspoteffects) {
|
||||
spotterrain = STONE; /* 0 */
|
||||
spotloc.x = spotloc.y = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* returns first matching monster */
|
||||
|
||||
Reference in New Issue
Block a user