mirror of
https://github.com/brues-code/SuperCleveRoidMacros.git
synced 2026-09-16 03:38:00 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
004eebc9f7 | ||
|
|
63b484b1ea | ||
|
|
cf47d8caba | ||
|
|
71f8f74237 | ||
|
|
1a98a05b7e |
@@ -970,7 +970,10 @@ function CleveRoids.TestForActiveAction(actions)
|
|||||||
actions.active.oom = (manaToCheck < actions.active.spell.cost)
|
actions.active.oom = (manaToCheck < actions.active.spell.cost)
|
||||||
end
|
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)
|
local onCooldown = (start > 0 and duration > 0)
|
||||||
|
|
||||||
if actions.active.isReactive then
|
if actions.active.isReactive then
|
||||||
@@ -3901,6 +3904,17 @@ function CleveRoids.OnUpdate(self)
|
|||||||
-- PERFORMANCE: Single GetTime() call per frame
|
-- PERFORMANCE: Single GetTime() call per frame
|
||||||
local time = GetTime()
|
local time = GetTime()
|
||||||
|
|
||||||
|
-- Coalesced macro/spell/action-bar rebuild (armed by UPDATE_MACROS,
|
||||||
|
-- SPELLS_CHANGED and PLAYER_LOGIN). Debounced so the login burst -
|
||||||
|
-- SPELLS_CHANGED fires several times as the spellbook populates - collapses
|
||||||
|
-- into a single rebuild. Runs even before `ready` so spells/talents are
|
||||||
|
-- indexed before the init timer's first action-bar pass; RebuildMacros
|
||||||
|
-- itself skips the 120-slot action-bar rebuild until ready.
|
||||||
|
if CR.macroRebuildTime and time >= CR.macroRebuildTime then
|
||||||
|
CR.macroRebuildTime = nil
|
||||||
|
CR.RebuildMacros()
|
||||||
|
end
|
||||||
|
|
||||||
-- PERFORMANCE: Early exit if not ready (before any other checks)
|
-- PERFORMANCE: Early exit if not ready (before any other checks)
|
||||||
if not CR.ready then
|
if not CR.ready then
|
||||||
-- Handle initialization timer only when not ready
|
-- Handle initialization timer only when not ready
|
||||||
@@ -3939,10 +3953,21 @@ function CleveRoids.OnUpdate(self)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- PERFORMANCE: Delayed WDB warmup after login (ensures GetItemInfo works after WDB clear)
|
-- Coalesced re-index after async item data arrives (GET_ITEM_INFO_RECEIVED).
|
||||||
if CR.wdbWarmupTime and time >= CR.wdbWarmupTime then
|
-- ClassicAPI warms the item cache asynchronously, so items that were still
|
||||||
CR.wdbWarmupTime = nil
|
-- uncached during an earlier index pass land here once their
|
||||||
CR.DoWDBWarmup()
|
-- SMSG_ITEM_QUERY_SINGLE response resolves. Bursts are debounced into one
|
||||||
|
-- re-index via CR.itemInfoReindexTime (armed by the event handler).
|
||||||
|
if CR.itemInfoReindexTime and time >= CR.itemInfoReindexTime then
|
||||||
|
CR.itemInfoReindexTime = nil
|
||||||
|
-- In combat: drop it; PLAYER_LEAVE_COMBAT does a full re-index once safe.
|
||||||
|
if not UnitAffectingCombat("player") then
|
||||||
|
CR.lastItemIndexTime = GetTime()
|
||||||
|
CR.IndexItems()
|
||||||
|
CR.Actions = {}
|
||||||
|
CR.Macros = {}
|
||||||
|
CR.IndexActionBars()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- PERFORMANCE: Cache refresh rate calculation (avoid per-frame division)
|
-- PERFORMANCE: Cache refresh rate calculation (avoid per-frame division)
|
||||||
@@ -4189,11 +4214,7 @@ function GameTooltip.SetAction(self, slot)
|
|||||||
|
|
||||||
local current_spell_data = CleveRoids.GetSpell(action_name)
|
local current_spell_data = CleveRoids.GetSpell(action_name)
|
||||||
if current_spell_data and current_spell_data.id then
|
if current_spell_data and current_spell_data.id then
|
||||||
if current_spell_data.spellSlot and current_spell_data.bookType then
|
GameTooltip:SetSpellByID(current_spell_data.id)
|
||||||
GameTooltip:SetSpell(current_spell_data.spellSlot, current_spell_data.bookType)
|
|
||||||
else
|
|
||||||
GameTooltip:SetSpellByID(current_spell_data.id)
|
|
||||||
end
|
|
||||||
GameTooltip:Show()
|
GameTooltip:Show()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@@ -4626,7 +4647,7 @@ function GetActionCooldown(slot)
|
|||||||
return GetInventoryItemCooldown("player", slotId)
|
return GetInventoryItemCooldown("player", slotId)
|
||||||
end
|
end
|
||||||
|
|
||||||
if a.spell then
|
if a.spell and a.spell.spellSlot then
|
||||||
return GetSpellCooldown(a.spell.spellSlot, a.spell.bookType)
|
return GetSpellCooldown(a.spell.spellSlot, a.spell.bookType)
|
||||||
elseif a.item then
|
elseif a.item then
|
||||||
if a.item.bagID and a.item.slot then
|
if a.item.bagID and a.item.slot then
|
||||||
@@ -4825,6 +4846,7 @@ CleveRoids.Frame:RegisterEvent("UPDATE_MACROS")
|
|||||||
CleveRoids.Frame:RegisterEvent("SPELLS_CHANGED")
|
CleveRoids.Frame:RegisterEvent("SPELLS_CHANGED")
|
||||||
CleveRoids.Frame:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
|
CleveRoids.Frame:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
|
||||||
CleveRoids.Frame:RegisterEvent("BAG_UPDATE_DELAYED")
|
CleveRoids.Frame:RegisterEvent("BAG_UPDATE_DELAYED")
|
||||||
|
CleveRoids.Frame:RegisterEvent("GET_ITEM_INFO_RECEIVED")
|
||||||
CleveRoids.Frame:RegisterEvent("PLAYER_EQUIPMENT_CHANGED")
|
CleveRoids.Frame:RegisterEvent("PLAYER_EQUIPMENT_CHANGED")
|
||||||
CleveRoids.Frame:RegisterEvent("UNIT_PET")
|
CleveRoids.Frame:RegisterEvent("UNIT_PET")
|
||||||
|
|
||||||
@@ -4963,59 +4985,13 @@ function CleveRoids.Frame:PLAYER_LOGIN()
|
|||||||
CleveRoids.IndexPetSpells()
|
CleveRoids.IndexPetSpells()
|
||||||
CleveRoids.initializationTimer = GetTime() + 1.5
|
CleveRoids.initializationTimer = GetTime() + 1.5
|
||||||
|
|
||||||
|
-- Guarantee a full index (talents + macros + action bars) even if
|
||||||
|
-- UPDATE_MACROS / SPELLS_CHANGED happen not to fire before the init timer.
|
||||||
|
-- Coalesces with those events' arming; RebuildMacros runs once for the burst.
|
||||||
|
CleveRoids.macroRebuildTime = GetTime() + 0.3
|
||||||
|
|
||||||
-- PERFORMANCE: Initialize event-driven cache states
|
-- PERFORMANCE: Initialize event-driven cache states
|
||||||
CleveRoids._cachedPlayerInCombat = UnitAffectingCombat("player") and true or false
|
CleveRoids._cachedPlayerInCombat = UnitAffectingCombat("player") and true or false
|
||||||
|
|
||||||
-- Schedule delayed WDB warmup (loads items into client cache via tooltip scan)
|
|
||||||
-- This ensures GetItemInfo() works for all inventory items after a WDB clear
|
|
||||||
CleveRoids.wdbWarmupTime = GetTime() + 3.0 -- 3 second delay after login
|
|
||||||
end
|
|
||||||
|
|
||||||
-- PERFORMANCE: WDB warmup - tooltip scan all bag items to ensure they're cached
|
|
||||||
-- This prevents GetItemInfo() returning nil for items after a WDB clear
|
|
||||||
function CleveRoids.DoWDBWarmup()
|
|
||||||
if CleveRoids.wdbWarmupDone then return end
|
|
||||||
CleveRoids.wdbWarmupDone = true
|
|
||||||
|
|
||||||
-- Create a hidden tooltip for scanning if it doesn't exist
|
|
||||||
local tip = CleveRoidsWDBTip
|
|
||||||
if not tip then
|
|
||||||
tip = CreateFrame("GameTooltip", "CleveRoidsWDBTip", UIParent, "GameTooltipTemplate")
|
|
||||||
tip:SetOwner(WorldFrame, "ANCHOR_NONE")
|
|
||||||
end
|
|
||||||
|
|
||||||
local scanned = 0
|
|
||||||
|
|
||||||
-- Scan all bag slots
|
|
||||||
for bag = 0, 4 do
|
|
||||||
local slots = GetContainerNumSlots(bag) or 0
|
|
||||||
for slot = 1, slots do
|
|
||||||
if C_Container.GetContainerItemID(bag, slot) then
|
|
||||||
-- Tooltip scan loads the item into WDB
|
|
||||||
tip:ClearLines()
|
|
||||||
tip:SetBagItem(bag, slot)
|
|
||||||
scanned = scanned + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Scan equipped items
|
|
||||||
for slot = 1, 19 do
|
|
||||||
if GetInventoryItemID("player", slot) then
|
|
||||||
tip:ClearLines()
|
|
||||||
tip:SetInventoryItem("player", slot)
|
|
||||||
scanned = scanned + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Now trigger a full item index to populate the cache with valid data
|
|
||||||
if CleveRoids.IndexItems then
|
|
||||||
CleveRoids.IndexItems()
|
|
||||||
end
|
|
||||||
|
|
||||||
if CleveRoids.debug then
|
|
||||||
CleveRoids.Print("|cff88ff88[WDB Warmup]|r Scanned " .. scanned .. " items into cache")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function CleveRoids.Frame:ADDON_LOADED(addon)
|
function CleveRoids.Frame:ADDON_LOADED(addon)
|
||||||
@@ -5652,35 +5628,44 @@ function CleveRoids.Frame:PLAYER_TARGET_CHANGED()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function CleveRoids.Frame:UPDATE_MACROS()
|
-- Full rebuild of the macro/spell/talent/action-bar index. Invoked from the
|
||||||
|
-- update loop when macroRebuildTime elapses (armed by UPDATE_MACROS /
|
||||||
|
-- SPELLS_CHANGED / PLAYER_LOGIN), never inline from an event - so a burst of
|
||||||
|
-- those events collapses into one rebuild.
|
||||||
|
function CleveRoids.RebuildMacros()
|
||||||
CleveRoids.currentSequence = nil
|
CleveRoids.currentSequence = nil
|
||||||
-- Explicitly nil tables before re-assignment
|
|
||||||
CleveRoids.ParsedMsg = nil;
|
|
||||||
CleveRoids.ParsedMsg = {}
|
CleveRoids.ParsedMsg = {}
|
||||||
|
|
||||||
CleveRoids.Macros = nil;
|
|
||||||
CleveRoids.Macros = {}
|
CleveRoids.Macros = {}
|
||||||
|
|
||||||
CleveRoids.Actions = nil;
|
|
||||||
CleveRoids.Actions = {}
|
CleveRoids.Actions = {}
|
||||||
|
|
||||||
CleveRoids.Sequences = nil;
|
|
||||||
CleveRoids.Sequences = {}
|
CleveRoids.Sequences = {}
|
||||||
|
|
||||||
CleveRoids.IndexSpells()
|
CleveRoids.IndexSpells()
|
||||||
CleveRoids.IndexTalents()
|
CleveRoids.IndexTalents()
|
||||||
CleveRoids.IndexPetSpells()
|
CleveRoids.IndexPetSpells()
|
||||||
CleveRoids.IndexActionBars()
|
|
||||||
|
-- Action-bar indexing is wasted before `ready` (GetAction early-returns
|
||||||
|
-- while not ready), and the +1.5s init timer rebuilds the bars once anyway.
|
||||||
|
-- Skipping it here keeps the pre-ready login rebuilds from fanning 120 slot
|
||||||
|
-- updates out to Blizzard/pfUI/Bongos buttons.
|
||||||
|
if CleveRoids.ready then
|
||||||
|
CleveRoids.IndexActionBars()
|
||||||
|
end
|
||||||
|
|
||||||
if CleveRoidMacros.realtime == 0 then
|
if CleveRoidMacros.realtime == 0 then
|
||||||
CleveRoids.QueueActionUpdate()
|
CleveRoids.QueueActionUpdate()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function CleveRoids.Frame:UPDATE_MACROS()
|
||||||
|
-- Debounce: collapse bursts (login, rapid macro edits) into one rebuild.
|
||||||
|
CleveRoids.macroRebuildTime = GetTime() + 0.3
|
||||||
|
end
|
||||||
|
|
||||||
function CleveRoids.Frame:SPELLS_CHANGED()
|
function CleveRoids.Frame:SPELLS_CHANGED()
|
||||||
-- PERFORMANCE: Clear spell caches when spells change (learn new ranks, etc.)
|
-- Clear spell caches immediately (cheap); defer the heavy rebuild.
|
||||||
CleveRoids.spellIdCache = {}
|
CleveRoids.spellIdCache = {}
|
||||||
CleveRoids.spellNameCache = {}
|
CleveRoids.spellNameCache = {}
|
||||||
CleveRoids.Frame:UPDATE_MACROS()
|
CleveRoids.macroRebuildTime = GetTime() + 0.3
|
||||||
end
|
end
|
||||||
|
|
||||||
function CleveRoids.Frame:ACTIONBAR_SLOT_CHANGED()
|
function CleveRoids.Frame:ACTIONBAR_SLOT_CHANGED()
|
||||||
@@ -5691,6 +5676,23 @@ function CleveRoids.Frame:ACTIONBAR_SLOT_CHANGED()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- ClassicAPI fires GET_ITEM_INFO_RECEIVED when an async item-cache fill lands
|
||||||
|
-- (the hooked GetItemInfo auto-warms on a miss). It fires for EVERY fill in the
|
||||||
|
-- game though - quest DB scans, AH sweeps, chat-link hovers, inspects - so we
|
||||||
|
-- ignore anything not in pendingItemInfo (items we own that missed the last
|
||||||
|
-- index pass). That check is O(1) and keeps unrelated bursts free.
|
||||||
|
function CleveRoids.Frame:GET_ITEM_INFO_RECEIVED()
|
||||||
|
local pending = CleveRoids.pendingItemInfo
|
||||||
|
if not (pending and pending[arg1]) then return end
|
||||||
|
-- Skip during combat; PLAYER_LEAVE_COMBAT re-indexes once it's safe.
|
||||||
|
if UnitAffectingCombat("player") then return end
|
||||||
|
-- Arm once per burst; the update loop clears it after re-indexing. Later
|
||||||
|
-- arrivals re-arm it, guaranteeing the final resolved state is captured.
|
||||||
|
if not CleveRoids.itemInfoReindexTime then
|
||||||
|
CleveRoids.itemInfoReindexTime = GetTime() + 0.5
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function CleveRoids.Frame:BAG_UPDATE_DELAYED()
|
function CleveRoids.Frame:BAG_UPDATE_DELAYED()
|
||||||
-- In combat: Skip expensive indexing but still queue icon update
|
-- In combat: Skip expensive indexing but still queue icon update
|
||||||
-- so conditionals like [inbag] re-evaluate (they use live bag APIs)
|
-- so conditionals like [inbag] re-evaluate (they use live bag APIs)
|
||||||
@@ -5707,10 +5709,15 @@ function CleveRoids.Frame:BAG_UPDATE_DELAYED()
|
|||||||
CleveRoids.lastItemIndexTime = now
|
CleveRoids.lastItemIndexTime = now
|
||||||
CleveRoids.IndexItems()
|
CleveRoids.IndexItems()
|
||||||
|
|
||||||
-- Directly clear all relevant caches and force a UI refresh for all buttons.
|
-- Rebuild action bars so item-dependent macro resolution refreshes.
|
||||||
CleveRoids.Actions = {}
|
-- Skipped before `ready` (GetAction early-returns; the +1.5s init timer
|
||||||
CleveRoids.Macros = {}
|
-- builds the bars), which keeps bag-fill events during login from firing
|
||||||
CleveRoids.IndexActionBars()
|
-- a full 120-slot rebuild each time.
|
||||||
|
if CleveRoids.ready then
|
||||||
|
CleveRoids.Actions = {}
|
||||||
|
CleveRoids.Macros = {}
|
||||||
|
CleveRoids.IndexActionBars()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Always queue icon update so conditionals like [inbag] re-evaluate
|
-- Always queue icon update so conditionals like [inbag] re-evaluate
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ local function ResolvePfUnit(frame, fallbackName)
|
|||||||
name = strlower(name)
|
name = strlower(name)
|
||||||
|
|
||||||
local candidates = { "target", "targettarget", "player", "pet" }
|
local candidates = { "target", "targettarget", "player", "pet" }
|
||||||
local i
|
|
||||||
for i = 1, 4 do
|
for i = 1, 4 do
|
||||||
table.insert(candidates, "party"..i)
|
table.insert(candidates, "party"..i)
|
||||||
table.insert(candidates, "partypet"..i)
|
table.insert(candidates, "partypet"..i)
|
||||||
@@ -156,7 +155,6 @@ end
|
|||||||
function Extension.RegisterPartyScripts()
|
function Extension.RegisterPartyScripts()
|
||||||
if not pfUI or not pfUI.uf or not pfUI.uf.group then return end
|
if not pfUI or not pfUI.uf or not pfUI.uf.group then return end
|
||||||
|
|
||||||
local i
|
|
||||||
for i = 0, 4 do
|
for i = 0, 4 do
|
||||||
local frame = pfUI.uf.group[i]
|
local frame = pfUI.uf.group[i]
|
||||||
if frame then
|
if frame then
|
||||||
@@ -184,7 +182,6 @@ end
|
|||||||
function Extension.RegisterRaidScripts()
|
function Extension.RegisterRaidScripts()
|
||||||
if not pfUI or not pfUI.uf or not pfUI.uf.raid then return end
|
if not pfUI or not pfUI.uf or not pfUI.uf.raid then return end
|
||||||
|
|
||||||
local i
|
|
||||||
for i = 1, 40 do
|
for i = 1, 40 do
|
||||||
local frame = pfUI.uf.raid[i]
|
local frame = pfUI.uf.raid[i]
|
||||||
if frame then
|
if frame then
|
||||||
@@ -336,7 +333,6 @@ end
|
|||||||
function Extension.RegisterRaidMarkScripts()
|
function Extension.RegisterRaidMarkScripts()
|
||||||
if not pfUI or not pfUI.raidmarkers or not pfUI.raidmarkers.rows then return end
|
if not pfUI or not pfUI.raidmarkers or not pfUI.raidmarkers.rows then return end
|
||||||
|
|
||||||
local i
|
|
||||||
for i = 1, 8 do
|
for i = 1, 8 do
|
||||||
local row = pfUI.raidmarkers.rows[i]
|
local row = pfUI.raidmarkers.rows[i]
|
||||||
if row then
|
if row then
|
||||||
|
|||||||
@@ -238,6 +238,14 @@ function CleveRoids.IndexItems()
|
|||||||
local items = {}
|
local items = {}
|
||||||
local NUM_BAG_SLOTS = NUM_BAG_SLOTS -- Upvalue for bag constant
|
local NUM_BAG_SLOTS = NUM_BAG_SLOTS -- Upvalue for bag constant
|
||||||
|
|
||||||
|
-- Rebuilt each pass: itemIDs the player owns that GetItemInfo couldn't
|
||||||
|
-- resolve yet (cold cache under ClassicAPI's async warmup). The
|
||||||
|
-- GET_ITEM_INFO_RECEIVED handler consults this so it only re-indexes for
|
||||||
|
-- our own uncached items and ignores the flood of unrelated fills (quest
|
||||||
|
-- DB scans, AH, chat-link hovers, inspects) in O(1).
|
||||||
|
local pendingItemInfo = {}
|
||||||
|
CleveRoids.pendingItemInfo = pendingItemInfo
|
||||||
|
|
||||||
-- PERFORMANCE: Local function references
|
-- PERFORMANCE: Local function references
|
||||||
local GetContainerNumSlots = GetContainerNumSlots
|
local GetContainerNumSlots = GetContainerNumSlots
|
||||||
local GetContainerItemInfo = GetContainerItemInfo
|
local GetContainerItemInfo = GetContainerItemInfo
|
||||||
@@ -281,6 +289,9 @@ function CleveRoids.IndexItems()
|
|||||||
if lowerName ~= name then
|
if lowerName ~= name then
|
||||||
items[lowerName] = name
|
items[lowerName] = name
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
-- Owned but not cached yet; wait for GET_ITEM_INFO_RECEIVED.
|
||||||
|
pendingItemInfo[itemID] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -318,6 +329,9 @@ function CleveRoids.IndexItems()
|
|||||||
if lowerName ~= name then
|
if lowerName ~= name then
|
||||||
items[lowerName] = name
|
items[lowerName] = name
|
||||||
end
|
end
|
||||||
|
else
|
||||||
|
-- Owned but not cached yet; wait for GET_ITEM_INFO_RECEIVED.
|
||||||
|
pendingItemInfo[itemID] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -421,6 +435,27 @@ end
|
|||||||
|
|
||||||
function CleveRoids.GetSpell(text)
|
function CleveRoids.GetSpell(text)
|
||||||
text = CleveRoids.Trim(text)
|
text = CleveRoids.Trim(text)
|
||||||
|
|
||||||
|
-- Explicit "spell:<id>" 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 rs, _, rank = string.find(text, "[^%s]%((Rank %d+)%)$")
|
||||||
local name = rank and string.sub(text, 1, rs) or text
|
local name = rank and string.sub(text, 1, rs) or text
|
||||||
|
|
||||||
@@ -508,6 +543,12 @@ end
|
|||||||
function CleveRoids.GetItem(text)
|
function CleveRoids.GetItem(text)
|
||||||
if not text or text == "" then return end
|
if not text or text == "" then return end
|
||||||
|
|
||||||
|
-- Explicit "item:<id>" 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 Items = CleveRoids.Items
|
||||||
local item = Items[text] or Items[tostring(text)]
|
local item = Items[text] or Items[tostring(text)]
|
||||||
if not item then
|
if not item then
|
||||||
|
|||||||
-12
@@ -117,18 +117,6 @@ local cachedSpellDurations = {}
|
|||||||
local spellDurationCacheTime = {}
|
local spellDurationCacheTime = {}
|
||||||
local SPELL_CACHE_DURATION = 0.5 -- Re-scan every 0.5 seconds (haste can change mid-fight)
|
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)
|
-- 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
|
-- If targetRank is specified (e.g., "Rank 5"), finds that specific rank
|
||||||
local function GetSpellSlotByName(targetSpellName, targetRank)
|
local function GetSpellSlotByName(targetSpellName, targetRank)
|
||||||
|
|||||||
Reference in New Issue
Block a user