From a103fb5168fed98ef4c87f5220fba17fbdc7d807 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Fri, 20 Mar 2026 08:14:08 -0700 Subject: [PATCH] fix: key macro cooldown cache by macro ID instead of slot index The macro primary spell cache was keyed by action bar slot index, so switching characters or rearranging macros could return stale spell IDs from the previous character's macro in that slot. Now keyed by macro ID, which is stable per-macro regardless of which slot it occupies. --- include/ui/game_screen.hpp | 6 +++--- src/ui/game_screen.cpp | 9 ++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/include/ui/game_screen.hpp b/include/ui/game_screen.hpp index ecdeab68..a4ca889b 100644 --- a/include/ui/game_screen.hpp +++ b/include/ui/game_screen.hpp @@ -435,9 +435,9 @@ private: void loadExtendedCostDBC(); std::string formatExtendedCost(uint32_t extendedCostId, game::GameHandler& gameHandler); - // Macro cooldown cache: maps macro slot index → resolved primary spell ID (0 = no spell found) - std::unordered_map macroPrimarySpellCache_; - uint32_t resolveMacroPrimarySpellId(int slotIndex, game::GameHandler& gameHandler); + // Macro cooldown cache: maps macro ID → resolved primary spell ID (0 = no spell found) + std::unordered_map macroPrimarySpellCache_; + uint32_t resolveMacroPrimarySpellId(uint32_t macroId, game::GameHandler& gameHandler); // Death Knight rune bar: client-predicted fill (0.0=depleted, 1.0=ready) for smooth animation float runeClientFill_[6] = {1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f}; diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index bceb3372..57f82c0d 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -8642,11 +8642,10 @@ VkDescriptorSet GameScreen::getSpellIcon(uint32_t spellId, pipeline::AssetManage return ds; } -uint32_t GameScreen::resolveMacroPrimarySpellId(int slotIndex, game::GameHandler& gameHandler) { - auto cacheIt = macroPrimarySpellCache_.find(slotIndex); +uint32_t GameScreen::resolveMacroPrimarySpellId(uint32_t macroId, game::GameHandler& gameHandler) { + auto cacheIt = macroPrimarySpellCache_.find(macroId); if (cacheIt != macroPrimarySpellCache_.end()) return cacheIt->second; - uint32_t macroId = gameHandler.getActionBar()[slotIndex].id; const std::string& macroText = gameHandler.getMacroText(macroId); uint32_t result = 0; if (!macroText.empty()) { @@ -8678,7 +8677,7 @@ uint32_t GameScreen::resolveMacroPrimarySpellId(int slotIndex, game::GameHandler break; } } - macroPrimarySpellCache_[slotIndex] = result; + macroPrimarySpellCache_[macroId] = result; return result; } @@ -8733,7 +8732,7 @@ void GameScreen::renderActionBar(game::GameHandler& gameHandler) { float macroCooldownRemaining = 0.0f; float macroCooldownTotal = 0.0f; if (slot.type == game::ActionBarSlot::MACRO && slot.id != 0 && !onCooldown) { - uint32_t macroSpellId = resolveMacroPrimarySpellId(absSlot, gameHandler); + uint32_t macroSpellId = resolveMacroPrimarySpellId(slot.id, gameHandler); if (macroSpellId != 0) { float cd = gameHandler.getSpellCooldown(macroSpellId); if (cd > 0.0f) {