From 2f17546c1a63d2a3e3a2f0349fb9ef99f1c75502 Mon Sep 17 00:00:00 2001 From: Brues <5278969+brues-code@users.noreply.github.com> Date: Thu, 21 May 2026 16:45:52 -0500 Subject: [PATCH] UseAction hooks: GetActionInfo + GetMacroSpell, drop tooltip scans MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The three UseAction hooks in libtotem / libpredict / libcast all did the same dance: filter out macros via GetActionText, then tooltip-scan the action to recover the spell name + rank. ClassicAPI's GetActionInfo + GetMacroSpell make both steps unnecessary: - GetActionInfo returns ("spell", spellID) or ("macro", macroSlot) - GetMacroSpell resolves a macroSlot to (name, rank, spellID) at the highest known rank, parsed engine-side at macro save time So macros are no longer skipped — they resolve to their cast spell just like a raw spell action. libtotem queue gains a real spellID (the previous "no spellId available, icon-based fallback" comment is obsolete). libcast also wins: it can feed the resolved spellID through FindSpellBookSlotByID + libspell.GetSpellInfo(slot, "spell") without the name-with-rank-suffix string concat round-trip. Drops libtipscan:GetScanner("prediction") usage in libtotem and libpredict, and libtipscan:GetScanner("libcast") in libcast. --- libs/libcast.lua | 24 ++++++++++++++++++------ libs/libpredict.lua | 12 ++++++++---- libs/libtotem.lua | 20 +++++++++++++------- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/libs/libcast.lua b/libs/libcast.lua index 2b22026e..72e06f3c 100644 --- a/libs/libcast.lua +++ b/libs/libcast.lua @@ -48,7 +48,6 @@ if pfUI.client > 11200 then return end if pfUI.api.libcast then return end local lastcasttex, lastrank, _ -local scanner = libtipscan:GetScanner("libcast") local libcast = CreateFrame("Frame", "pfEnemyCast") local player = UnitName("player") @@ -550,13 +549,26 @@ hooksecurefunc("CastSpellByName", function(spellCasted, target) end) hooksecurefunc("UseAction", function(slot, target, button) - if GetActionText(slot) or not IsCurrentAction(slot) then return end + if not IsCurrentAction(slot) then return end - scanner:SetAction(slot) - local rawSpellName, rank = scanner:Line(1) - if not rawSpellName then return end -- ignore if the spell is not found + -- Resolve action slot → spellID (handles both spell and macro actions), + -- then resolve to spellbook slot for libspell. GetMacroSpell returns the + -- highest rank the player actually knows, so FindSpellBookSlotByID's + -- "spell must be in spellbook" requirement is satisfied. + local kind, id = GetActionInfo(slot) + local spellID + if kind == "spell" then + spellID = id + elseif kind == "macro" then + local _, _, sid = GetMacroSpell(id) + spellID = sid + end + if not spellID then return end - local cachedRawSpellName, cachedRank, cachedTexture, cachedCastingTime, _, _, cachedSpellId, cachedBookType = libspell.GetSpellInfo(rawSpellName .. (rank and ("(" .. rank .. ")") or "")) + local sbSlot = FindSpellBookSlotByID(spellID) + if not sbSlot then return end + + local cachedRawSpellName, cachedRank, cachedTexture, cachedCastingTime, _, _, cachedSpellId, cachedBookType = libspell.GetSpellInfo(sbSlot, BOOKTYPE_SPELL) CastCustom(cachedSpellId, cachedBookType, cachedRawSpellName, cachedRank, cachedTexture, cachedCastingTime) end) diff --git a/libs/libpredict.lua b/libs/libpredict.lua index e8ae0e14..1b8c8ba8 100644 --- a/libs/libpredict.lua +++ b/libs/libpredict.lua @@ -1074,12 +1074,16 @@ hooksecurefunc("CastSpellByName", function(effect, target) end end) -local scanner = libtipscan:GetScanner("prediction") hooksecurefunc("UseAction", function(slot, target, selfcast) if not libpredict.sender.enabled then return end - if GetActionText(slot) or not IsCurrentAction(slot) then return end - scanner:SetAction(slot) - local effect, rank = scanner:Line(1) + if not IsCurrentAction(slot) then return end + local kind, id = GetActionInfo(slot) + local effect, rank + if kind == "spell" then + effect, rank = GetSpellInfo(id) + elseif kind == "macro" then + effect, rank = GetMacroSpell(id) + end if not effect then return end spell_queue[1] = effect spell_queue[2] = effect.. ( rank or "" ) diff --git a/libs/libtotem.lua b/libs/libtotem.lua index e0bd7c68..97560dfa 100644 --- a/libs/libtotem.lua +++ b/libs/libtotem.lua @@ -259,13 +259,19 @@ hooksecurefunc("CastSpell", function(id, bookType) libtotem:CheckAddQueue(name, rank, icon, spellId) end) --- Hook UseAction (no spellId available, icon-based fallback) -local scanner = libtipscan:GetScanner("prediction") +-- Hook UseAction. GetActionInfo + GetMacroSpell give us the spellID +-- directly for both spell-action and macro-action slots, so the +-- tooltip-scan fallback (and the "no spellId available" caveat) goes away. hooksecurefunc("UseAction", function(slot, target, selfcast) - if GetActionText(slot) or not IsCurrentAction(slot) then return end - scanner:SetAction(slot) - local name, rank = scanner:Line(1) - local icon = GetActionTexture(slot) + if not IsCurrentAction(slot) then return end + local kind, id = GetActionInfo(slot) + local name, rank, spellID + if kind == "spell" then + spellID = id + name, rank = GetSpellInfo(id) + elseif kind == "macro" then + name, rank, spellID = GetMacroSpell(id) + end if not name then return end - libtotem:CheckAddQueue(name, rank, icon, nil) + libtotem:CheckAddQueue(name, rank, GetActionTexture(slot), spellID) end) \ No newline at end of file