stop occupation during problem countdown

A user recently complained that he started an activity such as
searching and specified a repeat count, right after getting--and not
realizing the significance of--the first message in the countdown
sequence for turning into stone.  He suggested that subsequent messages
interrupt multi-turn activity so that the player has a chance to do
something to prevent imminent death.  This implements that, with the
added wrinkle that it won't interrupt if the activity is something that
might save the character's life:  attempting to eat a tin that is either
sure to help (if ID'd as food that cures stoning) or a desparate gamble
(if unID'd).  Some hooks for similar behavior for other conditions like
turning into slime are included, although no tins can help for anything
other than petrification so far.

     Shouldn't fatal illness have an end-is-near countdown too?
This commit is contained in:
nethack.rankin
2005-02-01 03:46:31 +00:00
parent 9b27216b2a
commit 191db348ec
4 changed files with 63 additions and 5 deletions

View File

@@ -82,6 +82,7 @@ adding more candles than required to total 7 to a candelabrum which
give correct message when a spellcasting monster summons other monsters
correct experience calculation for monsters that cause nonphysical damage
monsters evading a kick on noteleport levels would cause a "teleports" message
interrupt current activity during certain stages of petrification or vomiting
Platform- and/or Interface-Specific Fixes

View File

@@ -570,6 +570,7 @@ E void FDECL(consume_oeaten, (struct obj *,int));
E boolean FDECL(maybe_finished_meal, (BOOLEAN_P));
E void FDECL(set_tin_variety, (struct obj *,int));
E int FDECL(tin_variety_txt, (char *,int *));
E boolean FDECL(Popeye, (int));
/* ### end.c ### */

View File

@@ -2652,4 +2652,42 @@ boolean stopping;
return FALSE;
}
/* Tin of <something> to the rescue? Decide whether current occupation
is an attempt to eat a tin of something capable of saving hero's life.
We don't care about consumption of non-tinned food here because special
effects there take place on first bite rather than at end of occupation.
[Popeye the Sailor gets out of trouble by eating tins of spinach. :-] */
boolean
Popeye(threat)
int threat;
{
struct obj *otin;
int mndx;
if (occupation != opentin) return FALSE;
otin = context.tin.tin;
/* make sure hero still has access to tin */
if (!carried(otin) && !obj_here(otin, u.ux, u.uy)) return FALSE;
/* unknown tin is assumed to be helpful */
if (!otin->known) return TRUE;
/* known tin is helpful if it will stop life-threatening problem */
mndx = otin->corpsenm;
switch (threat) {
/* note: not used; hunger code bypasses stop_occupation() when eating */
case HUNGER:
return (mndx != NON_PM || otin->spe == 1);
/* flesh from lizards and acidic critters stops petrification */
case STONED:
return (mndx >= LOW_PM && (mndx == PM_LIZARD || acidic(&mons[mndx])));
/* no tins can cure these (yet?) */
case SLIMED:
case SICK:
case VOMITING:
break;
default:
break;
}
return FALSE;
}
/*eat.c*/

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)timeout.c 3.5 2003/11/18 */
/* SCCS Id: @(#)timeout.c 3.5 2005/01/31 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -30,10 +30,24 @@ stoned_dialogue()
if (i > 0L && i <= SIZE(stoned_texts))
pline(stoned_texts[SIZE(stoned_texts) - i]);
if (i == 5L)
switch ((int) i) {
case 5: /* slowing down */
HFast = 0L;
if (i == 3L)
nomul(-3);
if (multi > 0) nomul(0);
break;
case 4: /* limbs stiffening */
/* just one move left to save oneself so quit fiddling around;
don't stop attempt to eat tin--might be lizard or acidic */
if (!Popeye(STONED)) stop_occupation();
if (multi > 0) nomul(0);
break;
case 3: /* limbs turned to stone */
stop_occupation();
nomul(-3); /* can't move anymore */
break;
default:
break;
}
exercise(A_DEX, FALSE);
}
@@ -59,12 +73,16 @@ vomiting_dialogue()
case 0:
vomit();
morehungry(20);
stop_occupation();
if (multi > 0) nomul(0);
break;
case 2:
make_stunned(HStun + d(2,4), FALSE);
if (!Popeye(VOMITING)) stop_occupation();
/* fall through */
case 3:
make_confused(HConfusion + d(2,4), FALSE);
if (multi > 0) nomul(0);
break;
}
exercise(A_CON, FALSE);
@@ -134,7 +152,7 @@ slime_dialogue()
}
if (i == 3L) { /* limbs becoming oozy */
HFast = 0L; /* lose intrinsic speed */
stop_occupation();
if (!Popeye(SLIMED)) stop_occupation();
if (multi > 0) nomul(0);
}
exercise(A_DEX, FALSE);