annotate 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
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@106 175 -- This table is never copied, just referenced. It is the same for every row.
Zerotorescue@101 176 local columns = {
Zerotorescue@101 177 {
Zerotorescue@106 178 value = function(data, cols, realrow, column, table)
Zerotorescue@106 179 return IdToItemLink(data[realrow].rowData.id);
Zerotorescue@101 180 end,
Zerotorescue@101 181 }, -- item
Zerotorescue@101 182 {
Zerotorescue@106 183 value = function(data, cols, realrow, column, table)
Zerotorescue@106 184 return data[realrow].rowData.num;
Zerotorescue@101 185 end,
Zerotorescue@101 186 }, -- moving
Zerotorescue@101 187 {
Zerotorescue@106 188 value = function(data, cols, realrow, column, table)
Zerotorescue@106 189 return addon:DisplayItemCount(data[realrow].rowData.available, data[realrow].rowData.missing); -- available / missing
Zerotorescue@101 190 end,
Zerotorescue@106 191 color = function(data, cols, realrow, column, table)
Zerotorescue@106 192 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 };
Zerotorescue@101 193 end,
Zerotorescue@106 194 }, -- missing / available
Zerotorescue@101 195 };
Zerotorescue@101 196
Zerotorescue@106 197 -- Store the list with rows in this
Zerotorescue@106 198 local data = {};
Zerotorescue@101 199
Zerotorescue@101 200 for i, move in pairs(Mover:GetMoves()) do
Zerotorescue@106 201 table.insert(data, {
Zerotorescue@106 202 ["rowData"] = move, -- this is not a key usually found in a row item and ignored by the library
Zerotorescue@101 203 ["cols"] = columns,
Zerotorescue@106 204 });
Zerotorescue@101 205 end
Zerotorescue@101 206
Zerotorescue@101 207 addon:SetMoverFrameData(data);
Zerotorescue@101 208 end
Zerotorescue@81 209 end
Zerotorescue@81 210 end
Zerotorescue@81 211
Zerotorescue@84 212
Zerotorescue@84 213
Zerotorescue@84 214 -- Events
Zerotorescue@84 215
Zerotorescue@84 216 -- Player bank
Zerotorescue@84 217
Zerotorescue@84 218 function mod:BANKFRAME_OPENED()
Zerotorescue@84 219 addon:Debug("Scanner:BANKFRAME_OPENED");
Zerotorescue@84 220
Zerotorescue@84 221 mod:RegisterEvent("BANKFRAME_CLOSED");
Zerotorescue@84 222
Zerotorescue@84 223 -- Scan once when the bank is opened, but no need to scan after
Zerotorescue@84 224 mod:Scan(addon.Locations.Bank);
Zerotorescue@84 225 end
Zerotorescue@84 226
Zerotorescue@84 227 function mod:BANKFRAME_CLOSED()
Zerotorescue@81 228 addon:Debug("Scanner:BANKFRAME_CLOSED");
Zerotorescue@81 229
Zerotorescue@89 230 self:ClearCache();
Zerotorescue@89 231
Zerotorescue@81 232 mod:UnregisterEvent("BANKFRAME_CLOSED");
Zerotorescue@81 233
Zerotorescue@101 234 InventoriumItemMover:Hide();
Zerotorescue@101 235 Mover:ResetQueue();
Zerotorescue@80 236 end
Zerotorescue@80 237
Zerotorescue@84 238 -- Guild bank
Zerotorescue@84 239
Zerotorescue@84 240 local tmrScanGuild, scanned;
Zerotorescue@84 241 function mod:GUILDBANKBAGSLOTS_CHANGED()
Zerotorescue@84 242 -- This event is spammed the first time the guild bank is opened
Zerotorescue@84 243 if not scanned then
Zerotorescue@84 244 self:CancelTimer(tmrScanGuild, true); -- silent
Zerotorescue@84 245 tmrScanGuild = self:ScheduleTimer("DoScanGuild", 1);
Zerotorescue@84 246 end
Zerotorescue@80 247 end
Zerotorescue@80 248
Zerotorescue@84 249 function mod:DoScanGuild()
Zerotorescue@84 250 if not scanned then
Zerotorescue@89 251 addon:Debug("Scanner:DoScanGuild");
Zerotorescue@84 252
Zerotorescue@84 253 scanned = true;
Zerotorescue@84 254
Zerotorescue@84 255 self:Scan(addon.Locations.Guild);
Zerotorescue@84 256 end
Zerotorescue@84 257 end
Zerotorescue@80 258
Zerotorescue@84 259 function mod:GUILDBANKFRAME_CLOSED()
Zerotorescue@81 260 addon:Debug("Scanner:GUILDBANKFRAME_CLOSED");
Zerotorescue@81 261
Zerotorescue@84 262 scanned = nil;
Zerotorescue@89 263 self:ClearCache();
Zerotorescue@81 264
Zerotorescue@84 265 self:UnregisterEvent("GUILDBANKFRAME_CLOSED");
Zerotorescue@84 266 self:UnregisterEvent("GUILDBANKBAGSLOTS_CHANGED");
Zerotorescue@84 267
Zerotorescue@84 268 self:CancelTimer(tmrScanGuild, true); -- silent
Zerotorescue@80 269
Zerotorescue@101 270 InventoriumItemMover:Hide();
Zerotorescue@101 271 Mover:ResetQueue();
Zerotorescue@80 272 end
Zerotorescue@80 273
Zerotorescue@84 274 function mod:GUILDBANKFRAME_OPENED()
Zerotorescue@81 275 addon:Debug("Scanner:GUILDBANKFRAME_OPENED");
Zerotorescue@81 276
Zerotorescue@84 277 scanned = nil;
Zerotorescue@80 278
Zerotorescue@84 279 -- Get the contents for every tab into our cache
Zerotorescue@84 280 for tabId = 1, GetNumGuildBankTabs() do
Zerotorescue@84 281 local isViewable = select(3, GetGuildBankTabInfo(tabId));
Zerotorescue@84 282 if isViewable == 1 then
Zerotorescue@84 283 QueryGuildBankTab(tabId);
Zerotorescue@84 284 end
Zerotorescue@84 285 end
Zerotorescue@84 286
Zerotorescue@84 287 self:RegisterEvent("GUILDBANKFRAME_CLOSED");
Zerotorescue@84 288 self:RegisterEvent("GUILDBANKBAGSLOTS_CHANGED");
Zerotorescue@80 289 end
Zerotorescue@80 290
Zerotorescue@80 291 function mod:OnEnable()
Zerotorescue@80 292 -- Scan once when the bankframe is opened
Zerotorescue@84 293 self:RegisterEvent("BANKFRAME_OPENED");
Zerotorescue@84 294 self:RegisterEvent("GUILDBANKFRAME_OPENED");
Zerotorescue@80 295
Zerotorescue@80 296 Mover = addon:GetModule("Mover");
Zerotorescue@101 297
Zerotorescue@101 298 if not InventoriumItemMover then
Zerotorescue@101 299 addon:CreateMoverFrame(OnMoveAccept, OnMoveCancel);
Zerotorescue@101 300 end
Zerotorescue@80 301 end
Zerotorescue@80 302
Zerotorescue@80 303 function mod:OnDisable()
Zerotorescue@80 304 Mover = nil;
Zerotorescue@101 305 currentLocation = nil;
Zerotorescue@101 306 paused = nil;
Zerotorescue@80 307
Zerotorescue@80 308 -- Bank
Zerotorescue@84 309 self:UnregisterEvent("BANKFRAME_OPENED");
Zerotorescue@80 310
Zerotorescue@80 311 -- Guild
Zerotorescue@84 312 self:GUILDBANKFRAME_CLOSED();
Zerotorescue@84 313 self:UnregisterEvent("GUILDBANKFRAME_OPENED");
Zerotorescue@80 314 end
Zerotorescue@80 315
Zerotorescue@80 316 function mod:Pause()
Zerotorescue@80 317 paused = true;
Zerotorescue@80 318 end
Zerotorescue@80 319
Zerotorescue@80 320 function mod:Unpause()
Zerotorescue@80 321 paused = nil;
Zerotorescue@80 322 end