Mercurial > wow > inventory
view Modules/Scanner.lua @ 101:6ae44d372360
The confirmation window when refilling from the (guild) bank is enabled can now be skipped at the general config. It defaults to false.
Added a window displaying a list of movable items when at least one is available at the (guild) bank.
Resetting the queue when closing the storage.
author | Zerotorescue |
---|---|
date | Tue, 11 Jan 2011 19:48:35 +0100 |
parents | 252292b703ce |
children | d3fbb5676a5e |
line wrap: on
line source
local addon = select(2, ...); local mod = addon:NewModule("Scanner", "AceEvent-3.0", "AceTimer-3.0"); addon.Locations = { Bag = 0, Bank = 1, Guild = 2, }; local Mover, paused, currentLocation; local itemCache = {}; local function OnMoveAccept(this) mod:Pause(); Mover:BeginMove(currentLocation, mod.Unpause); InventoriumItemMover:Hide(); end local function OnMoveCancel(this) Mover:ResetQueue(); currentLocation = nil; InventoriumItemMover:Hide(); end function mod:ClearCache() table.wipe(itemCache); end function mod:CacheLocation(location, remember) -- Reset cache just in case it was filled self:ClearCache(); if location == addon.Locations.Bag or location == addon.Locations.Bank then 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, ((location == addon.Locations.Bag and stop) or (location == 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.ContainerItem:New(); itemCache[itemId] = itemMove; 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 for tabId = 1, GetNumGuildBankTabs() do local isViewable = select(3, GetGuildBankTabInfo(tabId)); if isViewable == 1 then local slotId = (MAX_GUILDBANK_SLOTS_PER_TAB or 98); -- start by scanning the last slot while slotId ~= 0 do -- A not equal-comparison should be quicker than a larger than-comparison local itemLink = GetGuildBankItemLink(tabId, slotId); local itemId = itemLink and addon:GetItemId(itemLink); local itemCount = itemLink and select(2, GetGuildBankItemInfo(tabId, slotId)); if itemLink and itemId and itemCount and itemCount > 0 then -- If there is actually an item in this slot local itemMove; if not itemCache[itemId] then -- If this is the first time we see this item, make a new object itemMove = addon.ContainerItem:New(); itemCache[itemId] = itemMove; 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 end end else error("Invalid location provided for CacheLocation. 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"); currentLocation = location; self:CacheLocation(location, true); -- Go through all groups for groupName, values in pairs(addon.db.profile.groups) do local trackAt = addon:GetOptionByKey(groupName, "trackAtCharacters"); local localItemData = addon:GetOptionByKey(groupName, "localItemData"); if values.items and trackAt[playerName] and addon:GetOptionByKey(groupName, "autoRefill") and (location ~= addon.Locations.Bank or not localItemData or not localItemData["Bank"]) 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 (but only do so if this location also has enough available) local missingItems = itemCache[itemId] and (minLocalStock - addon:GetLocalItemCount(itemId, groupName)); if itemCache[itemId] and missingItems > 0 then -- Check how many are available local availableItems = ((itemCache[itemId] and itemCache[itemId].totalCount) or 0); -- Calculate how many we'll be moving (less missing than available? use missing, otherwise use available) local moving = (((missingItems <= availableItems) and missingItems) or availableItems); if availableItems > 0 then --addon:Print("Insufficient " .. IdToItemLink(itemId) .. " but this location has " .. availableItems .. " (moving " .. moving .. ")"); Mover:AddMove(itemId, moving, missingItems, availableItems); else --addon:Print("Insufficient " .. IdToItemLink(itemId)); end end end end end self:ClearCache(); if Mover:HasMoves() then if addon.db.profile.defaults.autoRefillSkipConfirm then OnMoveAccept(true); else local data = {}; local columns = { { value = function(d, cols, realrow, column, table) return IdToItemLink(d[realrow].colorargs[2]); end, }, -- item { value = function(d, cols, realrow, column, table) local queue = Mover:GetMoves(); return queue[d[realrow].colorargs[1]].num; end, }, -- moving { value = function(d, cols, realrow, column, table) local queue = Mover:GetMoves(); return queue[d[realrow].colorargs[1]].missing; end, }, -- missing { value = function(d, cols, realrow, column, table) local queue = Mover:GetMoves(); return queue[d[realrow].colorargs[1]].available; end, color = function(d, cols, realrow, column, table) local queue = Mover:GetMoves(); return ((queue[d[realrow].colorargs[1]].available < queue[d[realrow].colorargs[1]].missing) and { r = 1, g = 0, b = 0, a = 1 }) or { r = 1, g = 1, b = 1, a = 1 }; end, }, -- available }; local queue = Mover:GetMoves(); for i, move in pairs(Mover:GetMoves()) do local row = { ["colorargs"] = { i, queue[i].id }, ["cols"] = columns, }; table.insert(data, row); end addon:SetMoverFrameData(data); --[[ StaticPopupDialogs["InventoriumRefill"] = { text = "There are items that can be refilled from this location, do you wish to proceed?", button1 = YES, button2 = NO, OnAccept = function() mod:Pause(); Mover:BeginMove(location, self.Unpause); end, timeout = 0, whileDead = 1, hideOnEscape = 1, exclusive = 1, }; StaticPopup_Show("InventoriumRefill");]] end end end -- Events -- Player bank function mod:BANKFRAME_OPENED() addon:Debug("Scanner:BANKFRAME_OPENED"); mod:RegisterEvent("BANKFRAME_CLOSED"); -- Scan once when the bank is opened, but no need to scan after mod:Scan(addon.Locations.Bank); end function mod:BANKFRAME_CLOSED() addon:Debug("Scanner:BANKFRAME_CLOSED"); self:ClearCache(); mod:UnregisterEvent("BANKFRAME_CLOSED"); --StaticPopup_Hide("InventoriumRefill"); InventoriumItemMover:Hide(); Mover:ResetQueue(); end -- Guild bank local tmrScanGuild, scanned; function mod:GUILDBANKBAGSLOTS_CHANGED() -- This event is spammed the first time the guild bank is opened if not scanned then self:CancelTimer(tmrScanGuild, true); -- silent tmrScanGuild = self:ScheduleTimer("DoScanGuild", 1); end end function mod:DoScanGuild() if not scanned then addon:Debug("Scanner:DoScanGuild"); scanned = true; self:Scan(addon.Locations.Guild); end end function mod:GUILDBANKFRAME_CLOSED() addon:Debug("Scanner:GUILDBANKFRAME_CLOSED"); scanned = nil; self:ClearCache(); self:UnregisterEvent("GUILDBANKFRAME_CLOSED"); self:UnregisterEvent("GUILDBANKBAGSLOTS_CHANGED"); self:CancelTimer(tmrScanGuild, true); -- silent --StaticPopup_Hide("InventoriumRefill"); InventoriumItemMover:Hide(); Mover:ResetQueue(); end function mod:GUILDBANKFRAME_OPENED() addon:Debug("Scanner:GUILDBANKFRAME_OPENED"); scanned = nil; -- Get the contents for every tab into our cache for tabId = 1, GetNumGuildBankTabs() do local isViewable = select(3, GetGuildBankTabInfo(tabId)); if isViewable == 1 then QueryGuildBankTab(tabId); end end self:RegisterEvent("GUILDBANKFRAME_CLOSED"); self:RegisterEvent("GUILDBANKBAGSLOTS_CHANGED"); end function mod:OnEnable() -- Scan once when the bankframe is opened self:RegisterEvent("BANKFRAME_OPENED"); self:RegisterEvent("GUILDBANKFRAME_OPENED"); Mover = addon:GetModule("Mover"); if not InventoriumItemMover then addon:CreateMoverFrame(OnMoveAccept, OnMoveCancel); end end function mod:OnDisable() Mover = nil; currentLocation = nil; paused = nil; -- Bank self:UnregisterEvent("BANKFRAME_OPENED"); -- Guild self:GUILDBANKFRAME_CLOSED(); self:UnregisterEvent("GUILDBANKFRAME_OPENED"); end function mod:Pause() paused = true; end function mod:Unpause() paused = nil; end