diff --git a/include/game/game_handler.hpp b/include/game/game_handler.hpp index 3fd92f22..40d3d96f 100644 --- a/include/game/game_handler.hpp +++ b/include/game/game_handler.hpp @@ -2194,6 +2194,7 @@ public: auto it = itemInfoCache_.find(itemId); return (it != itemInfoCache_.end()) ? &it->second : nullptr; } + const std::unordered_map& getItemInfoCache() const { return itemInfoCache_; } // Request item info from server if not already cached/pending void ensureItemInfo(uint32_t entry) { if (entry == 0 || itemInfoCache_.count(entry) || pendingItemQueries_.count(entry)) return; diff --git a/src/ui/game_screen.cpp b/src/ui/game_screen.cpp index fafe0379..c356fdef 100644 --- a/src/ui/game_screen.cpp +++ b/src/ui/game_screen.cpp @@ -8660,7 +8660,8 @@ uint32_t GameScreen::resolveMacroPrimarySpellId(uint32_t macroId, game::GameHand for (char& c : cl) c = static_cast(std::tolower(static_cast(c))); bool isCast = (cl.rfind("/cast ", 0) == 0); bool isCastSeq = (cl.rfind("/castsequence ", 0) == 0); - if (!isCast && !isCastSeq) continue; + bool isUse = (cl.rfind("/use ", 0) == 0); + if (!isCast && !isCastSeq && !isUse) continue; size_t sp2 = cmdLine.find(' '); if (sp2 == std::string::npos) continue; std::string spellArg = cmdLine.substr(sp2 + 1); @@ -8688,10 +8689,26 @@ uint32_t GameScreen::resolveMacroPrimarySpellId(uint32_t macroId, game::GameHand if (spellArg.empty()) continue; std::string spLow = spellArg; for (char& c : spLow) c = static_cast(std::tolower(static_cast(c))); - for (uint32_t sid : gameHandler.getKnownSpells()) { - std::string sn = gameHandler.getSpellName(sid); - for (char& c : sn) c = static_cast(std::tolower(static_cast(c))); - if (sn == spLow) { result = sid; break; } + if (isUse) { + // /use resolves an item name → find the item's on-use spell ID + for (const auto& [entry, info] : gameHandler.getItemInfoCache()) { + if (!info.valid) continue; + std::string iName = info.name; + for (char& c : iName) c = static_cast(std::tolower(static_cast(c))); + if (iName == spLow) { + for (const auto& sp : info.spells) { + if (sp.spellId != 0 && sp.spellTrigger == 0) { result = sp.spellId; break; } + } + break; + } + } + } else { + // /cast and /castsequence resolve a spell name + for (uint32_t sid : gameHandler.getKnownSpells()) { + std::string sn = gameHandler.getSpellName(sid); + for (char& c : sn) c = static_cast(std::tolower(static_cast(c))); + if (sn == spLow) { result = sid; break; } + } } break; } @@ -8875,7 +8892,8 @@ void GameScreen::renderActionBar(game::GameHandler& gameHandler) { for (char& c : cl) c = static_cast(std::tolower(static_cast(c))); bool isCastCmd = (cl.rfind("/cast ", 0) == 0 || cl == "/cast"); bool isCastSeqCmd = (cl.rfind("/castsequence ", 0) == 0); - if (!isCastCmd && !isCastSeqCmd) continue; + bool isUseCmd = (cl.rfind("/use ", 0) == 0); + if (!isCastCmd && !isCastSeqCmd && !isUseCmd) continue; size_t sp2 = cmdLine.find(' '); if (sp2 == std::string::npos) continue; showArg = cmdLine.substr(sp2 + 1);