--[[ kRestack() is a global function and can be used in any addon or macro |
Some of the functionality is based on ArkInventory's restacking function, kudos! |
|
Usage: /restack [bags, bank, auto] ]] |
|
SlashCmdList["RESTACK"] = function(s) kRestack(s) end |
SLASH_RESTACK1 = "/restack" |
|
--[[ insert backpack and default bank container ]] |
local container = { bags = { 0 }, bank = { -1 } } |
|
--[[ initialize user's bag and bank identifiers ]] |
for i = 1, NUM_BAG_SLOTS do table.insert(container.bags, i) end |
for i = NUM_BAG_SLOTS + 1, NUM_BAG_SLOTS + NUM_BANKBAGSLOTS do table.insert(container.bank, i) end |
|
local function DecodeItemId(itemlink) |
return select(3, strfind(itemlink, "item:(%d+)")) |
end |
|
local function RestackFindPartial(cb, cs, id, loc) |
for _, bag in pairs(container[loc]) do |
for slot = GetContainerNumSlots(bag), 1, -1 do |
if not (bag == cb and slot == cs) then |
local item = GetContainerItemLink(bag, slot) |
if item then |
local itemId = DecodeItemId(item) |
if itemId == id then |
local _, count, locked = GetContainerItemInfo(bag, slot) |
local stack = select(8, GetItemInfo(itemId)) |
if count < stack then return true, bag, slot, count end |
end |
end |
end |
end |
end |
return false |
end |
|
local function RestackFindSpecial(ct, loc) |
for _, bag in pairs(container[loc]) do |
local _, bt = GetContainerNumFreeSlots(bag) |
if bt == 0 then |
for slot = 1, GetContainerNumSlots(bag) do |
local item = GetContainerItemLink(bag, slot) |
if item then |
local itemEquipLoc = select(8, GetItemInfo(h)) |
if itemEquipLoc ~= "INVTYPE_BAG" then |
local it = GetItemFamily(h) |
if bit.band(it, ct) > 0 then return true, bag, slot end |
end |
end |
end |
end |
end |
return false |
end |
|
local function RestackBags(loc) |
local changed = false |
for _, bag in pairs(container[loc]) do |
for slot = 1, GetContainerNumSlots(bag) do |
while true do |
local locked = select(3, GetContainerItemInfo(bag, slot)) |
if locked then |
coroutine.yield() |
else |
break |
end |
end |
|
local item = GetContainerItemLink(bag, slot) |
|
if item then |
local itemId = DecodeItemId(item) |
local stack = select(8, GetItemInfo(itemId)) |
local count = select(2, GetContainerItemInfo(bag, slot)) |
|
if stack > count then |
local locked, ok, pb, ps, pc |
|
while true do |
ok, pb, ps, pc = RestackFindPartial(bag, slot, itemId, loc) |
locked = ok and select(3, GetContainerItemInfo(pb, ps)) or false |
|
if locked then |
coroutine.yield() |
else |
break |
end |
end |
|
if ok then |
ClearCursor() |
PickupContainerItem(pb, ps) |
PickupContainerItem(bag, slot) |
ClearCursor() |
|
changed = true |
end |
end |
end |
end |
end |
return changed |
end |
|
local frame = CreateFrame("FRAME") |
frame:RegisterEvent("BAG_UPDATE") |
frame:SetScript("OnEvent", function() |
if AutoRestack and type(restacker) ~= "thread" then |
kRestack("bags", true) |
end |
end) |
|
function kRestack(loc, nowarn) |
if loc ~= "bags" and loc ~= "bank" then |
if loc == "auto" then |
if not AutoStack then |
AutoStack = true |
local tog = "|cff55FF55ON" |
else |
AutoStack = false |
local tog = "|cffFF5555OFF" |
end |
print("|cff44CCFFk|cffFFFFAARestack |cffFFFFFFAuto-stacking toggled", tog) |
else |
print("|cff44CCFFk|cffFFFFAARestack") |
print("- Usage: /restack [bags, bank]") |
print("- /restack auto (toggles auto-stacking. default: off)") |
end |
|
do return end |
end |
|
if type(restacker) ~= "thread" or coroutine.status(restacker) == "dead" then |
restacker = coroutine.create(function() |
local changed = true |
while changed == true do |
changed = RestackBags(loc) |
end |
|
for _, bag in pairs(container[loc]) do |
local _, bt = GetContainerNumFreeSlots(bag) |
if bt ~= 0 then |
for slot = 1, GetContainerNumSlots(bag) do |
while true do |
local locked = select( 3, GetContainerItemInfo(bag, slot)) |
|
if locked then |
coroutine.yield() |
else |
break |
end |
end |
|
local item = GetContainerItemLink(bag, slot) |
|
if not item then |
local locked, ok, sb, ss |
|
while true do |
ok, sb, ss = RestackFindSpecial(bt, loc) |
locked = ok and select(3, GetContainerItemInfo(sb, ss)) or false |
|
if locked then |
coroutine.yield() |
else |
break |
end |
end |
|
if ok then |
ClearCursor() |
PickupContainerItem(sb, ss) |
PickupContainerItem(bag, slot) |
ClearCursor() |
end |
end |
end |
end |
end |
frame:SetScript("OnUpdate", function() end) |
end) |
frame:SetScript("OnUpdate", function() |
if type(restacker) == "thread" then coroutine.resume(restacker) end |
end) |
else |
if not nowarn then |
print("|cff33A1DEk|cffFFFFFFRestack |cffFF5555Restacking is already in progress, please wait.") |
end |
end |
end |