From ff96cd36870030774863a6ed4ef07060234f2524 Mon Sep 17 00:00:00 2001 From: "George V." Date: Wed, 8 Apr 2026 03:27:30 +0300 Subject: [PATCH] feat: support separate boss health bars per dimension Add dimension-aware tracking for boss mobs and update the boss health GUI system to maintain independent state for each dimension (Overworld, Nether, End). This prevents conflicts when multiple bosses exist across different dimensions simultaneously. - Add `getDimension()` to `BossMob` base class and implement in `EnderDragon` and `WitherBoss` - Replace static boss GUI state with dimension-indexed storage - Introduce `getIndexFromDimension()` helper for dimension mapping - Update rendering logic to use per-dimension state - Isolate darkening effects and health display per dimension Ported from LCERenewed commit 5ec8a0e41ba8146aba450258d8620cd3cb0299e0 by 3UR --- Minecraft.Client/BossMobGuiInfo.cpp | 25 +++++++++++++++------- Minecraft.Client/BossMobGuiInfo.h | 10 +++++---- Minecraft.Client/Common/UI/UIScene_HUD.cpp | 21 ++++++++++++------ Minecraft.Client/GameRenderer.cpp | 5 +++-- Minecraft.World/BossMob.h | 1 + Minecraft.World/EnderDragon.h | 1 + Minecraft.World/WitherBoss.h | 1 + 7 files changed, 44 insertions(+), 20 deletions(-) diff --git a/Minecraft.Client/BossMobGuiInfo.cpp b/Minecraft.Client/BossMobGuiInfo.cpp index 1cc3cae8..f18fabf6 100644 --- a/Minecraft.Client/BossMobGuiInfo.cpp +++ b/Minecraft.Client/BossMobGuiInfo.cpp @@ -1,16 +1,25 @@ #include "stdafx.h" #include "BossMobGuiInfo.h" #include "../Minecraft.World/BossMob.h" +#include "../Minecraft.World/LevelData.h" -float BossMobGuiInfo::healthProgress = 0.0f; -int BossMobGuiInfo::displayTicks = 0; -wstring BossMobGuiInfo::name = L""; -bool BossMobGuiInfo::darkenWorld = false; +float BossMobGuiInfo::healthProgress[3] = { 0.0f, 0.0f, 0.0f }; +int BossMobGuiInfo::displayTicks[3] = { 0, 0, 0 }; +wstring BossMobGuiInfo::name[3]; +bool BossMobGuiInfo::darkenWorld[3] = { false, false, false }; void BossMobGuiInfo::setBossHealth(shared_ptr boss, bool darkenWorld) { - healthProgress = (float) boss->getHealth() / (float) boss->getMaxHealth(); - displayTicks = SharedConstants::TICKS_PER_SECOND * 5; - name = boss->getAName(); - BossMobGuiInfo::darkenWorld = darkenWorld; + int idx = getIndexFromDimension(boss->getDimension()); + healthProgress[idx] = (float) boss->getHealth() / (float) boss->getMaxHealth(); + displayTicks[idx] = SharedConstants::TICKS_PER_SECOND * 5; + name[idx] = boss->getAName(); + BossMobGuiInfo::darkenWorld[idx] = darkenWorld; +} + +int BossMobGuiInfo::getIndexFromDimension(int dimension) +{ + if (dimension == LevelData::DIMENSION_NETHER) return 1; + if (dimension == LevelData::DIMENSION_END) return 2; + return 0; } \ No newline at end of file diff --git a/Minecraft.Client/BossMobGuiInfo.h b/Minecraft.Client/BossMobGuiInfo.h index bc0d46c9..9bdf2444 100644 --- a/Minecraft.Client/BossMobGuiInfo.h +++ b/Minecraft.Client/BossMobGuiInfo.h @@ -5,10 +5,12 @@ class BossMob; class BossMobGuiInfo { public: - static float healthProgress; - static int displayTicks; - static wstring name; - static bool darkenWorld; + static float healthProgress[3]; + static int displayTicks[3]; + static wstring name[3]; + static bool darkenWorld[3]; static void setBossHealth(shared_ptr boss, bool darkenWorld); + + static int getIndexFromDimension(int dimension); }; \ No newline at end of file diff --git a/Minecraft.Client/Common/UI/UIScene_HUD.cpp b/Minecraft.Client/Common/UI/UIScene_HUD.cpp index 1559a6ec..14f35908 100644 --- a/Minecraft.Client/Common/UI/UIScene_HUD.cpp +++ b/Minecraft.Client/Common/UI/UIScene_HUD.cpp @@ -124,8 +124,9 @@ void UIScene_HUD::tick() return; } + int idx = BossMobGuiInfo::getIndexFromDimension(pMinecraft->localplayers[m_iPad]->dimension); // Is boss present? - bool noBoss = BossMobGuiInfo::name.empty() || BossMobGuiInfo::displayTicks <= 0; + bool noBoss = BossMobGuiInfo::name[idx].empty() || BossMobGuiInfo::displayTicks[idx] <= 0; if (noBoss) { if (m_showDragonHealth) @@ -143,14 +144,14 @@ void UIScene_HUD::tick() } else { - BossMobGuiInfo::displayTicks--; + BossMobGuiInfo::displayTicks[idx]--; m_ticksWithNoBoss = 0; - SetDragonHealth(BossMobGuiInfo::healthProgress); + SetDragonHealth(BossMobGuiInfo::healthProgress[idx]); if (!m_showDragonHealth) { - SetDragonLabel(BossMobGuiInfo::name); + SetDragonLabel(BossMobGuiInfo::name[idx]); ShowDragonHealth(true); } } @@ -248,7 +249,15 @@ void UIScene_HUD::handleReload() m_labelDisplayName.setVisible(m_lastShowDisplayName); - SetDragonLabel(BossMobGuiInfo::name); + Minecraft* pMinecraft = Minecraft::GetInstance(); + + int idx = 0; + if(pMinecraft->localplayers[m_iPad] != nullptr) + { + idx = BossMobGuiInfo::getIndexFromDimension(pMinecraft->localplayers[m_iPad]->dimension); + } + + SetDragonLabel(BossMobGuiInfo::name[idx]); SetSelectedLabel(L""); for(unsigned int i = 0; i < CHAT_LINES_COUNT; ++i) @@ -258,7 +267,7 @@ void UIScene_HUD::handleReload() m_labelJukebox.init(L""); int iGuiScale; - Minecraft *pMinecraft = Minecraft::GetInstance(); + if(pMinecraft->localplayers[m_iPad] == nullptr || pMinecraft->localplayers[m_iPad]->m_iScreenSection == C4JRender::VIEWPORT_TYPE_FULLSCREEN) { iGuiScale=app.GetGameSettings(m_iPad,eGameSetting_UISize); diff --git a/Minecraft.Client/GameRenderer.cpp b/Minecraft.Client/GameRenderer.cpp index c65e4b16..0e4dfbf6 100644 --- a/Minecraft.Client/GameRenderer.cpp +++ b/Minecraft.Client/GameRenderer.cpp @@ -228,14 +228,15 @@ void GameRenderer::tick(bool first) // 4J - add bFirst PIXEndNamedEvent(); darkenWorldAmountO = darkenWorldAmount; - if (BossMobGuiInfo::darkenWorld) + int idx = BossMobGuiInfo::getIndexFromDimension((int)mc->level->dimension); + if (BossMobGuiInfo::darkenWorld[idx]) { darkenWorldAmount += 1.0f / (static_cast(SharedConstants::TICKS_PER_SECOND) * 1); if (darkenWorldAmount > 1) { darkenWorldAmount = 1; } - BossMobGuiInfo::darkenWorld = false; + BossMobGuiInfo::darkenWorld[idx] = false; } else if (darkenWorldAmount > 0) { diff --git a/Minecraft.World/BossMob.h b/Minecraft.World/BossMob.h index bd24c46c..73f35692 100644 --- a/Minecraft.World/BossMob.h +++ b/Minecraft.World/BossMob.h @@ -6,4 +6,5 @@ public: virtual float getMaxHealth() = 0; virtual float getHealth() = 0; virtual wstring getAName() = 0; + virtual int getDimension() = 0; }; \ No newline at end of file diff --git a/Minecraft.World/EnderDragon.h b/Minecraft.World/EnderDragon.h index 9f39767e..f63e890e 100644 --- a/Minecraft.World/EnderDragon.h +++ b/Minecraft.World/EnderDragon.h @@ -186,4 +186,5 @@ public: virtual wstring getAName() { return app.GetString(IDS_ENDERDRAGON); }; virtual float getHealth() { return LivingEntity::getHealth(); }; virtual float getMaxHealth() { return LivingEntity::getMaxHealth(); }; + virtual int getDimension() { return Entity::dimension; } }; diff --git a/Minecraft.World/WitherBoss.h b/Minecraft.World/WitherBoss.h index 47e2dff1..a0d98379 100644 --- a/Minecraft.World/WitherBoss.h +++ b/Minecraft.World/WitherBoss.h @@ -106,4 +106,5 @@ public: virtual float getMaxHealth() { return Monster::getMaxHealth(); }; virtual float getHealth() { return Monster::getHealth(); }; virtual wstring getAName() { return app.GetString(IDS_WITHER); }; + virtual int getDimension() { return Entity::dimension; } }; \ No newline at end of file