From 89109dc9f41166cb9fb9c5b42f7e13ba447c202d Mon Sep 17 00:00:00 2001 From: qndel Date: Fri, 29 Apr 2022 08:06:59 +0200 Subject: [PATCH] HP bar tweaks and fixes (#4525) * HP bar tweaks and fixes --- Source/monster.cpp | 1 + Source/qol/monhealthbar.cpp | 29 ++++++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/Source/monster.cpp b/Source/monster.cpp index 95b9d4f50..3a46e86b7 100644 --- a/Source/monster.cpp +++ b/Source/monster.cpp @@ -4311,6 +4311,7 @@ void ProcessMonsters() } else { monster._mhitpoints += monster.mLevel; } + monster._mhitpoints = std::min(monster._mhitpoints, monster._mmaxhp); // prevent going over max HP with part of a single regen tick } if (IsTileVisible(monster.position.tile) && monster._msquelch == 0) { diff --git a/Source/qol/monhealthbar.cpp b/Source/qol/monhealthbar.cpp index e5331d377..942b0776d 100644 --- a/Source/qol/monhealthbar.cpp +++ b/Source/qol/monhealthbar.cpp @@ -4,6 +4,8 @@ * Adds monster health bar QoL feature */ +#include + #include "DiabloUI/art_draw.h" #include "control.h" #include "cursor.h" @@ -16,6 +18,7 @@ namespace { Art healthBox; Art resistance; Art health; +Art healthBlue; Art playerExpTags; } // namespace @@ -27,6 +30,11 @@ void InitMonsterHealthBar() LoadMaskedArt("data\\healthbox.pcx", &healthBox, 1, 1); LoadArt("data\\health.pcx", &health); + std::array data; + data[234] = 185; + data[235] = 186; + data[236] = 187; + LoadMaskedArt("data\\health.pcx", &healthBlue, 1, 1, &data); LoadMaskedArt("data\\resistance.pcx", &resistance, 6, 1); LoadMaskedArt("data\\monstertags.pcx", &playerExpTags, 5, 1); @@ -44,6 +52,7 @@ void FreeMonsterHealthBar() { healthBox.Unload(); health.Unload(); + healthBlue.Unload(); resistance.Unload(); } @@ -54,6 +63,7 @@ void DrawMonsterHealthBar(const Surface &out) assert(healthBox.surface != nullptr); assert(health.surface != nullptr); + assert(healthBlue.surface != nullptr); assert(resistance.surface != nullptr); if (currlevel == 0) @@ -64,6 +74,7 @@ void DrawMonsterHealthBar(const Surface &out) const Monster &monster = Monsters[pcursmonst]; const int width = healthBox.w(); + const int barWidth = health.w(); const int height = healthBox.h(); Point position = { (gnScreenWidth - width) / 2, 18 }; @@ -76,13 +87,23 @@ void DrawMonsterHealthBar(const Surface &out) const int border = 3; - const int maxLife = std::max(monster._mmaxhp, monster._mhitpoints); + int multiplier = 0; + int currLife = monster._mhitpoints; + // lifestealing monsters can reach HP exceeding their max + if (monster._mhitpoints > monster._mmaxhp) { + multiplier = monster._mhitpoints / monster._mmaxhp; + currLife = monster._mhitpoints - monster._mmaxhp * multiplier; + if (currLife == 0 && multiplier > 0) { + multiplier--; + currLife = monster._mmaxhp; + } + } DrawArt(out, position, &healthBox); DrawHalfTransparentRectTo(out, position.x + border, position.y + border, width - (border * 2), height - (border * 2)); - int barProgress = (width * monster._mhitpoints) / maxLife; + int barProgress = (barWidth * currLife) / monster._mmaxhp; if (barProgress != 0) { - DrawArt(out, position + Displacement { border + 1, border + 1 }, &health, 0, barProgress, height - (border * 2) - 2); + DrawArt(out, position + Displacement { border + 1, border + 1 }, multiplier > 0 ? &healthBlue : &health, 0, barProgress, height - (border * 2) - 2); } constexpr auto getBorderColor = [](MonsterClass monsterClass) { @@ -121,6 +142,8 @@ void DrawMonsterHealthBar(const Surface &out) style |= UiFlags::ColorWhite; DrawString(out, monster.mName, { position, { width, height } }, style); + if (multiplier > 0) + DrawString(out, fmt::format("x{:d}", multiplier), { position, { width - 2, height } }, UiFlags::ColorWhite | UiFlags::AlignRight | UiFlags::VerticalCenter); if (monster._uniqtype != 0 || MonsterKillCounts[monster.MType->mtype] >= 15) { monster_resistance immunes[] = { IMMUNE_MAGIC, IMMUNE_FIRE, IMMUNE_LIGHTNING }; monster_resistance resists[] = { RESIST_MAGIC, RESIST_FIRE, RESIST_LIGHTNING };