Partially ready for prime time

Wobin [05-01-14 - 14:57]
Partially ready for prime time
Filename
Roomba.lua
Roomba.txt
bindings.xml
media/Roomba.dds
media/RoombaSearch.dds
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