From 03400f28812dbf3f2ab35048e6769c373cfd9b8a Mon Sep 17 00:00:00 2001 From: nolt Date: Thu, 28 May 2026 10:45:30 +0000 Subject: [PATCH 1/5] switchable monsters hpbar DESCRIPTION: Pressing F8 toggles health bars above all alive monsters on the screen. The health bar uses the same segmented style as the hover-over bar shown at the top of the screen when mousing over a monster. Pressing F8 again hides the bars. HOW IT WORKS: - F8 - toggles monster HP bars on/off - Each bar consists of 20 red segments - The bar appears above the monster's head (~60 units above BoundingBox) - Bars are only drawn when the monster is on screen (visibility check using CameraProjection::WorldToScreen) - F8 - toggles monster HP bars on/off - Each bar consists of 20 red segments - The bar appears above the monster's head (~60 units above BoundingBox) - Bars are only drawn when the monster is on screen (visibility check using CameraProjection::WorldToScreen) --- .../UI/NewUI/Character/NewUINameWindow.cpp | 81 ++++++++++++++++++- .../UI/NewUI/Character/NewUINameWindow.h | 9 ++- 2 files changed, 86 insertions(+), 4 deletions(-) diff --git a/src/source/UI/NewUI/Character/NewUINameWindow.cpp b/src/source/UI/NewUI/Character/NewUINameWindow.cpp index 7fb66f2e4..d7da48d72 100644 --- a/src/source/UI/NewUI/Character/NewUINameWindow.cpp +++ b/src/source/UI/NewUI/Character/NewUINameWindow.cpp @@ -14,6 +14,8 @@ #include "GameLogic/Items/PersonalShopTitleImp.h" #include "GameLogic/Events/MatchEvent.h" #include "World/MapInfra/MapManager.h" +#include "Camera/CameraProjection.h" +#include "Camera/CameraState.h" // DevEditor forward declarations (must be at global scope) #ifdef _EDITOR @@ -25,6 +27,8 @@ using namespace SEASON3B; namespace { constexpr int GROUND_ITEM_LABEL_BUILD_BUDGET_PER_FRAME = 32; + +bool s_bF8KeyPressed = false; } ////////////////////////////////////////////////////////////////////// @@ -37,6 +41,7 @@ SEASON3B::CNewUINameWindow::CNewUINameWindow() m_Pos.x = m_Pos.y = 0; m_bShowItemName = false; + m_bShowMonsterHealthBar = false; } SEASON3B::CNewUINameWindow::~CNewUINameWindow() @@ -91,6 +96,13 @@ bool SEASON3B::CNewUINameWindow::UpdateKeyEvent() bool SEASON3B::CNewUINameWindow::Update() { + const bool bF8Down = (GetAsyncKeyState(VK_F8) & 0x8000) != 0; + if (bF8Down && !s_bF8KeyPressed) + { + m_bShowMonsterHealthBar = !m_bShowMonsterHealthBar; + } + s_bF8KeyPressed = bF8Down; + return true; } @@ -102,6 +114,7 @@ bool SEASON3B::CNewUINameWindow::Render() RenderTimes(); matchEvent::RenderMatchTimes(); RenderBooleans(); + RenderMonsterHealthBars(); DrawPersonalShopTitleImp(); DisableAlphaBlend(); return true; @@ -175,7 +188,9 @@ void SEASON3B::CNewUINameWindow::RenderName() glColor3f(50.f / 255.f, 10 / 255.f, 0.f); RenderColor((float)(ScreenX + borderWidth), (float)(ScreenY + borderWidth), stepsWidth, 1.f); - int stepHP = (int)(c->HealthStatus * steps); + float health = c->HealthStatus; + if (health < 0.0f) health = 1.0f; + int stepHP = (int)(health * steps); glColor3f(250.f / 255.f, 10 / 255.f, 0.f); for (int k = 0; k < stepHP; ++k) @@ -238,6 +253,70 @@ void SEASON3B::CNewUINameWindow::RenderName() } } +void SEASON3B::CNewUINameWindow::RenderMonsterHealthBars() +{ + if (!m_bShowMonsterHealthBar) + return; + + for (int i = 0; i < MAX_CHARACTERS_CLIENT; i++) + { + CHARACTER* c = &CharactersClient[i]; + OBJECT* o = &c->Object; + + if (!o->Live || !o->Visible || o->Kind != KIND_MONSTER) + continue; + + vec3_t Position; + Vector(o->Position[0], o->Position[1], o->Position[2] + o->BoundingBoxMax[2] + 60.f, Position); + + int ScreenX, ScreenY; + vec3_t transformPos; + VectorTransform(Position, g_Camera.Matrix, transformPos); + if (transformPos[2] >= 0) + continue; + + BeginOpengl(); + CameraProjection::WorldToScreen(g_Camera, Position, &ScreenX, &ScreenY); + EndOpengl(); + + const auto steps = 20; + const auto borderWidth = 2.f; + const auto widthPerStep = 4; + const auto stepSeparatorWidth = 1; + const auto stepsWidth = steps * widthPerStep - 2 * stepSeparatorWidth; + const auto totalWidth = stepsWidth + borderWidth * 2; + + auto hpBarX = ScreenX - (int)(totalWidth / 2); + auto hpBarY = ScreenY; + + EnableAlphaTest(); + glColor4f(0.f, 0.f, 0.f, 0.5f); + RenderColor((float)(hpBarX + 1), (float)(hpBarY + 1), totalWidth, 5.f); + + EnableAlphaBlend(); + glColor3f(0.2f, 0.0f, 0.0f); + RenderColor((float)hpBarX, (float)hpBarY, totalWidth, 5.f); + + glColor3f(50.f / 255.f, 10 / 255.f, 0.f); + RenderColor((float)(hpBarX + borderWidth), (float)(hpBarY + borderWidth), stepsWidth, 1.f); + + float health = c->HealthStatus; + if (health < 0.0f) health = 1.0f; + int stepHP = (int)(health * steps); + + glColor3f(250.f / 255.f, 10 / 255.f, 0.f); + for (int k = 0; k < stepHP; ++k) + { + RenderColor( + (float)(hpBarX + borderWidth + (k * widthPerStep)), + (float)(hpBarY + borderWidth), + widthPerStep - stepSeparatorWidth, + 2.f); + } + DisableAlphaBlend(); + } +} + float SEASON3B::CNewUINameWindow::GetLayerDepth() { return 1.0f; diff --git a/src/source/UI/NewUI/Character/NewUINameWindow.h b/src/source/UI/NewUI/Character/NewUINameWindow.h index 2fef79ba2..04655b146 100644 --- a/src/source/UI/NewUI/Character/NewUINameWindow.h +++ b/src/source/UI/NewUI/Character/NewUINameWindow.h @@ -11,7 +11,7 @@ namespace SEASON3B { - // ̸ + // ������ �̸� class CNewUINameWindow : public CNewUIObj { public: @@ -33,10 +33,13 @@ namespace SEASON3B private: void RenderName(); - CNewUIManager* m_pNewUIMng; // UI Ŵ. - POINT m_Pos; // â ġ. + CNewUIManager* m_pNewUIMng; // UI �Ŵ���. + POINT m_Pos; // â�� ��ġ. bool m_bShowItemName; + bool m_bShowMonsterHealthBar; + + void RenderMonsterHealthBars(); }; } From 0ec5b7dc4eccd19315552d030557105b80d55249 Mon Sep 17 00:00:00 2001 From: nolt Date: Thu, 28 May 2026 17:14:38 +0200 Subject: [PATCH 2/5] changed to solid bar --- .../UI/NewUI/Character/NewUINameWindow.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/source/UI/NewUI/Character/NewUINameWindow.cpp b/src/source/UI/NewUI/Character/NewUINameWindow.cpp index d7da48d72..35990d55c 100644 --- a/src/source/UI/NewUI/Character/NewUINameWindow.cpp +++ b/src/source/UI/NewUI/Character/NewUINameWindow.cpp @@ -263,7 +263,7 @@ void SEASON3B::CNewUINameWindow::RenderMonsterHealthBars() CHARACTER* c = &CharactersClient[i]; OBJECT* o = &c->Object; - if (!o->Live || !o->Visible || o->Kind != KIND_MONSTER) + if (!o->Live || !o->Visible || o->Alpha <= 0.f || c->Dead > 0 || o->Kind != KIND_MONSTER) continue; vec3_t Position; @@ -279,6 +279,11 @@ void SEASON3B::CNewUINameWindow::RenderMonsterHealthBars() CameraProjection::WorldToScreen(g_Camera, Position, &ScreenX, &ScreenY); EndOpengl(); + if (ScreenX < -100 || ScreenY < -100 + || ScreenX > (int)(WindowWidth + 100) + || ScreenY > (int)(WindowHeight + 100)) + continue; + const auto steps = 20; const auto borderWidth = 2.f; const auto widthPerStep = 4; @@ -302,15 +307,15 @@ void SEASON3B::CNewUINameWindow::RenderMonsterHealthBars() float health = c->HealthStatus; if (health < 0.0f) health = 1.0f; - int stepHP = (int)(health * steps); - glColor3f(250.f / 255.f, 10 / 255.f, 0.f); - for (int k = 0; k < stepHP; ++k) + float fillWidth = stepsWidth * health; + if (fillWidth > 0.f) { + glColor3f(250.f / 255.f, 10.f / 255.f, 0.f); RenderColor( - (float)(hpBarX + borderWidth + (k * widthPerStep)), + (float)(hpBarX + borderWidth), (float)(hpBarY + borderWidth), - widthPerStep - stepSeparatorWidth, + fillWidth, 2.f); } DisableAlphaBlend(); From 11f2c1d76de07bb70783917cb3cd404dbb77ae36 Mon Sep 17 00:00:00 2001 From: nolt Date: Thu, 28 May 2026 17:29:34 +0200 Subject: [PATCH 3/5] help and translation added --- src/Localization/Game.de.resx | 3 +++ src/Localization/Game.en.resx | 3 +++ src/Localization/Game.es.resx | 3 +++ src/Localization/Game.id.resx | 3 +++ src/Localization/Game.ja.resx | 3 +++ src/Localization/Game.pl.resx | 3 +++ src/Localization/Game.pt.resx | 3 +++ src/Localization/Game.ru.resx | 3 +++ src/Localization/Game.tl.resx | 3 +++ src/Localization/Game.uk.resx | 3 +++ src/Localization/Game.zh-TW.resx | 3 +++ .../UI/NewUI/Character/NewUINameWindow.cpp | 17 ++++++----------- src/source/UI/NewUI/Dialogs/NewUIHelpWindow.cpp | 1 + 13 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/Localization/Game.de.resx b/src/Localization/Game.de.resx index a75102d12..ef6313c59 100644 --- a/src/Localization/Game.de.resx +++ b/src/Localization/Game.de.resx @@ -496,6 +496,9 @@ F4 : Größe des Chatfensters anpassen legacy_id=124 + + F8 - Monster-HP-Balken ein/aus + F9 - 3D-Kamera umschalten diff --git a/src/Localization/Game.en.resx b/src/Localization/Game.en.resx index 59ea5d363..20d08b5f5 100644 --- a/src/Localization/Game.en.resx +++ b/src/Localization/Game.en.resx @@ -496,6 +496,9 @@ F4 : Adjust Chat Window size legacy_id=124 + + F8 - Toggle Monster HP Bar + F9 - Toggle 3D Camera diff --git a/src/Localization/Game.es.resx b/src/Localization/Game.es.resx index 7c49ad844..481814d85 100644 --- a/src/Localization/Game.es.resx +++ b/src/Localization/Game.es.resx @@ -496,6 +496,9 @@ F4: Ajustar el tamaño de la ventana de chat legacy_id=124 + + F8 - Mostrar/ocultar barra de HP de monstruos + F9 - Alternar cámara 3D diff --git a/src/Localization/Game.id.resx b/src/Localization/Game.id.resx index 98979f5f5..0418f6d0e 100644 --- a/src/Localization/Game.id.resx +++ b/src/Localization/Game.id.resx @@ -496,6 +496,9 @@ F4 : Sesuaikan ukuran Jendela Obrolan legacy_id=124 + + F8 - Aktifkan/Nonaktifkan Bar HP Monster + F9 - Alihkan Kamera 3D diff --git a/src/Localization/Game.ja.resx b/src/Localization/Game.ja.resx index 83bf26d3d..262e0bacf 100644 --- a/src/Localization/Game.ja.resx +++ b/src/Localization/Game.ja.resx @@ -496,6 +496,9 @@ F4:チャットウィンドウのサイズ調整 legacy_id=124 + + F8 - モンスター体力バー表示切替 + Enter:チャットウィンドウ On/Off legacy_id=125 diff --git a/src/Localization/Game.pl.resx b/src/Localization/Game.pl.resx index 43095d2cf..b039dfc60 100644 --- a/src/Localization/Game.pl.resx +++ b/src/Localization/Game.pl.resx @@ -496,6 +496,9 @@ F4: Dostosuj rozmiar okna czatu legacy_id=124 + + F8 - Włącz/wyłącz pasek życia potworów + F9 - Przełącz kamerę 3D diff --git a/src/Localization/Game.pt.resx b/src/Localization/Game.pt.resx index 03d254230..c5f6bb250 100644 --- a/src/Localization/Game.pt.resx +++ b/src/Localization/Game.pt.resx @@ -496,6 +496,9 @@ F4: Ajustar o tamanho da janela de bate-papo legacy_id=124 + + F8 - Ativar/desativar barra de HP dos monstros + F9 - Alternar câmera 3D diff --git a/src/Localization/Game.ru.resx b/src/Localization/Game.ru.resx index f36c0930f..269108397 100644 --- a/src/Localization/Game.ru.resx +++ b/src/Localization/Game.ru.resx @@ -496,6 +496,9 @@ F4: настроить размер окна чата. legacy_id=124 + + F8 - Включить/выключить полосу HP монстров + F9 - Переключить 3D-камеру diff --git a/src/Localization/Game.tl.resx b/src/Localization/Game.tl.resx index 86af77ba3..52602c0a0 100644 --- a/src/Localization/Game.tl.resx +++ b/src/Localization/Game.tl.resx @@ -496,6 +496,9 @@ F4 : Ayusin ang laki ng Chat Window legacy_id=124 + + F8 - I-on/I-off ang HP Bar ng Monster + F9 - I-toggle ang 3D Camera diff --git a/src/Localization/Game.uk.resx b/src/Localization/Game.uk.resx index 65c1f3ab1..b3c452c44 100644 --- a/src/Localization/Game.uk.resx +++ b/src/Localization/Game.uk.resx @@ -496,6 +496,9 @@ F4 : Налаштувати розмір вікна чату legacy_id=124 + + F8 - Увімкнути/вимкнути смужку HP монстрів + F9 - Перемкнути 3D-камеру diff --git a/src/Localization/Game.zh-TW.resx b/src/Localization/Game.zh-TW.resx index 188115bf4..99b36d443 100644 --- a/src/Localization/Game.zh-TW.resx +++ b/src/Localization/Game.zh-TW.resx @@ -496,6 +496,9 @@ F4 : 調整聊天視窗大小 legacy_id=124 + + F8 - 開啟/關閉怪物血條 + F9 - 切換 3D 攝影機 diff --git a/src/source/UI/NewUI/Character/NewUINameWindow.cpp b/src/source/UI/NewUI/Character/NewUINameWindow.cpp index 35990d55c..d7da48d72 100644 --- a/src/source/UI/NewUI/Character/NewUINameWindow.cpp +++ b/src/source/UI/NewUI/Character/NewUINameWindow.cpp @@ -263,7 +263,7 @@ void SEASON3B::CNewUINameWindow::RenderMonsterHealthBars() CHARACTER* c = &CharactersClient[i]; OBJECT* o = &c->Object; - if (!o->Live || !o->Visible || o->Alpha <= 0.f || c->Dead > 0 || o->Kind != KIND_MONSTER) + if (!o->Live || !o->Visible || o->Kind != KIND_MONSTER) continue; vec3_t Position; @@ -279,11 +279,6 @@ void SEASON3B::CNewUINameWindow::RenderMonsterHealthBars() CameraProjection::WorldToScreen(g_Camera, Position, &ScreenX, &ScreenY); EndOpengl(); - if (ScreenX < -100 || ScreenY < -100 - || ScreenX > (int)(WindowWidth + 100) - || ScreenY > (int)(WindowHeight + 100)) - continue; - const auto steps = 20; const auto borderWidth = 2.f; const auto widthPerStep = 4; @@ -307,15 +302,15 @@ void SEASON3B::CNewUINameWindow::RenderMonsterHealthBars() float health = c->HealthStatus; if (health < 0.0f) health = 1.0f; + int stepHP = (int)(health * steps); - float fillWidth = stepsWidth * health; - if (fillWidth > 0.f) + glColor3f(250.f / 255.f, 10 / 255.f, 0.f); + for (int k = 0; k < stepHP; ++k) { - glColor3f(250.f / 255.f, 10.f / 255.f, 0.f); RenderColor( - (float)(hpBarX + borderWidth), + (float)(hpBarX + borderWidth + (k * widthPerStep)), (float)(hpBarY + borderWidth), - fillWidth, + widthPerStep - stepSeparatorWidth, 2.f); } DisableAlphaBlend(); diff --git a/src/source/UI/NewUI/Dialogs/NewUIHelpWindow.cpp b/src/source/UI/NewUI/Dialogs/NewUIHelpWindow.cpp index 68694f4ed..b4c4059ac 100644 --- a/src/source/UI/NewUI/Dialogs/NewUIHelpWindow.cpp +++ b/src/source/UI/NewUI/Dialogs/NewUIHelpWindow.cpp @@ -132,6 +132,7 @@ bool SEASON3B::CNewUIHelpWindow::Render() // Insert engine-added camera and MU Helper hotkey entries between F4 // and the rest of the shipped entries. const wchar_t* const extraHelpLines[] = { + I18N::Game::F8ToggleMonsterHPBar, I18N::Game::F9Toggle3DCamera, I18N::Game::F10LockUnlockCameraZoom, I18N::Game::F11ResetCameraView, From dce6cb1f4d5e50079e6b522103442a3d570b0e7c Mon Sep 17 00:00:00 2001 From: nolt Date: Thu, 28 May 2026 19:45:02 +0200 Subject: [PATCH 4/5] resovle issue and fix bar --- .../UI/NewUI/Character/NewUINameWindow.cpp | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/source/UI/NewUI/Character/NewUINameWindow.cpp b/src/source/UI/NewUI/Character/NewUINameWindow.cpp index d7da48d72..0914c87ff 100644 --- a/src/source/UI/NewUI/Character/NewUINameWindow.cpp +++ b/src/source/UI/NewUI/Character/NewUINameWindow.cpp @@ -96,12 +96,19 @@ bool SEASON3B::CNewUINameWindow::UpdateKeyEvent() bool SEASON3B::CNewUINameWindow::Update() { - const bool bF8Down = (GetAsyncKeyState(VK_F8) & 0x8000) != 0; - if (bF8Down && !s_bF8KeyPressed) + if (GetFocus() == g_hWnd) { - m_bShowMonsterHealthBar = !m_bShowMonsterHealthBar; + const bool bF8Down = (GetAsyncKeyState(VK_F8) & 0x8000) != 0; + if (bF8Down && !s_bF8KeyPressed) + { + m_bShowMonsterHealthBar = !m_bShowMonsterHealthBar; + } + s_bF8KeyPressed = bF8Down; + } + else + { + s_bF8KeyPressed = false; } - s_bF8KeyPressed = bF8Down; return true; } @@ -258,12 +265,14 @@ void SEASON3B::CNewUINameWindow::RenderMonsterHealthBars() if (!m_bShowMonsterHealthBar) return; + BeginOpengl(); + for (int i = 0; i < MAX_CHARACTERS_CLIENT; i++) { CHARACTER* c = &CharactersClient[i]; OBJECT* o = &c->Object; - if (!o->Live || !o->Visible || o->Kind != KIND_MONSTER) + if (!o->Live || !o->Visible || o->Alpha <= 0.f || c->Dead > 0 || o->Kind != KIND_MONSTER) continue; vec3_t Position; @@ -275,9 +284,12 @@ void SEASON3B::CNewUINameWindow::RenderMonsterHealthBars() if (transformPos[2] >= 0) continue; - BeginOpengl(); CameraProjection::WorldToScreen(g_Camera, Position, &ScreenX, &ScreenY); - EndOpengl(); + + if (ScreenX < -100 || ScreenY < -100 + || ScreenX > (int)(WindowWidth + 100) + || ScreenY > (int)(WindowHeight + 100)) + continue; const auto steps = 20; const auto borderWidth = 2.f; @@ -302,19 +314,21 @@ void SEASON3B::CNewUINameWindow::RenderMonsterHealthBars() float health = c->HealthStatus; if (health < 0.0f) health = 1.0f; - int stepHP = (int)(health * steps); - glColor3f(250.f / 255.f, 10 / 255.f, 0.f); - for (int k = 0; k < stepHP; ++k) + float fillWidth = stepsWidth * health; + if (fillWidth > 0.f) { + glColor3f(250.f / 255.f, 10.f / 255.f, 0.f); RenderColor( - (float)(hpBarX + borderWidth + (k * widthPerStep)), + (float)(hpBarX + borderWidth), (float)(hpBarY + borderWidth), - widthPerStep - stepSeparatorWidth, + fillWidth, 2.f); } DisableAlphaBlend(); } + + EndOpengl(); } float SEASON3B::CNewUINameWindow::GetLayerDepth() From 825c5d3acf5bf95b87a6178c49845b036205893e Mon Sep 17 00:00:00 2001 From: nolt Date: Thu, 28 May 2026 21:18:10 +0200 Subject: [PATCH 5/5] fixed focus and render --- .../UI/NewUI/Character/NewUINameWindow.cpp | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/src/source/UI/NewUI/Character/NewUINameWindow.cpp b/src/source/UI/NewUI/Character/NewUINameWindow.cpp index 0914c87ff..1d4b5b7fa 100644 --- a/src/source/UI/NewUI/Character/NewUINameWindow.cpp +++ b/src/source/UI/NewUI/Character/NewUINameWindow.cpp @@ -96,19 +96,12 @@ bool SEASON3B::CNewUINameWindow::UpdateKeyEvent() bool SEASON3B::CNewUINameWindow::Update() { - if (GetFocus() == g_hWnd) + const bool bF8Down = (GetAsyncKeyState(VK_F8) & 0x8000) != 0; + if (bF8Down && !s_bF8KeyPressed) { - const bool bF8Down = (GetAsyncKeyState(VK_F8) & 0x8000) != 0; - if (bF8Down && !s_bF8KeyPressed) - { - m_bShowMonsterHealthBar = !m_bShowMonsterHealthBar; - } - s_bF8KeyPressed = bF8Down; - } - else - { - s_bF8KeyPressed = false; + m_bShowMonsterHealthBar = !m_bShowMonsterHealthBar; } + s_bF8KeyPressed = bF8Down; return true; } @@ -265,8 +258,6 @@ void SEASON3B::CNewUINameWindow::RenderMonsterHealthBars() if (!m_bShowMonsterHealthBar) return; - BeginOpengl(); - for (int i = 0; i < MAX_CHARACTERS_CLIENT; i++) { CHARACTER* c = &CharactersClient[i]; @@ -287,8 +278,8 @@ void SEASON3B::CNewUINameWindow::RenderMonsterHealthBars() CameraProjection::WorldToScreen(g_Camera, Position, &ScreenX, &ScreenY); if (ScreenX < -100 || ScreenY < -100 - || ScreenX > (int)(WindowWidth + 100) - || ScreenY > (int)(WindowHeight + 100)) + || ScreenX > (REFERENCE_WIDTH + 100) + || ScreenY > (REFERENCE_HEIGHT + 100)) continue; const auto steps = 20; @@ -327,8 +318,6 @@ void SEASON3B::CNewUINameWindow::RenderMonsterHealthBars() } DisableAlphaBlend(); } - - EndOpengl(); } float SEASON3B::CNewUINameWindow::GetLayerDepth()