feat: Occupied Bag Swap
This commit is contained in:
@@ -28,6 +28,7 @@ Data\EquipmentScanner.lua
|
||||
Data\EquipmentSets.lua
|
||||
|
||||
Sorting\SortEngine.lua
|
||||
Sorting\BagReplacer.lua
|
||||
|
||||
# UI Lua must load before XML so OnLoad handlers exist
|
||||
UI\ItemButton.lua
|
||||
|
||||
@@ -0,0 +1,476 @@
|
||||
--===========================================================================
|
||||
-- BagReplacer: Auto-replace occupied bags by evacuating items first
|
||||
--===========================================================================
|
||||
local addon = Guda
|
||||
local BagReplacer = {}
|
||||
addon.Modules.BagReplacer = BagReplacer
|
||||
|
||||
BagReplacer.inProgress = false
|
||||
|
||||
local C = addon.Constants
|
||||
|
||||
--===========================================================================
|
||||
-- Lock-wait mechanism (independent from SortEngine)
|
||||
--===========================================================================
|
||||
local replacerFrame = CreateFrame("Frame")
|
||||
local pendingSlots = {} -- flat array: {bagID1, slot1, bagID2, slot2, ...}
|
||||
local pendingCount = 0
|
||||
local pendingSet = {} -- bagID*1000+slot -> true
|
||||
local waitingForLocks = false
|
||||
local onLocksCleared = nil
|
||||
|
||||
local function AddPendingLock(bagID, slot)
|
||||
local key = bagID * 1000 + slot
|
||||
if not pendingSet[key] then
|
||||
pendingSet[key] = true
|
||||
pendingCount = pendingCount + 1
|
||||
pendingSlots[pendingCount * 2 - 1] = bagID
|
||||
pendingSlots[pendingCount * 2] = slot
|
||||
end
|
||||
end
|
||||
|
||||
local function ClearPendingLocks()
|
||||
for k in pairs(pendingSet) do pendingSet[k] = nil end
|
||||
for i = 1, pendingCount * 2 do pendingSlots[i] = nil end
|
||||
pendingCount = 0
|
||||
end
|
||||
|
||||
local function AnyPendingLocked()
|
||||
if pendingCount == 0 then return false end
|
||||
for i = 1, pendingCount do
|
||||
local bagID = pendingSlots[i * 2 - 1]
|
||||
local slot = pendingSlots[i * 2]
|
||||
if bagID and slot then
|
||||
local _, _, locked = GetContainerItemInfo(bagID, slot)
|
||||
if locked then return true end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
replacerFrame:RegisterEvent("ITEM_LOCK_CHANGED")
|
||||
replacerFrame:SetScript("OnEvent", function()
|
||||
if waitingForLocks and onLocksCleared then
|
||||
if not AnyPendingLocked() then
|
||||
waitingForLocks = false
|
||||
local cb = onLocksCleared
|
||||
onLocksCleared = nil
|
||||
ClearPendingLocks()
|
||||
cb()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local function WaitForLocksCleared(callback, timeout)
|
||||
local minDelay = 0.5
|
||||
Guda_ScheduleTimer(minDelay, function()
|
||||
if not AnyPendingLocked() then
|
||||
ClearPendingLocks()
|
||||
callback()
|
||||
return
|
||||
end
|
||||
waitingForLocks = true
|
||||
onLocksCleared = callback
|
||||
local remaining = (timeout or 2.0) - minDelay
|
||||
if remaining < 0.5 then remaining = 0.5 end
|
||||
Guda_ScheduleTimer(remaining, function()
|
||||
if waitingForLocks then
|
||||
waitingForLocks = false
|
||||
onLocksCleared = nil
|
||||
ClearPendingLocks()
|
||||
ClearCursor()
|
||||
callback()
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
--===========================================================================
|
||||
-- Check if item can go in a specific bag (mirrors SortEngine logic)
|
||||
--===========================================================================
|
||||
local function CanItemGoInBag(itemLink, targetBagID)
|
||||
if targetBagID == 0 or targetBagID == -1 or targetBagID == -2 then
|
||||
return true
|
||||
end
|
||||
local bagType = addon.Modules.Utils:GetSpecializedBagType(targetBagID)
|
||||
if not bagType then
|
||||
return true
|
||||
end
|
||||
local preferredType = addon.Modules.Utils:GetItemPreferredContainer(itemLink)
|
||||
return preferredType == bagType
|
||||
end
|
||||
|
||||
--===========================================================================
|
||||
-- Build list of free slots across all bags except the target bag
|
||||
-- Returns: { {bagID, slotID, bagType}, ... }
|
||||
--===========================================================================
|
||||
local function GetAvailableFreeSlots(excludeBagID)
|
||||
local freeSlots = {}
|
||||
local count = 0
|
||||
|
||||
-- Iterate bags 0-4, skipping the excluded bag
|
||||
for bagID = 0, C.BAG_LAST do
|
||||
if bagID ~= excludeBagID then
|
||||
local numSlots = GetContainerNumSlots(bagID)
|
||||
if numSlots and numSlots > 0 then
|
||||
local bagType = addon.Modules.Utils:GetSpecializedBagType(bagID)
|
||||
for slot = 1, numSlots do
|
||||
local texture = GetContainerItemInfo(bagID, slot)
|
||||
if not texture then
|
||||
count = count + 1
|
||||
freeSlots[count] = { bagID = bagID, slot = slot, bagType = bagType }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return freeSlots, count
|
||||
end
|
||||
|
||||
--===========================================================================
|
||||
-- Get items in a bag
|
||||
-- Returns: { {slot, itemLink}, ... }, count
|
||||
--===========================================================================
|
||||
local function GetBagItems(bagID)
|
||||
local items = {}
|
||||
local count = 0
|
||||
local numSlots = GetContainerNumSlots(bagID)
|
||||
|
||||
if not numSlots or numSlots == 0 then
|
||||
return items, 0
|
||||
end
|
||||
|
||||
for slot = 1, numSlots do
|
||||
local texture = GetContainerItemInfo(bagID, slot)
|
||||
if texture then
|
||||
local link = GetContainerItemLink(bagID, slot)
|
||||
count = count + 1
|
||||
items[count] = { slot = slot, itemLink = link }
|
||||
end
|
||||
end
|
||||
|
||||
return items, count
|
||||
end
|
||||
|
||||
--===========================================================================
|
||||
-- BuildEvacuationPlan: assign each item to a free slot, reserve stash slot
|
||||
-- Returns: plan table or nil, errorMsg
|
||||
--===========================================================================
|
||||
function BagReplacer:BuildEvacuationPlan(targetBagID)
|
||||
local items, itemCount = GetBagItems(targetBagID)
|
||||
addon:DebugSort("[BagReplacer] BuildEvacuationPlan: bag %d has %d items", targetBagID, itemCount)
|
||||
if itemCount == 0 then
|
||||
return { moves = {}, stashBag = nil, stashSlot = nil, itemCount = 0 }, nil
|
||||
end
|
||||
|
||||
local freeSlots, freeCount = GetAvailableFreeSlots(targetBagID)
|
||||
local needed = itemCount + 1 -- +1 for stashing the new bag from cursor
|
||||
addon:DebugSort("[BagReplacer] Need %d free slots (items+stash), have %d", needed, freeCount)
|
||||
|
||||
if freeCount < needed then
|
||||
return nil, string.format(
|
||||
"Not enough free bag space. Need %d free slots, have %d.",
|
||||
needed, freeCount
|
||||
)
|
||||
end
|
||||
|
||||
-- Separate free slots into specialized and regular
|
||||
local regularFree = {}
|
||||
local regularCount = 0
|
||||
local specializedFree = {} -- keyed by bagType
|
||||
for i = 1, freeCount do
|
||||
local fs = freeSlots[i]
|
||||
if fs.bagType then
|
||||
if not specializedFree[fs.bagType] then
|
||||
specializedFree[fs.bagType] = {}
|
||||
end
|
||||
local t = specializedFree[fs.bagType]
|
||||
t[table.getn(t) + 1] = fs
|
||||
else
|
||||
regularCount = regularCount + 1
|
||||
regularFree[regularCount] = fs
|
||||
end
|
||||
end
|
||||
|
||||
local moves = {}
|
||||
local moveCount = 0
|
||||
local regularIdx = 1 -- next regular free slot to use
|
||||
|
||||
-- Assign each item to a free slot
|
||||
for i = 1, itemCount do
|
||||
local item = items[i]
|
||||
local assigned = false
|
||||
|
||||
-- Try specialized bag first if item has a preferred type
|
||||
if item.itemLink then
|
||||
local preferredType = addon.Modules.Utils:GetItemPreferredContainer(item.itemLink)
|
||||
if preferredType and specializedFree[preferredType] then
|
||||
local specSlots = specializedFree[preferredType]
|
||||
if table.getn(specSlots) > 0 then
|
||||
local fs = specSlots[table.getn(specSlots)]
|
||||
specSlots[table.getn(specSlots)] = nil
|
||||
moveCount = moveCount + 1
|
||||
moves[moveCount] = {
|
||||
fromBag = targetBagID, fromSlot = item.slot,
|
||||
toBag = fs.bagID, toSlot = fs.slot
|
||||
}
|
||||
addon:DebugSort("[BagReplacer] Plan move #%d: bag%d/slot%d -> bag%d/slot%d (specialized %s)", moveCount, targetBagID, item.slot, fs.bagID, fs.slot, preferredType)
|
||||
assigned = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Fall back to regular free slot
|
||||
if not assigned then
|
||||
if regularIdx <= regularCount then
|
||||
local fs = regularFree[regularIdx]
|
||||
regularIdx = regularIdx + 1
|
||||
moveCount = moveCount + 1
|
||||
moves[moveCount] = {
|
||||
fromBag = targetBagID, fromSlot = item.slot,
|
||||
toBag = fs.bagID, toSlot = fs.slot
|
||||
}
|
||||
addon:DebugSort("[BagReplacer] Plan move #%d: bag%d/slot%d -> bag%d/slot%d (regular)", moveCount, targetBagID, item.slot, fs.bagID, fs.slot)
|
||||
assigned = true
|
||||
end
|
||||
end
|
||||
|
||||
if not assigned then
|
||||
addon:DebugSort("[BagReplacer] Failed to assign slot %d to a free slot", item.slot)
|
||||
return nil, string.format(
|
||||
"Not enough compatible bag space. Need %d free slots, have %d.",
|
||||
needed, freeCount
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
-- Reserve a regular free slot for stashing the new bag from cursor
|
||||
local stashBag, stashSlot
|
||||
if regularIdx <= regularCount then
|
||||
local fs = regularFree[regularIdx]
|
||||
stashBag = fs.bagID
|
||||
stashSlot = fs.slot
|
||||
addon:DebugSort("[BagReplacer] Stash slot: bag%d/slot%d", stashBag, stashSlot)
|
||||
else
|
||||
-- No regular free slot left for stash - check if any specialized slot works
|
||||
-- (new bag is a container item, needs a regular slot)
|
||||
return nil, string.format(
|
||||
"Not enough free bag space. Need %d free slots, have %d.",
|
||||
needed, freeCount
|
||||
)
|
||||
end
|
||||
|
||||
return {
|
||||
moves = moves,
|
||||
stashBag = stashBag,
|
||||
stashSlot = stashSlot,
|
||||
itemCount = itemCount
|
||||
}, nil
|
||||
end
|
||||
|
||||
--===========================================================================
|
||||
-- Abort: cleanup on failure
|
||||
--===========================================================================
|
||||
function BagReplacer:Abort(reason)
|
||||
addon:DebugSort("[BagReplacer] Abort: %s", reason or "unknown")
|
||||
ClearCursor()
|
||||
ClearPendingLocks()
|
||||
waitingForLocks = false
|
||||
onLocksCleared = nil
|
||||
self.inProgress = false
|
||||
if reason then
|
||||
addon:Print(reason)
|
||||
end
|
||||
-- Refresh UI
|
||||
if addon.Modules.BagFrame and addon.Modules.BagFrame.Update then
|
||||
addon.Modules.BagFrame:Update()
|
||||
end
|
||||
end
|
||||
|
||||
--===========================================================================
|
||||
-- FinishReplacement: pick up new bag from stash, equip it, handle old bag
|
||||
--===========================================================================
|
||||
function BagReplacer:FinishReplacement(invSlot, stashBag, stashSlot)
|
||||
addon:DebugSort("[BagReplacer] FinishReplacement: picking up new bag from bag%d/slot%d, equipping to invSlot %d", stashBag, stashSlot, invSlot)
|
||||
-- Verify new bag is still in stash slot
|
||||
local stashTexture = GetContainerItemInfo(stashBag, stashSlot)
|
||||
if not stashTexture then
|
||||
self:Abort("Bag replacement failed: stashed bag is missing.")
|
||||
return
|
||||
end
|
||||
|
||||
-- Pick up new bag from stash
|
||||
PickupContainerItem(stashBag, stashSlot)
|
||||
AddPendingLock(stashBag, stashSlot)
|
||||
|
||||
-- Wait briefly for pickup, then equip
|
||||
Guda_ScheduleTimer(0.3, function()
|
||||
if CursorHasItem and CursorHasItem() then
|
||||
addon:DebugSort("[BagReplacer] Equipping new bag to invSlot %d", invSlot)
|
||||
EquipCursorItem(invSlot)
|
||||
|
||||
-- Wait for equip to process, then try to place old bag
|
||||
Guda_ScheduleTimer(0.5, function()
|
||||
if CursorHasItem and CursorHasItem() then
|
||||
addon:DebugSort("[BagReplacer] Old bag on cursor, finding free slot to place it")
|
||||
-- Old bag is on cursor - try to find a free slot for it
|
||||
local freeSlots, freeCount = GetAvailableFreeSlots(-999) -- exclude nothing
|
||||
for i = 1, freeCount do
|
||||
local fs = freeSlots[i]
|
||||
if not fs.bagType then -- regular slot only
|
||||
addon:DebugSort("[BagReplacer] Placing old bag into bag%d/slot%d", fs.bagID, fs.slot)
|
||||
PickupContainerItem(fs.bagID, fs.slot)
|
||||
ClearCursor()
|
||||
break
|
||||
end
|
||||
end
|
||||
-- If still on cursor, that's fine - user can place manually
|
||||
end
|
||||
|
||||
ClearPendingLocks()
|
||||
waitingForLocks = false
|
||||
onLocksCleared = nil
|
||||
BagReplacer.inProgress = false
|
||||
addon:Print("Bag replaced successfully!")
|
||||
|
||||
-- Refresh UI
|
||||
if addon.Modules.BagFrame and addon.Modules.BagFrame.Update then
|
||||
addon.Modules.BagFrame:Update()
|
||||
end
|
||||
-- Invalidate bag scanner cache
|
||||
if addon.Modules.BagScanner and addon.Modules.BagScanner.InvalidateCache then
|
||||
addon.Modules.BagScanner:InvalidateCache()
|
||||
end
|
||||
end)
|
||||
else
|
||||
BagReplacer:Abort("Bag replacement failed: could not pick up new bag.")
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--===========================================================================
|
||||
-- ExecuteNextMove: move one item, wait for lock, recurse
|
||||
--===========================================================================
|
||||
function BagReplacer:ExecuteNextMove(plan, index, invSlot)
|
||||
local moves = plan.moves
|
||||
local totalMoves = table.getn(moves)
|
||||
|
||||
-- All moves done - finish replacement
|
||||
if index > totalMoves then
|
||||
addon:DebugSort("[BagReplacer] All %d moves complete, finishing replacement", totalMoves)
|
||||
self:FinishReplacement(invSlot, plan.stashBag, plan.stashSlot)
|
||||
return
|
||||
end
|
||||
|
||||
local move = moves[index]
|
||||
addon:DebugSort("[BagReplacer] ExecuteNextMove %d/%d: bag%d/slot%d -> bag%d/slot%d", index, totalMoves, move.fromBag, move.fromSlot, move.toBag, move.toSlot)
|
||||
|
||||
-- Verify source slot still has an item (player may have moved it)
|
||||
local sourceTexture = GetContainerItemInfo(move.fromBag, move.fromSlot)
|
||||
if not sourceTexture then
|
||||
addon:DebugSort("[BagReplacer] Source slot empty, skipping move %d", index)
|
||||
-- Item already gone, skip to next
|
||||
self:ExecuteNextMove(plan, index + 1, invSlot)
|
||||
return
|
||||
end
|
||||
|
||||
-- Check if source is locked
|
||||
local _, _, locked = GetContainerItemInfo(move.fromBag, move.fromSlot)
|
||||
if locked then
|
||||
addon:DebugSort("[BagReplacer] Source slot locked, waiting for unlock")
|
||||
-- Wait for it to unlock, then retry this move
|
||||
AddPendingLock(move.fromBag, move.fromSlot)
|
||||
WaitForLocksCleared(function()
|
||||
BagReplacer:ExecuteNextMove(plan, index, invSlot)
|
||||
end)
|
||||
return
|
||||
end
|
||||
|
||||
-- Execute the move
|
||||
PickupContainerItem(move.fromBag, move.fromSlot)
|
||||
PickupContainerItem(move.toBag, move.toSlot)
|
||||
ClearCursor()
|
||||
|
||||
-- Track locks
|
||||
AddPendingLock(move.fromBag, move.fromSlot)
|
||||
AddPendingLock(move.toBag, move.toSlot)
|
||||
|
||||
-- Wait for locks to clear, then next move
|
||||
WaitForLocksCleared(function()
|
||||
BagReplacer:ExecuteNextMove(plan, index + 1, invSlot)
|
||||
end)
|
||||
end
|
||||
|
||||
--===========================================================================
|
||||
-- Execute: main entry point
|
||||
--===========================================================================
|
||||
function BagReplacer:Execute(targetBagID, invSlot)
|
||||
addon:DebugSort("[BagReplacer] Execute: targetBagID=%d, invSlot=%d", targetBagID, invSlot)
|
||||
|
||||
-- Guard: already in progress
|
||||
if self.inProgress then
|
||||
addon:DebugSort("[BagReplacer] Blocked: replacement already in progress")
|
||||
addon:Print("Cannot replace bag: another replacement is in progress.")
|
||||
return
|
||||
end
|
||||
|
||||
-- Guard: sorting in progress
|
||||
local SortEngine = addon.Modules.SortEngine
|
||||
if SortEngine and SortEngine.sortingInProgress then
|
||||
addon:DebugSort("[BagReplacer] Blocked: sorting in progress")
|
||||
addon:Print("Cannot replace bag while sorting is in progress.")
|
||||
return
|
||||
end
|
||||
|
||||
-- Guard: combat
|
||||
if UnitAffectingCombat("player") then
|
||||
addon:DebugSort("[BagReplacer] Blocked: in combat")
|
||||
addon:Print("Cannot replace bag during combat.")
|
||||
return
|
||||
end
|
||||
|
||||
-- Check if bag is empty (normal equip works)
|
||||
local _, itemCount = GetBagItems(targetBagID)
|
||||
if itemCount == 0 then
|
||||
addon:DebugSort("[BagReplacer] Bag is empty, using normal equip")
|
||||
if EquipCursorItem then
|
||||
EquipCursorItem(invSlot)
|
||||
elseif PutItemInBag then
|
||||
PutItemInBag(invSlot)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Build evacuation plan
|
||||
local plan, errorMsg = self:BuildEvacuationPlan(targetBagID)
|
||||
if not plan then
|
||||
addon:DebugSort("[BagReplacer] Plan failed: %s", errorMsg)
|
||||
addon:Print(errorMsg)
|
||||
return -- cursor untouched, user keeps holding new bag
|
||||
end
|
||||
|
||||
-- Start replacement
|
||||
self.inProgress = true
|
||||
addon:Print(string.format("Replacing bag: moving %d items...", plan.itemCount))
|
||||
addon:DebugSort("[BagReplacer] Starting replacement: %d moves, stash at bag%d/slot%d", table.getn(plan.moves), plan.stashBag, plan.stashSlot)
|
||||
|
||||
-- Step 1: Stash the new bag from cursor into the reserved free slot
|
||||
addon:DebugSort("[BagReplacer] Stashing cursor item to bag%d/slot%d", plan.stashBag, plan.stashSlot)
|
||||
PickupContainerItem(plan.stashBag, plan.stashSlot)
|
||||
-- This places cursor item (new bag) into stashSlot
|
||||
AddPendingLock(plan.stashBag, plan.stashSlot)
|
||||
|
||||
-- Wait for stash to complete, then start evacuating
|
||||
WaitForLocksCleared(function()
|
||||
-- Verify the new bag was stashed
|
||||
local stashTexture = GetContainerItemInfo(plan.stashBag, plan.stashSlot)
|
||||
if not stashTexture then
|
||||
BagReplacer:Abort("Bag replacement failed: could not stash new bag.")
|
||||
return
|
||||
end
|
||||
addon:DebugSort("[BagReplacer] Stash confirmed, beginning evacuation")
|
||||
-- Begin moving items out of target bag
|
||||
BagReplacer:ExecuteNextMove(plan, 1, invSlot)
|
||||
end)
|
||||
end
|
||||
+50
-24
@@ -3,6 +3,9 @@
|
||||
|
||||
local addon = Guda
|
||||
|
||||
-- Forward declaration (defined later near bag slot handlers)
|
||||
local Guda_TryEquipBagOnSlot
|
||||
|
||||
local BagFrame = {}
|
||||
addon.Modules.BagFrame = BagFrame
|
||||
|
||||
@@ -555,13 +558,7 @@ local function CreateBagFlyout(parent)
|
||||
btn:SetScript("OnReceiveDrag", function()
|
||||
if this and this.bagID and this.bagID ~= 0 and CursorHasItem and CursorHasItem() then
|
||||
local inv = ContainerIDToInventoryID(this.bagID)
|
||||
if EquipCursorItem then
|
||||
EquipCursorItem(inv)
|
||||
elseif PutItemInBag then
|
||||
PutItemInBag(inv)
|
||||
end
|
||||
Guda_BagSlot_Update(this, this.bagID)
|
||||
if BagFrame and BagFrame.Update then BagFrame:Update() end
|
||||
Guda_TryEquipBagOnSlot(this.bagID, inv, this)
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -2641,12 +2638,18 @@ local function HookBagContainers()
|
||||
local button = getglobal(buttonName)
|
||||
|
||||
if button then
|
||||
local bagID = i
|
||||
local originalOnClick = button:GetScript("OnClick")
|
||||
button:SetScript("OnClick", function()
|
||||
local mouseButton = arg1 or "LeftButton" -- Vanilla uses global arg1
|
||||
if mouseButton == "LeftButton" then
|
||||
-- Open Guda Bag View instead of default bag
|
||||
BagFrame:Toggle()
|
||||
-- If cursor has an item, try bag replacement instead of toggle
|
||||
if CursorHasItem and CursorHasItem() then
|
||||
local invSlot = ContainerIDToInventoryID(bagID)
|
||||
Guda_TryEquipBagOnSlot(bagID, invSlot, nil)
|
||||
else
|
||||
BagFrame:Toggle()
|
||||
end
|
||||
else
|
||||
-- Allow right-click and other buttons to work normally
|
||||
if originalOnClick then
|
||||
@@ -2654,6 +2657,14 @@ local function HookBagContainers()
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Hook OnReceiveDrag for drag-drop bag replacement
|
||||
button:SetScript("OnReceiveDrag", function()
|
||||
if CursorHasItem and CursorHasItem() then
|
||||
local invSlot = ContainerIDToInventoryID(bagID)
|
||||
Guda_TryEquipBagOnSlot(bagID, invSlot, nil)
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3043,6 +3054,34 @@ function Guda_BagSlot_ApplyBackdrop(button)
|
||||
button:SetBackdropBorderColor(fbBorder[1], fbBorder[2], fbBorder[3], fbBorder[4])
|
||||
end
|
||||
|
||||
-- Try to equip a bag from cursor onto a bag slot, auto-replacing if occupied
|
||||
Guda_TryEquipBagOnSlot = function(bagID, invSlot, button)
|
||||
if not CursorHasItem or not CursorHasItem() then return end
|
||||
|
||||
-- Check if current bag has items
|
||||
local numSlots = GetContainerNumSlots(bagID)
|
||||
local hasItems = false
|
||||
if numSlots and numSlots > 0 then
|
||||
for slot = 1, numSlots do
|
||||
local texture = GetContainerItemInfo(bagID, slot)
|
||||
if texture then hasItems = true; break end
|
||||
end
|
||||
end
|
||||
|
||||
if hasItems and addon.Modules.BagReplacer then
|
||||
addon.Modules.BagReplacer:Execute(bagID, invSlot)
|
||||
else
|
||||
if EquipCursorItem then
|
||||
EquipCursorItem(invSlot)
|
||||
elseif PutItemInBag then
|
||||
PutItemInBag(invSlot)
|
||||
end
|
||||
end
|
||||
|
||||
if button then Guda_BagSlot_Update(button, bagID) end
|
||||
if BagFrame and BagFrame.Update then BagFrame:Update() end
|
||||
end
|
||||
|
||||
-- OnLoad handler for bag slot buttons
|
||||
function Guda_BagSlot_OnLoad(button, bagID)
|
||||
-- Hide borders from ItemButtonTemplate
|
||||
@@ -3094,13 +3133,7 @@ function Guda_BagSlot_OnLoad(button, bagID)
|
||||
button:SetScript("OnReceiveDrag", function()
|
||||
if this and this.bagID and this.bagID ~= 0 and CursorHasItem and CursorHasItem() then
|
||||
local inv = ContainerIDToInventoryID(this.bagID)
|
||||
if EquipCursorItem then
|
||||
EquipCursorItem(inv)
|
||||
elseif PutItemInBag then
|
||||
PutItemInBag(inv)
|
||||
end
|
||||
Guda_BagSlot_Update(this, this.bagID)
|
||||
if BagFrame and BagFrame.Update then BagFrame:Update() end
|
||||
Guda_TryEquipBagOnSlot(this.bagID, inv, this)
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -3227,14 +3260,7 @@ function Guda_BagSlot_OnClick(button, bagID)
|
||||
if which == "LeftButton" then
|
||||
if bagID ~= 0 and CursorHasItem and CursorHasItem() then
|
||||
local invSlot = ContainerIDToInventoryID(bagID)
|
||||
if EquipCursorItem then
|
||||
EquipCursorItem(invSlot)
|
||||
else
|
||||
if PutItemInBag then PutItemInBag(invSlot) end
|
||||
end
|
||||
-- Update visuals after attempted equip
|
||||
Guda_BagSlot_Update(button, bagID)
|
||||
BagFrame:Update()
|
||||
Guda_TryEquipBagOnSlot(bagID, invSlot, button)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user