diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 7e5a24e18..885b9cd01 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -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 diff --git a/include/youprop.h b/include/youprop.h index 60ed6af57..a8c6488c8 100644 --- a/include/youprop.h +++ b/include/youprop.h @@ -120,9 +120,13 @@ #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 diff --git a/src/do.c b/src/do.c index 01a2a4c9e..3f9bf05ef 100644 --- 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; diff --git a/src/insight.c b/src/insight.c index 50584fe3b..4314304e7 100644 --- a/src/insight.c +++ b/src/insight.c @@ -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) diff --git a/src/potion.c b/src/potion.c index 2e2ce4640..a8bad0fa1 100644 --- a/src/potion.c +++ b/src/potion.c @@ -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