UseAction hooks: GetActionInfo + GetMacroSpell, drop tooltip scans

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.
This commit is contained in:
Brues
2026-05-21 16:45:57 -05:00
parent 8e635afeed
commit 2f17546c1a
3 changed files with 39 additions and 17 deletions
+18 -6
View File
@@ -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)
+8 -4
View File
@@ -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 "" )
+13 -7
View File
@@ -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)