From aed8c94544dde4b8366bd59a976791d91232eb7e Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 18 Mar 2026 12:21:41 -0700 Subject: [PATCH] feat: add instance difficulty indicator on minimap Show Normal/Heroic/25-Man difficulty badge below zone name when inside a dungeon or raid instance. Orange-highlighted for heroic modes. --- include/game/game_handler.hpp | 6 ++++++ src/game/game_handler.cpp | 2 ++ src/ui/game_screen.cpp | 25 +++++++++++++++++++++++++ 3 files changed, 33 insertions(+) diff --git a/include/game/game_handler.hpp b/include/game/game_handler.hpp index 254a6d79..9f362cb0 100644 --- a/include/game/game_handler.hpp +++ b/include/game/game_handler.hpp @@ -1230,6 +1230,11 @@ public: void closeBarberShop() { barberShopOpen_ = false; } void sendAlterAppearance(uint32_t hairStyle, uint32_t hairColor, uint32_t facialHair); + // Instance difficulty (0=5N, 1=5H, 2=25N, 3=25H for WotLK) + uint32_t getInstanceDifficulty() const { return instanceDifficulty_; } + bool isInstanceHeroic() const { return instanceIsHeroic_; } + bool isInInstance() const { return inInstance_; } + /** True when ghost is within 40 yards of corpse position (same map). */ bool canReclaimCorpse() const; /** Seconds remaining on the PvP corpse-reclaim delay, or 0 if the reclaim is available now. */ @@ -2867,6 +2872,7 @@ private: // Instance difficulty uint32_t instanceDifficulty_ = 0; bool instanceIsHeroic_ = false; + bool inInstance_ = false; // Raid target markers (icon 0-7 -> guid; 0 = empty slot) std::array raidTargetGuids_ = {}; diff --git a/src/game/game_handler.cpp b/src/game/game_handler.cpp index 301ca142..a9b9262e 100644 --- a/src/game/game_handler.cpp +++ b/src/game/game_handler.cpp @@ -16458,6 +16458,7 @@ void GameHandler::handleInstanceDifficulty(network::Packet& packet) { } else { instanceIsHeroic_ = (instanceDifficulty_ == 1); } + inInstance_ = true; LOG_INFO("Instance difficulty: ", instanceDifficulty_, " heroic=", instanceIsHeroic_); // Announce difficulty change to the player (only when it actually changes) @@ -22386,6 +22387,7 @@ void GameHandler::handleNewWorld(network::Packet& packet) { } currentMapId_ = mapId; + inInstance_ = false; // cleared on map change; re-set if SMSG_INSTANCE_DIFFICULTY follows if (socket) { socket->tracePacketsFor(std::chrono::seconds(12), "new_world"); } diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index 26c38c32..7c2cd196 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -19650,6 +19650,31 @@ void GameScreen::renderMinimapMarkers(game::GameHandler& gameHandler) { } } + // Instance difficulty indicator — just below zone name, inside minimap top edge + if (gameHandler.isInInstance()) { + static const char* kDiffLabels[] = {"Normal", "Heroic", "25 Normal", "25 Heroic"}; + uint32_t diff = gameHandler.getInstanceDifficulty(); + const char* label = (diff < 4) ? kDiffLabels[diff] : "Unknown"; + + ImFont* font = ImGui::GetFont(); + float fontSize = ImGui::GetFontSize() * 0.85f; + ImVec2 ts = font->CalcTextSizeA(fontSize, FLT_MAX, 0.0f, label); + float tx = centerX - ts.x * 0.5f; + // Position below zone name: top edge + zone font size + small gap + float ty = centerY - mapRadius + 4.0f + ImGui::GetFontSize() + 2.0f; + float pad = 2.0f; + + // Color-code: heroic=orange, normal=light gray + ImU32 bgCol = gameHandler.isInstanceHeroic() ? IM_COL32(120, 60, 0, 180) : IM_COL32(0, 0, 0, 160); + ImU32 textCol = gameHandler.isInstanceHeroic() ? IM_COL32(255, 180, 50, 255) : IM_COL32(200, 200, 200, 220); + + drawList->AddRectFilled( + ImVec2(tx - pad, ty - pad), + ImVec2(tx + ts.x + pad, ty + ts.y + pad), + bgCol, 2.0f); + drawList->AddText(font, fontSize, ImVec2(tx, ty), textCol, label); + } + // Hover tooltip and right-click context menu { ImVec2 mouse = ImGui::GetMousePos();