From f7d8bfc0a3134c4c8388a7505525de382bc4cc84 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 9 Oct 2022 16:57:06 -0700 Subject: [PATCH] more PR #892 - strength lose due to poison Refine pull request #802 by entrez. Applying damage within a loop could potentially damage the hero multiple times, maybe using up an amulet of life saving and then killing hero anyway, or causing rehumanization and taking further HP from normal form, or both, causing rehumanization and then using up amulet of life saving. Accumulate the damage in the loop and then apply it as a unit. --- src/attrib.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/attrib.c b/src/attrib.c index 7684c057c..0db15de8a 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -192,6 +192,7 @@ adjattrib( return TRUE; } +/* strength gain */ void gainstr(struct obj *otmp, int incr, boolean givemsg) { @@ -209,30 +210,35 @@ gainstr(struct obj *otmp, int incr, boolean givemsg) givemsg ? -1 : 1); } -/* may kill you; cause may be poison or monster like 'a' */ +/* strength loss, may kill you; cause may be poison or monster like 'a' */ void losestr(int num, const char *knam, schar k_format) { int uhpmin = minuhpmax(1), olduhpmax = u.uhpmax; - int ustr = ABASE(A_STR) - num; - - /* in case HP loss kills the hero once Str hits the minimum */ - if (!knam || !*knam) { - knam = "terminal frailty"; - k_format = KILLED_BY; - } + int ustr = ABASE(A_STR) - num, amt, dmg; + dmg = 0; while (ustr < ATTRMIN(A_STR)) { ++ustr; --num; - losehp(6, knam, k_format); + amt = rn1(4, 3); /* (0..(4-1))+3 => 3..6; used to use flat 6 here */ + dmg += amt; if (Upolyd) { - u.mhmax -= 6; + u.mhmax -= min(amt, u.mhmax - 1); } else { - setuhpmax(u.uhpmax - 6); + setuhpmax(u.uhpmax - amt); } g.context.botl = TRUE; } + if (dmg) { + /* in case damage is fatal and caller didn't supply killer reason */ + if (!knam || !*knam) { + knam = "terminal frailty"; + k_format = KILLED_BY; + } + losehp(dmg, knam, k_format); + } + if (u.uhpmax < uhpmin) { setuhpmax(min(olduhpmax, uhpmin)); if (!Drain_resistance)