From b932a07cba075443c0f5bcc247e62b475df244ab Mon Sep 17 00:00:00 2001 From: Vladislav Khorev Date: Sat, 7 Nov 2026 01:57:29 +0600 Subject: [PATCH] Fixing player HP display --- src/MenuManager.cpp | 43 ++++++++++++++++++++------ src/game_server/IGameServer.h | 2 -- src/game_server/InternalGameServer.cpp | 2 -- 3 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/MenuManager.cpp b/src/MenuManager.cpp index 28abb8d..d8581be 100644 --- a/src/MenuManager.cpp +++ b/src/MenuManager.cpp @@ -420,9 +420,24 @@ namespace FRG { } void MenuManager::refreshHudVisibility() { - const auto itemIds = server_.snapshot()->inventoryItemIds; - const auto snapshot = server_.snapshot(); + // The initial state can be loaded after the gameplay HUD was first + // constructed (notably for the remote campaign). Keep the root derived + // from the authoritative snapshot instead of relying on the transition + // callback to switch between day and Darklands HUDs. + // Pushed in-game screens (inventory, phone, journal, and pause menu) + // temporarily own the UI root while keeping the logical UI state as + // Gameplay. Do not replace those roots from the per-frame refresh. + if (uiState_ == GameUiState::Gameplay && uiManager.menuStackSize() == 0) { + const auto desiredRoot = gameplayHudRoot(); + if (uiManager.getRoot() != desiredRoot) { + uiManager.replaceRoot(desiredRoot); + applyCurrentHealthBar(); + setupGameplayHudCallbacks(); + } + } + + const auto itemIds = snapshot->inventoryItemIds; const TutorialStep step = snapshot->tutorialStep; const bool tutorial = snapshot->isTutorialActive(); const bool hasPhone = std::find(itemIds.begin(), itemIds.end(), "phone") != itemIds.end(); @@ -2212,17 +2227,25 @@ namespace FRG { void MenuManager::applyCurrentHealthBar() { logger() << "MenuManager::applyCurrentHealthBar called step 1" << std::endl; - const auto state = server_.snapshot(); - logger() << "currentPlayerMaxHp_ is " << state->playerMaxHp << std::endl; - if (state->playerMaxHp <= 0.f) return; - logger() << "MenuManager::applyCurrentHealthBar called step 2" << std::endl; - logger() << "currentPlayerHp_ is " << state->playerHp << std::endl; + const auto snapshot = server_.snapshot(); + if (!snapshot) return; - const float fraction = std::clamp(state->playerHp / state->playerMaxHp, 0.f, 1.f); + const auto playerIt = snapshot->players.find(server_.localPlayerId()); + if (playerIt == snapshot->players.end()) return; + + const CharacterState& playerState = playerIt->second.state; + const float hp = playerState.hp; + const float maxHp = playerState.initialHp; + logger() << "currentPlayerMaxHp_ is " << maxHp << std::endl; + if (maxHp <= 0.f) return; + logger() << "MenuManager::applyCurrentHealthBar called step 2" << std::endl; + logger() << "currentPlayerHp_ is " << hp << std::endl; + + const float fraction = std::clamp(hp / maxHp, 0.f, 1.f); uiManager.setSliderValue("healthBarFill", fraction); - std::string hpText = std::to_string(static_cast(state->playerHp)) + "/" + - std::to_string(static_cast(state->playerMaxHp)); + std::string hpText = std::to_string(static_cast(hp)) + "/" + + std::to_string(static_cast(maxHp)); if (hpText.size() < 7) hpText.insert(0, 7 - hpText.size(), ' '); uiManager.setText("healthValue", hpText); } diff --git a/src/game_server/IGameServer.h b/src/game_server/IGameServer.h index 54043eb..68edf7a 100644 --- a/src/game_server/IGameServer.h +++ b/src/game_server/IGameServer.h @@ -46,8 +46,6 @@ struct GameSnapshot { bool isDarklands = false; bool isNight = false; bool isDawn = false; - float playerHp = 0.f; - float playerMaxHp = 0.f; int money = 0; TutorialStep tutorialStep = TutorialStep::Completed; bool tutorialPhoneChatScreenOpened = false; diff --git a/src/game_server/InternalGameServer.cpp b/src/game_server/InternalGameServer.cpp index 1e6f680..cd24a7b 100644 --- a/src/game_server/InternalGameServer.cpp +++ b/src/game_server/InternalGameServer.cpp @@ -192,8 +192,6 @@ GameSnapshot InternalGameServer::buildSnapshot() const result.isDarklands = state_.isDarklands; result.isNight = state_.isNight; result.isDawn = state_.isDawn; - result.playerHp = state_.playerHp; - result.playerMaxHp = state_.playerMaxHp; result.money = state_.money; result.tutorialStep = state_.tutorialStep; result.tutorialPhoneChatScreenOpened = state_.tutorialPhoneChatScreenOpened;