prayer fix for being in poison gas cloud region
Like stuck-in-wall, there might not be any place to move the hero in order to escape a poison gas cloud. That could result in "fix all troubles" becoming stuck in a loop. 3.6.something fixed the stuck-in-wall case by temporarily conferring Passes_walls. Fix the in-poison-region case by temporarily conferring Magical_breathing. Not adequately tested... I don't think that this fixes "#K4252: NH 3.7 Prayer Bug" where the game hung during a couple out of scores of prayers. I didn't see any other fix-trouble cases that seemed likely to remain unfixed and end up with repair attempts retrying.
This commit is contained in:
+21
-4
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.7 do_wear.c $NHDT-Date: 1720895740 2024/07/13 18:35:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.188 $ */
|
/* NetHack 3.7 do_wear.c $NHDT-Date: 1727251255 2024/09/25 08:00:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.191 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
@@ -940,9 +940,24 @@ Amulet_on(void)
|
|||||||
case AMULET_OF_LIFE_SAVING:
|
case AMULET_OF_LIFE_SAVING:
|
||||||
case AMULET_VERSUS_POISON:
|
case AMULET_VERSUS_POISON:
|
||||||
case AMULET_OF_REFLECTION:
|
case AMULET_OF_REFLECTION:
|
||||||
case AMULET_OF_MAGICAL_BREATHING:
|
|
||||||
case FAKE_AMULET_OF_YENDOR:
|
case FAKE_AMULET_OF_YENDOR:
|
||||||
break;
|
break;
|
||||||
|
case AMULET_OF_MAGICAL_BREATHING: {
|
||||||
|
boolean was_in_poison_gas;
|
||||||
|
|
||||||
|
/* amulet is already on; we need to check hero's gas-cloud status
|
||||||
|
when it was off */
|
||||||
|
EMagical_breathing &= ~W_AMUL;
|
||||||
|
was_in_poison_gas = region_danger();
|
||||||
|
EMagical_breathing |= W_AMUL;
|
||||||
|
if (was_in_poison_gas) {
|
||||||
|
You("are no longer bothered by the poison gas.");
|
||||||
|
makeknown(AMULET_OF_MAGICAL_BREATHING);
|
||||||
|
}
|
||||||
|
/* no need to check for becoming able to breathe underwater;
|
||||||
|
if we are underwater, we already can or we would have drowned */
|
||||||
|
break;
|
||||||
|
}
|
||||||
case AMULET_OF_UNCHANGING:
|
case AMULET_OF_UNCHANGING:
|
||||||
if (Slimed)
|
if (Slimed)
|
||||||
make_slimed(0L, (char *) 0);
|
make_slimed(0L, (char *) 0);
|
||||||
@@ -1039,8 +1054,7 @@ Amulet_off(void)
|
|||||||
break;
|
break;
|
||||||
case AMULET_OF_MAGICAL_BREATHING:
|
case AMULET_OF_MAGICAL_BREATHING:
|
||||||
if (Underwater) {
|
if (Underwater) {
|
||||||
/* HMagical_breathing must be set off
|
/* HMagical_breathing must be set off before calling drown() */
|
||||||
before calling drown() */
|
|
||||||
setworn((struct obj *) 0, W_AMUL);
|
setworn((struct obj *) 0, W_AMUL);
|
||||||
if (!cant_drown(gy.youmonst.data) && !Swimming) {
|
if (!cant_drown(gy.youmonst.data) && !Swimming) {
|
||||||
You("suddenly inhale an unhealthy amount of %s!",
|
You("suddenly inhale an unhealthy amount of %s!",
|
||||||
@@ -1049,6 +1063,9 @@ Amulet_off(void)
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* FIXME: we need a poison gas region check here
|
||||||
|
*/
|
||||||
break;
|
break;
|
||||||
case AMULET_OF_STRANGULATION:
|
case AMULET_OF_STRANGULATION:
|
||||||
if (Strangled) {
|
if (Strangled) {
|
||||||
|
|||||||
+9
-2
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.7 region.c $NHDT-Date: 1723580898 2024/08/13 20:28:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.98 $ */
|
/* NetHack 3.7 region.c $NHDT-Date: 1727251269 2024/09/25 08:01:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.104 $ */
|
||||||
/* Copyright (c) 1996 by Jean-Christophe Collet */
|
/* Copyright (c) 1996 by Jean-Christophe Collet */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -1410,7 +1410,14 @@ region_safety(void)
|
|||||||
|
|
||||||
if (n > 1 || (n == 1 && !r)) {
|
if (n > 1 || (n == 1 && !r)) {
|
||||||
/* multiple overlapping cloud regions or non-expiring one */
|
/* multiple overlapping cloud regions or non-expiring one */
|
||||||
safe_teleds(TELEDS_NO_FLAGS);
|
(void) safe_teleds(TELEDS_NO_FLAGS);
|
||||||
|
/* maybe there's no safe place available; must get hero out of danger
|
||||||
|
or prayer's "fix all troubles" result will get stuck in a loop */
|
||||||
|
if (region_danger()) {
|
||||||
|
set_itimeout(&HMagical_breathing, (long) (d(4, 4) + 4));
|
||||||
|
/* not already Breathless or wouldn't be in region danger */
|
||||||
|
You_feel("able to breathe.");
|
||||||
|
}
|
||||||
} else if (r) {
|
} else if (r) {
|
||||||
remove_region(r);
|
remove_region(r);
|
||||||
pline_The("gas cloud enveloping you dissipates.");
|
pline_The("gas cloud enveloping you dissipates.");
|
||||||
|
|||||||
+39
-3
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.7 timeout.c $NHDT-Date: 1723580900 2024/08/13 20:28:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.190 $ */
|
/* NetHack 3.7 timeout.c $NHDT-Date: 1727251273 2024/09/25 08:01:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.193 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/*-Copyright (c) Robert Patrick Rankin, 2018. */
|
/*-Copyright (c) Robert Patrick Rankin, 2018. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
@@ -56,6 +56,8 @@ static const struct propname {
|
|||||||
/* timed pass-walls is a potential prayer result if surrounded by stone
|
/* timed pass-walls is a potential prayer result if surrounded by stone
|
||||||
with nowhere to be safely teleported to */
|
with nowhere to be safely teleported to */
|
||||||
{ PASSES_WALLS, "pass thru walls" },
|
{ PASSES_WALLS, "pass thru walls" },
|
||||||
|
/* likewise for magical breathing vs poison gas regions */
|
||||||
|
{ MAGICAL_BREATHING, "magical breathing" },
|
||||||
/* timed fire resistance and water walking are possible in explore mode
|
/* timed fire resistance and water walking are possible in explore mode
|
||||||
(as well as in wizard mode) after life-saving in lava if it fails to
|
(as well as in wizard mode) after life-saving in lava if it fails to
|
||||||
teleport the hero to safety and player declines to die */
|
teleport the hero to safety and player declines to die */
|
||||||
@@ -92,7 +94,6 @@ static const struct propname {
|
|||||||
{ TELEPORT_CONTROL, "teleport control" },
|
{ TELEPORT_CONTROL, "teleport control" },
|
||||||
{ FLYING, "flying" },
|
{ FLYING, "flying" },
|
||||||
{ SWIMMING, "swimming" },
|
{ SWIMMING, "swimming" },
|
||||||
{ MAGICAL_BREATHING, "magical breathing" },
|
|
||||||
{ SLOW_DIGESTION, "slow digestion" },
|
{ SLOW_DIGESTION, "slow digestion" },
|
||||||
{ HALF_SPDAM, "half spell damage" },
|
{ HALF_SPDAM, "half spell damage" },
|
||||||
{ HALF_PHDAM, "half physical damage" },
|
{ HALF_PHDAM, "half physical damage" },
|
||||||
@@ -534,7 +535,33 @@ phaze_dialogue(void)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (((HPasses_walls & TIMEOUT) % 2L) && i > 0L && i <= SIZE(phaze_texts))
|
if (((HPasses_walls & TIMEOUT) % 2L) && i > 0L && i <= SIZE(phaze_texts))
|
||||||
pline1(phaze_texts[SIZE(phaze_texts) - i]);
|
pline("%s", phaze_texts[SIZE(phaze_texts) - i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Similar to Passes_walls, if prayer tries to save hero from a poison
|
||||||
|
gas region but can't, (HMagical_breathing & TIMEOUT) will be set to
|
||||||
|
a small value. Unlike Passes_walls, there's no joke message. */
|
||||||
|
static NEARDATA const char *const region_texts[] = {
|
||||||
|
"You seem to have some trouble breathing.",
|
||||||
|
"The air here seems foul.",
|
||||||
|
};
|
||||||
|
|
||||||
|
staticfn void
|
||||||
|
region_dialogue(void)
|
||||||
|
{
|
||||||
|
boolean breathless, in_poison_gas_cloud;
|
||||||
|
long r = (HMagical_breathing & TIMEOUT), i = r / 2L;
|
||||||
|
|
||||||
|
/* might have poly'd into non-breather or moved out of gas cloud */
|
||||||
|
HMagical_breathing &= ~TIMEOUT;
|
||||||
|
breathless = breathless(&mons[u.umonnum]);
|
||||||
|
in_poison_gas_cloud = region_danger();
|
||||||
|
HMagical_breathing |= r;
|
||||||
|
if (breathless || !in_poison_gas_cloud)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((r % 2L) && i > 0L && i <= SIZE(region_texts))
|
||||||
|
pline("%s", region_texts[SIZE(region_texts) - i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* when a status timeout is fatal, keep the status line indicator shown
|
/* when a status timeout is fatal, keep the status line indicator shown
|
||||||
@@ -600,6 +627,8 @@ nh_timeout(void)
|
|||||||
levitation_dialogue();
|
levitation_dialogue();
|
||||||
if (HPasses_walls & TIMEOUT)
|
if (HPasses_walls & TIMEOUT)
|
||||||
phaze_dialogue();
|
phaze_dialogue();
|
||||||
|
if (HMagical_breathing & TIMEOUT)
|
||||||
|
region_dialogue();
|
||||||
if (HSleepy & TIMEOUT)
|
if (HSleepy & TIMEOUT)
|
||||||
sleep_dialogue();
|
sleep_dialogue();
|
||||||
if (u.mtimedone && !--u.mtimedone) {
|
if (u.mtimedone && !--u.mtimedone) {
|
||||||
@@ -844,6 +873,13 @@ nh_timeout(void)
|
|||||||
!Upolyd ? "normal" : "unusual");
|
!Upolyd ? "normal" : "unusual");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MAGICAL_BREATHING:
|
||||||
|
if (!Breathless) {
|
||||||
|
if (region_danger())
|
||||||
|
You("cough%s",
|
||||||
|
Poison_resistance ? "." : " and spit blood!");
|
||||||
|
}
|
||||||
|
break;
|
||||||
case STRANGLED:
|
case STRANGLED:
|
||||||
svk.killer.format = KILLED_BY;
|
svk.killer.format = KILLED_BY;
|
||||||
Strcpy(svk.killer.name,
|
Strcpy(svk.killer.name,
|
||||||
|
|||||||
Reference in New Issue
Block a user