From cba99b52c38b212cd81b5f3e37bebfe0a88aaa7c Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Thu, 15 Mar 2007 05:24:45 +0000 Subject: [PATCH] re-do the #H260 lava fix Instead of duplicating the bits of spoteffects() which are relevant to pools of water and lava when standing still, split spoteffects in two in order to call the relevant half directly. --- include/extern.h | 2 +- src/allmain.c | 2 +- src/hack.c | 148 ++++++++++++++++++++++++----------------------- 3 files changed, 77 insertions(+), 75 deletions(-) diff --git a/include/extern.h b/include/extern.h index 690769faf..6e4bcf533 100644 --- a/include/extern.h +++ b/include/extern.h @@ -776,8 +776,8 @@ E boolean FDECL(invocation_pos, (XCHAR_P,XCHAR_P)); E boolean FDECL(test_move, (int, int, int, int, int)); E void NDECL(domove); E void NDECL(invocation_message); +E boolean FDECL(pooleffects, (BOOLEAN_P)); E void FDECL(spoteffects, (BOOLEAN_P)); -E void NDECL(stayeffects); E char *FDECL(in_rooms, (XCHAR_P,XCHAR_P,int)); E boolean FDECL(in_town, (int,int)); E void FDECL(check_special_room, (BOOLEAN_P)); diff --git a/src/allmain.c b/src/allmain.c index b9d329097..70b975413 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -322,7 +322,7 @@ boolean resuming; !(moves % 15) && !rn2(2)) do_vicinity_map(); if (u.utrap && u.utraptype == TT_LAVA) sink_into_lava(); /* when/if hero escapes from lava, he can't just stay there */ - else if (!u.umoved) stayeffects(); + else if (!u.umoved) (void)pooleffects(FALSE); } /* actual time passed */ diff --git a/src/hack.c b/src/hack.c index d3d51b7f6..2f474f5f5 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1551,6 +1551,80 @@ invocation_message() } } +/* extracted from spoteffects; called by spoteffects to check for entering or + leaving a pool of water/lava, and by moveloop to check for staying on one */ +boolean +pooleffects(newspot) /* returns true to skip rest of spoteffects */ +boolean newspot; /* true if called by spoteffects */ +{ + /* check for leaving water */ + if (u.uinwater) { + boolean still_inwater = FALSE; /* assume we're getting out */ + + if (!is_pool(u.ux,u.uy)) { + if (Is_waterlevel(&u.uz)) + You("pop into an air bubble."); + else if (is_lava(u.ux, u.uy)) + You("leave the water..."); /* oops! */ + else + You("are on solid %s again.", + is_ice(u.ux, u.uy) ? "ice" : "land"); + } else if (Is_waterlevel(&u.uz)) { + still_inwater = TRUE; + } else if (Levitation) { + You("pop out of the water like a cork!"); + } else if (Flying) { + You("fly out of the water."); + } else if (Wwalking) { + You("slowly rise above the surface."); + } else { + still_inwater = TRUE; + } + if (!still_inwater) { + boolean was_underwater = (Underwater && !Is_waterlevel(&u.uz)); + + u.uinwater = 0; /* leave the water */ + if (was_underwater) { /* restore vision */ + docrt(); + vision_full_recalc = 1; + } + } + } + + /* check for entering water or lava */ + if (!u.ustuck && !Levitation && !Flying && + (is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy))) { +#ifdef STEED + if (u.usteed && (is_flyer(u.usteed->data) || + is_floater(u.usteed->data) || is_clinger(u.usteed->data))) { + /* floating or clinging steed keeps hero safe (is_flyer() test + is redundant; it can't be true since Flying yielded false) */ + return FALSE; + } else if (u.usteed) { + /* steed enters pool */ + dismount_steed(Underwater ? DISMOUNT_FELL : DISMOUNT_GENERIC); + /* dismount_steed() -> float_down() -> pickup() + (float_down doesn't do autopickup on Air or Water) */ + if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) return FALSE; + /* even if we actually end up at same location, float_down() + has already done spoteffect()'s trap and pickup actions */ + if (newspot) check_special_room(FALSE); /* spoteffects */ + return TRUE; + } + /* not mounted */ +#endif /* STEED */ + + /* drown(),lava_effects() return true if hero changes + location while surviving the problem */ + if (is_lava(u.ux, u.uy)) { + if (lava_effects()) return TRUE; + } else if (!Wwalking) { + if (drown()) return TRUE; + } + } + return FALSE; +} + void spoteffects(pick) boolean pick; @@ -1577,59 +1651,8 @@ boolean pick; spotterrain = levl[u.ux][u.uy].typ; spotloc.x = u.ux, spotloc.y = u.uy; - if(u.uinwater) { - int was_underwater; + if (pooleffects(TRUE)) goto spotdone; - if (!is_pool(u.ux,u.uy)) { - if (Is_waterlevel(&u.uz)) - You("pop into an air bubble."); - else if (is_lava(u.ux, u.uy)) - You("leave the water..."); /* oops! */ - else - You("are on solid %s again.", - is_ice(u.ux, u.uy) ? "ice" : "land"); - } - else if (Is_waterlevel(&u.uz)) - goto stillinwater; - else if (Levitation) - You("pop out of the water like a cork!"); - else if (Flying) - You("fly out of the water."); - else if (Wwalking) - You("slowly rise above the surface."); - else - goto stillinwater; - was_underwater = Underwater && !Is_waterlevel(&u.uz); - u.uinwater = 0; /* leave the water */ - if (was_underwater) { /* restore vision */ - docrt(); - vision_full_recalc = 1; - } - } -stillinwater:; - if (!Levitation && !u.ustuck && !Flying) { - /* limit recursive calls through teleds() */ - if (is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)) { -#ifdef STEED - if (u.usteed && !is_flyer(u.usteed->data) && - !is_floater(u.usteed->data) && - !is_clinger(u.usteed->data)) { - dismount_steed(Underwater ? - DISMOUNT_FELL : DISMOUNT_GENERIC); - /* dismount_steed() -> float_down() -> pickup() */ - if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz)) - 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()) goto spotdone; - } else if (!Wwalking) { - if (drown()) goto spotdone; - } - } - } check_special_room(FALSE); #ifdef SINKS if(IS_SINK(levl[u.ux][u.uy].typ) && Levitation) @@ -1741,27 +1764,6 @@ stillinwater:; return; } -/* called if hero stays in the same spot while time passes */ -void -stayeffects() -{ - /* leave the trickier cases to spoteffects()... */ - if (u.uinwater) { - if (!is_pool(u.ux, u.uy)) spoteffects(FALSE); - } else if ((is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)) && - !(u.ustuck || Levitation || Flying)) { -#ifdef STEED - if (u.usteed) - spoteffects(FALSE); - else -#endif - if (is_lava(u.ux, u.uy)) - (void)lava_effects(); - else if (!Wwalking) - (void)drown(); - } -} - /* returns first matching monster */ STATIC_OVL struct monst * monstinroom(mdat,roomno)