annotate Modules/Scanner.lua @ 89:a12d22ef3f39

AceSerializer has been enabled again as it?s used when exporting/importing groups. All other unused libraries are now really removed. Adjusted debug function to format only when a debug channel is available. Fixed moving from guild banks, checking if items are locked is different then with banks. Now unregistering the item locking event so it doesn?t continue to try to move every time an item is switched after the automated cycle has finished. (geeezus, this description is a total overkill) Fixed item queueing. Queue all when there?s a group without any items inside no longer crashes. Removing cached container data after closing a container.
author Zerotorescue
date Fri, 07 Jan 2011 22:19:03 +0100
parents 3bec0ea44607
children 31493364b163
rev   line source
Zerotorescue@80 1 local addon = select(2, ...);
Zerotorescue@84 2 local mod = addon:NewModule("Scanner", "AceEvent-3.0", "AceTimer-3.0");
Zerotorescue@80 3
Zerotorescue@80 4 addon.Locations = {
Zerotorescue@80 5 Bag = 0,
Zerotorescue@80 6 Bank = 1,
Zerotorescue@80 7 Guild = 2,
Zerotorescue@80 8 };
Zerotorescue@80 9
Zerotorescue@80 10 local Mover, paused;
Zerotorescue@80 11 local itemCache = {};
Zerotorescue@80 12
Zerotorescue@80 13 function mod:ClearCache()
Zerotorescue@80 14 table.wipe(itemCache);
Zerotorescue@80 15 end
Zerotorescue@80 16
Zerotorescue@80 17 function mod:CacheLocation(location, remember)
Zerotorescue@89 18 -- Reset cache just in case it was filled
Zerotorescue@89 19 self:ClearCache();
Zerotorescue@89 20
Zerotorescue@80 21 if location == addon.Locations.Bag or location == addon.Locations.Bank then
Zerotorescue@80 22 local start, stop;
Zerotorescue@80 23 if location == addon.Locations.Bag then
Zerotorescue@80 24 start = 0;
Zerotorescue@80 25 stop = NUM_BAG_SLOTS;
Zerotorescue@80 26 else
Zerotorescue@80 27 -- If we requested the bank then we don't want the bag info
Zerotorescue@80 28 start = ( NUM_BAG_SLOTS + 1 );
Zerotorescue@80 29 stop = ( NUM_BAG_SLOTS + NUM_BANKBAGSLOTS );
Zerotorescue@80 30 end
Zerotorescue@80 31
Zerotorescue@80 32 -- Go through all our bags, including the backpack
Zerotorescue@81 33 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
Zerotorescue@80 34 -- Scan the default 100 slots whenever we're at a non-existing index
Zerotorescue@80 35 local bagId = (i == (stop + 1) and BANK_CONTAINER) or i;
Zerotorescue@80 36 local slotId = GetContainerNumSlots(bagId);
Zerotorescue@80 37
Zerotorescue@80 38 while slotId ~= 0 do
Zerotorescue@80 39 -- A not equal-comparison should be quicker than a larger than-comparison
Zerotorescue@80 40
Zerotorescue@80 41 local itemId = GetContainerItemID(bagId, slotId);
Zerotorescue@80 42 local itemCount = itemId and select(2, GetContainerItemInfo(bagId, slotId));
Zerotorescue@80 43
Zerotorescue@80 44 if itemId and itemCount and itemCount > 0 then
Zerotorescue@80 45 local itemMove;
Zerotorescue@80 46 if not itemCache[itemId] then
Zerotorescue@80 47 -- If this is the first time we see this item, make a new object
Zerotorescue@81 48 itemMove = addon.ContainerItem:New();
Zerotorescue@81 49 itemCache[itemId] = itemMove;
Zerotorescue@80 50 else
Zerotorescue@80 51 -- If we had this item in another slot too
Zerotorescue@80 52 itemMove = itemCache[itemId];
Zerotorescue@80 53 end
Zerotorescue@80 54
Zerotorescue@81 55 itemMove:AddLocation(bagId, slotId, itemCount);
Zerotorescue@80 56 end
Zerotorescue@80 57
Zerotorescue@80 58 -- Continue scanning a different slot
Zerotorescue@80 59 slotId = (slotId - 1);
Zerotorescue@80 60 end
Zerotorescue@80 61 end
Zerotorescue@80 62 elseif location == addon.Locations.Guild then
Zerotorescue@84 63 for tabId = 1, GetNumGuildBankTabs() do
Zerotorescue@84 64 local isViewable = select(3, GetGuildBankTabInfo(tabId));
Zerotorescue@80 65
Zerotorescue@84 66 if isViewable == 1 then
Zerotorescue@84 67 local slotId = (MAX_GUILDBANK_SLOTS_PER_TAB or 98); -- start by scanning the last slot
Zerotorescue@80 68
Zerotorescue@84 69 while slotId ~= 0 do
Zerotorescue@84 70 -- A not equal-comparison should be quicker than a larger than-comparison
Zerotorescue@84 71
Zerotorescue@84 72 local itemLink = GetGuildBankItemLink(tabId, slotId);
Zerotorescue@84 73 local itemId = itemLink and addon:GetItemID(itemLink);
Zerotorescue@84 74 local itemCount = itemLink and select(2, GetGuildBankItemInfo(tabId, slotId));
Zerotorescue@84 75
Zerotorescue@84 76 if itemLink and itemId and itemCount and itemCount > 0 then
Zerotorescue@84 77 -- If there is actually an item in this slot
Zerotorescue@84 78 local itemMove;
Zerotorescue@84 79 if not itemCache[itemId] then
Zerotorescue@84 80 -- If this is the first time we see this item, make a new object
Zerotorescue@84 81 itemMove = addon.ContainerItem:New();
Zerotorescue@84 82 itemCache[itemId] = itemMove;
Zerotorescue@84 83 else
Zerotorescue@84 84 -- If we had this item in another slot too
Zerotorescue@84 85 itemMove = itemCache[itemId];
Zerotorescue@84 86 end
Zerotorescue@84 87
Zerotorescue@84 88 itemMove:AddLocation(tabId, slotId, itemCount);
Zerotorescue@84 89 end
Zerotorescue@84 90
Zerotorescue@84 91 -- Continue scanning a different slot
Zerotorescue@84 92 slotId = (slotId - 1);
Zerotorescue@80 93 end
Zerotorescue@80 94 end
Zerotorescue@80 95 end
Zerotorescue@80 96 else
Zerotorescue@82 97 error("Invalid location provided for CacheLocation. Must be Bank or Guild.");
Zerotorescue@80 98 end
Zerotorescue@80 99
Zerotorescue@80 100 if not remember then
Zerotorescue@80 101 -- Copy the table as clearing the cache wipes it empty (and tables are passed by reference)
Zerotorescue@80 102 local cacheCopy = CopyTable(itemCache);
Zerotorescue@80 103
Zerotorescue@80 104 self:ClearCache();
Zerotorescue@80 105
Zerotorescue@80 106 return cacheCopy;
Zerotorescue@80 107 end
Zerotorescue@80 108 end
Zerotorescue@80 109
Zerotorescue@80 110 function mod:Scan(location)
Zerotorescue@80 111 -- We might pause the scanning when we invoke moves ourself
Zerotorescue@80 112 if paused then
Zerotorescue@80 113 return;
Zerotorescue@80 114 end
Zerotorescue@80 115
Zerotorescue@80 116 local playerName = UnitName("player");
Zerotorescue@80 117
Zerotorescue@80 118 self:CacheLocation(location, true);
Zerotorescue@80 119
Zerotorescue@80 120 -- Go through all groups
Zerotorescue@80 121 for groupName, values in pairs(addon.db.profile.groups) do
Zerotorescue@80 122 local trackAt = addon:GetOptionByKey(groupName, "trackAtCharacters");
Zerotorescue@84 123 local localItemData = addon:GetOptionByKey(groupName, "localItemData");
Zerotorescue@80 124
Zerotorescue@82 125 if values.items and trackAt[playerName] and addon:GetOptionByKey(groupName, "autoRefill") and (location ~= addon.Locations.Bank or not localItemData or not localItemData["Bank"]) then
Zerotorescue@80 126 -- Is this character interested in this data?
Zerotorescue@80 127
Zerotorescue@80 128 local minLocalStock = addon:GetOptionByKey(groupName, "minLocalStock");
Zerotorescue@80 129
Zerotorescue@80 130 -- Go through all items
Zerotorescue@80 131 for itemId, _ in pairs(values.items) do
Zerotorescue@80 132
Zerotorescue@81 133 -- Check if we have enough items local (but only do so if this location also has enough available)
Zerotorescue@81 134 local missingItems = itemCache[itemId] and (minLocalStock - addon:GetLocalItemCount(itemId, groupName));
Zerotorescue@80 135
Zerotorescue@81 136 if itemCache[itemId] and missingItems > 0 then
Zerotorescue@80 137 -- Check how many are available
Zerotorescue@81 138 local availableItems = ((itemCache[itemId] and itemCache[itemId].totalCount) or 0);
Zerotorescue@80 139
Zerotorescue@80 140 if availableItems > 0 then
Zerotorescue@80 141 print("Insufficient " .. select(2, GetItemInfo(itemId)) .. " but this location has " .. availableItems .. " (moving " .. missingItems .. ")");
Zerotorescue@80 142
Zerotorescue@80 143 Mover:AddMove(itemId, missingItems);
Zerotorescue@80 144 else
Zerotorescue@81 145 print("Insufficient " .. IdToItemLink(itemId));
Zerotorescue@80 146 end
Zerotorescue@80 147 end
Zerotorescue@80 148 end
Zerotorescue@80 149 end
Zerotorescue@80 150 end
Zerotorescue@80 151
Zerotorescue@80 152 self:ClearCache();
Zerotorescue@80 153
Zerotorescue@81 154 if Mover:HasMoves() then
Zerotorescue@81 155 StaticPopupDialogs["InventoriumRefill"] = {
Zerotorescue@81 156 text = "There are items that can be refilled from this location, do you wish to proceed?",
Zerotorescue@81 157 button1 = YES,
Zerotorescue@81 158 button2 = NO,
Zerotorescue@81 159 OnAccept = function()
Zerotorescue@81 160 mod:Pause();
Zerotorescue@81 161 Mover:BeginMove(location, self.Unpause);
Zerotorescue@81 162 end,
Zerotorescue@81 163 timeout = 0,
Zerotorescue@81 164 whileDead = 1,
Zerotorescue@81 165 hideOnEscape = 1,
Zerotorescue@82 166 exclusive = 1,
Zerotorescue@81 167 };
Zerotorescue@81 168 StaticPopup_Show("InventoriumRefill");
Zerotorescue@81 169 end
Zerotorescue@81 170 end
Zerotorescue@81 171
Zerotorescue@84 172
Zerotorescue@84 173
Zerotorescue@84 174 -- Events
Zerotorescue@84 175
Zerotorescue@84 176 -- Player bank
Zerotorescue@84 177
Zerotorescue@84 178 function mod:BANKFRAME_OPENED()
Zerotorescue@84 179 addon:Debug("Scanner:BANKFRAME_OPENED");
Zerotorescue@84 180
Zerotorescue@84 181 mod:RegisterEvent("BANKFRAME_CLOSED");
Zerotorescue@84 182
Zerotorescue@84 183 -- Scan once when the bank is opened, but no need to scan after
Zerotorescue@84 184 mod:Scan(addon.Locations.Bank);
Zerotorescue@84 185 end
Zerotorescue@84 186
Zerotorescue@84 187 function mod:BANKFRAME_CLOSED()
Zerotorescue@81 188 addon:Debug("Scanner:BANKFRAME_CLOSED");
Zerotorescue@81 189
Zerotorescue@89 190 self:ClearCache();
Zerotorescue@89 191
Zerotorescue@81 192 mod:UnregisterEvent("BANKFRAME_CLOSED");
Zerotorescue@81 193
Zerotorescue@81 194 StaticPopup_Hide("InventoriumRefill");
Zerotorescue@80 195 end
Zerotorescue@80 196
Zerotorescue@84 197 -- Guild bank
Zerotorescue@84 198
Zerotorescue@84 199 local tmrScanGuild, scanned;
Zerotorescue@84 200 function mod:GUILDBANKBAGSLOTS_CHANGED()
Zerotorescue@84 201 -- This event is spammed the first time the guild bank is opened
Zerotorescue@84 202 if not scanned then
Zerotorescue@84 203 self:CancelTimer(tmrScanGuild, true); -- silent
Zerotorescue@84 204 tmrScanGuild = self:ScheduleTimer("DoScanGuild", 1);
Zerotorescue@84 205 end
Zerotorescue@80 206 end
Zerotorescue@80 207
Zerotorescue@84 208 function mod:DoScanGuild()
Zerotorescue@84 209 if not scanned then
Zerotorescue@89 210 addon:Debug("Scanner:DoScanGuild");
Zerotorescue@84 211
Zerotorescue@84 212 scanned = true;
Zerotorescue@84 213
Zerotorescue@84 214 self:Scan(addon.Locations.Guild);
Zerotorescue@84 215 end
Zerotorescue@84 216 end
Zerotorescue@80 217
Zerotorescue@84 218 function mod:GUILDBANKFRAME_CLOSED()
Zerotorescue@81 219 addon:Debug("Scanner:GUILDBANKFRAME_CLOSED");
Zerotorescue@81 220
Zerotorescue@84 221 scanned = nil;
Zerotorescue@89 222 self:ClearCache();
Zerotorescue@81 223
Zerotorescue@84 224 self:UnregisterEvent("GUILDBANKFRAME_CLOSED");
Zerotorescue@84 225 self:UnregisterEvent("GUILDBANKBAGSLOTS_CHANGED");
Zerotorescue@84 226
Zerotorescue@84 227 self:CancelTimer(tmrScanGuild, true); -- silent
Zerotorescue@80 228
Zerotorescue@81 229 StaticPopup_Hide("InventoriumRefill");
Zerotorescue@80 230 end
Zerotorescue@80 231
Zerotorescue@84 232 function mod:GUILDBANKFRAME_OPENED()
Zerotorescue@81 233 addon:Debug("Scanner:GUILDBANKFRAME_OPENED");
Zerotorescue@81 234
Zerotorescue@84 235 scanned = nil;
Zerotorescue@80 236
Zerotorescue@84 237 -- Get the contents for every tab into our cache
Zerotorescue@84 238 for tabId = 1, GetNumGuildBankTabs() do
Zerotorescue@84 239 local isViewable = select(3, GetGuildBankTabInfo(tabId));
Zerotorescue@84 240 if isViewable == 1 then
Zerotorescue@84 241 QueryGuildBankTab(tabId);
Zerotorescue@84 242 end
Zerotorescue@84 243 end
Zerotorescue@84 244
Zerotorescue@84 245 self:RegisterEvent("GUILDBANKFRAME_CLOSED");
Zerotorescue@84 246 self:RegisterEvent("GUILDBANKBAGSLOTS_CHANGED");
Zerotorescue@80 247 end
Zerotorescue@80 248
Zerotorescue@80 249 function mod:OnEnable()
Zerotorescue@80 250 -- Scan once when the bankframe is opened
Zerotorescue@84 251 self:RegisterEvent("BANKFRAME_OPENED");
Zerotorescue@84 252 self:RegisterEvent("GUILDBANKFRAME_OPENED");
Zerotorescue@80 253
Zerotorescue@80 254 Mover = addon:GetModule("Mover");
Zerotorescue@80 255 end
Zerotorescue@80 256
Zerotorescue@80 257 function mod:OnDisable()
Zerotorescue@80 258 Mover = nil;
Zerotorescue@80 259
Zerotorescue@80 260 -- Bank
Zerotorescue@84 261 self:UnregisterEvent("BANKFRAME_OPENED");
Zerotorescue@80 262
Zerotorescue@80 263 -- Guild
Zerotorescue@84 264 self:GUILDBANKFRAME_CLOSED();
Zerotorescue@84 265 self:UnregisterEvent("GUILDBANKFRAME_OPENED");
Zerotorescue@80 266 end
Zerotorescue@80 267
Zerotorescue@80 268 function mod:Pause()
Zerotorescue@80 269 paused = true;
Zerotorescue@80 270 end
Zerotorescue@80 271
Zerotorescue@80 272 function mod:Unpause()
Zerotorescue@80 273 paused = nil;
Zerotorescue@80 274 end