]> granicus.if.org Git - nethack/commitdiff
wounded legs fixes
authorPatR <rankin@nethack.org>
Mon, 3 Jan 2022 21:44:05 +0000 (13:44 -0800)
committerPatR <rankin@nethack.org>
Mon, 3 Jan 2022 21:44:05 +0000 (13:44 -0800)
Document 'HWounded_legs' vs 'EWounded_legs'; they aren't used the way
other properties use their intrinsic and extrinsic values.  And they
switch from hero to steed when riding.  (Can't start riding when
hero's legs are wounded and the steed's legs magically heal when hero
dismounts, so existing wounds never transfer from one to the other.)

Having one leg become injured when the other already was would cure
the other leg but keep the longer of their two timeouts for the new
injury.  Eliminate that mystery cure.  Since their timeouts aren't
tracked separately, the best that can be done is to make both legs
eventually recover at the same time.

Make ^X report which leg is the wounded one when only one of them is.
(It already implicitly reports the both-legs case by using plural.)

When zapping a wand of probing downward while riding, include wounded
leg feedback for the steed.

Simplify wounded leg feedback when probing self a little bit.

Make drinking blessed potions of full healing cure wounded legs for
hero when not mounted or for steed when mounted.  (The latter is a
bit strange--hero drinks potion, steed gets affected--but it's magic.)

Make drinking uncursed potions of full healing or blessed potions of
extra healing cure wounded legs for hero (but not steed; the magic
either isn't that strong or maybe not that reliable...).

doc/fixes37.0
include/youprop.h
src/do.c
src/insight.c
src/potion.c

index 7e5a24e18b1d40792cc91970af5ad4f96dce30d4..885b9cd01dc61859a0d168c8594a4b24b8003543 100644 (file)
@@ -729,6 +729,10 @@ allow fire-command to automatically use a polearm, if wielding it
 make '$' command also count gold carried inside containers
 fleeing leprechauns bury their gold after teleporting
 allow #tipping container contents directly into another container
+when one leg is wounded, have ^X report which (already used plural if both)
+wand of probing used on steed ('z >') didn't include wounded leg(s) feedback
+getting wounded in one leg when the other was already wounded miraculously
+       healed old leg and kept longer of their recovery timeouts for new one
 
 
 Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
@@ -1312,6 +1316,10 @@ track peak maximum HP and peak maximum energy/power; no noticeable effect
 give some dragon armor extra effects when worn
 issue messages during last stage of food poisoning/terminal illness countdown
        when hero's demise is imminent
+drinking blessed potion of full healing heals wounded legs, either hero's or
+       steed's (when riding, wounded leg injury applies to steed, not hero)
+drinking uncursed potion of full healing or blessed potion of extra healing
+       heal hero's wounded legs when not riding; no effect on steed if riding
 
 
 Platform- and/or Interface-Specific New Features
index 60ed6af5790d1432edd2b08328794f883d1d64c4..a8c6488c8e07222fe6b429b815e7007944fc3c33 100644 (file)
 #define EFumbling u.uprops[FUMBLING].extrinsic
 #define Fumbling (HFumbling || EFumbling)
 
+/* HWounded_legs indicates whether wounded leg(s) condition exists and
+   holds the timeout for recovery; EWounded_legs uses the worn-ring bits
+   to track left vs right vs both and is meaningless when HWounded_legs
+   is zero; both values apply to steed rather than to hero when riding */
 #define HWounded_legs u.uprops[WOUNDED_LEGS].intrinsic
 #define EWounded_legs u.uprops[WOUNDED_LEGS].extrinsic
-#define Wounded_legs (HWounded_legs || EWounded_legs)
+#define Wounded_legs (HWounded_legs) /* (don't include EWounded_legs here) */
 
 #define HSleepy u.uprops[SLEEPY].intrinsic
 #define ESleepy u.uprops[SLEEPY].extrinsic
index 01a2a4c9ec6586afba68c3db1733b90124485229..3f9bf05ef8ff59a2855eb1ca95ea6ec17acfcea0 100644 (file)
--- a/src/do.c
+++ b/src/do.c
@@ -2137,20 +2137,24 @@ set_wounded_legs(long side, int timex)
      * You still call this function, but don't lose hp.
      * Caller is also responsible for adjusting messages.
      */
-
     g.context.botl = 1;
     if (!Wounded_legs)
         ATEMP(A_DEX)--;
 
-    if (!Wounded_legs || (HWounded_legs & TIMEOUT) < timex)
+    if (!Wounded_legs || (HWounded_legs & TIMEOUT) < (long) timex)
         set_itimeout(&HWounded_legs, (long) timex);
-    EWounded_legs = side;
+    /* the leg being wounded and its timeout might differ from one
+       attack to the next, but we don't track the legs separately;
+       3.7: both legs will ultimately heal together; this used to use
+       direct assignment instead of bitwise-OR so getting wounded in
+       one leg mysteriously healed the other */
+    EWounded_legs |= side;
     (void) encumber_msg();
 }
 
 void
-heal_legs(int how) /* 0: ordinary, 1: dismounting steed,
-                      2: limbs turn to stone */
+heal_legs(
+    int how) /* 0: ordinary, 1: dismounting steed, 2: limbs turn to stone */
 {
     if (Wounded_legs) {
         g.context.botl = 1;
index 50584fe3bab632b85c25a079033d211e80ad5fe1..4314304e7c88a20df4d625ba5b38a3c8aac4fd94 100644 (file)
@@ -1013,21 +1013,31 @@ status_enlightenment(int mode, int final)
         }
     }
     if (Wounded_legs) {
+        /* EWounded_legs is used to track left/right/both rather than some
+           form of extrinsic impairment; HWounded_legs is used for timeout;
+           both apply to steed instead of hero when mounted */
+        long whichleg = (EWounded_legs & BOTH_SIDES);
+        const char *bp = u.usteed ? mbodypart(u.usteed, LEG) : body_part(LEG),
+            *article = "a ", /* precedes "wounded", so never "an " */
+            *leftright = "";
+
+        if (whichleg == BOTH_SIDES)
+            bp = makeplural(bp), article = "";
+        else
+            leftright = (whichleg == LEFT_SIDE) ? "left " : "right ";
+        Sprintf(buf, "%swounded %s%s", article, leftright, bp);
+
         /* when mounted, Wounded_legs applies to steed rather than to
            hero; we only report steed's wounded legs in wizard mode */
         if (u.usteed) { /* not `Riding' here */
             if (wizard && steedname) {
-                Strcpy(buf, steedname);
-                *buf = highc(*buf);
-                enl_msg(buf, " has", " had", " wounded legs", "");
+                char steednambuf[BUFSZ];
+
+                Strcpy(steednambuf, steedname);
+                *steednambuf = highc(*steednambuf);
+                enl_msg(steednambuf, " has ", " had ", buf, "");
             }
         } else {
-            long wl = (EWounded_legs & BOTH_SIDES);
-            const char *bp = body_part(LEG), *article = "a ";
-
-            if (wl == BOTH_SIDES)
-                bp = makeplural(bp), article = "";
-            Sprintf(buf, "%swounded %s", article, bp);
             you_have(buf, "");
         }
     }
@@ -2841,8 +2851,20 @@ mstatusline(struct monst *mtmp)
                             ? ", digesting you"
                             : is_animal(u.ustuck->data) ? ", swallowing you"
                                : ", engulfing you");
