From f9947300da7c6236c1029c0a6582dc4b7390a655 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Tue, 17 Mar 2026 19:14:17 -0700 Subject: [PATCH] feat: show zone entry text on every zone crossing via SMSG_INIT_WORLD_STATES Previously the "Entering: [Zone]" overlay only triggered when the terrain renderer loaded a new map. Now it also fires whenever worldStateZoneId_ changes (sent by the server via SMSG_INIT_WORLD_STATES on each zone crossing), giving correct "Entering: Ironforge", "Entering: Wailing Caverns" etc. display for sub-zones and dungeon entries without requiring a full map reload. - Added lastKnownWorldStateZoneId_ to track server-reported zone changes - renderZoneText() now takes GameHandler& to access getWorldStateZoneId() and getWhoAreaName() for name lookup via WorldMapArea.dbc cache - Renderer zone name still checked as a fallback for map-level transitions - Both sources de-duplicate to avoid triggering the same text twice --- include/ui/game_screen.hpp | 3 ++- src/ui/game_screen.cpp | 26 +++++++++++++++++++++----- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/include/ui/game_screen.hpp b/include/ui/game_screen.hpp index 6a7212b9..3acd13b0 100644 --- a/include/ui/game_screen.hpp +++ b/include/ui/game_screen.hpp @@ -634,7 +634,8 @@ private: float zoneTextTimer_ = 0.0f; std::string zoneTextName_; std::string lastKnownZoneName_; - void renderZoneText(); + uint32_t lastKnownWorldStateZoneId_ = 0; + void renderZoneText(game::GameHandler& gameHandler); void renderWeatherOverlay(game::GameHandler& gameHandler); // Cooldown tracker diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index 7358a59c..e26815e5 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -744,7 +744,7 @@ void GameScreen::render(game::GameHandler& gameHandler) { renderPvpHonorToasts(); renderItemLootToasts(); renderResurrectFlash(); - renderZoneText(); + renderZoneText(gameHandler); renderWeatherOverlay(gameHandler); // World map (M key toggle handled inside) @@ -20496,15 +20496,31 @@ void GameScreen::renderWhisperToasts() { // Zone discovery text — "Entering: " fades in/out at screen centre // --------------------------------------------------------------------------- -void GameScreen::renderZoneText() { - // Poll the renderer for zone name changes +void GameScreen::renderZoneText(game::GameHandler& gameHandler) { + // Poll worldStateZoneId for server-driven zone changes (fires on every zone crossing, + // including sub-zones like Ironforge within Dun Morogh). + uint32_t wsZoneId = gameHandler.getWorldStateZoneId(); + if (wsZoneId != 0 && wsZoneId != lastKnownWorldStateZoneId_) { + lastKnownWorldStateZoneId_ = wsZoneId; + std::string wsName = gameHandler.getWhoAreaName(wsZoneId); + if (!wsName.empty()) { + zoneTextName_ = wsName; + zoneTextTimer_ = ZONE_TEXT_DURATION; + } + } + + // Also poll the renderer for zone name changes (covers map-level transitions + // where worldStateZoneId may not change immediately). auto* appRenderer = core::Application::getInstance().getRenderer(); if (appRenderer) { const std::string& zoneName = appRenderer->getCurrentZoneName(); if (!zoneName.empty() && zoneName != lastKnownZoneName_) { lastKnownZoneName_ = zoneName; - zoneTextName_ = zoneName; - zoneTextTimer_ = ZONE_TEXT_DURATION; + // Only override if the worldState hasn't already queued this zone + if (zoneTextName_ != zoneName) { + zoneTextName_ = zoneName; + zoneTextTimer_ = ZONE_TEXT_DURATION; + } } }