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
|
meditating monsters stop meditating when affected by something which wakes
|
||||||
sleeping mosnters
|
sleeping mosnters
|
||||||
monsters capable of hiding can't do so when trapped or while holding you
|
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
|
Platform- and/or Interface-Specific Fixes
|
||||||
|
|||||||
+32
-6
@@ -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. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -1504,10 +1504,28 @@ void
|
|||||||
spoteffects(pick)
|
spoteffects(pick)
|
||||||
boolean pick;
|
boolean pick;
|
||||||
{
|
{
|
||||||
|
static int inspoteffects = 0;
|
||||||
|
static coord spotloc;
|
||||||
|
static int spotterrain;
|
||||||
static struct trap *spottrap = (struct trap *)0;
|
static struct trap *spottrap = (struct trap *)0;
|
||||||
static unsigned spottraptyp = NO_TRAP;
|
static unsigned spottraptyp = NO_TRAP;
|
||||||
|
struct trap *trap = t_at(u.ux, u.uy);
|
||||||
register struct monst *mtmp;
|
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) {
|
if(u.uinwater) {
|
||||||
int was_underwater;
|
int was_underwater;
|
||||||
|
|
||||||
@@ -1552,10 +1570,13 @@ stillinwater:;
|
|||||||
pick = FALSE;
|
pick = FALSE;
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
|
/* drown(),lava_effects() return true if hero changes
|
||||||
|
location while surviving the problem */
|
||||||
if (is_lava(u.ux, u.uy)) {
|
if (is_lava(u.ux, u.uy)) {
|
||||||
if (lava_effects()) return;
|
if (lava_effects()) goto spotdone;
|
||||||
} else if (!Wwalking && drown())
|
} else if (!Wwalking) {
|
||||||
return;
|
if (drown()) goto spotdone;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
check_special_room(FALSE);
|
check_special_room(FALSE);
|
||||||
@@ -1564,7 +1585,6 @@ stillinwater:;
|
|||||||
dosinkfall();
|
dosinkfall();
|
||||||
#endif
|
#endif
|
||||||
if (!in_steed_dismounting) { /* if dismounting, we'll check again later */
|
if (!in_steed_dismounting) { /* if dismounting, we'll check again later */
|
||||||
struct trap *trap = t_at(u.ux, u.uy);
|
|
||||||
boolean pit;
|
boolean pit;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1646,6 +1666,12 @@ stillinwater:;
|
|||||||
}
|
}
|
||||||
mnexto(mtmp); /* have to move the monster */
|
mnexto(mtmp); /* have to move the monster */
|
||||||
}
|
}
|
||||||
|
spotdone:
|
||||||
|
if (!--inspoteffects) {
|
||||||
|
spotterrain = STONE; /* 0 */
|
||||||
|
spotloc.x = spotloc.y = 0;
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns first matching monster */
|
/* returns first matching monster */
|
||||||
|
|||||||
Reference in New Issue
Block a user