annotate Modules/Scanner.lua @ 104:8502f02bf543

Increased edge size to make them more visible. Item mover window is no longer setting point to itself. Lowered description position so it doesn?t overlap the title.
author Zerotorescue
date Tue, 11 Jan 2011 23:13:40 +0100
parents 6ae44d372360
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