Mercurial > wow > inventory
view Scanner.lua @ 80:c0bf2ddb5288
Added initial item refilling from the bank/guild. Not yet fully functional.
author | Zerotorescue |
---|---|
date | Wed, 05 Jan 2011 13:05:15 +0100 |
parents | |
children | 58617c7827fa |
line wrap: on
line source
local addon = select(2, ...); local mod = addon:NewModule("Scanner", "AceEvent-3.0"); addon.Locations = { Bag = 0, Bank = 1, Guild = 2, }; local Mover, paused; local itemCache = {}; local function _GetItemCount(itemId, location) if location == addon.Locations.Bank then -- No longer using GetItemCount as this includes equiped items and containers (e.g. bank bags) --return (GetItemCount(itemId, true) - GetItemCount(itemId, false)); -- GetItemCount(X, true) provides count for bag+bank, GetItemCount(X, false) provides just bag, so (GetItemCount(X, true) - GetItemCount(X, false)) = just bank return ((itemCache[itemId] and itemCache[itemId].totalCount) or 0); elseif location == addon.Locations.Guild then return ((itemCache[itemId] and itemCache[itemId].totalCount) or 0); else error("Invalid location provided for the local _GetItemCount. Must be Bag or Bank."); end end local function GetItemID(link) return tonumber(link:match("|Hitem:([-0-9]+):")); end function mod:ClearCache() table.wipe(itemCache); end function mod:CacheLocation(location, remember) if location == addon.Locations.Bag or location == addon.Locations.Bank then -- Reset cache just in case it was filled self:ClearCache(); local start, stop; if location == addon.Locations.Bag then start = 0; stop = NUM_BAG_SLOTS; else -- If we requested the bank then we don't want the bag info start = ( NUM_BAG_SLOTS + 1 ); stop = ( NUM_BAG_SLOTS + NUM_BANKBAGSLOTS ); end -- Go through all our bags, including the backpack for i = start, ((addon.Locations.Bag and stop) or (addon.Locations.Bank and (stop + 1))) do -- if scanning bags stop at normal bag slot, if scanning bank, stop one later to allow BANK_CONTAINER to be scanned too -- Scan the default 100 slots whenever we're at a non-existing index local bagId = (i == (stop + 1) and BANK_CONTAINER) or i; local slotId = GetContainerNumSlots(bagId); while slotId ~= 0 do -- A not equal-comparison should be quicker than a larger than-comparison local itemId = GetContainerItemID(bagId, slotId); local itemCount = itemId and select(2, GetContainerItemInfo(bagId, slotId)); if itemId and itemCount and itemCount > 0 then local itemMove; if not itemCache[itemId] then -- If this is the first time we see this item, make a new object itemMove = addon.ItemMove:New(); else -- If we had this item in another slot too itemMove = itemCache[itemId]; end itemMove.AddLocation(bagId, slotId, itemCount); end -- Continue scanning a different slot slotId = (slotId - 1); end end elseif location == addon.Locations.Guild then -- Reset cache before we scan self:ClearCache(); local tabId = GetCurrentGuildBankTab(); local slotId = (MAX_GUILDBANK_SLOTS_PER_TAB or 98); -- start by scanning the last slot if tabId == nil or tabId < 1 then return; end while slotId ~= 0 do -- A not equal-comparison should be quicker than a larger than-comparison -- If there is actually an item in this slot local itemLink = GetGuildBankItemLink(tabId, slotId); local itemId = itemLink and GetItemId(itemLink); local itemCount = itemLink and select(2, GetGuildBankItemInfo(tabId, slotId)); if itemLink and itemId and itemCount and itemCount > 0 then local itemMove; if not itemCache[itemId] then -- If this is the first time we see this item, make a new object itemMove = addon.ItemMove:New(); else -- If we had this item in another slot too itemMove = itemCache[itemId]; end itemMove.AddLocation(tabId, slotId, itemCount); end -- Continue scanning a different slot slotId = (slotId - 1); end else error("Invalid location provided for the local _GetItemCount. Must be Bank or Guild."); end if not remember then -- Copy the table as clearing the cache wipes it empty (and tables are passed by reference) local cacheCopy = CopyTable(itemCache); self:ClearCache(); return cacheCopy; end end function mod:Scan(location) -- We might pause the scanning when we invoke moves ourself if paused then return; end local playerName = UnitName("player"); self:CacheLocation(location, true); -- Go through all groups for groupName, values in pairs(addon.db.profile.groups) do local trackAt = addon:GetOptionByKey(groupName, "trackAtCharacters"); if values.items and trackAt[playerName] then -- Is this character interested in this data? local minLocalStock = addon:GetOptionByKey(groupName, "minLocalStock"); -- Go through all items for itemId, _ in pairs(values.items) do -- Check if we have enough items local local missingItems = (minLocalStock - addon:GetLocalItemCount(itemId, groupName)); if missingItems > 0 then -- Check how many are available local availableItems = _GetItemCount(itemId, location); if availableItems > 0 then print("Insufficient " .. select(2, GetItemInfo(itemId)) .. " but this location has " .. availableItems .. " (moving " .. missingItems .. ")"); Mover:AddMove(itemId, missingItems); else print("Insufficient " .. select(2, GetItemInfo(itemId))); end end end end end self:ClearCache(); self:Pause(); Mover:BeginMove(location, self.Unpause); end local function BANKFRAME_OPENED() -- Scan once when the bank is opened, but no need to scan after mod:Scan(addon.Locations.Bank); addon:Debug("Scanner:BANKFRAME_OPENED"); end -- Remember which tabs were scanned and don't scan them again local guildBankTabsScanned = {}; local function GUILDBANKFRAME_CLOSED() mod:UnregisterEvent("GUILDBANKFRAME_CLOSED"); mod:UnregisterEvent("GUILDBANKBAGSLOTS_CHANGED"); table.wipe(guildBankTabsScanned); addon:Debug("Scanner:GUILDBANKFRAME_CLOSED"); end local function GUILDBANKBAGSLOTS_CHANGED() if not guildBankTabsScanned[GetCurrentGuildBankTab()] then mod:Scan(addon.Locations.Guild); guildBankTabsScanned[GetCurrentGuildBankTab()] = true; addon:Debug("Scanner:GUILDBANKBAGSLOTS_CHANGED (" .. GetCurrentGuildBankTab() .. ") - scanning"); else addon:Debug("Scanner:GUILDBANKBAGSLOTS_CHANGED (" .. GetCurrentGuildBankTab() .. ") - not scanning"); end end local function GUILDBANKFRAME_OPENED() table.wipe(guildBankTabsScanned); mod:RegisterEvent("GUILDBANKFRAME_CLOSED", GUILDBANKFRAME_CLOSED); mod:RegisterEvent("GUILDBANKBAGSLOTS_CHANGED", GUILDBANKBAGSLOTS_CHANGED); addon:Debug("Scanner:GUILDBANKFRAME_OPENED"); end function mod:OnEnable() -- Scan once when the bankframe is opened mod:RegisterEvent("BANKFRAME_OPENED", BANKFRAME_OPENED); mod:RegisterEvent("GUILDBANKFRAME_OPENED", GUILDBANKFRAME_OPENED); Mover = addon:GetModule("Mover"); end function mod:OnDisable() Mover = nil; -- Bank mod:UnregisterEvent("BANKFRAME_OPENED"); -- Guild GUILDBANKFRAME_CLOSED(); mod:UnregisterEvent("GUILDBANKFRAME_OPENED"); end function mod:Pause() paused = true; end function mod:Unpause() paused = nil; end