]> granicus.if.org Git - nethack/commitdiff
stop occupation during problem countdown
authornethack.rankin <nethack.rankin>
Tue, 1 Feb 2005 03:46:31 +0000 (03:46 +0000)
committernethack.rankin <nethack.rankin>
Tue, 1 Feb 2005 03:46:31 +0000 (03:46 +0000)
     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?

doc/fixes34.4
include/extern.h
src/eat.c
src/timeout.c

index 30eae353211e075f0d70345111e3caf61abe8b5e..e898b22ebd81eab70ca76180fdd95bef0b72453f 100644 (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
index d42b34ae89a57584281de59f54048e018546f328..6ca4c60929aef9622a40e023ac79a94ea4db8d00 100644 (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 ### */
 
index 9790ba9005978927e9badf2d563efc96dc88fcb3..a4a6c583bc07f4291b38e5546464cd59799325fa 100644 (file)
--- a/src/eat.c
+++ b/src/eat.c
@@ -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*/
index a458ca7d3a7b58ef16935ec9f3ac3d3166e09611..24434a78d2b0ff1ca2c136a6c2657b3a6d6a4296 100644 (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);