annotate 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
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@101 10 local Mover, paused, currentLocation;
Zerotorescue@80 11 local itemCache = {};
Zerotorescue@80 12
Zerotorescue@101 13 local function OnMoveAccept(this)
Zerotorescue@101 14 mod:Pause();
Zerotorescue@101 15 Mover:BeginMove(currentLocation, mod.Unpause);
Zerotorescue@101 16
Zerotorescue@101 17 InventoriumItemMover:Hide();
Zerotorescue@101 18 end
Zerotorescue@101 19
Zerotorescue@101 20 local function OnMoveCancel(this)
Zerotorescue@101 21 Mover:ResetQueue();
Zerotorescue@101 22 currentLocation = nil;
Zerotorescue@101 23
Zerotorescue@101 24 InventoriumItemMover:Hide();
Zerotorescue@101 25 end
Zerotorescue@101 26
Zerotorescue@80 27 function mod:ClearCache()
Zerotorescue@80 28 table.wipe(itemCache);
Zerotorescue@80 29 end
Zerotorescue@80 30
Zerotorescue@80 31 function mod:CacheLocation(location, remember)
Zerotorescue@89 32 -- Reset cache just in case it was filled
Zerotorescue@89 33 self:ClearCache();
Zerotorescue@89 34
Zerotorescue@80 35 if location == addon.Locations.Bag or location == addon.Locations.Bank then
Zerotorescue@80 36 local start, stop;
Zerotorescue@80 37 if location == addon.Locations.Bag then
Zerotorescue@80 38 start = 0;
Zerotorescue@80 39 stop = NUM_BAG_SLOTS;
Zerotorescue@80 40 else
Zerotorescue@80 41 -- If we requested the bank then we don't want the bag info
Zerotorescue@80 42 start = ( NUM_BAG_SLOTS + 1 );
Zerotorescue@80 43 stop = ( NUM_BAG_SLOTS + NUM_BANKBAGSLOTS );
Zerotorescue@80 44 end
Zerotorescue@80 45
Zerotorescue@80 46 -- Go through all our bags, including the backpack
Zerotorescue@81 47 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 48 -- Scan the default 100 slots whenever we're at a non-existing index
Zerotorescue@80 49 local bagId = (i == (stop + 1) and BANK_CONTAINER) or i;
Zerotorescue@80 50 local slotId = GetContainerNumSlots(bagId);
Zerotorescue@80 51
Zerotorescue@80 52 while slotId ~= 0 do
Zerotorescue@80 53 -- A not equal-comparison should be quicker than a larger than-comparison
Zerotorescue@80 54
Zerotorescue@80 55 local itemId = GetContainerItemID(bagId, slotId);
Zerotorescue@80 56 local itemCount = itemId and select(2, GetContainerItemInfo(bagId, slotId));
Zerotorescue@80 57
Zerotorescue@80 58 if itemId and itemCount and itemCount > 0 then
Zerotorescue@80 59 local itemMove;
Zerotorescue@80 60 if not itemCache[itemId] then
Zerotorescue@80 61 -- If this is the first time we see this item, make a new object
Zerotorescue@81 62 itemMove = addon.ContainerItem:New();
Zerotorescue@81 63 itemCache[itemId] = itemMove;
Zerotorescue@80 64 else
Zerotorescue@80 65 -- If we had this item in another slot too
Zerotorescue@80 66 itemMove = itemCache[itemId];
Zerotorescue@80 67 end
Zerotorescue@80 68
Zerotorescue@81 69 itemMove:AddLocation(bagId, slotId, itemCount);
Zerotorescue@80 70 end
Zerotorescue@80 71
Zerotorescue@80 72 -- Continue scanning a different slot
Zerotorescue@80 73 slotId = (slotId - 1);
Zerotorescue@80 74 end
Zerotorescue@80 75 end
Zerotorescue@80 76 elseif location == addon.Locations.Guild then
Zerotorescue@84 77 for tabId = 1, GetNumGuildBankTabs() do
Zerotorescue@84 78 local isViewable = select(3, GetGuildBankTabInfo(tabId));
Zerotorescue@80 79
Zerotorescue@84 80 if isViewable == 1 then
Zerotorescue@84 81 local slotId = (MAX_GUILDBANK_SLOTS_PER_TAB or 98); -- start by scanning the last slot
Zerotorescue@80 82
Zerotorescue@84 83 while slotId ~= 0 do
Zerotorescue@84 84 -- A not equal-comparison should be quicker than a larger than-comparison
Zerotorescue@84 85
Zerotorescue@84 86 local itemLink = GetGuildBankItemLink(tabId, slotId);
Zerotorescue@95 87 local itemId = itemLink and addon:GetItemId(itemLink);
Zerotorescue@84 88 local itemCount = itemLink and select(2, GetGuildBankItemInfo(tabId, slotId));
Zerotorescue@84 89
Zerotorescue@84 90 if itemLink and itemId and itemCount and itemCount > 0 then
Zerotorescue@84 91 -- If there is actually an item in this slot
Zerotorescue@84 92 local itemMove;
Zerotorescue@84 93 if not itemCache[itemId] then
Zerotorescue@84 94 -- If this is the first time we see this item, make a new object
Zerotorescue@84 95 itemMove = addon.ContainerItem:New();
Zerotorescue@84 96 itemCache[itemId] = itemMove;
Zerotorescue@84 97 else
Zerotorescue@84 98 -- If we had this item in another slot too
Zerotorescue@84 99 itemMove = itemCache[itemId];
Zerotorescue@84 100 end
Zerotorescue@84 101
Zerotorescue@84 102 itemMove:AddLocation(tabId, slotId, itemCount);
Zerotorescue@84 103 end
Zerotorescue@84 104
Zerotorescue@84 105 -- Continue scanning a different slot
Zerotorescue@84 106 slotId = (slotId - 1);
Zerotorescue@80 107 end
Zerotorescue@80 108 end
Zerotorescue@80 109 end
Zerotorescue@80 110 else
Zerotorescue@82 111 error("Invalid location provided for CacheLocation. Must be Bank or Guild.");
Zerotorescue@80 112 end
Zerotorescue@80 113
Zerotorescue@80 114 if not remember then
Zerotorescue@80 115 -- Copy the table as clearing the cache wipes it empty (and tables are passed by reference)
Zerotorescue@80 116 local cacheCopy = CopyTable(itemCache);
Zerotorescue@80 117
Zerotorescue@80 118 self:ClearCache();
Zerotorescue@80 119
Zerotorescue@80 120 return cacheCopy;
Zerotorescue@80 121 end
Zerotorescue@80 122 end
Zerotorescue@80 123
Zerotorescue@80 124 function mod:Scan(location)
Zerotorescue@80 125 -- We might pause the scanning when we invoke moves ourself
Zerotorescue@80 126 if paused then
Zerotorescue@80 127 return;
Zerotorescue@80 128 end
Zerotorescue@80 129
Zerotorescue@80 130 local playerName = UnitName("player");
Zerotorescue@80 131
Zerotorescue@101 132 currentLocation = location;
Zerotorescue@80 133 self:CacheLocation(location, true);
Zerotorescue@80 134
Zerotorescue@80 135 -- Go through all groups
Zerotorescue@80 136 for groupName, values in pairs(addon.db.profile.groups) do
Zerotorescue@80 137 local trackAt = addon:GetOptionByKey(groupName, "trackAtCharacters");
Zerotorescue@84 138 local localItemData = addon:GetOptionByKey(groupName, "localItemData");
Zerotorescue@80 139
Zerotorescue@82 140 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 141 -- Is this character interested in this data?
Zerotorescue@80 142
Zerotorescue@80 143 local minLocalStock = addon:GetOptionByKey(groupName, "minLocalStock");
Zerotorescue@80 144
Zerotorescue@80 145 -- Go through all items
Zerotorescue@80 146 for itemId, _ in pairs(values.items) do
Zerotorescue@80 147
Zerotorescue@81 148 -- Check if we have enough items local (but only do so if this location also has enough available)
Zerotorescue@81 149 local missingItems = itemCache[itemId] and (minLocalStock - addon:GetLocalItemCount(itemId, groupName));
Zerotorescue@80 150
Zerotorescue@81 151 if itemCache[itemId] and missingItems > 0 then
Zerotorescue@80 152 -- Check how many are available
Zerotorescue@81 153 local availableItems = ((itemCache[itemId] and itemCache[itemId].totalCount) or 0);
Zerotorescue@101 154 -- Calculate how many we'll be moving (less missing than available? use missing, otherwise use available)
Zerotorescue@101 155 local moving = (((missingItems <= availableItems) and missingItems) or availableItems);
Zerotorescue@80 156
Zerotorescue@80 157 if availableItems > 0 then
Zerotorescue@101 158 --addon:Print("Insufficient " .. IdToItemLink(itemId) .. " but this location has " .. availableItems .. " (moving " .. moving .. ")");
Zerotorescue@80 159
Zerotorescue@101 160 Mover:AddMove(itemId, moving, missingItems, availableItems);
Zerotorescue@80 161 else
Zerotorescue@101 162 --addon:Print("Insufficient " .. IdToItemLink(itemId));
Zerotorescue@80 163 end
Zerotorescue@80 164 end
Zerotorescue@80 165 end
Zerotorescue@80 166 end
Zerotorescue@80 167 end
Zerotorescue@80 168
Zerotorescue@80 169 self:ClearCache();
Zerotorescue@80 170
Zerotorescue@81 171 if Mover:HasMoves() then
Zerotorescue@101 172 if addon.db.profile.defaults.autoRefillSkipConfirm then
Zerotorescue@101 173 OnMoveAccept(true);
Zerotorescue@101 174 else
Zerotorescue@101 175 local data = {};
Zerotorescue@101 176
Zerotorescue@101 177 local columns = {
Zerotorescue@101 178 {
Zerotorescue@101 179 value = function(d, cols, realrow, column, table)
Zerotorescue@101 180 return IdToItemLink(d[realrow].colorargs[2]);
Zerotorescue@101 181 end,
Zerotorescue@101 182 }, -- item
Zerotorescue@101 183 {
Zerotorescue@101 184 value = function(d, cols, realrow, column, table)
Zerotorescue@101 185 local queue = Mover:GetMoves();
Zerotorescue@101 186 return queue[d[realrow].colorargs[1]].num;
Zerotorescue@101 187 end,
Zerotorescue@101 188 }, -- moving
Zerotorescue@101 189 {
Zerotorescue@101 190 value = function(d, cols, realrow, column, table)
Zerotorescue@101 191 local queue = Mover:GetMoves();
Zerotorescue@101 192 return queue[d[realrow].colorargs[1]].missing;
Zerotorescue@101 193 end,
Zerotorescue@101 194 }, -- missing
Zerotorescue@101 195 {
Zerotorescue@101 196 value = function(d, cols, realrow, column, table)
Zerotorescue@101 197 local queue = Mover:GetMoves();
Zerotorescue@101 198 return queue[d[realrow].colorargs[1]].available;
Zerotorescue@101 199 end,
Zerotorescue@101 200 color = function(d, cols, realrow, column, table)
Zerotorescue@101 201 local queue = Mover:GetMoves();
Zerotorescue@101 202 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 };
Zerotorescue@101 203 end,
Zerotorescue@101 204 }, -- available
Zerotorescue@101 205 };
Zerotorescue@101 206
Zerotorescue@101 207 local queue = Mover:GetMoves();
Zerotorescue@101 208
Zerotorescue@101 209 for i, move in pairs(Mover:GetMoves()) do
Zerotorescue@101 210 local row = {
Zerotorescue@101 211 ["colorargs"] = { i, queue[i].id },
Zerotorescue@101 212 ["cols"] = columns,
Zerotorescue@101 213 };
Zerotorescue@101 214
Zerotorescue@101 215 table.insert(data, row);
Zerotorescue@101 216 end
Zerotorescue@101 217
Zerotorescue@101 218 addon:SetMoverFrameData(data);
Zerotorescue@101 219
Zerotorescue@101 220 --[[
Zerotorescue@101 221 StaticPopupDialogs["InventoriumRefill"] = {
Zerotorescue@101 222 text = "There are items that can be refilled from this location, do you wish to proceed?",
Zerotorescue@101 223 button1 = YES,
Zerotorescue@101 224 button2 = NO,
Zerotorescue@101 225 OnAccept = function()
Zerotorescue@101 226 mod:Pause();
Zerotorescue@101 227 Mover:BeginMove(location, self.Unpause);
Zerotorescue@101 228 end,
Zerotorescue@101 229 timeout = 0,
Zerotorescue@101 230 whileDead = 1,
Zerotorescue@101 231 hideOnEscape = 1,
Zerotorescue@101 232 exclusive = 1,
Zerotorescue@101 233 };
Zerotorescue@101 234 StaticPopup_Show("InventoriumRefill");]]
Zerotorescue@101 235 end
Zerotorescue@81 236 end
Zerotorescue@81 237 end
Zerotorescue@81 238
Zerotorescue@84 239
Zerotorescue@84 240
Zerotorescue@84 241 -- Events
Zerotorescue@84 242
Zerotorescue@84 243 -- Player bank
Zerotorescue@84 244
Zerotorescue@84 245 function mod:BANKFRAME_OPENED()
Zerotorescue@84 246 addon:Debug("Scanner:BANKFRAME_OPENED");
Zerotorescue@84 247
Zerotorescue@84 248 mod:RegisterEvent("BANKFRAME_CLOSED");
Zerotorescue@84 249
Zerotorescue@84 250 -- Scan once when the bank is opened, but no need to scan after
Zerotorescue@84 251 mod:Scan(addon.Locations.Bank);
Zerotorescue@84 252 end
Zerotorescue@84 253
Zerotorescue@84 254 function mod:BANKFRAME_CLOSED()
Zerotorescue@81 255 addon:Debug("Scanner:BANKFRAME_CLOSED");
Zerotorescue@81 256
Zerotorescue@89 257 self:ClearCache();
Zerotorescue@89 258
Zerotorescue@81 259 mod:UnregisterEvent("BANKFRAME_CLOSED");
Zerotorescue@81 260
Zerotorescue@101 261 --StaticPopup_Hide("InventoriumRefill");
Zerotorescue@101 262 InventoriumItemMover:Hide();
Zerotorescue@101 263 Mover:ResetQueue();
Zerotorescue@80 264 end
Zerotorescue@80 265
Zerotorescue@84 266 -- Guild bank
Zerotorescue@84 267
Zerotorescue@84 268 local tmrScanGuild, scanned;
Zerotorescue@84 269 function mod:GUILDBANKBAGSLOTS_CHANGED()
Zerotorescue@84 270 -- This event is spammed the first time the guild bank is opened
Zerotorescue@84 271 if not scanned then
Zerotorescue@84 272 self:CancelTimer(tmrScanGuild, true); -- silent
Zerotorescue@84 273 tmrScanGuild = self:ScheduleTimer("DoScanGuild", 1);
Zerotorescue@84 274 end
Zerotorescue@80 275 end
Zerotorescue@80 276
Zerotorescue@84 277 function mod:DoScanGuild()
Zerotorescue@84 278 if not scanned then
Zerotorescue@89 279 addon:Debug("Scanner:DoScanGuild");
Zerotorescue@84 280
Zerotorescue@84 281 scanned = true;
Zerotorescue@84 282
Zerotorescue@84 283 self:Scan(addon.Locations.Guild);
Zerotorescue@84 284 end
Zerotorescue@84 285 end
Zerotorescue@80 286
Zerotorescue@84 287 function mod:GUILDBANKFRAME_CLOSED()
Zerotorescue@81 288 addon:Debug("Scanner:GUILDBANKFRAME_CLOSED");
Zerotorescue@81 289
Zerotorescue@84 290 scanned = nil;
Zerotorescue@89 291 self:ClearCache();
Zerotorescue@81 292
Zerotorescue@84 293 self:UnregisterEvent("GUILDBANKFRAME_CLOSED");
Zerotorescue@84 294 self:UnregisterEvent("GUILDBANKBAGSLOTS_CHANGED");
Zerotorescue@84 295
Zerotorescue@84 296 self:CancelTimer(tmrScanGuild, true); -- silent
Zerotorescue@80 297
Zerotorescue@101 298 --StaticPopup_Hide("InventoriumRefill");
Zerotorescue@101 299 InventoriumItemMover:Hide();
Zerotorescue@101 300 Mover:ResetQueue();
Zerotorescue@80 301 end
Zerotorescue@80 302
Zerotorescue@84 303 function mod:GUILDBANKFRAME_OPENED()
Zerotorescue@81 304 addon:Debug("Scanner:GUILDBANKFRAME_OPENED");
Zerotorescue@81 305
Zerotorescue@84 306 scanned = nil;
Zerotorescue@80 307
Zerotorescue@84 308 -- Get the contents for every tab into our cache
Zerotorescue@84 309 for tabId = 1, GetNumGuildBankTabs() do
Zerotorescue@84 310 local isViewable = select(3, GetGuildBankTabInfo(tabId));
Zerotorescue@84 311 if isViewable == 1 then
Zerotorescue@84 312 QueryGuildBankTab(tabId);
Zerotorescue@84 313 end
Zerotorescue@84 314 end
Zerotorescue@84 315
Zerotorescue@84 316 self:RegisterEvent("GUILDBANKFRAME_CLOSED");
Zerotorescue@84 317 self:RegisterEvent("GUILDBANKBAGSLOTS_CHANGED");
Zerotorescue@80 318 end
Zerotorescue@80 319
Zerotorescue@80 320 function mod:OnEnable()
Zerotorescue@80 321 -- Scan once when the bankframe is opened
Zerotorescue@84 322 self:RegisterEvent("BANKFRAME_OPENED");
Zerotorescue@84 323 self:RegisterEvent("GUILDBANKFRAME_OPENED");
Zerotorescue@80 324
Zerotorescue@80 325 Mover = addon:GetModule("Mover");
Zerotorescue@101 326
Zerotorescue@101 327 if not InventoriumItemMover then
Zerotorescue@101 328 addon:CreateMoverFrame(OnMoveAccept, OnMoveCancel);
Zerotorescue@101 329 end
Zerotorescue@80 330 end
Zerotorescue@80 331
Zerotorescue@80 332 function mod:OnDisable()
Zerotorescue@80 333 Mover = nil;
Zerotorescue@101 334 currentLocation = nil;
Zerotorescue@101 335 paused = nil;
Zerotorescue@80 336
Zerotorescue@80 337 -- Bank
Zerotorescue@84 338 self:UnregisterEvent("BANKFRAME_OPENED");
Zerotorescue@80 339
Zerotorescue@80 340 -- Guild
Zerotorescue@84 341 self:GUILDBANKFRAME_CLOSED();
Zerotorescue@84 342 self:UnregisterEvent("GUILDBANKFRAME_OPENED");
Zerotorescue@80 343 end
Zerotorescue@80 344
Zerotorescue@80 345 function mod:Pause()
Zerotorescue@80 346 paused = true;
Zerotorescue@80 347 end
Zerotorescue@80 348
Zerotorescue@80 349 function mod:Unpause()
Zerotorescue@80 350 paused = nil;
Zerotorescue@80 351 end