From e9a25a0a1c9365d655d26eba16a9b3de32723a67 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 26 Sep 2024 23:00:42 -0700 Subject: [PATCH] sanity_check: current hero health better than max Changes to setuhpmax() a couple of days ago to deal with sanity_check for "current hero health as monster better than maximum" ended up triggering sanity_check about "current hero health better than maximum" when gaining experience level(s) while polymorphed. --- include/extern.h | 2 +- src/attrib.c | 12 ++++++------ src/eat.c | 4 ++-- src/end.c | 2 +- src/exper.c | 12 +++++++----- src/mcastu.c | 3 ++- src/polyself.c | 2 +- src/pray.c | 15 ++++++--------- src/trap.c | 2 +- src/wizcmds.c | 6 ++++-- 10 files changed, 31 insertions(+), 29 deletions(-) diff --git a/include/extern.h b/include/extern.h index 357131d5c..91fb732a5 100644 --- a/include/extern.h +++ b/include/extern.h @@ -202,7 +202,7 @@ extern void vary_init_attr(void); extern void adjabil(int, int); extern int newhp(void); extern int minuhpmax(int); -extern void setuhpmax(int); +extern void setuhpmax(int, boolean); extern int adjuhploss(int, int); extern schar acurr(int); extern schar acurrstr(void); diff --git a/src/attrib.c b/src/attrib.c index 78fd1d3ca..859b5b44a 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -243,18 +243,18 @@ losestr(int num, const char *knam, schar k_format) if (Upolyd) { /* when still poly'd, reduce you-as-monst maxHP; never below 1 */ - setuhpmax(max(u.mhmax - dmg, 1)); /* acts as setmhmax() */ + setuhpmax(max(u.mhmax - dmg, 1), FALSE); /* acts as setmhmax() */ } else if (!waspolyd) { /* not polymorphed now and didn't rehumanize when taking damage; reduce max HP, but not below uhpmin */ if (u.uhpmax > uhpmin) - setuhpmax(max(u.uhpmax - dmg, uhpmin)); + setuhpmax(max(u.uhpmax - dmg, uhpmin), FALSE); } disp.botl = TRUE; } #if 0 /* only possible if uhpmax was already less than uhpmin */ if (!Upolyd && u.uhpmax < uhpmin) { - setuhpmax(min(olduhpmax, uhpmin)); + setuhpmax(min(olduhpmax, uhpmin), FALSE); if (!Drain_resistance) losexp(NULL); /* won't be fatal when no 'drainer' is supplied */ } @@ -370,7 +370,7 @@ poisoned( int olduhp = u.uhp, newuhpmax = u.uhpmax - (loss / 2); - setuhpmax(max(newuhpmax, minuhpmax(3))); + setuhpmax(max(newuhpmax, minuhpmax(3)), TRUE); /*True: see FIXME*/ loss = adjuhploss(loss, olduhp); losehp(loss, pkiller, kprefix); /* poison damage */ @@ -1148,9 +1148,9 @@ minuhpmax(int altmin) /* update u.uhpmax or u.mhmax and values of other things that depend upon whichever of them is relevant */ void -setuhpmax(int newmax) +setuhpmax(int newmax, boolean even_when_polyd) { - if (!Upolyd) { + if (!Upolyd || even_when_polyd) { if (newmax != u.uhpmax) { u.uhpmax = newmax; if (u.uhpmax > u.uhppeak) diff --git a/src/eat.c b/src/eat.c index 9f2498b77..9b992e1c7 100644 --- a/src/eat.c +++ b/src/eat.c @@ -2464,7 +2464,7 @@ fpostfx(struct obj *otmp) u.mh += otmp->cursed ? -rnd(20) : rnd(20), disp.botl = TRUE; if (u.mh > u.mhmax) { if (!rn2(17)) - u.mhmax++; + setuhpmax(u.mhmax + 1, FALSE); u.mh = u.mhmax; } else if (u.mh <= 0) { rehumanize(); @@ -2473,7 +2473,7 @@ fpostfx(struct obj *otmp) u.uhp += otmp->cursed ? -rnd(20) : rnd(20), disp.botl = TRUE; if (u.uhp > u.uhpmax) { if (!rn2(17)) - setuhpmax(u.uhpmax + 1); + setuhpmax(u.uhpmax + 1, FALSE); u.uhp = u.uhpmax; } else if (u.uhp <= 0) { svk.killer.format = KILLED_BY_AN; diff --git a/src/end.c b/src/end.c index d50420ea2..519b599dc 100644 --- a/src/end.c +++ b/src/end.c @@ -702,7 +702,7 @@ savelife(int how) u.ulevel = 1; uhpmin = minuhpmax(10); if (u.uhpmax < uhpmin) - setuhpmax(uhpmin); + setuhpmax(uhpmin, TRUE); u.uhp = min(u.uhpmax, givehp); if (Upolyd) /* Unchanging, or death which bypasses losing hit points */ u.mh = min(u.mhmax, givehp); diff --git a/src/exper.c b/src/exper.c index 1fe07dcd1..aee851126 100644 --- a/src/exper.c +++ b/src/exper.c @@ -251,14 +251,14 @@ losexp( num = (int) u.uhpinc[u.ulevel]; u.uhpmax -= num; if (u.uhpmax < uhpmin) - setuhpmax(uhpmin); + setuhpmax(uhpmin, TRUE); /* uhpmax might try to go up if it has previously been reduced by strength loss or by a fire trap or by an attack by Death which all use a different minimum than life-saving or experience loss; we don't allow it to go up because that contradicts assumptions elsewhere (such as healing wielder who drains with Stormbringer) */ if (u.uhpmax > olduhpmax) - setuhpmax(olduhpmax); + setuhpmax(olduhpmax, TRUE); u.uhp -= num; if (u.uhp < 1) @@ -306,7 +306,8 @@ newexplevel(void) void pluslvl( boolean incr) /* True: incremental experience growth; - * False: potion of gain level or wraith corpse */ + * False: potion of gain level or wraith corpse + * or wizard mode #levelchange */ { int hpinc, eninc; @@ -317,12 +318,13 @@ pluslvl( in order to retain normal human/whatever increase for later) */ if (Upolyd) { hpinc = monhp_per_lvl(&gy.youmonst); - u.mhmax += hpinc; u.mh += hpinc; + setuhpmax(u.mhmax, FALSE); /* acts as setmhmax() when Upolyd */ } hpinc = newhp(); u.uhp += hpinc; - setuhpmax(u.uhpmax + hpinc); /* will lower u.uhp if it exceeds uhpmax */ + setuhpmax(u.uhpmax + hpinc, TRUE); /* will lower u.uhp if it exceeds + * u.uhpmax */ /* increase spell power/energy points */ eninc = newpw(); diff --git a/src/mcastu.c b/src/mcastu.c index 1eb8e5dfd..8c28b2507 100644 --- a/src/mcastu.c +++ b/src/mcastu.c @@ -392,9 +392,10 @@ touch_of_death(struct monst *mtmp) } else { /* HP manipulation similar to poisoned(attrib.c) */ int olduhp = u.uhp, + uhpmin = minuhpmax(3), newuhpmax = u.uhpmax - drain; - setuhpmax(max(newuhpmax, minuhpmax(3))); + setuhpmax(max(newuhpmax, uhpmin), FALSE); dmg = adjuhploss(dmg, olduhp); /* reduce pending damage if uhp has * already been reduced due to drop * in uhpmax */ diff --git a/src/polyself.c b/src/polyself.c index a40570f83..736c62dff 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -383,7 +383,7 @@ newman(void) hpmax = u.ulevel; /* min of 1 HP per level */ /* retain same proportion for current HP; u.uhp * hpmax / u.uhpmax */ u.uhp = rounddiv((long) u.uhp * (long) hpmax, u.uhpmax); - u.uhpmax = hpmax; + setuhpmax(hpmax, TRUE); /* might reduce u.uhp */ /* * Do the same for spell power. */ diff --git a/src/pray.c b/src/pray.c index a983c4de9..0adf67129 100644 --- a/src/pray.c +++ b/src/pray.c @@ -368,7 +368,7 @@ fix_curse_trouble(struct obj *otmp, const char *what) staticfn void fix_worst_trouble(int trouble) { - int i, maxhp, polyd = NON_PM; + int i, maxhp; struct obj *otmp = 0; const char *what = (const char *) 0; static NEARDATA const char leftglow[] = "Your left ring softly glows", @@ -420,19 +420,16 @@ fix_worst_trouble(int trouble) You_feel("much better."); if (Upolyd) { maxhp = u.mhmax + rnd(5); - setuhpmax(max(maxhp, 5 + 1)); + setuhpmax(max(maxhp, 5 + 1), FALSE); /* acts as setmhmax() */ u.mh = u.mhmax; - polyd = u.umonnum; - u.umonnum = u.umonster; /* temporarily unpolymorph so that next - * setuhpmax() call deals with u.uhpmax */ } maxhp = u.uhpmax; if (maxhp < u.ulevel * 5 + 11) maxhp += rnd(5); - setuhpmax(max(maxhp, 5 + 1)); - u.uhp = u.uhpmax; - if (polyd != NON_PM) - u.umonnum = polyd; /* restore Upolyd */ + /* True: update u.uhpmax even if currently poly'd */ + setuhpmax(max(maxhp, 5 + 1), TRUE); + u.uhp = u.uhpmax; /* setuhpmax() will do this when u.uhp is higher + * than u.uhpmax; prayer also does this if lower */ disp.botl = TRUE; break; case TROUBLE_COLLAPSING: diff --git a/src/trap.c b/src/trap.c index 2671a1e4f..9e791e1c5 100644 --- a/src/trap.c +++ b/src/trap.c @@ -4154,7 +4154,7 @@ dofiretrap( u.uhpmax -= rn2(min(u.uhpmax, num + 1)), disp.botl = TRUE; } /* note: no 'else' here */ if (u.uhpmax < uhpmin) { - setuhpmax(min(olduhpmax, uhpmin)); /* sets disp.botl */ + setuhpmax(min(olduhpmax, uhpmin), FALSE); /* sets disp.botl */ if (!Drain_resistance) losexp(NULL); /* never fatal when 'drainer' is Null */ } diff --git a/src/wizcmds.c b/src/wizcmds.c index 454b4deb9..88dd27aac 100644 --- a/src/wizcmds.c +++ b/src/wizcmds.c @@ -444,16 +444,17 @@ wiz_flip_level(void) int wiz_level_change(void) { - char buf[BUFSZ] = DUMMY; + char buf[BUFSZ], dummy = '\0'; int newlevel = 0; int ret; + buf[0] = '\0'; /* in case EDIT_GETLIN is enabled */ getlin("To what experience level do you want to be set?", buf); (void) mungspaces(buf); if (buf[0] == '\033' || buf[0] == '\0') ret = 0; else - ret = sscanf(buf, "%d", &newlevel); + ret = sscanf(buf, "%d%c", &newlevel, &dummy); if (ret != 1) { pline1(Never_mind); @@ -480,6 +481,7 @@ wiz_level_change(void) while (u.ulevel < newlevel) pluslvl(FALSE); } + /* blessed full healing or restore ability won't fix any lost levels */ u.ulevelmax = u.ulevel; return ECMD_OK; }