-    if (mtmp == u.usteed)
+    if (mtmp == u.usteed) {
         Strcat(info, ", carrying you");
+        if (Wounded_legs) {
+            /* EWounded_legs is used to track left/right/both rather than
+               some form of extrinsic impairment; HWounded_legs is used for
+               timeout; both apply to steed instead of hero when mounted */
+            long legs = (EWounded_legs & BOTH_SIDES);
+            const char *what = mbodypart(mtmp, LEG);
+
+            if (legs == BOTH_SIDES)
+                what = makeplural(what);
+            Sprintf(eos(info), ", injured %s", what);
+        }
+    }
 
     /* avoid "Status of the invisible newt ..., invisible" */
     /* and unlike a normal mon_nam, use "saddled" even if it has a name */
@@ -2892,12 +2914,17 @@ ustatusline(void)
     }
     if (Stunned)
         Strcat(info, ", stunned");
-    if (!u.usteed && Wounded_legs) {
-        long legs = (EWounded_legs | HWounded_legs);
+    if (Wounded_legs && !u.usteed) {
+        /* EWounded_legs is used to track left/right/both rather than some
+           form of extrinsic impairment; HWounded_legs is used for timeout;
+           both apply to steed instead of hero when mounted */
+        long legs = (EWounded_legs & BOTH_SIDES);
         const char *what = body_part(LEG);
 
-        if ((legs & BOTH_SIDES) == BOTH_SIDES)
+        if (legs == BOTH_SIDES)
             what = makeplural(what);
+        /* when it's just one leg, ^X reports which, left or right;
+           ustatusline() doesn't, in order to keep the output a bit shorter */
         Sprintf(eos(info), ", injured %s", what);
     }
     if (Glib)
index 2e2ce464061f3b646030a9f96285b229b46dc566..a8bad0fa1dd510d36e46f844b017fec200ac7992 100644 (file)
@@ -1074,6 +1074,10 @@ peffect_extra_healing(struct obj *otmp)
     (void) make_hallucinated(0L, TRUE, 0L);
     exercise(A_CON, TRUE);
     exercise(A_STR, TRUE);
+    /* blessed potion also heals wounded legs unless riding (where leg
+       wounds apply to the steed rather than to the hero) */
+    if (Wounded_legs && (otmp->blessed && !u.usteed))
+        heal_legs(0);
 }
 
 static void
@@ -1091,6 +1095,10 @@ peffect_full_healing(struct obj *otmp)
     (void) make_hallucinated(0L, TRUE, 0L);
     exercise(A_STR, TRUE);
     exercise(A_CON, TRUE);
+    /* blessed potion heals wounded legs even when riding (so heals steed's
+       legs--it's magic); uncursed potion heals hero's legs unless riding */
+    if (Wounded_legs && (otmp->blessed || (!otmp->cursed && !u.usteed)))
+        heal_legs(0);
 }
 
 static void