mirror of
https://github.com/brues-code/SuperCleveRoidMacros.git
synced 2026-09-16 03:38:00 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
40cf2c8010 | ||
|
|
a5a0b9c00a | ||
|
|
6e57ff01dc | ||
|
|
9cd79d682d | ||
|
|
f54eda5ae3 | ||
|
|
653f8db3d7 |
+41
-69
@@ -273,24 +273,17 @@ local function BuildEquipmentCache()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Fallback: manual slot enumeration
|
-- Fallback: manual slot enumeration via ClassicAPI (id + decorated name),
|
||||||
|
-- no link string built. C_Item.GetItemName carries random-suffix decoration
|
||||||
|
-- and falls back to the base name internally, so it replaces the old
|
||||||
|
-- bracket-name / GetItemInfo two-step in a single call.
|
||||||
for slot = 1, 19 do
|
for slot = 1, 19 do
|
||||||
local link = GetInventoryItemLink("player", slot)
|
local id = GetInventoryItemID("player", slot)
|
||||||
if link then
|
if id then
|
||||||
local _, _, id = string_find(link, "item:(%d+)")
|
_equippedItemIDs[slot] = id
|
||||||
local _, _, nameInBrackets = string_find(link, "%[(.+)%]")
|
local name = C_Item.GetItemName({ equipmentSlotIndex = slot })
|
||||||
|
if name then
|
||||||
if id then
|
_equippedItemNames[slot] = string_lower(name)
|
||||||
_equippedItemIDs[slot] = tonumber(id)
|
|
||||||
end
|
|
||||||
if nameInBrackets then
|
|
||||||
_equippedItemNames[slot] = string_lower(nameInBrackets)
|
|
||||||
elseif id then
|
|
||||||
-- Fallback: resolve via GetItemInfo
|
|
||||||
local itemName = GetItemInfo(tonumber(id))
|
|
||||||
if itemName then
|
|
||||||
_equippedItemNames[slot] = string_lower(itemName)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -350,8 +343,7 @@ function CleveRoids.FindItemLocation(item)
|
|||||||
if numericItem then
|
if numericItem then
|
||||||
-- Check if it's an equipment slot (1-19)
|
-- Check if it's an equipment slot (1-19)
|
||||||
if numericItem >= 1 and numericItem <= 19 then
|
if numericItem >= 1 and numericItem <= 19 then
|
||||||
local link = GetInventoryItemLink("player", numericItem)
|
if GetInventoryItemID("player", numericItem) then
|
||||||
if link then
|
|
||||||
return { type = "inventory", inventoryID = numericItem }
|
return { type = "inventory", inventoryID = numericItem }
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
@@ -3466,11 +3458,8 @@ function CleveRoids.ValidateCooldown(args, ignoreGCD)
|
|||||||
-- If this is a numeric slot (1-19), resolve to the equipped item's name
|
-- If this is a numeric slot (1-19), resolve to the equipped item's name
|
||||||
local slotNum = tonumber(name)
|
local slotNum = tonumber(name)
|
||||||
if slotNum and slotNum >= 1 and slotNum <= 19 then
|
if slotNum and slotNum >= 1 and slotNum <= 19 then
|
||||||
local link = GetInventoryItemLink("player", slotNum)
|
local itemName = C_Item.GetItemName({ equipmentSlotIndex = slotNum })
|
||||||
if link then
|
if itemName then name = itemName end
|
||||||
local _, _, itemName = string.find(link, "%[(.+)%]")
|
|
||||||
if itemName then name = itemName end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
args = {name = name}
|
args = {name = name}
|
||||||
else
|
else
|
||||||
@@ -3481,11 +3470,8 @@ function CleveRoids.ValidateCooldown(args, ignoreGCD)
|
|||||||
-- If this is a numeric slot (1-19), resolve to the equipped item's name
|
-- If this is a numeric slot (1-19), resolve to the equipped item's name
|
||||||
local slotNum = tonumber(name)
|
local slotNum = tonumber(name)
|
||||||
if slotNum and slotNum >= 1 and slotNum <= 19 then
|
if slotNum and slotNum >= 1 and slotNum <= 19 then
|
||||||
local link = GetInventoryItemLink("player", slotNum)
|
local itemName = C_Item.GetItemName({ equipmentSlotIndex = slotNum })
|
||||||
if link then
|
if itemName then name = itemName end
|
||||||
local _, _, itemName = string.find(link, "%[(.+)%]")
|
|
||||||
if itemName then name = itemName end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
args.name = name
|
args.name = name
|
||||||
else
|
else
|
||||||
@@ -4869,13 +4855,11 @@ function CleveRoids.HasItem(item)
|
|||||||
if type(item) == "string" and item ~= "" then
|
if type(item) == "string" and item ~= "" then
|
||||||
local itemLower = string.lower(item)
|
local itemLower = string.lower(item)
|
||||||
|
|
||||||
-- Check equipped slots for substring match
|
-- Check equipped slots for substring match (decorated name, no link build)
|
||||||
for slot = 0, 19 do
|
for slot = 1, 19 do
|
||||||
local link = GetInventoryItemLink("player", slot)
|
local name = C_Item.GetItemName({ equipmentSlotIndex = slot })
|
||||||
if link then
|
if name and string.find(string.lower(name), itemLower, 1, true) then
|
||||||
if string.find(string.lower(link), itemLower, 1, true) then
|
return true
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -4884,11 +4868,9 @@ function CleveRoids.HasItem(item)
|
|||||||
local size = GetContainerNumSlots(bag)
|
local size = GetContainerNumSlots(bag)
|
||||||
if size and size > 0 then
|
if size and size > 0 then
|
||||||
for slotIndex = 1, size do
|
for slotIndex = 1, size do
|
||||||
local link = GetContainerItemLink(bag, slotIndex)
|
local name = C_Item.GetItemName({ bagID = bag, slotIndex = slotIndex })
|
||||||
if link then
|
if name and string.find(string.lower(name), itemLower, 1, true) then
|
||||||
if string.find(string.lower(link), itemLower, 1, true) then
|
return true
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -4933,14 +4915,12 @@ function CleveRoids.GetItemCooldown(item)
|
|||||||
local itemLower = string.lower(item)
|
local itemLower = string.lower(item)
|
||||||
local start, dur, en
|
local start, dur, en
|
||||||
|
|
||||||
-- Check equipped slots for substring match
|
-- Check equipped slots for substring match (decorated name, no link build)
|
||||||
for slot = 0, 19 do
|
for slot = 1, 19 do
|
||||||
local link = GetInventoryItemLink("player", slot)
|
local name = C_Item.GetItemName({ equipmentSlotIndex = slot })
|
||||||
if link then
|
if name and string.find(string.lower(name), itemLower, 1, true) then
|
||||||
if string.find(string.lower(link), itemLower, 1, true) then
|
start, dur, en = GetInventoryItemCooldown("player", slot)
|
||||||
start, dur, en = GetInventoryItemCooldown("player", slot)
|
return _norm(start, dur, en)
|
||||||
return _norm(start, dur, en)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -4949,12 +4929,10 @@ function CleveRoids.GetItemCooldown(item)
|
|||||||
local size = GetContainerNumSlots(bag)
|
local size = GetContainerNumSlots(bag)
|
||||||
if size and size > 0 then
|
if size and size > 0 then
|
||||||
for slotIndex = 1, size do
|
for slotIndex = 1, size do
|
||||||
local link = GetContainerItemLink(bag, slotIndex)
|
local name = C_Item.GetItemName({ bagID = bag, slotIndex = slotIndex })
|
||||||
if link then
|
if name and string.find(string.lower(name), itemLower, 1, true) then
|
||||||
if string.find(string.lower(link), itemLower, 1, true) then
|
start, dur, en = GetContainerItemCooldown(bag, slotIndex)
|
||||||
start, dur, en = GetContainerItemCooldown(bag, slotIndex)
|
return _norm(start, dur, en)
|
||||||
return _norm(start, dur, en)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -5887,13 +5865,10 @@ CleveRoids.Keywords = {
|
|||||||
local itemName = name
|
local itemName = name
|
||||||
local slotNum = tonumber(name)
|
local slotNum = tonumber(name)
|
||||||
if slotNum and slotNum >= 1 and slotNum <= 19 then
|
if slotNum and slotNum >= 1 and slotNum <= 19 then
|
||||||
-- Resolve slot number to item name
|
-- Resolve slot number to item name (decorated, no link build)
|
||||||
local link = GetInventoryItemLink("player", slotNum)
|
local extractedName = C_Item.GetItemName({ equipmentSlotIndex = slotNum })
|
||||||
if link then
|
if extractedName then
|
||||||
local _, _, extractedName = string.find(link, "%[(.+)%]")
|
itemName = extractedName
|
||||||
if extractedName then
|
|
||||||
itemName = extractedName
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -5925,13 +5900,10 @@ CleveRoids.Keywords = {
|
|||||||
local itemName = name
|
local itemName = name
|
||||||
local slotNum = tonumber(name)
|
local slotNum = tonumber(name)
|
||||||
if slotNum and slotNum >= 1 and slotNum <= 19 then
|
if slotNum and slotNum >= 1 and slotNum <= 19 then
|
||||||
-- Resolve slot number to item name
|
-- Resolve slot number to item name (decorated, no link build)
|
||||||
local link = GetInventoryItemLink("player", slotNum)
|
local extractedName = C_Item.GetItemName({ equipmentSlotIndex = slotNum })
|
||||||
if link then
|
if extractedName then
|
||||||
local _, _, extractedName = string.find(link, "%[(.+)%]")
|
itemName = extractedName
|
||||||
if extractedName then
|
|
||||||
itemName = extractedName
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -46,10 +46,8 @@ CleveRoids.spellNameCache = {}
|
|||||||
local GetTime = GetTime
|
local GetTime = GetTime
|
||||||
local UnitExists = UnitExists
|
local UnitExists = UnitExists
|
||||||
local UnitAffectingCombat = UnitAffectingCombat
|
local UnitAffectingCombat = UnitAffectingCombat
|
||||||
local GetContainerItemLink = GetContainerItemLink
|
|
||||||
local GetContainerItemInfo = GetContainerItemInfo
|
local GetContainerItemInfo = GetContainerItemInfo
|
||||||
local GetContainerNumSlots = GetContainerNumSlots
|
local GetContainerNumSlots = GetContainerNumSlots
|
||||||
local GetInventoryItemLink = GetInventoryItemLink
|
|
||||||
local GetItemInfo = GetItemInfo
|
local GetItemInfo = GetItemInfo
|
||||||
local PickupContainerItem = PickupContainerItem
|
local PickupContainerItem = PickupContainerItem
|
||||||
local PickupInventoryItem = PickupInventoryItem
|
local PickupInventoryItem = PickupInventoryItem
|
||||||
@@ -63,7 +61,6 @@ local ipairs = ipairs
|
|||||||
local type = type
|
local type = type
|
||||||
local tonumber = tonumber
|
local tonumber = tonumber
|
||||||
local tostring = tostring
|
local tostring = tostring
|
||||||
local string_find = string.find
|
|
||||||
local string_lower = string.lower
|
local string_lower = string.lower
|
||||||
local string_gsub = string.gsub
|
local string_gsub = string.gsub
|
||||||
local table_insert = table.insert
|
local table_insert = table.insert
|
||||||
@@ -672,21 +669,27 @@ function CleveRoids.GetReagentCount(reagentName)
|
|||||||
for slot = 1, slots do
|
for slot = 1, slots do
|
||||||
local _, count = GetContainerItemInfo(bag, slot)
|
local _, count = GetContainerItemInfo(bag, slot)
|
||||||
count = count or 0
|
count = count or 0
|
||||||
local link = GetContainerItemLink and GetContainerItemLink(bag, slot)
|
-- Base itemID straight off the slot (no link string, no regex).
|
||||||
if link then
|
local id = C_Container.GetContainerItemID(bag, slot)
|
||||||
local _, _, idstr = string.find(link, "item:(%d+)")
|
if id then
|
||||||
local id = idstr and tonumber(idstr) or nil
|
local match
|
||||||
if (wantId and id == wantId) or (not wantId and string.find(link, "%["..reagentName.."%]")) then
|
if wantId then
|
||||||
total = total + count
|
match = (id == wantId)
|
||||||
|
else
|
||||||
|
local name = C_Item.GetItemNameByID(id)
|
||||||
|
if name then
|
||||||
|
match = (name == reagentName)
|
||||||
|
else
|
||||||
|
-- Name not cached yet: fall back to a tooltip scan (expensive, rare)
|
||||||
|
local tip = CRM_GetBagScanTip()
|
||||||
|
tip:ClearLines()
|
||||||
|
tip:SetBagItem(bag, slot)
|
||||||
|
local left1 = _G[tip:GetName().."TextLeft1"]
|
||||||
|
local tname = left1 and left1:GetText()
|
||||||
|
match = (tname == reagentName)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
else
|
if match then
|
||||||
-- Fallback: scan bag slot tooltip for the name (expensive, only when no link)
|
|
||||||
local tip = CRM_GetBagScanTip()
|
|
||||||
tip:ClearLines()
|
|
||||||
tip:SetBagItem(bag, slot)
|
|
||||||
local left1 = _G[tip:GetName().."TextLeft1"]
|
|
||||||
local name = left1 and left1:GetText()
|
|
||||||
if name and name == reagentName then
|
|
||||||
total = total + count
|
total = total + count
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -701,17 +704,18 @@ end
|
|||||||
function CleveRoids.GetLiveItemCount(itemName)
|
function CleveRoids.GetLiveItemCount(itemName)
|
||||||
if not itemName or itemName == "" then return 0 end
|
if not itemName or itemName == "" then return 0 end
|
||||||
-- Escape Lua pattern special chars in item name to avoid crashes
|
-- Escape Lua pattern special chars in item name to avoid crashes
|
||||||
local escaped = string.gsub(itemName, "([%(%)%.%%%+%-%*%?%[%]%^%$])", "%%%1")
|
local wantLower = string.lower(itemName)
|
||||||
local pattern = "%[" .. escaped .. "%]"
|
|
||||||
local lowerPattern = string.lower(pattern)
|
|
||||||
local total = 0
|
local total = 0
|
||||||
for bag = 0, 4 do
|
for bag = 0, 4 do
|
||||||
local slots = GetContainerNumSlots(bag) or 0
|
local slots = GetContainerNumSlots(bag) or 0
|
||||||
for slot = 1, slots do
|
for slot = 1, slots do
|
||||||
local link = GetContainerItemLink and GetContainerItemLink(bag, slot)
|
local id = C_Container.GetContainerItemID(bag, slot)
|
||||||
if link and string.find(string.lower(link), lowerPattern) then
|
if id then
|
||||||
local _, count = GetContainerItemInfo(bag, slot)
|
local name = C_Item.GetItemNameByID(id)
|
||||||
total = total + (count or 0)
|
if name and string.lower(name) == wantLower then
|
||||||
|
local _, count = GetContainerItemInfo(bag, slot)
|
||||||
|
total = total + (count or 0)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -2689,11 +2693,13 @@ function CleveRoids.DoWithConditionals(msg, hook, fixEmptyTargetFunc, targetBefo
|
|||||||
CastSpellByName(castMsg)
|
CastSpellByName(castMsg)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- For other actions like UseContainerItem etc.
|
-- For other actions like item use etc. Pass the resolved unit token so
|
||||||
|
-- item-use can target it directly (DoUse -> C_Item.UseItemByName); action
|
||||||
|
-- closures that only take (msg) simply ignore the extra arg.
|
||||||
if CleveRoids.equipDebugLog then
|
if CleveRoids.equipDebugLog then
|
||||||
CleveRoids.Print("|cff00ff00[EquipLog] Calling action('" .. tostring(msg) .. "')|r")
|
CleveRoids.Print("|cff00ff00[EquipLog] Calling action('" .. tostring(msg) .. "')|r")
|
||||||
end
|
end
|
||||||
action(msg)
|
action(msg, conditionals.target)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -3100,15 +3106,17 @@ end
|
|||||||
-- PERFORMANCE: Module-level action to avoid closure allocation per call
|
-- PERFORMANCE: Module-level action to avoid closure allocation per call
|
||||||
local function _startAttackAction()
|
local function _startAttackAction()
|
||||||
if not UnitExists("target") or CleveRoids.IsUnitDead("target") then TargetNearestEnemy() end
|
if not UnitExists("target") or CleveRoids.IsUnitDead("target") then TargetNearestEnemy() end
|
||||||
-- Check both event-based flag AND action bar state for reliable detection
|
-- Ground truth is the real action-bar state, NOT the cached autoAttack flag.
|
||||||
|
-- The flag can drift stale-true (e.g. set optimistically after AttackTarget below,
|
||||||
|
-- or a target dying without PLAYER_LEAVE_COMBAT firing), which would make us wrongly
|
||||||
|
-- believe we're already swinging and skip the attack. Use the ORIGINAL API here:
|
||||||
|
-- the overridden global IsCurrentAction just echoes the cached flag for the attack
|
||||||
|
-- slot, so it can't detect drift. Fall back to the flag only if the slot is unknown.
|
||||||
local isAttacking = CleveRoids.CurrentSpell.autoAttack
|
local isAttacking = CleveRoids.CurrentSpell.autoAttack
|
||||||
if not isAttacking then
|
local slot = CleveRoids.GetProxyActionSlot(CleveRoids.Localized.Attack)
|
||||||
-- Fallback: check action bar state via IsCurrentAction
|
if slot then
|
||||||
local slot = CleveRoids.GetProxyActionSlot(CleveRoids.Localized.Attack)
|
isAttacking = CleveRoids.Hooks.IsCurrentAction(slot) and true or false
|
||||||
if slot and IsCurrentAction(slot) then
|
CleveRoids.CurrentSpell.autoAttack = isAttacking
|
||||||
CleveRoids.CurrentSpell.autoAttack = true
|
|
||||||
isAttacking = true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
if not isAttacking and not CleveRoids.CurrentSpell.autoAttackLock and UnitExists("target") and UnitCanAttack("player", "target") then
|
if not isAttacking and not CleveRoids.CurrentSpell.autoAttackLock and UnitExists("target") and UnitCanAttack("player", "target") then
|
||||||
CleveRoids.CurrentSpell.autoAttackLock = true
|
CleveRoids.CurrentSpell.autoAttackLock = true
|
||||||
@@ -3194,6 +3202,36 @@ function CleveRoids.DoConditionalClearTarget(msg)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Resolve an EQUIPPED inventory slot (1-19) holding the item, or nil.
|
||||||
|
-- C_Item.UseItemByName only searches bags, so equipped-only items (trinkets,
|
||||||
|
-- weapons) must be fired via their slot. Prefer nampower's fast lookup; fall
|
||||||
|
-- back to a manual scan for clients without FindPlayerItemSlot (< v2.18).
|
||||||
|
local function FindEquippedItemSlot(msg, itemId)
|
||||||
|
local API = CleveRoids.NampowerAPI
|
||||||
|
if type(API) == "table" and API.FindItemFast then
|
||||||
|
local info = API.FindItemFast(itemId or msg)
|
||||||
|
if info and info.inventoryID then return info.inventoryID end
|
||||||
|
-- Found only in bags (or not at all) -> not an equipped-only item.
|
||||||
|
if info then return nil end
|
||||||
|
end
|
||||||
|
-- Fallback scan of equipped slots by ID or name, read straight from each
|
||||||
|
-- slot via ClassicAPI (GetInventoryItemID / C_Item.GetItemNameByID) -- no
|
||||||
|
-- link string built, no "item:"/"|h[..]|h" parse. Slots are 1-19.
|
||||||
|
local wantLower = (not itemId) and string_lower(msg) or nil
|
||||||
|
for slot = 1, 19 do
|
||||||
|
local id = GetInventoryItemID("player", slot)
|
||||||
|
if id then
|
||||||
|
if itemId then
|
||||||
|
if id == itemId then return slot end
|
||||||
|
else
|
||||||
|
local nm = C_Item.GetItemNameByID(id)
|
||||||
|
if nm and string_lower(nm) == wantLower then return slot end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
-- Attempts to use or equip an item by a set of conditionals
|
-- Attempts to use or equip an item by a set of conditionals
|
||||||
-- Also checks if a condition is a spell so that you can mix item and spell use
|
-- Also checks if a condition is a spell so that you can mix item and spell use
|
||||||
-- msg: The raw message intercepted from a /use or /equip command
|
-- msg: The raw message intercepted from a /use or /equip command
|
||||||
@@ -3205,184 +3243,42 @@ function CleveRoids.DoUse(msg)
|
|||||||
|
|
||||||
local handled = false
|
local handled = false
|
||||||
|
|
||||||
local action = function(msg)
|
local action = function(msg, unit)
|
||||||
-- Defensive: make sure we are not in "split stack" mode and nothing is on the cursor
|
-- Defensive: make sure we are not in "split stack" mode and nothing is on the cursor
|
||||||
if type(CloseStackSplitFrame) == "function" then CloseStackSplitFrame() end
|
if type(CloseStackSplitFrame) == "function" then CloseStackSplitFrame() end
|
||||||
if CursorHasItem and CursorHasItem() then ClearCursor() end
|
if CursorHasItem and CursorHasItem() then ClearCursor() end
|
||||||
|
|
||||||
-- Try to interpret the message as a direct inventory slot ID first.
|
-- Only pass a cast target when it actually exists, so a stale @unit doesn't
|
||||||
|
-- waste a consumable. Self-use items (potions/food/hearth) ignore it anyway.
|
||||||
|
local useUnit = (unit and UnitExists(unit)) and unit or nil
|
||||||
|
|
||||||
|
-- Direct equipped inventory slot ID (1-19): use it in place.
|
||||||
local slotId = tonumber(msg)
|
local slotId = tonumber(msg)
|
||||||
if slotId and slotId >= 1 and slotId <= 19 then -- Character slots are 1-19
|
if slotId and slotId >= 1 and slotId <= 19 then
|
||||||
ClearCursor() -- extra safety before using equipped items
|
ClearCursor() -- extra safety before using equipped items
|
||||||
UseInventoryItem(slotId)
|
UseInventoryItem(slotId)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Try to interpret as item ID (numbers > 19)
|
-- Equipped items (trinkets, weapons) live outside bags, so C_Item.UseItemByName
|
||||||
-- v2.18+: Use FindPlayerItemSlot directly for item IDs (no name resolution needed)
|
-- can't reach them. Fire an equipped match through its slot first.
|
||||||
if slotId and slotId > 19 then
|
local invSlot = FindEquippedItemSlot(msg, slotId)
|
||||||
local API = CleveRoids.NampowerAPI
|
if invSlot then
|
||||||
-- v2.18+: Native lookup can find item directly by ID
|
ClearCursor()
|
||||||
if API and API.features and API.features.hasFindPlayerItemSlot then
|
if CleveRoids.equipDebugLog then
|
||||||
local itemInfo = API.FindItemFast(slotId)
|
CleveRoids.Print("|cff888888[UseLog] /use " .. msg .. " via UseInventoryItem(" .. invSlot .. ")|r")
|
||||||
if itemInfo then
|
|
||||||
ClearCursor()
|
|
||||||
if itemInfo.inventoryID then
|
|
||||||
if CleveRoids.equipDebugLog then
|
|
||||||
CleveRoids.Print("|cff888888[UseLog] /use " .. slotId .. " via UseInventoryItem(" .. itemInfo.inventoryID .. ") [v2.18 ID lookup]|r")
|
|
||||||
end
|
|
||||||
UseInventoryItem(itemInfo.inventoryID)
|
|
||||||
return
|
|
||||||
elseif itemInfo.bagID and itemInfo.slot then
|
|
||||||
if CleveRoids.equipDebugLog then
|
|
||||||
CleveRoids.Print("|cff888888[UseLog] /use " .. slotId .. " via UseContainerItem(" .. itemInfo.bagID .. "," .. itemInfo.slot .. ") [v2.18 ID lookup]|r")
|
|
||||||
end
|
|
||||||
UseContainerItem(itemInfo.bagID, itemInfo.slot)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Item not found by ID - fail
|
|
||||||
if CleveRoids.equipDebugLog then
|
|
||||||
CleveRoids.Print("|cffff8800[UseLog] Item ID " .. slotId .. " not found in inventory [v2.18]|r")
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Fallback: Resolve item ID to name for legacy lookup
|
|
||||||
local itemName = nil
|
|
||||||
if API and API.GetItemName then
|
|
||||||
itemName = API.GetItemName(slotId)
|
|
||||||
end
|
|
||||||
-- Fall back to GetItemInfo
|
|
||||||
if not itemName and GetItemInfo then
|
|
||||||
itemName = GetItemInfo(slotId)
|
|
||||||
end
|
|
||||||
if itemName then
|
|
||||||
if CleveRoids.equipDebugLog then
|
|
||||||
CleveRoids.Print("|cff888888[UseLog] Resolved item ID " .. slotId .. " to '" .. itemName .. "'|r")
|
|
||||||
end
|
|
||||||
msg = itemName -- Replace ID with name for subsequent lookups
|
|
||||||
else
|
|
||||||
if CleveRoids.equipDebugLog then
|
|
||||||
CleveRoids.Print("|cffff8800[UseLog] Could not resolve item ID " .. slotId .. " - item not in cache|r")
|
|
||||||
end
|
|
||||||
-- Item not in client cache - can't resolve without seeing it first
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- v2.18+: Use native fast lookup (much faster than Lua cache + scan)
|
|
||||||
local API = CleveRoids.NampowerAPI
|
|
||||||
if API and API.features and API.features.hasFindPlayerItemSlot then
|
|
||||||
local itemInfo = API.FindItemFast(msg)
|
|
||||||
if itemInfo then
|
|
||||||
ClearCursor()
|
|
||||||
if itemInfo.inventoryID then
|
|
||||||
if CleveRoids.equipDebugLog then
|
|
||||||
CleveRoids.Print("|cff888888[UseLog] /use " .. msg .. " via UseInventoryItem(" .. itemInfo.inventoryID .. ") [v2.18 native]|r")
|
|
||||||
end
|
|
||||||
UseInventoryItem(itemInfo.inventoryID)
|
|
||||||
return
|
|
||||||
elseif itemInfo.bagID and itemInfo.slot then
|
|
||||||
if CleveRoids.equipDebugLog then
|
|
||||||
CleveRoids.Print("|cff888888[UseLog] /use " .. msg .. " via UseContainerItem(" .. itemInfo.bagID .. "," .. itemInfo.slot .. ") [v2.18 native]|r")
|
|
||||||
end
|
|
||||||
UseContainerItem(itemInfo.bagID, itemInfo.slot)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- v2.18 lookup didn't find item - fall through to legacy path
|
|
||||||
-- (might be partial match or different case that native doesn't handle)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- PERFORMANCE: Try cache lookup first (O(1) instead of O(n) scan)
|
|
||||||
-- IMPORTANT: Validate cache hits to prevent stale data during combat
|
|
||||||
-- (IndexItems() is skipped during combat, so cache may have old bag/slot locations)
|
|
||||||
local location = CleveRoids.FindItemLocation(msg)
|
|
||||||
if location then
|
|
||||||
local cacheValid = false
|
|
||||||
local qname = string_lower(msg)
|
|
||||||
|
|
||||||
if location.type == "inventory" then
|
|
||||||
-- Validate: check if this slot actually contains the item we want
|
|
||||||
local link = GetInventoryItemLink("player", location.inventoryID)
|
|
||||||
if link then
|
|
||||||
local _, _, nm = string_find(link, "|h%[(.-)%]|h")
|
|
||||||
if nm and string_lower(nm) == qname then
|
|
||||||
cacheValid = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
-- Validate: check if this bag slot actually contains the item we want
|
|
||||||
local link = GetContainerItemLink(location.bag, location.slot)
|
|
||||||
if link then
|
|
||||||
local _, _, nm = string_find(link, "|h%[(.-)%]|h")
|
|
||||||
if nm and string_lower(nm) == qname then
|
|
||||||
cacheValid = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if cacheValid then
|
|
||||||
ClearCursor()
|
|
||||||
if location.type == "inventory" then
|
|
||||||
if CleveRoids.equipDebugLog then
|
|
||||||
CleveRoids.Print("|cff888888[UseLog] /use " .. msg .. " via UseInventoryItem(" .. location.inventoryID .. ") [cached]|r")
|
|
||||||
end
|
|
||||||
UseInventoryItem(location.inventoryID)
|
|
||||||
else
|
|
||||||
if CleveRoids.equipDebugLog then
|
|
||||||
CleveRoids.Print("|cff888888[UseLog] /use " .. msg .. " via UseContainerItem(" .. location.bag .. "," .. location.slot .. ") [cached]|r")
|
|
||||||
end
|
|
||||||
UseContainerItem(location.bag, location.slot)
|
|
||||||
end
|
|
||||||
return
|
|
||||||
elseif CleveRoids.equipDebugLog then
|
|
||||||
CleveRoids.Print("|cff888888[UseLog] /use " .. msg .. " - cache STALE, falling back to scan|r")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Slow path fallback: full scan for substring matches or cache miss
|
|
||||||
local qname = string_lower(msg)
|
|
||||||
|
|
||||||
-- Search equipped inventory slots first (for trinkets, etc.)
|
|
||||||
for slot = 0, 19 do
|
|
||||||
local link = GetInventoryItemLink("player", slot)
|
|
||||||
if link then
|
|
||||||
local _, _, nm = string_find(link, "|h%[(.-)%]|h")
|
|
||||||
if nm and string_lower(nm) == qname then
|
|
||||||
if CleveRoids.equipDebugLog then
|
|
||||||
CleveRoids.Print("|cff888888[UseLog] /use " .. msg .. " via UseInventoryItem(" .. slot .. ")|r")
|
|
||||||
end
|
|
||||||
ClearCursor()
|
|
||||||
UseInventoryItem(slot)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Then search bags
|
|
||||||
for bag = 0, 4 do
|
|
||||||
local numSlots = GetContainerNumSlots(bag) or 0
|
|
||||||
for bagSlot = 1, numSlots do
|
|
||||||
local link = GetContainerItemLink(bag, bagSlot)
|
|
||||||
if link then
|
|
||||||
local _, _, nm = string_find(link, "|h%[(.-)%]|h")
|
|
||||||
if nm and string_lower(nm) == qname then
|
|
||||||
if CleveRoids.equipDebugLog then
|
|
||||||
CleveRoids.Print("|cff888888[UseLog] /use " .. msg .. " via UseContainerItem(" .. bag .. "," .. bagSlot .. ")|r")
|
|
||||||
end
|
|
||||||
ClearCursor()
|
|
||||||
UseContainerItem(bag, bagSlot)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
UseInventoryItem(invSlot)
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Bag path: one ClassicAPI call finds the item in bags and dispatches by
|
||||||
|
-- type (potion/food/scroll/on-use), honoring `useUnit` for targeted-spell
|
||||||
|
-- items. itemIDs pass as numbers; names/links pass through unchanged.
|
||||||
if CleveRoids.equipDebugLog then
|
if CleveRoids.equipDebugLog then
|
||||||
CleveRoids.Print("|cff888888[UseLog] /use " .. msg .. " - not found in equipped slots or bags|r")
|
CleveRoids.Print("|cff888888[UseLog] /use " .. msg .. " via C_Item.UseItemByName(" .. tostring(slotId or msg) .. ", " .. tostring(useUnit) .. ")|r")
|
||||||
end
|
end
|
||||||
|
C_Item.UseItemByName(slotId or msg, useUnit)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- PERFORMANCE: Use numeric iteration to avoid pairs() iterator allocation
|
-- PERFORMANCE: Use numeric iteration to avoid pairs() iterator allocation
|
||||||
@@ -3408,12 +3304,9 @@ local function FindItemInBagsByName(itemName)
|
|||||||
for bag = 0, 4 do
|
for bag = 0, 4 do
|
||||||
local numSlots = GetContainerNumSlots(bag) or 0
|
local numSlots = GetContainerNumSlots(bag) or 0
|
||||||
for slot = 1, numSlots do
|
for slot = 1, numSlots do
|
||||||
local link = GetContainerItemLink(bag, slot)
|
local name = C_Item.GetItemName({ bagID = bag, slotIndex = slot })
|
||||||
if link then
|
if name and string_lower(name) == lowerName then
|
||||||
local _, _, name = string_find(link, "|h%[(.-)%]|h")
|
return bag, slot
|
||||||
if name and string_lower(name) == lowerName then
|
|
||||||
return bag, slot
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -3550,12 +3443,7 @@ function CleveRoids.EquipBagItem(msg, slotOrOffhand)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Note what's currently in the target slot so we can invalidate its cache
|
-- Note what's currently in the target slot so we can invalidate its cache
|
||||||
local oldSlotLink = GetInventoryItemLink("player", invslot)
|
local oldSlotName = C_Item.GetItemName({ equipmentSlotIndex = invslot })
|
||||||
local oldSlotName = nil
|
|
||||||
if oldSlotLink then
|
|
||||||
local _, _, name = string_find(oldSlotLink, "|h%[(.-)%]|h")
|
|
||||||
oldSlotName = name
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Helper to invalidate displaced item's cache
|
-- Helper to invalidate displaced item's cache
|
||||||
local function InvalidateDisplacedItem()
|
local function InvalidateDisplacedItem()
|
||||||
@@ -3572,10 +3460,9 @@ function CleveRoids.EquipBagItem(msg, slotOrOffhand)
|
|||||||
local pairedSlots = {[13] = 14, [14] = 13, [16] = 17, [17] = 16, [11] = 12, [12] = 11}
|
local pairedSlots = {[13] = 14, [14] = 13, [16] = 17, [17] = 16, [11] = 12, [12] = 11}
|
||||||
local checkSlot = pairedSlots[invslot]
|
local checkSlot = pairedSlots[invslot]
|
||||||
if checkSlot then
|
if checkSlot then
|
||||||
local link = GetInventoryItemLink("player", checkSlot)
|
local slotItemName = C_Item.GetItemName({ equipmentSlotIndex = checkSlot })
|
||||||
if link then
|
if slotItemName then
|
||||||
local _, _, slotItemName = string_find(link, "|h%[(.-)%]|h")
|
if string_lower(slotItemName) == string_lower(msg) then
|
||||||
if slotItemName and string_lower(slotItemName) == string_lower(msg) then
|
|
||||||
-- Item found in paired slot - but prefer a bag copy if one exists
|
-- Item found in paired slot - but prefer a bag copy if one exists
|
||||||
local bagCopyBag, bagCopySlot = FindItemInBagsByName(msg)
|
local bagCopyBag, bagCopySlot = FindItemInBagsByName(msg)
|
||||||
if bagCopyBag then
|
if bagCopyBag then
|
||||||
@@ -3627,17 +3514,14 @@ function CleveRoids.EquipBagItem(msg, slotOrOffhand)
|
|||||||
-- Verify the item actually landed in the target slot
|
-- Verify the item actually landed in the target slot
|
||||||
-- EquipItemByName may silently no-op for same-named items in paired slots
|
-- EquipItemByName may silently no-op for same-named items in paired slots
|
||||||
-- (e.g., dual-wielding Scimitar: MH copy found first, "equipped" to same slot)
|
-- (e.g., dual-wielding Scimitar: MH copy found first, "equipped" to same slot)
|
||||||
local newLink = GetInventoryItemLink("player", invslot)
|
local newName = C_Item.GetItemName({ equipmentSlotIndex = invslot })
|
||||||
if newLink then
|
if newName and string_lower(newName) == string_lower(msg) then
|
||||||
local _, _, newName = string_find(newLink, "|h%[(.-)%]|h")
|
if CleveRoids.Items then
|
||||||
if newName and string_lower(newName) == string_lower(msg) then
|
CleveRoids.Items[msg] = nil
|
||||||
if CleveRoids.Items then
|
CleveRoids.Items[string_lower(msg)] = nil
|
||||||
CleveRoids.Items[msg] = nil
|
|
||||||
CleveRoids.Items[string_lower(msg)] = nil
|
|
||||||
end
|
|
||||||
InvalidateDisplacedItem()
|
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
|
InvalidateDisplacedItem()
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
-- Verification failed - EquipItemByName didn't place item in target slot
|
-- Verification failed - EquipItemByName didn't place item in target slot
|
||||||
if CleveRoids.equipDebugLog then
|
if CleveRoids.equipDebugLog then
|
||||||
@@ -3679,10 +3563,9 @@ function CleveRoids.EquipBagItem(msg, slotOrOffhand)
|
|||||||
local ok = pcall(EquipItemByName, item.name, invslot)
|
local ok = pcall(EquipItemByName, item.name, invslot)
|
||||||
if ok then
|
if ok then
|
||||||
-- Verify the item actually landed in the target slot (same guard as above)
|
-- Verify the item actually landed in the target slot (same guard as above)
|
||||||
local newLink = GetInventoryItemLink("player", invslot)
|
local newName = C_Item.GetItemName({ equipmentSlotIndex = invslot })
|
||||||
if newLink then
|
if newName then
|
||||||
local _, _, newName = string_find(newLink, "|h%[(.-)%]|h")
|
if string_lower(newName) == string_lower(item.name) then
|
||||||
if newName and string_lower(newName) == string_lower(item.name) then
|
|
||||||
if CleveRoids.Items then
|
if CleveRoids.Items then
|
||||||
CleveRoids.Items[item.name] = nil
|
CleveRoids.Items[item.name] = nil
|
||||||
CleveRoids.Items[string_lower(item.name)] = nil
|
CleveRoids.Items[string_lower(item.name)] = nil
|
||||||
@@ -5261,8 +5144,7 @@ function CleveRoids.DoWDBWarmup()
|
|||||||
for bag = 0, 4 do
|
for bag = 0, 4 do
|
||||||
local slots = GetContainerNumSlots(bag) or 0
|
local slots = GetContainerNumSlots(bag) or 0
|
||||||
for slot = 1, slots do
|
for slot = 1, slots do
|
||||||
local link = GetContainerItemLink(bag, slot)
|
if C_Container.GetContainerItemID(bag, slot) then
|
||||||
if link then
|
|
||||||
-- Tooltip scan loads the item into WDB
|
-- Tooltip scan loads the item into WDB
|
||||||
tip:ClearLines()
|
tip:ClearLines()
|
||||||
tip:SetBagItem(bag, slot)
|
tip:SetBagItem(bag, slot)
|
||||||
@@ -5272,9 +5154,8 @@ function CleveRoids.DoWDBWarmup()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Scan equipped items
|
-- Scan equipped items
|
||||||
for slot = 0, 19 do
|
for slot = 1, 19 do
|
||||||
local link = GetInventoryItemLink("player", slot)
|
if GetInventoryItemID("player", slot) then
|
||||||
if link then
|
|
||||||
tip:ClearLines()
|
tip:ClearLines()
|
||||||
tip:SetInventoryItem("player", slot)
|
tip:SetInventoryItem("player", slot)
|
||||||
scanned = scanned + 1
|
scanned = scanned + 1
|
||||||
@@ -7327,9 +7208,9 @@ local function FindItemInBags(itemName)
|
|||||||
local searchName = string.lower(itemName)
|
local searchName = string.lower(itemName)
|
||||||
for bag = 0, 4 do
|
for bag = 0, 4 do
|
||||||
for slot = 1, GetContainerNumSlots(bag) do
|
for slot = 1, GetContainerNumSlots(bag) do
|
||||||
local link = GetContainerItemLink(bag, slot)
|
local id = C_Container.GetContainerItemID(bag, slot)
|
||||||
if link then
|
if id then
|
||||||
local _, _, foundName = string.find(link, "%[(.+)%]")
|
local foundName = C_Item.GetItemNameByID(id)
|
||||||
if foundName and string.find(string.lower(foundName), searchName, 1, true) then
|
if foundName and string.find(string.lower(foundName), searchName, 1, true) then
|
||||||
return bag, slot, foundName
|
return bag, slot, foundName
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -156,10 +156,9 @@ end
|
|||||||
function CleveRoids.IndexEquippedItems()
|
function CleveRoids.IndexEquippedItems()
|
||||||
local items = CleveRoids.Items or {}
|
local items = CleveRoids.Items or {}
|
||||||
|
|
||||||
for inventoryID = 0, 19 do
|
for inventoryID = 1, 19 do
|
||||||
local link = GetInventoryItemLink("player", inventoryID)
|
local itemID = GetInventoryItemID("player", inventoryID)
|
||||||
if link then
|
if itemID then
|
||||||
local _, _, itemID = string.find(link, "item:(%d+)")
|
|
||||||
local name, link, _, _, itemType, itemSubType, _, _, texture = GetItemInfo(itemID)
|
local name, link, _, _, itemType, itemSubType, _, _, texture = GetItemInfo(itemID)
|
||||||
if name then
|
if name then
|
||||||
local count = GetInventoryItemCount("player", inventoryID)
|
local count = GetInventoryItemCount("player", inventoryID)
|
||||||
@@ -199,10 +198,9 @@ function CleveRoids.IndexEquipSlot(inventoryID)
|
|||||||
if not inventoryID then return end
|
if not inventoryID then return end
|
||||||
|
|
||||||
local items = CleveRoids.Items or {}
|
local items = CleveRoids.Items or {}
|
||||||
local link = GetInventoryItemLink("player", inventoryID)
|
local itemID = GetInventoryItemID("player", inventoryID)
|
||||||
|
|
||||||
if link then
|
if itemID then
|
||||||
local _, _, itemID = string.find(link, "item:(%d+)")
|
|
||||||
local name, itemLink, _, _, itemType, itemSubType, _, _, texture = GetItemInfo(itemID)
|
local name, itemLink, _, _, itemType, itemSubType, _, _, texture = GetItemInfo(itemID)
|
||||||
if name then
|
if name then
|
||||||
local count = GetInventoryItemCount("player", inventoryID)
|
local count = GetInventoryItemCount("player", inventoryID)
|
||||||
@@ -265,21 +263,17 @@ function CleveRoids.IndexItems()
|
|||||||
|
|
||||||
-- PERFORMANCE: Local function references
|
-- PERFORMANCE: Local function references
|
||||||
local GetContainerNumSlots = GetContainerNumSlots
|
local GetContainerNumSlots = GetContainerNumSlots
|
||||||
local GetContainerItemLink = GetContainerItemLink
|
|
||||||
local GetContainerItemInfo = GetContainerItemInfo
|
local GetContainerItemInfo = GetContainerItemInfo
|
||||||
local GetInventoryItemLink = GetInventoryItemLink
|
|
||||||
local GetInventoryItemCount = GetInventoryItemCount
|
local GetInventoryItemCount = GetInventoryItemCount
|
||||||
|
|
||||||
-- Scan bags (reverse order to prefer first stack)
|
-- Scan bags (reverse order to prefer first stack)
|
||||||
for bagID = 0, NUM_BAG_SLOTS do
|
for bagID = 0, NUM_BAG_SLOTS do
|
||||||
local numSlots = GetContainerNumSlots(bagID)
|
local numSlots = GetContainerNumSlots(bagID)
|
||||||
for slot = numSlots, 1, -1 do
|
for slot = numSlots, 1, -1 do
|
||||||
local link = GetContainerItemLink(bagID, slot)
|
local itemID = C_Container.GetContainerItemID(bagID, slot)
|
||||||
if link then
|
if itemID then
|
||||||
local _, _, itemID = string_find(link, "item:(%d+)")
|
-- Decorated name for the duplicate fast-path (no link string built)
|
||||||
|
local linkName = C_Item.GetItemName({ bagID = bagID, slotIndex = slot })
|
||||||
-- PERFORMANCE: Try to extract name from link first to check for duplicates
|
|
||||||
local _, _, linkName = string_find(link, "%[(.+)%]")
|
|
||||||
local existing = linkName and items[linkName]
|
local existing = linkName and items[linkName]
|
||||||
|
|
||||||
if existing then
|
if existing then
|
||||||
@@ -317,13 +311,11 @@ function CleveRoids.IndexItems()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Scan equipped items
|
-- Scan equipped items
|
||||||
for inventoryID = 0, 19 do
|
for inventoryID = 1, 19 do
|
||||||
local link = GetInventoryItemLink("player", inventoryID)
|
local itemID = GetInventoryItemID("player", inventoryID)
|
||||||
if link then
|
if itemID then
|
||||||
local _, _, itemID = string_find(link, "item:(%d+)")
|
-- Decorated name for the duplicate fast-path (no link string built)
|
||||||
|
local linkName = C_Item.GetItemName({ equipmentSlotIndex = inventoryID })
|
||||||
-- PERFORMANCE: Try to extract name from link first
|
|
||||||
local _, _, linkName = string_find(link, "%[(.+)%]")
|
|
||||||
local existing = linkName and items[linkName]
|
local existing = linkName and items[linkName]
|
||||||
|
|
||||||
if existing then
|
if existing then
|
||||||
@@ -477,10 +469,8 @@ local function makeInventoryItem(inventoryID, link, Items)
|
|||||||
if not link then link = GetInventoryItemLink("player", inventoryID) end
|
if not link then link = GetInventoryItemLink("player", inventoryID) end
|
||||||
if not link then return end
|
if not link then return end
|
||||||
|
|
||||||
local _, _, itemID = string_find(link, "item:(%d+)")
|
local itemID = GetInventoryItemID("player", inventoryID)
|
||||||
itemID = itemID and tonumber(itemID) or nil
|
local name = C_Item.GetItemName({ equipmentSlotIndex = inventoryID })
|
||||||
|
|
||||||
local name = itemID and GetItemInfo(itemID) or nil
|
|
||||||
local texture = GetInventoryItemTexture("player", inventoryID)
|
local texture = GetInventoryItemTexture("player", inventoryID)
|
||||||
local count = GetInventoryItemCount("player", inventoryID)
|
local count = GetInventoryItemCount("player", inventoryID)
|
||||||
|
|
||||||
@@ -509,14 +499,12 @@ local function makeBagItem(bagID, slot, link, Items)
|
|||||||
end
|
end
|
||||||
if not link then return end
|
if not link then return end
|
||||||
|
|
||||||
local _, _, itemID = string_find(link, "item:(%d+)")
|
local itemID = C_Container.GetContainerItemID(bagID, slot)
|
||||||
itemID = itemID and tonumber(itemID) or nil
|
|
||||||
|
|
||||||
local name, _, _, _, _, _, _, _, texture = GetItemInfo(itemID)
|
local name = C_Item.GetItemName(ItemLocation:CreateFromBagAndSlot(bagID, slot))
|
||||||
local count = 0
|
local count = 0
|
||||||
local tex, itemCount = GetContainerItemInfo(bagID, slot)
|
local texture, itemCount = GetContainerItemInfo(bagID, slot)
|
||||||
if itemCount then count = itemCount end
|
if itemCount then count = itemCount end
|
||||||
if not texture then texture = tex end
|
|
||||||
|
|
||||||
local it = {
|
local it = {
|
||||||
bagID = bagID,
|
bagID = bagID,
|
||||||
@@ -574,9 +562,7 @@ function CleveRoids.GetItem(text)
|
|||||||
for inv = 1, 19 do
|
for inv = 1, 19 do
|
||||||
local link = GetInventoryItemLink("player", inv)
|
local link = GetInventoryItemLink("player", inv)
|
||||||
if link then
|
if link then
|
||||||
local _, _, itemID = string_find(link, "item:(%d+)")
|
local itemID = GetInventoryItemID("player", inv)
|
||||||
itemID = itemID and tonumber(itemID) or nil
|
|
||||||
|
|
||||||
if qid and itemID and qid == itemID then
|
if qid and itemID and qid == itemID then
|
||||||
return makeInventoryItem(inv, link, Items)
|
return makeInventoryItem(inv, link, Items)
|
||||||
elseif qname then
|
elseif qname then
|
||||||
@@ -595,9 +581,7 @@ function CleveRoids.GetItem(text)
|
|||||||
for slot = 1, slots do
|
for slot = 1, slots do
|
||||||
local link = GetContainerItemLink(bag, slot)
|
local link = GetContainerItemLink(bag, slot)
|
||||||
if link then
|
if link then
|
||||||
local _, _, itemID = string_find(link, "item:(%d+)")
|
local itemID = C_Container.GetContainerItemID(bag, slot)
|
||||||
itemID = itemID and tonumber(itemID) or nil
|
|
||||||
|
|
||||||
if qid and itemID and qid == itemID then
|
if qid and itemID and qid == itemID then
|
||||||
return makeBagItem(bag, slot, link, Items)
|
return makeBagItem(bag, slot, link, Items)
|
||||||
elseif qname then
|
elseif qname then
|
||||||
@@ -720,18 +704,16 @@ function CleveRoids.FindItemQuick(text)
|
|||||||
if cached then
|
if cached then
|
||||||
-- Validate: check if item is actually at the cached location
|
-- Validate: check if item is actually at the cached location
|
||||||
if cached.inventoryID then
|
if cached.inventoryID then
|
||||||
local link = GetInventoryItemLink("player", cached.inventoryID)
|
if qid then
|
||||||
if link then
|
if GetInventoryItemID("player", cached.inventoryID) == qid then
|
||||||
local nm = GetNameFromLink(link)
|
cached._validated = true
|
||||||
|
return cached -- Cache is valid
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local nm = C_Item.GetItemName({ equipmentSlotIndex = cached.inventoryID })
|
||||||
if nm and qname and string_lower(nm) == qname then
|
if nm and qname and string_lower(nm) == qname then
|
||||||
cached._validated = true
|
cached._validated = true
|
||||||
return cached -- Cache is valid
|
return cached -- Cache is valid
|
||||||
elseif qid then
|
|
||||||
local _, _, itemID = string_find(link, "item:(%d+)")
|
|
||||||
if itemID and tonumber(itemID) == qid then
|
|
||||||
cached._validated = true
|
|
||||||
return cached -- Cache is valid
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- Cache is stale - item not at cached equipped slot, invalidate
|
-- Cache is stale - item not at cached equipped slot, invalidate
|
||||||
@@ -740,18 +722,16 @@ function CleveRoids.FindItemQuick(text)
|
|||||||
Items[string_lower(cached.name)] = nil
|
Items[string_lower(cached.name)] = nil
|
||||||
end
|
end
|
||||||
elseif cached.bagID and cached.slot then
|
elseif cached.bagID and cached.slot then
|
||||||
local link = GetContainerItemLink(cached.bagID, cached.slot)
|
if qid then
|
||||||
if link then
|
if C_Container.GetContainerItemID(cached.bagID, cached.slot) == qid then
|
||||||
local nm = GetNameFromLink(link)
|
cached._validated = true
|
||||||
|
return cached -- Cache is valid
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local nm = C_Item.GetItemName({ bagID = cached.bagID, slotIndex = cached.slot })
|
||||||
if nm and qname and string_lower(nm) == qname then
|
if nm and qname and string_lower(nm) == qname then
|
||||||
cached._validated = true
|
cached._validated = true
|
||||||
return cached -- Cache is valid
|
return cached -- Cache is valid
|
||||||
elseif qid then
|
|
||||||
local _, _, itemID = string_find(link, "item:(%d+)")
|
|
||||||
if itemID and tonumber(itemID) == qid then
|
|
||||||
cached._validated = true
|
|
||||||
return cached -- Cache is valid
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- Cache is stale - item not at cached bag slot, invalidate
|
-- Cache is stale - item not at cached bag slot, invalidate
|
||||||
@@ -791,20 +771,17 @@ function CleveRoids.FindItemQuick(text)
|
|||||||
for slot = 1, slots do
|
for slot = 1, slots do
|
||||||
local link = GetContainerItemLink(bag, slot)
|
local link = GetContainerItemLink(bag, slot)
|
||||||
if link then
|
if link then
|
||||||
local _, _, itemID = string_find(link, "item:(%d+)")
|
local itemID = C_Container.GetContainerItemID(bag, slot)
|
||||||
if itemID then
|
-- ID match: fast path
|
||||||
itemID = tonumber(itemID)
|
if qid and qid == itemID then
|
||||||
-- ID match: fast path
|
return makeBagItem(bag, slot, link, Items)
|
||||||
if qid and qid == itemID then
|
end
|
||||||
|
-- Name match: extract name from link (faster than GetItemInfo)
|
||||||
|
if qname then
|
||||||
|
local nm = GetNameFromLink(link)
|
||||||
|
if nm and string_lower(nm) == qname then
|
||||||
return makeBagItem(bag, slot, link, Items)
|
return makeBagItem(bag, slot, link, Items)
|
||||||
end
|
end
|
||||||
-- Name match: extract name from link (faster than GetItemInfo)
|
|
||||||
if qname then
|
|
||||||
local nm = GetNameFromLink(link)
|
|
||||||
if nm and string_lower(nm) == qname then
|
|
||||||
return makeBagItem(bag, slot, link, Items)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -818,25 +795,19 @@ end
|
|||||||
function CleveRoids.IsItemEquipped(text, inventoryId)
|
function CleveRoids.IsItemEquipped(text, inventoryId)
|
||||||
if not text or not inventoryId then return false end
|
if not text or not inventoryId then return false end
|
||||||
|
|
||||||
local link = GetInventoryItemLink("player", inventoryId)
|
local currentID = GetInventoryItemID("player", inventoryId)
|
||||||
if not link then return false end
|
|
||||||
|
|
||||||
local _, _, currentID = string_find(link, "item:(%d+)")
|
|
||||||
if not currentID then return false end
|
if not currentID then return false end
|
||||||
|
|
||||||
-- Check by ID (fast path)
|
-- Check by ID (fast path)
|
||||||
local textId = tonumber(text)
|
local textId = tonumber(text)
|
||||||
if textId and textId == tonumber(currentID) then
|
if textId and textId == currentID then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check by name - extract from link instead of GetItemInfo for performance
|
-- Check by name (decorated, so suffixed gear still matches)
|
||||||
local currentName = GetNameFromLink(link)
|
local currentName = C_Item.GetItemName({ equipmentSlotIndex = inventoryId })
|
||||||
if currentName then
|
if currentName and string_lower(currentName) == string_lower(text) then
|
||||||
local textLower = string_lower(text)
|
return true
|
||||||
if string_lower(currentName) == textLower then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|||||||
+1
-6
@@ -6918,12 +6918,7 @@ function CleveRoids.ApplyEquipmentModifier(spellID, baseDuration)
|
|||||||
local modifiedDuration = modifier.modifier(baseDuration, itemID)
|
local modifiedDuration = modifier.modifier(baseDuration, itemID)
|
||||||
|
|
||||||
if modifiedDuration ~= baseDuration and CleveRoids.debug then
|
if modifiedDuration ~= baseDuration and CleveRoids.debug then
|
||||||
local itemName = "Unknown"
|
local itemName = C_Item.GetItemName({ equipmentSlotIndex = modifier.slot }) or "Unknown"
|
||||||
local itemLink = GetInventoryItemLink("player", modifier.slot)
|
|
||||||
if itemLink then
|
|
||||||
local _, _, _n = string.find(itemLink, "%[(.-)%]")
|
|
||||||
itemName = _n or "Unknown"
|
|
||||||
end
|
|
||||||
|
|
||||||
DEFAULT_CHAT_FRAME:AddMessage(
|
DEFAULT_CHAT_FRAME:AddMessage(
|
||||||
string.format("|cffff00ff[Equipment Modifier]|r %s (ID:%d): %ds -> %ds (item: %s [%d])",
|
string.format("|cffff00ff[Equipment Modifier]|r %s (ID:%d): %ds -> %ds (item: %s [%d])",
|
||||||
|
|||||||
Reference in New Issue
Block a user