Mercurial > wow > inventory
view Modules/Scanner.lua @ 106:d3fbb5676a5e
Added tooltips to the item refill window headers.
Now color coding the availibility of items at the item refill window.
Added a hide help text option (which is off by default).
Renamed all premade groups to a new naming pattern; ?Profession - Category - Detail?, e.g. ?Inscription - Glyphs by class - Death Knight?. To continue getting notified about updates to a selected premade group, you must re-add them.
Repositioned elements of the item refill frame to fit better.
No longer using colorsargs to remember the index of a queued move, but instead providing a reference to the move itself in the new ?rowData? property of each row.
Added tooltips to the headers of the sort table.
Merged missing and available columns together (showing available / missing) and sorting on available now sorts on percentage of how many of the missing items are available.
Moving and available columns are now aligned to the right.
Added an ?extra? config group which contains the additional (but completely optional) settings. Moved color codes adjustments, forget character, auto refill skip confirm and hide help info options to this group.
author | Zerotorescue |
---|---|
date | Wed, 12 Jan 2011 19:58:39 +0100 |
parents | 6ae44d372360 |
children | 3bbad0429d87 |
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 -- This table is never copied, just referenced. It is the same for every row. local columns = { { value = function(data, cols, realrow, column, table) return IdToItemLink(data[realrow].rowData.id); end, }, -- item { value = function(data, cols, realrow, column, table) return data[realrow].rowData.num; end, }, -- moving { value = function(data, cols, realrow, column, table) return addon:DisplayItemCount(data[realrow].rowData.available, data[realrow].rowData.missing); -- available / missing end, color = function(data, cols, realrow, column, table) return ((data[realrow].rowData.available < data[realrow].rowData.missing) and { r = 1, g = 0, b = 0, a = 1 }) or { r = 1, g = 1, b = 1, a = 1 }; end, }, -- missing / available }; -- Store the list with rows in this local data = {}; for i, move in pairs(Mover:GetMoves()) do table.insert(data, { ["rowData"] = move, -- this is not a key usually found in a row item and ignored by the library ["cols"] = columns, }); end addon:SetMoverFrameData(data); 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"); 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 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