diff --git a/Roomba.lua b/Roomba.lua index ed6c46c..ce5a067 100644 --- a/Roomba.lua +++ b/Roomba.lua @@ -6,12 +6,12 @@ Roomba = {} -LibStub("AceTimer-3.0"):Embed(Roomba) local LAM = LibStub:GetLibrary("LibAddonMenu-1.0") local BACKPACK = ZO_PlayerInventoryBackpack.data local GUILDBANK = ZO_GuildBankBackpack.data local DELAY = 150 + local containerHooks = { INVENTORY_BACKPACK, INVENTORY_BANK, INVENTORY_GUILD_BANK } Roomba.currentInventory = {} @@ -21,6 +21,12 @@ local function GetItemID(link) return tonumber(string.match(string.match(link, "%d+:"), "%d+")) end +function Roomba.dmsg(msg) + if Roomba.Debugging then d(msg) end +end + +local dmsg = Roomba.dmsg + function GetInstanceId(target, slotId) for i,v in ipairs(target) do if v.data.slotIndex == slotId then return v.data.itemInstanceId end @@ -71,6 +77,13 @@ local function AuditCurrentInventory() end end + +local function HaveStuffToStack() + local bank = Roomba.guildInfo[GetSelectedGuildBankId()] + if type(bank) == "table" and next(bank.duplicates) then return true end + return false +end + local checkingBank = false local currentBank = 1 @@ -78,10 +91,10 @@ local currentBank = 1 function Roomba.RoombaReady() if not checkingBank then checkingBank = true else return end local bank = Roomba.guildInfo[GetSelectedGuildBankId()] - if not bank then return end + if not bank then return end Roomba.guildInfo[GetSelectedGuildBankId()] = ClearGuildDetails(GetSelectedGuildBankId()) bank = Roomba.guildInfo[GetSelectedGuildBankId()] - d("Bank is ready: " ..#GUILDBANK) + dmsg("Bank is ready: " .. #GUILDBANK) -- We only need to store A) slots with items for index, slot in ipairs(GUILDBANK) do if slot.data.equipType == 0 then -- Equipped gear cannot be stacked @@ -101,7 +114,10 @@ function Roomba.RoombaReady() end end end - d("Number of duplicates: " .. #bank.duplicates) + zo_callLater(function() checkingBank = nil end, 3000) + if KEYBIND_STRIP:HasKeybindButtonGroup(Roomba.runDescriptor) then + KEYBIND_STRIP:UpdateKeybindButtonGroup(Roomba.runDescriptor) + end end --[[ @@ -132,7 +148,7 @@ end function Roomba.SelectGuildBank(...) local eventId, guildBankId = ... currentBank = guildBankId - checkingBank = nil + checkingBank = nil end transitBag = {} @@ -142,15 +158,15 @@ function Roomba.ReturnItemsToBank(...) local error = ... local slot -- Now that we've stacked it all lets move it back - d("Getting next to move back to bank") + dmsg("Getting next to move back to bank") currentReturnIndex, slot = next(inBagCollection) if slot then if error then - d("trying again") + dmsg("trying again") return zo_callLater(Roomba.ReturnItemsToBank, 2000) end if FindSlot(BACKPACK, slot.bagSlot) then - d("Moving stuff back from ".. slot.bagSlot) + dmsg("Moving stuff back from ".. slot.bagSlot) return TransferToGuildBank(INVENTORY_BACKPACK, slot.bagSlot) else -- we have a space, move to next @@ -159,11 +175,11 @@ function Roomba.ReturnItemsToBank(...) end else -- No more to move, we're complete - d("unregistering") + dmsg("unregistering") EVENT_MANAGER:UnregisterForEvent("RoombaGuildBankError", EVENT_GUILD_BANK_TRANSFER_ERROR) EVENT_MANAGER:UnregisterForEvent("RoombaGuildBankSuccess", EVENT_GUILD_BANK_ITEM_ADDED) -- Kick off the next transaction - d("Finished processing item") + dmsg("Finished processing item") ResetAll() return zo_callLater(Roomba.BeginProcess, DELAY) end @@ -173,23 +189,23 @@ function Roomba.BankItemsReceived(...) local _, gslot = ... local id = GetInstanceId(GUILDBANK, gslot) if id ~= cInstanceId then return end - d("Moved successfully to slot " ..gslot) + dmsg("Moved successfully to slot " ..gslot) -- We've moved one back! Remove it from contention local slot = table.remove(inBagCollection, currentReturnIndex) currentReturnIndex = nil - d("Clearing slot " .. slot.bagSlot) + dmsg("Clearing slot " .. slot.bagSlot) return zo_callLater(Roomba.ReturnItemsToBank, DELAY) end function Roomba.StartStacking() - d("Found an item to stack") + dmsg("Found an item to stack") baseSlot = nil EVENT_MANAGER:UnregisterForEvent("RoombaInventoryAdded", EVENT_INVENTORY_SINGLE_SLOT_UPDATE) for _,slot in pairs(inBagCollection) do if not baseSlot then -- We want to stack everything on this - d("Setting ".. slot.bagSlot .." as base slot") + dmsg("Setting ".. slot.bagSlot .." as base slot") baseSlot = slot else baseSlot.count, baseSlot.stack = GetSlotStackSize(INVENTORY_BACKPACK, slot.bagSlot) @@ -206,7 +222,7 @@ function Roomba.StartStacking() if (result) then result = CallSecureProtected("PlaceInInventory", INVENTORY_BACKPACK, baseSlot.bagSlot) end end ClearCursor() - d("Stacked item in backpack") + dmsg("Stacked item in backpack") end end baseSlot = nil @@ -222,11 +238,14 @@ function Roomba.ReceiveItems(...) if baseSlot then return end -- We're still stacking local _, bagId, slotId = ... if bagId ~= INVENTORY_BACKPACK then return end - if not cInstanceId then return end + if not cInstanceId then return end + if IsItemJunk(INVENTORY_BACKPACK, slotId) then + SetItemIsJunk(INVENTORY_BACKPACK, slotId, false) + return zo_callLater(function(...) Roomba.ReceiveItems(...) end, 1000) + end if not GetInstanceId(BACKPACK, slotId) then return end -- are we empty if GetInstanceId(BACKPACK, slotId) ~= cInstanceId then return end - d("Checking " .. bagId .. " inventory slot " .. slotId .. " to match ".. cInstanceId .. " with " .. (GetInstanceId(BACKPACK, slotId) or "nothing")) - SetItemIsJunk(INVENTORY_BACKPACK, slotId, false) + dmsg("Checking " .. bagId .. " inventory slot " .. slotId .. " to match ".. cInstanceId .. " with " .. (GetInstanceId(BACKPACK, slotId) or "nothing")) cSlot.bagSlot = slotId table.insert(inBagCollection, cSlot) -- If we have another slot to move @@ -253,17 +272,26 @@ function Roomba.BeginProcess() -- Clear this batch inBagCollection = {} -- And start off the job - d("Stacking up ".. zo_strformat(SI_TOOLTIP_ITEM_NAME, GetItemLink(3, cSlot.slot, LINK_STYLE_DEFAULT))) - EVENT_MANAGER:RegisterForEvent("RoombaInventoryAdded", EVENT_INVENTORY_SINGLE_SLOT_UPDATE, Roomba.ReceiveItems) - SetItemIsJunk(3, cSlot.slot, false) -- unjunk everything + dmsg("Stacking up ".. zo_strformat(SI_TOOLTIP_ITEM_NAME, GetItemLink(3, cSlot.slot, LINK_STYLE_DEFAULT))) + + -- If it suddenly doesn't exist, try the next in the list + if not FindSlot(GUILDBANK, cSlot.slot) then return zo_callLater(Roomba.BeginProcess, DELAY) end + + EVENT_MANAGER:RegisterForEvent("RoombaInventoryAdded", EVENT_INVENTORY_SINGLE_SLOT_UPDATE, Roomba.ReceiveItems) TransferFromGuildBank(cSlot.slot) else - d("Nothing to restack") + dmsg("Nothing to restack") + -- Now rescan and show/hide roomba button + Roomba.RoombaReady() return false end return true end +local function IsUsePossible(name) + return true +end + local function RoombaLoaded(eventCode, addOnName) if(addOnName ~= "Roomba") then @@ -274,7 +302,30 @@ local function RoombaLoaded(eventCode, addOnName) } GetGuildDetails() - SLASH_COMMANDS["/roomba"] = Roomba.BeginProcess + + SLASH_COMMANDS["/roombadebug"] = function() Roomba.Debugging = not Roomba.Debugging d("Turning debug ".. (Roomba.Debugging and "on" or "off")) end + + ZO_CreateStringId("SI_BINDING_NAME_RUN_ROOMBA", "Run Roomba") + ZO_CreateStringId("SI_BINDING_NAME_RESCAN_ROOMBA", "Rescan Bank") + + Roomba.runDescriptor = { + alignment = KEYBIND_STRIP_ALIGN_LEFT, + { + name = "Run Roomba", -- or function that returns a name + keybind = "RUN_ROOMBA", + callback = function(descriptor) Roomba.BeginProcess() end, -- First and only argument is this descriptor table + visible = function(descriptor) return HaveStuffToStack() end, -- An optional predicate, if present returning true indicates that this descriptor is visible, otherwise it is not + icon = [[Roomba\media\Roomba.dds]], -- or a function that returns an icon path, an optional icon to display to the right of the name + }, + { + name = "Scan Bank", -- or function that returns a name + keybind = "RESCAN_ROOMBA", + callback = function(descriptor) Roomba.RoombaReady() end, -- First and only argument is this descriptor table + visible = function(descriptor) return ZO_GuildBankBackpackLoading:IsHidden() end, -- An optional predicate, if present returning true indicates that this descriptor is visible, otherwise it is not + icon = [[Roomba\media\RoombaSearch.dds]], -- or a function that returns an icon path, an optional icon to display to the right of the name + }, + + } settings = ZO_SavedVars:New("Roomba_Settings", 3, nil, defaults) @@ -282,6 +333,14 @@ local function RoombaLoaded(eventCode, addOnName) EVENT_MANAGER:RegisterForEvent("RoombaReady", EVENT_GUILD_BANK_ITEMS_READY, function() zo_callLater(Roomba.RoombaReady, 1000) end) -- Clear the flag when swapping banks EVENT_MANAGER:RegisterForEvent("RoombaSelected", EVENT_GUILD_BANK_SELECTED, Roomba.SelectGuildBank) + EVENT_MANAGER:RegisterForEvent("RoombaGuildBankOpen", EVENT_OPEN_GUILD_BANK, function() + if not KEYBIND_STRIP:HasKeybindButtonGroup(Roomba.runDescriptor) then + KEYBIND_STRIP:AddKeybindButtonGroup(Roomba.runDescriptor) + end end) + EVENT_MANAGER:RegisterForEvent("RoombaGuildBankOpen", EVENT_CLOSE_GUILD_BANK, function() + if KEYBIND_STRIP:HasKeybindButtonGroup(Roomba.runDescriptor) then + KEYBIND_STRIP:RemoveKeybindButtonGroup(Roomba.runDescriptor) + end end) end EVENT_MANAGER:RegisterForEvent("RoombaLoaded", EVENT_ADD_ON_LOADED, RoombaLoaded) \ No newline at end of file diff --git a/Roomba.txt b/Roomba.txt index edb6c3e..9cda37e 100644 --- a/Roomba.txt +++ b/Roomba.txt @@ -8,4 +8,5 @@ libs/LibStub/LibStub.lua libs/AceTimer-3.0/AceTimer-3.0.lua libs\LibAddonMenu-1.0\LibAddonMenu-1.0.lua -Roomba.lua \ No newline at end of file +Roomba.lua +bindings.xml \ No newline at end of file diff --git a/bindings.xml b/bindings.xml new file mode 100644 index 0000000..ce3d2f6 --- /dev/null +++ b/bindings.xml @@ -0,0 +1,12 @@ +<Bindings> + <Layer name="General"> + <Category name="Roomba"> + <Action name="RUN_ROOMBA"> + <Down>Roomba.BeginProcess()</Down> + </Action> + <Action name="RESCAN_ROOMBA"> + <Down>Roomba.RoombaReady()</Down> + </Action> + </Category> + </Layer> +</Bindings> \ No newline at end of file diff --git a/media/Roomba.dds b/media/Roomba.dds new file mode 100644 index 0000000..140383f Binary files /dev/null and b/media/Roomba.dds differ diff --git a/media/RoombaSearch.dds b/media/RoombaSearch.dds new file mode 100644 index 0000000..bb0989a Binary files /dev/null and b/media/RoombaSearch.dds differ