Quantcast

Adds plugin files

Jon Crenshaw [02-14-16 - 05:12]
Adds plugin files
Filename
changelog.txt
kRestack.lua
kRestack.toc
diff --git a/changelog.txt b/changelog.txt
new file mode 100644
index 0000000..240ce01
--- /dev/null
+++ b/changelog.txt
@@ -0,0 +1,62 @@
+40000.1 -- 2010-10-13
+- 4.0 toc update.
+- "arg1" bug fix.
+
+1.1.1 -- 2009-12-08
+- 3.3 toc update.
+
+1.1 -- 2009-08-14
+- Fixed a bug with multiple "special" bags conflicting with each other.
+- Version bump.
+
+1.0.9 -- 2009-08-04
+- TOC updated to 3.2
+
+1.0.8 -- 2009-07-08
+- Some memory optimizations.
+- Extended bag hooking to cover all of the bag open/close events.
+
+1.0.7 -- 2009-06-16
+- Code optimizations.
+- In addition to restacking the player's bags, left-clicking the LDB plugin will now restack bank or guild vault when viewing them.
+
+1.0.6 -- 2009-06-11
+- Item looping now resets properly after finding and moving a matching partial stack. The entire process should now be much more stable and orderly.
+- Special bags with partial stacks and no free bag slots should now be correctly filled with partial stacks from other bags.
+- Set the LDB plugin to load when an addon with LDB embedded is loaded.
+- Changed LDB data object type to "launcher".
+
+1.0.5a -- 2009-06-06
+- LDB conditionals in place.
+- File structure and toc changes. Removed LDB libs that should be loaded anyway if there's a display.
+
+1.0.5 -- 2009-06-06
+- Fixed a bug in class/profession item sorting. A check wasn't in place to see if the item of the same type was a container, the result was bags in the inventory being equipped over the one already there.
+
+1.0.4 -- 2009-06-02
+- Throttled "OnUpdate" yield script.
+- Minor backpack hook change.
+- SavedVariables now account wide; settings still per-character.
+
+1.0.3 -- 2009-05-23
+- Removed auto-stacking from the TRADE_SHOW event.
+
+1.0.2a -- 2009-05-22
+- Added missing label text for LDB plugin.
+
+1.0.2 -- 2009-05-22
+- Added support for Data Broker. Left-click stacks bags, right-click opens menu.
+
+1.0.1 -- 2009-05-19
+- Fixed the handling of initializing saved variables when updating from 0.9
+- Fixed a bug that disabled guild tab switching when guild bank auto-stacking is turned off.
+
+1.0 -- 2009-05-18
+- Added support for restacking guild vault tabs.
+- Hooked bag auto-stack to LOOT_OPEN and TRADE_SHOW, and guild bank auto-stack to GUILDBANKFRAME_OPENED and SetCurrentGuildBankTab(i).
+- Extended auto-stack toggle to enable or disable bags, bank, or guild bank individually.
+- Will now move items that can go into special class/profession bags into those bags if possible (soul shards, herbs, arrows, etc).
+- Cleaned up and commented code.
+
+0.9 -- 2009-05-13
+- Added option to auto-stack when opening bags or bank, off by default. Toggle with '/restack auto'
\ No newline at end of file
diff --git a/kRestack.lua b/kRestack.lua
new file mode 100644
index 0000000..6d90288
--- /dev/null
+++ b/kRestack.lua
@@ -0,0 +1,264 @@
+--[[	kRestack 1.1 : Katae @ Anvilmar US
+
+		Usage:	/restack [bags, bank, guild] - manual run
+				/restack auto [bags, bank, guild] - toggles auto mode ]]
+
+local AS, atBank, atVault, isViewable, canDeposit, restacker, tabswap
+
+SLASH_RESTACK1 = "/restack"
+function SlashCmdList.RESTACK(s) kRestack(s) end
+
+-- pretty chat colors!
+local white, green, red = "|cffffffff", "|cff55ff55", "|cffff5555"
+local kR = "|cff44ccffk|cffffffaaRestack"..white
+
+-- set user's container identifers
+local container = { bags = { 0 }, bank = { -1 }, guild = { 42 } }
+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
+
+-- ldb plugin
+local function ldb()
+	local drop = CreateFrame("Frame", "kRestack", nil, "UIDropDownMenuTemplate")
+	LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject("kRestack", {
+	    type = "launcher",
+		label = "kRestack",
+	    icon = "Interface\\Icons\\INV_Crate_09",
+	    OnClick = function(self, button)
+	        if button == "RightButton" then
+				GameTooltip:Hide()
+				UIDropDownMenu_Initialize(drop, function() for _, opt in ipairs{
+					{ text = "= Restack =", isTitle = true },
+					{ text = "Backpack", func = function() kRestack("bags") end },
+					{ text = "Bank", disabled = not atBank, func = function() kRestack("bank") end },
+					{ text = "Guild Vault", disabled = not atVault, func = function() kRestack("guild", false, GetCurrentGuildBankTab()) end },
+					{ disabled = true },
+					{ text = "= Set Auto =", isTitle = true },
+					{ text = "Backpack", checked = AS.bags, func = function() kRestack("auto bags") end },
+					{ text = "Bank", checked = AS.bank, func = function() kRestack("auto bank") end },
+					{ text = "Guild Vault", checked = AS.guild, func = function() kRestack("auto guild") end },
+				} do UIDropDownMenu_AddButton(opt, 1) end end, "MENU")
+				return ToggleDropDownMenu(1, nil, drop, self, 0, 0)
+			elseif button == "LeftButton" then
+				kRestack(atBank and "bank" or atVault and "guild" or "bags")
+			end
+	    end,
+	})
+end
+
+-- watching some events
+local f = CreateFrame("Frame")
+f:RegisterEvent'ADDON_LOADED'
+f:RegisterEvent'BANKFRAME_OPENED'
+f:RegisterEvent'BANKFRAME_CLOSED'
+f:RegisterEvent'LOOT_OPENED'
+f:RegisterEvent'GUILDBANKFRAME_OPENED'
+f:RegisterEvent'GUILDBANKFRAME_CLOSED'
+f:SetScript("OnEvent", function(_, e, addon)
+	-- more ldb stuff
+	if e == "BANKFRAME_OPENED" then
+		atBank = true
+	elseif e == "BANKFRAME_CLOSED" then
+		atBank = false
+	elseif e == "GUILDBANKFRAME_OPENED" then
+		isViewable, canDeposit = select(3,GetGuildBankTabInfo(GetCurrentGuildBankTab()))
+		atVault = (IsGuildLeader() or (isViewable and canDeposit))
+	elseif e == "GUILDBANKFRAME_CLOSED" then
+		atVault = false
+	end
+	if e == "ADDON_LOADED" then
+		-- initialize SavedVariables
+		if addon == "kRestack" then
+			if type(AutoStack) ~= "table" then AutoStack = {} end
+			local c = UnitName("player").." - "..GetRealmName()
+			if type(AutoStack[c]) ~= "table" then AutoStack[c] = {} end
+			AS = AutoStack[c]
+			if AS.bags == nil then AS.bags = true end
+			if AS.bank == nil then AS.bank = true end
+			if AS.guild == nil then AS.guild = false end
+		-- loading ldb plugin
+		elseif LibStub and ldb then
+			if LibStub:GetLibrary("LibDataBroker-1.1", true) then ldb(); ldb = nil end
+		end
+	elseif AS.bank and e == "BANKFRAME_OPENED" then
+		kRestack("bank", true)
+	elseif AS.bags and e == "LOOT_OPENED" then
+		kRestack("bags", true)
+	elseif AS.guild and e == "GUILDBANKFRAME_OPENED" then
+		isViewable, canDeposit = select(3,GetGuildBankTabInfo(GetCurrentGuildBankTab()))
+		if (IsGuildLeader() or (isViewable and canDeposit)) then kRestack("guild", true, GetCurrentGuildBankTab()) end
+	end
+end)
+
+-- hooking auto-stacking
+for _, func in ipairs{"CloseAllBags","ToggleBackpack","ToggleBag","OpenBackpack","OpenAllBags","OpenBackpack","CloseBackpack"} do
+	hooksecurefunc(func, function() if AS.bags then kRestack("bags", true) end end)
+end
+
+local oSetCurrentGuildBankTab = SetCurrentGuildBankTab
+SetCurrentGuildBankTab = function(tab)
+	if type(restacker) == "thread" then
+		tabswap = tabswap + 1
+		if tabswap > 1 then restacker = nil end
+	end
+	-- going to lock tab switching while stacking is in progress
+	if type(restacker) ~= "thread" or coroutine.status(restacker) == "dead" then
+		oSetCurrentGuildBankTab(tab)
+		isViewable, canDeposit = select(3,GetGuildBankTabInfo(tab))
+		if AS.guild and (IsGuildLeader() or (isViewable and canDeposit)) then kRestack("guild", false, tab) end
+	end
+end
+
+-- yielding function; items will get locked and we have to wait
+local function coYield(loc, bag, slot, count)
+	local elapsed = 0
+	f:SetScript("OnUpdate", function(_, update)
+		elapsed = elapsed + update
+		if type(restacker) == "thread" and coroutine.status(restacker) == "suspended" and elapsed > 0.1 then
+			local locked = true
+			locked = loc == "guild" and (select(2, GetGuildBankItemInfo(bag, slot)) == count and true or false) or select(3, GetContainerItemInfo(bag, slot))
+			if not locked then coroutine.resume(restacker) end
+			elapsed = 0
+		end
+	end)
+	coroutine.yield()
+end
+
+-- main function
+function kRestack(loc, silent, tab)
+	if loc ~= "bags" and loc ~= "bank" and loc ~= "guild" then
+		if loc == "resume" then
+			-- manual resume if stuck
+			if coroutine.status(restacker) == "suspended" then
+				print(kR, "Resuming suspended thread.")
+				coroutine.resume(restacker)
+			else
+				print(kR, "No suspended threads to resume.")
+			end
+		else
+			loc = loc:match("auto (%a+)")
+			if loc == "bags" or loc == "bank" or loc == "guild" then
+				-- toggle auto-stack
+				AS[loc] = not AS[loc]
+				print(kR, "Auto-stacking for", loc:gsub("bags","your backpack"):gsub("bank","your bank"):gsub("guild","the guild vault"), "toggled", AS[loc] and green.."ON" or red.."OFF")
+			else
+				-- usage message
+				local bags = (AS.bags and green or red).."bags"..white
+				local bank = (AS.bank and green or red).."bank"..white
+				local guild = (AS.guild and green or red).."guild"..white
+
+				print(kR, "Usage:")
+				print(white.."-    /restack [bags, bank, guild] - Run restacker manually")
+				print(white.."-    /restack auto ["..bags..",", bank..",", guild.."] - Toggle auto-stacking")
+			end
+		end
+		return
+	end
+
+	if type(restacker) ~= "thread" or coroutine.status(restacker) == "dead" then
+		restacker = coroutine.create(function()
+			tabswap = 0
+			local changed = true
+			while changed do
+				changed = false
+				local vault = loc == "guild"
+				for _, bag in ipairs(container[loc]) do
+					if changed then break end
+					bag = vault and tab or bag
+					for slot = 1, (vault and MAX_GUILDBANK_SLOTS_PER_TAB or GetContainerNumSlots(bag)) do
+						while true and not vault do
+							local locked = select(3, GetContainerItemInfo(bag, slot))
+							if locked then coYield(loc, bag, slot) else break end
+						end
+						local item = vault and GetGuildBankItemLink(bag, slot) or GetContainerItemLink(bag, slot)
+						if item then
+							local itemid = tonumber(item:match("item:(%d+)"))
+							local stack = select(8, GetItemInfo(itemid))
+							local count = vault and select(2, GetGuildBankItemInfo(bag, slot)) or select(2, GetContainerItemInfo(bag, slot))
+
+							-- do "special" things with "special" items by moving them into "special" bags
+							if not vault and select(9, GetItemInfo(itemid)) ~= "INVTYPE_BAG" then
+								local bagType = (bag ~= 0 and bag ~= -1) and GetItemFamily(GetInventoryItemLink("player", ContainerIDToInventoryID(bag))) or 0
+								for _, sbag in ipairs(container[loc]) do
+									if sbag > 0 and GetContainerNumFreeSlots(sbag) > 0 then
+										local sbagID = ContainerIDToInventoryID(sbag)
+										local sbagType = GetItemFamily(GetInventoryItemLink("player", sbagID))
+										local itemType = GetItemFamily(item)
+
+										if sbagType > 0 and sbagType == itemType and bagType == 0 then
+											PickupContainerItem(bag, slot)
+											PutItemInBag(sbagID)
+											coYield(loc, bag, slot)
+											break
+										end
+									end
+								end
+							end
+							if count < stack then
+								-- found a partial stack
+								local locked, found, done, pbag, pslot
+								while true do
+									-- search through bags backwards for another partial stack with a matching itemid
+									for i = #container[loc], 1, -1 do
+										local _bag = container[loc][i]
+										if found or done then break end
+										local _slots = vault and MAX_GUILDBANK_SLOTS_PER_TAB or GetContainerNumSlots(_bag)
+										for _slot = _slots, 1, -1 do
+											if vault then _bag = bag end
+											if not (_bag == bag and _slot == slot) then
+												local _item = vault and GetGuildBankItemLink(_bag, _slot) or GetContainerItemLink(_bag, _slot)
+												if _item then
+													local _itemid = tonumber(_item:match("item:(%d+):"))
+													if _itemid == itemid then
+														local _stack = select(8, GetItemInfo(_itemid))
+														local _count = vault and select(2, GetGuildBankItemInfo(_bag, _slot)) or select(2, GetContainerItemInfo(_bag, _slot))
+														if _count < _stack then found, pbag, pslot = true, _bag, _slot; break end
+													end
+												end
+											else done = true; break end
+										end
+									end
+									if vault then break end
+									locked = found and select(3, GetContainerItemInfo(pbag, pslot)) or false
+									if locked then coYield(loc, pbag, pslot) else break end
+								end
+
+								if found then
+									ClearCursor()
+									if vault then
+										PickupGuildBankItem(pbag, pslot)
+										PickupGuildBankItem(bag, slot)
+										ClearCursor()
+										coYield(loc, bag, slot, count)
+									else
+										-- if second partial stack is inside a special bag, move the original stack into it
+										local bagType = (bag ~= 0 and bag ~= -1) and GetItemFamily(GetInventoryItemLink("player", ContainerIDToInventoryID(bag))) or 0
+										local pbagType = (pbag ~= 0 and pbag ~= -1) and GetItemFamily(GetInventoryItemLink("player", ContainerIDToInventoryID(pbag))) or 0
+										if pbagType > 0 and bagType == 0 then
+											PickupContainerItem(bag, slot)
+											PickupContainerItem(pbag, pslot)
+										else
+											PickupContainerItem(pbag, pslot)
+										 	PickupContainerItem(bag, slot)
+										end
+										ClearCursor()
+									end
+									changed = true
+									break
+								end
+							end
+						end
+					end
+				end
+			end
+			-- turn off yielding function
+			f:SetScript("OnUpdate", nil)
+		end)
+		coroutine.resume(restacker)
+	else
+		if not silent then
+			-- user is impatient or there is a stall, tell them so
+			print(kR..red, "Restacking in progress. (use '/restack resume' if stuck)")
+		end
+	end
+end
\ No newline at end of file
diff --git a/kRestack.toc b/kRestack.toc
new file mode 100644
index 0000000..c2efec2
--- /dev/null
+++ b/kRestack.toc
@@ -0,0 +1,7 @@
+## Interface: 40000
+## Title: |cff44ccffk|rRestack
+## Version: 40000.1
+## Author: Katae of Anvilmar
+## Notes: For all of your item stacking needs.
+## SavedVariables: AutoStack
+kRestack.lua
\ No newline at end of file