From 71f8f74237ad5840405dac64287a59e78cd64ff2 Mon Sep 17 00:00:00 2001 From: Brues <5278969+brues-code@users.noreply.github.com> Date: Thu, 6 Aug 2026 00:15:19 -0500 Subject: [PATCH] Support #showtooltip spell: and item: GetSpell/GetItem now resolve explicit spell:/item: ID forms. spell: prefers the player's spellbook entry via FindSpellBookSlotByID (per-rank and pet aware) for full cost/cooldown/usability, falling back to an id-only entry rendered via SetSpellByID for spells not in the book. item: reuses the existing numeric lookup for location-aware tooltips. Guard the id-only path against nil spellSlot/cost in TestForActiveAction and GetActionCooldown so display-only spell references don't crash. Remove the dead, no-op GetSpellSlotByID stub. --- Core.lua | 7 +++++-- Extensions/Tooltip/Generic.lua | 27 +++++++++++++++++++++++++++ Utility.lua | 12 ------------ 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/Core.lua b/Core.lua index 166622d..f486c3d 100644 --- a/Core.lua +++ b/Core.lua @@ -970,7 +970,10 @@ function CleveRoids.TestForActiveAction(actions) actions.active.oom = (manaToCheck < actions.active.spell.cost) end - local start, duration = GetSpellCooldown(actions.active.spell.spellSlot, actions.active.spell.bookType) + local start, duration = 0, 0 + if actions.active.spell.spellSlot then + start, duration = GetSpellCooldown(actions.active.spell.spellSlot, actions.active.spell.bookType) + end local onCooldown = (start > 0 and duration > 0) if actions.active.isReactive then @@ -4626,7 +4629,7 @@ function GetActionCooldown(slot) return GetInventoryItemCooldown("player", slotId) end - if a.spell then + if a.spell and a.spell.spellSlot then return GetSpellCooldown(a.spell.spellSlot, a.spell.bookType) elseif a.item then if a.item.bagID and a.item.slot then diff --git a/Extensions/Tooltip/Generic.lua b/Extensions/Tooltip/Generic.lua index 664f843..c48166e 100644 --- a/Extensions/Tooltip/Generic.lua +++ b/Extensions/Tooltip/Generic.lua @@ -421,6 +421,27 @@ end function CleveRoids.GetSpell(text) text = CleveRoids.Trim(text) + + -- Explicit "spell:" form. If the player knows the spell, reuse its cached + -- spellbook entry (full cost/cooldown/usability). FindSpellBookSlotByID + -- (ClassicAPI) resolves per-rank IDs and pet spells natively and returns the + -- same bookType string CleveRoids.Spells is keyed by. If the spell is not in + -- either book, fall back to an id-only entry that SetAction renders via + -- SetSpellByID; cost=0 keeps the downstream active-action checks nil-safe. + local _, _, spellId = string.find(text, "^spell:(%d+)$") + if spellId then + spellId = tonumber(spellId) + local slot, book = FindSpellBookSlotByID(spellId) + if slot then + local name, rank = GetSpellInfo(slot, book) + local byName = name and CleveRoids.Spells[book] and CleveRoids.Spells[book][name] + if byName then + return (rank and rank ~= "" and byName[rank]) or byName.highest or byName + end + end + return { id = spellId, texture = C_Spell.GetSpellTexture(spellId) or CleveRoids.unknownTexture, cost = 0 } + end + local rs, _, rank = string.find(text, "[^%s]%((Rank %d+)%)$") local name = rank and string.sub(text, 1, rs) or text @@ -508,6 +529,12 @@ end function CleveRoids.GetItem(text) if not text or text == "" then return end + -- Explicit "item:" form: force resolution by item ID. Reuses the numeric + -- lookup below (equipped -> bags -> GetItemInfo), so location-aware tooltip + -- rendering (SetInventoryItem/SetBagItem) still applies when the player has it. + local _, _, prefixedId = string.find(text, "^item:(%d+)$") + if prefixedId then text = prefixedId end + local Items = CleveRoids.Items local item = Items[text] or Items[tostring(text)] if not item then diff --git a/Utility.lua b/Utility.lua index e3f1f80..86495ec 100644 --- a/Utility.lua +++ b/Utility.lua @@ -117,18 +117,6 @@ local cachedSpellDurations = {} local spellDurationCacheTime = {} local SPELL_CACHE_DURATION = 0.5 -- Re-scan every 0.5 seconds (haste can change mid-fight) --- Get a spell's slot in the spellbook by spell ID -local function GetSpellSlotByID(targetSpellID) - local i = 1 - while true do - local spellName = GetSpellName(i, BOOKTYPE_SPELL) - if not spellName then break end - -- Note: spell ID matching done via GetSpellTexture comparison if needed - i = i + 1 - end - return nil, nil -end - -- Get a spell's slot in the spellbook by name (finds highest rank by default) -- If targetRank is specified (e.g., "Rank 5"), finds that specific rank local function GetSpellSlotByName(targetSpellName, targetRank)