annotate Modules/Scanner.lua @ 84:3bec0ea44607

Cleaned the Inventorium folder; moved all classes to classes directory, modules to modules directory and support addons to plugins directory. In addition support addons are now references within XML files rather than inside the TOC. Fixed the default local item count setting, you can now exclude bag and AH data from it. Fixed some mover algorithm bugs. Mover can no longer freeze the game but instead will terminate the process after a 1000 passes. Now reversing the moves table after making it, rather than every single time it is used. Fixed guild bank support. Now displaying the amount of items moved. Scanner now scans all guild bank tabs rather than only the current. Fixed a bug with local item data not being retrieved properly. Disabled ?enterClicksFirstButton? within dialogs as this causes the dialog to consume all keypress. Events are now at the addon object rather than local.
author Zerotorescue
date Thu, 06 Jan 2011 20:05:30 +0100
parents Scanner.lua@f885805da5d6
children a12d22ef3f39
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@80 18 if location == addon.Locations.Bag or location == addon.Locations.Bank then
Zerotorescue@80 19 -- Reset cache just in case it was filled
Zerotorescue@80 20 self:ClearCache();
Zerotorescue@80 21
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@80 63 -- Reset cache before we scan
Zerotorescue@80 64 self:ClearCache();
Zerotorescue@80 65
Zerotorescue@84 66 for tabId = 1, GetNumGuildBankTabs() do
Zerotorescue@84 67 local isViewable = select(3, GetGuildBankTabInfo(tabId));
Zerotorescue@80 68
Zerotorescue@84 69 if isViewable == 1 then
Zerotorescue@84 70 local slotId = (MAX_GUILDBANK_SLOTS_PER_TAB or 98); -- start by scanning the last slot
Zerotorescue@80 71
Zerotorescue@84 72 while slotId ~= 0 do
Zerotorescue@84 73 -- A not equal-comparison should be quicker than a larger than-comparison
Zerotorescue@84 74
Zerotorescue@84 75 local itemLink = GetGuildBankItemLink(tabId, slotId);
Zerotorescue@84 76 local itemId = itemLink and addon:GetItemID(itemLink);
Zerotorescue@84 77 local itemCount = itemLink and select(2, GetGuildBankItemInfo(tabId, slotId));
Zerotorescue@84 78
Zerotorescue@84 79 if itemLink and itemId and itemCount and itemCount > 0 then
Zerotorescue@84 80 -- If there is actually an item in this slot
Zerotorescue@84 81 local itemMove;
Zerotorescue@84 82 if not itemCache[itemId] then
Zerotorescue@84 83 -- If this is the first time we see this item, make a new object
Zerotorescue@84 84 itemMove = addon.ContainerItem:New();
Zerotorescue@84 85 itemCache[itemId] = itemMove;
Zerotorescue@84 86 else
Zerotorescue@84 87 -- If we had this item in another slot too
Zerotorescue@84 88 itemMove = itemCache[itemId];
Zerotorescue@84 89 end
Zerotorescue@84 90
Zerotorescue@84 91 itemMove:AddLocation(tabId, slotId, itemCount);
Zerotorescue@84 92 end
Zerotorescue@84 93
Zerotorescue@84 94 -- Continue scanning a different slot
Zerotorescue@84 95 slotId = (slotId - 1);
Zerotorescue@80 96 end
Zerotorescue@80 97 end
Zerotorescue@80 98 end
Zerotorescue@80 99 else
Zerotorescue@82 100 error("Invalid location provided for CacheLocation. Must be Bank or Guild.");
Zerotorescue@80 101 end
Zerotorescue@80 102
Zerotorescue@80 103 if not remember then
Zerotorescue@80 104 -- Copy the table as clearing the cache wipes it empty (and tables are passed by reference)
Zerotorescue@80 105 local cacheCopy = CopyTable(itemCache);
Zerotorescue@80 106
Zerotorescue@80 107 self:ClearCache();
Zerotorescue@80 108
Zerotorescue@80 109 return cacheCopy;
Zerotorescue@80 110 end
Zerotorescue@80 111 end
Zerotorescue@80 112
Zerotorescue@80 113 function mod:Scan(location)
Zerotorescue@80 114 -- We might pause the scanning when we invoke moves ourself
Zerotorescue@80 115 if paused then
Zerotorescue@80 116 return;
Zerotorescue@80 117 end
Zerotorescue@80 118
Zerotorescue@80 119 local playerName = UnitName("player");
Zerotorescue@80 120
Zerotorescue@80 121 self:CacheLocation(location, true);
Zerotorescue@80 122
Zerotorescue@80 123 -- Go through all groups
Zerotorescue@80 124 for groupName, values in pairs(addon.db.profile.groups) do
Zerotorescue@80 125 local trackAt = addon:GetOptionByKey(groupName, "trackAtCharacters");
Zerotorescue@84 126 local localItemData = addon:GetOptionByKey(groupName, "localItemData");
Zerotorescue@80 127
Zerotorescue@82 128 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 129 -- Is this character interested in this data?
Zerotorescue@80 130
Zerotorescue@80 131 local minLocalStock = addon:GetOptionByKey(groupName, "minLocalStock");
Zerotorescue@80 132
Zerotorescue@80 133 -- Go through all items
Zerotorescue@80 134 for itemId, _ in pairs(values.items) do
Zerotorescue@80 135
Zerotorescue@81 136 -- Check if we have enough items local (but only do so if this location also has enough available)
Zerotorescue@81 137 local missingItems = itemCache[itemId] and (minLocalStock - addon:GetLocalItemCount(itemId, groupName));
Zerotorescue@80 138
Zerotorescue@81 139 if itemCache[itemId] and missingItems > 0 then
Zerotorescue@80 140 -- Check how many are available
Zerotorescue@81 141 local availableItems = ((itemCache[itemId] and itemCache[itemId].totalCount) or 0);
Zerotorescue@80 142
Zerotorescue@80 143 if availableItems > 0 then
Zerotorescue@80 144 print("Insufficient " .. select(2, GetItemInfo(itemId)) .. " but this location has " .. availableItems .. " (moving " .. missingItems .. ")");
Zerotorescue@80 145
Zerotorescue@80 146 Mover:AddMove(itemId, missingItems);
Zerotorescue@80 147 else
Zerotorescue@81 148 print("Insufficient " .. IdToItemLink(itemId));
Zerotorescue@80 149 end
Zerotorescue@80 150 end
Zerotorescue@80 151 end
Zerotorescue@80 152 end
Zerotorescue@80 153 end
Zerotorescue@80 154
Zerotorescue@80 155 self:ClearCache();
Zerotorescue@80 156
Zerotorescue@81 157 if Mover:HasMoves() then
Zerotorescue@81 158 StaticPopupDialogs["InventoriumRefill"] = {
Zerotorescue@81 159 text = "There are items that can be refilled from this location, do you wish to proceed?",
Zerotorescue@81 160 button1 = YES,
Zerotorescue@81 161 button2 = NO,
Zerotorescue@81 162 OnAccept = function()
Zerotorescue@81 163 mod:Pause();
Zerotorescue@81 164 Mover:BeginMove(location, self.Unpause);
Zerotorescue@81 165 end,
Zerotorescue@81 166 timeout = 0,
Zerotorescue@81 167 whileDead = 1,
Zerotorescue@81 168 hideOnEscape = 1,
Zerotorescue@82 169 exclusive = 1,
Zerotorescue@81 170 };
Zerotorescue@81 171 StaticPopup_Show("InventoriumRefill");
Zerotorescue@81 172 end
Zerotorescue@81 173 end
Zerotorescue@81 174
Zerotorescue@84 175
Zerotorescue@84 176
Zerotorescue@84 177 -- Events
Zerotorescue@84 178
Zerotorescue@84 179 -- Player bank
Zerotorescue@84 180
Zerotorescue@84 181 function mod:BANKFRAME_OPENED()
Zerotorescue@84 182 addon:Debug("Scanner:BANKFRAME_OPENED");
Zerotorescue@84 183
Zerotorescue@84 184 mod:RegisterEvent("BANKFRAME_CLOSED");
Zerotorescue@84 185
Zerotorescue@84 186 -- Scan once when the bank is opened, but no need to scan after
Zerotorescue@84 187 mod:Scan(addon.Locations.Bank);
Zerotorescue@84 188 end
Zerotorescue@84 189
Zerotorescue@84 190 function mod:BANKFRAME_CLOSED()
Zerotorescue@81 191 addon:Debug("Scanner:BANKFRAME_CLOSED");
Zerotorescue@81 192
Zerotorescue@81 193 mod:UnregisterEvent("BANKFRAME_CLOSED");
Zerotorescue@81 194
Zerotorescue@81 195 StaticPopup_Hide("InventoriumRefill");
Zerotorescue@80 196 end
Zerotorescue@80 197
Zerotorescue@84 198 -- Guild bank
Zerotorescue@84 199
Zerotorescue@84 200 local tmrScanGuild, scanned;
Zerotorescue@84 201 function mod:GUILDBANKBAGSLOTS_CHANGED()
Zerotorescue@84 202 -- This event is spammed the first time the guild bank is opened
Zerotorescue@84 203 if not scanned then
Zerotorescue@84 204 self:CancelTimer(tmrScanGuild, true); -- silent
Zerotorescue@84 205 tmrScanGuild = self:ScheduleTimer("DoScanGuild", 1);
Zerotorescue@84 206 end
Zerotorescue@80 207 end
Zerotorescue@80 208
Zerotorescue@84 209 function mod:DoScanGuild()
Zerotorescue@84 210 if not scanned then
Zerotorescue@84 211 addon:Debug("Scanner:GUILDBANKBAGSLOTS_CHANGED");
Zerotorescue@84 212
Zerotorescue@84 213 scanned = true;
Zerotorescue@84 214
Zerotorescue@84 215 self:Scan(addon.Locations.Guild);
Zerotorescue@84 216 end
Zerotorescue@84 217 end
Zerotorescue@80 218
Zerotorescue@84 219 function mod:GUILDBANKFRAME_CLOSED()
Zerotorescue@81 220 addon:Debug("Scanner:GUILDBANKFRAME_CLOSED");
Zerotorescue@81 221
Zerotorescue@84 222 scanned = nil;
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