annotate Modules/Scanner.lua @ 143:8eb0f5b5a885

Fixed ?fully stocked? tooltip to say it uses the restock target setting rather than the global stock setting. Making sure the inventorium queuer frame is available before hiding it. Fixed an error with queueing items. Skip reasons are now sorted by importance (also by default). Now closing the queue window when you close your profession window.
author Zerotorescue
date Tue, 18 Jan 2011 23:48:16 +0100
parents 56f33abee1e3
children 12a8ea5af671
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@122 4 local _G = _G;
Zerotorescue@122 5 local select, pairs = _G.select, _G.pairs;
Zerotorescue@122 6 local twipe, tinsert, mceil = _G.table.wipe, _G.table.insert, _G.math.ceil;
Zerotorescue@122 7
Zerotorescue@101 8 local Mover, paused, currentLocation;
Zerotorescue@80 9 local itemCache = {};
Zerotorescue@80 10
Zerotorescue@110 11 local function OnMoveAccept()
Zerotorescue@101 12 mod:Pause();
Zerotorescue@101 13 Mover:BeginMove(currentLocation, mod.Unpause);
Zerotorescue@101 14
Zerotorescue@142 15 if InventoriumItemMover then
Zerotorescue@142 16 InventoriumItemMover:Hide();
Zerotorescue@142 17 end
Zerotorescue@101 18 end
Zerotorescue@101 19
Zerotorescue@110 20 local function OnMoveCancel()
Zerotorescue@101 21 Mover:ResetQueue();
Zerotorescue@101 22 currentLocation = nil;
Zerotorescue@101 23
Zerotorescue@142 24 if InventoriumItemMover then
Zerotorescue@142 25 InventoriumItemMover:Hide();
Zerotorescue@142 26 end
Zerotorescue@101 27 end
Zerotorescue@101 28
Zerotorescue@119 29 local function GetSmallCoinTextureString(coins)
Zerotorescue@119 30 if coins >= 10000000 then
Zerotorescue@119 31 -- When we have1000g, hide silver and copper
Zerotorescue@122 32 coins = (mceil(coins / 10000) * 10000);
Zerotorescue@119 33 elseif coins >= 10000 then
Zerotorescue@119 34 -- When we have 1g, hide copper
Zerotorescue@122 35 coins = (mceil(coins / 100) * 100);
Zerotorescue@119 36 end
Zerotorescue@119 37
Zerotorescue@119 38 return GetCoinTextureString(coins);
Zerotorescue@119 39 end
Zerotorescue@119 40
Zerotorescue@119 41 -- Refill moves window: refill form storage such as the bank, guild bank and mailbox
Zerotorescue@111 42 local function UseStorageRefillST()
Zerotorescue@142 43 if not InventoriumItemMover then
Zerotorescue@142 44 addon:CreateMoverFrame();
Zerotorescue@142 45 end
Zerotorescue@142 46
Zerotorescue@110 47 local frame = InventoriumItemMover; -- both for speed as code-consistency
Zerotorescue@110 48
Zerotorescue@110 49 -- Scrolling table with a list of items to be moved
Zerotorescue@110 50 local scrollTableWidth = ( frame.frmMeasureDummy:GetWidth() - 30 ); -- adjust width by the scrollbar size
Zerotorescue@110 51 local headers = {
Zerotorescue@110 52 {
Zerotorescue@110 53 ["name"] = "Item",
Zerotorescue@111 54 ["width"] = (scrollTableWidth * .60),
Zerotorescue@110 55 ["defaultsort"] = "asc",
Zerotorescue@110 56 ["comparesort"] = function(this, aRow, bRow, column)
Zerotorescue@110 57 local aName, _, aRarity = GetItemInfo(this:GetRow(aRow).rowData.itemId);
Zerotorescue@110 58 local bName, _, bRarity = GetItemInfo(this:GetRow(bRow).rowData.itemId);
Zerotorescue@110 59 local template = "%d%s";
Zerotorescue@110 60 aName = template:format((10 - (aRarity or 10)), (aName or ""):lower());
Zerotorescue@110 61 bName = template:format((10 - (bRarity or 10)), (bName or ""):lower());
Zerotorescue@110 62
Zerotorescue@110 63 if this.cols[column].sort == "dsc" then
Zerotorescue@110 64 return aName > bName;
Zerotorescue@110 65 else
Zerotorescue@110 66 return aName < bName;
Zerotorescue@110 67 end
Zerotorescue@110 68 end,
Zerotorescue@110 69 ["sort"] = "asc", -- when the data is set, use this column so sort the default data
Zerotorescue@110 70 ["tooltipTitle"] = (not addon.db.profile.defaults.hideHelp and "Item"),
Zerotorescue@110 71 ["tooltip"] = (not addon.db.profile.defaults.hideHelp and "Click to sort the list by item quality then item name."),
Zerotorescue@110 72 },
Zerotorescue@110 73 {
Zerotorescue@110 74 ["name"] = "Moving",
Zerotorescue@110 75 ["width"] = (scrollTableWidth * .15),
Zerotorescue@110 76 ["align"] = "RIGHT",
Zerotorescue@110 77 ["defaultsort"] = "dsc",
Zerotorescue@110 78 ["sortnext"] = 1,
Zerotorescue@110 79 ["tooltipTitle"] = (not addon.db.profile.defaults.hideHelp and "Moving"),
Zerotorescue@110 80 ["tooltip"] = (not addon.db.profile.defaults.hideHelp and "Click to sort the list by the amount of movable items."),
Zerotorescue@110 81 },
Zerotorescue@110 82 {
Zerotorescue@110 83 ["name"] = "Available",
Zerotorescue@111 84 ["width"] = (scrollTableWidth * .25),
Zerotorescue@110 85 ["align"] = "RIGHT",
Zerotorescue@110 86 ["defaultsort"] = "dsc",
Zerotorescue@110 87 ["sortnext"] = 1,
Zerotorescue@110 88 ["comparesort"] = function(this, aRow, bRow, column)
Zerotorescue@110 89 local aAvailablePercent = (this:GetRow(aRow).rowData.available / this:GetRow(aRow).rowData.missing);
Zerotorescue@110 90 local bAvailablePercent = (this:GetRow(bRow).rowData.available / this:GetRow(bRow).rowData.missing);
Zerotorescue@110 91
Zerotorescue@110 92 if this.cols[column].sort == "dsc" then
Zerotorescue@110 93 return aAvailablePercent > bAvailablePercent;
Zerotorescue@110 94 else
Zerotorescue@110 95 return aAvailablePercent < bAvailablePercent;
Zerotorescue@110 96 end
Zerotorescue@110 97 end,
Zerotorescue@110 98 ["tooltipTitle"] = (not addon.db.profile.defaults.hideHelp and "Item"),
Zerotorescue@110 99 ["tooltip"] = (not addon.db.profile.defaults.hideHelp and "Click to sort the list by the availibility percentage."),
Zerotorescue@110 100 },
Zerotorescue@110 101 };
Zerotorescue@110 102
Zerotorescue@110 103 local proceedButton = {
Zerotorescue@110 104 text = "Move Items",
Zerotorescue@110 105 tooltipTitle = (not addon.db.profile.defaults.hideHelp and "Move Items"),
Zerotorescue@110 106 tooltip = (not addon.db.profile.defaults.hideHelp and "Start moving these items from the bank."),
Zerotorescue@110 107 onClick = OnMoveAccept,
Zerotorescue@110 108 };
Zerotorescue@110 109 local cancelButton = {
Zerotorescue@110 110 text = "Cancel",
Zerotorescue@110 111 tooltipTitle = (not addon.db.profile.defaults.hideHelp and "Cancel"),
Zerotorescue@110 112 tooltip = (not addon.db.profile.defaults.hideHelp and "Do not move anything and close the window."),
Zerotorescue@110 113 onClick = OnMoveCancel,
Zerotorescue@110 114 };
Zerotorescue@110 115
Zerotorescue@132 116 addon:SetMoverFrameSettings("Inventorium Storage Refill", "The items listed below can be refilled from this location, do you wish to move them to your bags?", proceedButton, cancelButton, headers);
Zerotorescue@119 117 end
Zerotorescue@119 118
Zerotorescue@119 119 -- Merchant restock window: restock from a merchant by buying items needed
Zerotorescue@119 120 local function UseMerchantRestockST(totalCost)
Zerotorescue@142 121 if not InventoriumItemMover then
Zerotorescue@142 122 addon:CreateMoverFrame();
Zerotorescue@142 123 end
Zerotorescue@142 124
Zerotorescue@119 125 local frame = InventoriumItemMover; -- both for speed as code-consistency
Zerotorescue@119 126
Zerotorescue@119 127 -- Scrolling table with a list of items to be moved
Zerotorescue@119 128 local scrollTableWidth = ( frame.frmMeasureDummy:GetWidth() - 30 ); -- adjust width by the scrollbar size
Zerotorescue@119 129 local headers = {
Zerotorescue@119 130 {
Zerotorescue@119 131 ["name"] = "Item",
Zerotorescue@119 132 ["width"] = (scrollTableWidth * .60),
Zerotorescue@119 133 ["defaultsort"] = "asc",
Zerotorescue@119 134 ["comparesort"] = function(this, aRow, bRow, column)
Zerotorescue@119 135 local aName, _, aRarity = GetItemInfo(this:GetRow(aRow).rowData.itemId);
Zerotorescue@119 136 local bName, _, bRarity = GetItemInfo(this:GetRow(bRow).rowData.itemId);
Zerotorescue@119 137 local template = "%d%s";
Zerotorescue@119 138 aName = template:format((10 - (aRarity or 10)), (aName or ""):lower());
Zerotorescue@119 139 bName = template:format((10 - (bRarity or 10)), (bName or ""):lower());
Zerotorescue@119 140
Zerotorescue@119 141 if this.cols[column].sort == "dsc" then
Zerotorescue@119 142 return aName > bName;
Zerotorescue@119 143 else
Zerotorescue@119 144 return aName < bName;
Zerotorescue@119 145 end
Zerotorescue@119 146 end,
Zerotorescue@119 147 ["sort"] = "asc", -- when the data is set, use this column so sort the default data
Zerotorescue@119 148 ["tooltipTitle"] = (not addon.db.profile.defaults.hideHelp and "Item"),
Zerotorescue@119 149 ["tooltip"] = (not addon.db.profile.defaults.hideHelp and "Click to sort the list by item quality then item name."),
Zerotorescue@119 150 },
Zerotorescue@119 151 {
Zerotorescue@119 152 ["name"] = "Buying",
Zerotorescue@119 153 ["width"] = (scrollTableWidth * .20),
Zerotorescue@119 154 ["align"] = "RIGHT",
Zerotorescue@119 155 ["defaultsort"] = "dsc",
Zerotorescue@119 156 ["sortnext"] = 1,
Zerotorescue@119 157 ["tooltipTitle"] = (not addon.db.profile.defaults.hideHelp and "Buying"),
Zerotorescue@119 158 ["tooltip"] = (not addon.db.profile.defaults.hideHelp and "Click to sort the list by the amount of purchasable items."),
Zerotorescue@119 159 },
Zerotorescue@119 160 {
Zerotorescue@119 161 ["name"] = "Cost",
Zerotorescue@119 162 ["width"] = (scrollTableWidth * .20),
Zerotorescue@119 163 ["align"] = "RIGHT",
Zerotorescue@119 164 ["defaultsort"] = "dsc",
Zerotorescue@119 165 ["sortnext"] = 1,
Zerotorescue@119 166 ["tooltipTitle"] = (not addon.db.profile.defaults.hideHelp and "Cost"),
Zerotorescue@119 167 ["tooltip"] = (not addon.db.profile.defaults.hideHelp and "Click to sort the list by the total cost of buying all these items."),
Zerotorescue@119 168 },
Zerotorescue@119 169 };
Zerotorescue@119 170
Zerotorescue@119 171 local proceedButton = {
Zerotorescue@119 172 text = "Purchase Items",
Zerotorescue@119 173 tooltipTitle = (not addon.db.profile.defaults.hideHelp and "Purchase Items"),
Zerotorescue@119 174 tooltip = (not addon.db.profile.defaults.hideHelp and "Start purchasing these items from this merchant."),
Zerotorescue@119 175 onClick = OnMoveAccept,
Zerotorescue@119 176 };
Zerotorescue@119 177 local cancelButton = {
Zerotorescue@119 178 text = "Cancel",
Zerotorescue@119 179 tooltipTitle = (not addon.db.profile.defaults.hideHelp and "Cancel"),
Zerotorescue@119 180 tooltip = (not addon.db.profile.defaults.hideHelp and "Do not purchase anything and close the window."),
Zerotorescue@119 181 onClick = OnMoveCancel,
Zerotorescue@119 182 };
Zerotorescue@119 183
Zerotorescue@132 184 addon:SetMoverFrameSettings("Inventorium Merchant Restock", ("The following items can be restocked from this merchant for a total of %s. Do you wish to proceed?"):format(GetSmallCoinTextureString(totalCost)), proceedButton, cancelButton, headers);
Zerotorescue@110 185 end
Zerotorescue@110 186
Zerotorescue@80 187 function mod:ClearCache()
Zerotorescue@122 188 twipe(itemCache);
Zerotorescue@80 189 end
Zerotorescue@80 190
Zerotorescue@80 191 function mod:CacheLocation(location, remember)
Zerotorescue@89 192 -- Reset cache just in case it was filled
Zerotorescue@89 193 self:ClearCache();
Zerotorescue@89 194
Zerotorescue@80 195 if location == addon.Locations.Bag or location == addon.Locations.Bank then
Zerotorescue@80 196 local start, stop;
Zerotorescue@80 197 if location == addon.Locations.Bag then
Zerotorescue@80 198 start = 0;
Zerotorescue@80 199 stop = NUM_BAG_SLOTS;
Zerotorescue@80 200 else
Zerotorescue@80 201 -- If we requested the bank then we don't want the bag info
Zerotorescue@80 202 start = ( NUM_BAG_SLOTS + 1 );
Zerotorescue@80 203 stop = ( NUM_BAG_SLOTS + NUM_BANKBAGSLOTS );
Zerotorescue@80 204 end
Zerotorescue@80 205
Zerotorescue@80 206 -- Go through all our bags, including the backpack
Zerotorescue@81 207 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 208 -- Scan the default 100 slots whenever we're at a non-existing index
Zerotorescue@80 209 local bagId = (i == (stop + 1) and BANK_CONTAINER) or i;
Zerotorescue@80 210 local slotId = GetContainerNumSlots(bagId);
Zerotorescue@80 211
Zerotorescue@80 212 while slotId ~= 0 do
Zerotorescue@80 213 -- A not equal-comparison should be quicker than a larger than-comparison
Zerotorescue@80 214
Zerotorescue@80 215 local itemId = GetContainerItemID(bagId, slotId);
Zerotorescue@80 216 local itemCount = itemId and select(2, GetContainerItemInfo(bagId, slotId));
Zerotorescue@80 217
Zerotorescue@80 218 if itemId and itemCount and itemCount > 0 then
Zerotorescue@119 219 local containerItem;
Zerotorescue@80 220 if not itemCache[itemId] then
Zerotorescue@80 221 -- If this is the first time we see this item, make a new object
Zerotorescue@119 222 containerItem = addon.ContainerItem:New();
Zerotorescue@119 223 itemCache[itemId] = containerItem;
Zerotorescue@80 224 else
Zerotorescue@80 225 -- If we had this item in another slot too
Zerotorescue@119 226 containerItem = itemCache[itemId];
Zerotorescue@80 227 end
Zerotorescue@80 228
Zerotorescue@119 229 containerItem:AddLocation(bagId, slotId, itemCount);
Zerotorescue@80 230 end
Zerotorescue@80 231
Zerotorescue@80 232 -- Continue scanning a different slot
Zerotorescue@80 233 slotId = (slotId - 1);
Zerotorescue@80 234 end
Zerotorescue@80 235 end
Zerotorescue@80 236 elseif location == addon.Locations.Guild then
Zerotorescue@84 237 for tabId = 1, GetNumGuildBankTabs() do
Zerotorescue@110 238 local _, _, isViewable, _, _, remainingWithdrawals = GetGuildBankTabInfo(tabId);
Zerotorescue@80 239
Zerotorescue@110 240 if isViewable and (remainingWithdrawals > 0 or remainingWithdrawals == -1) then
Zerotorescue@84 241 local slotId = (MAX_GUILDBANK_SLOTS_PER_TAB or 98); -- start by scanning the last slot
Zerotorescue@80 242
Zerotorescue@84 243 while slotId ~= 0 do
Zerotorescue@84 244 -- A not equal-comparison should be quicker than a larger than-comparison
Zerotorescue@84 245
Zerotorescue@84 246 local itemLink = GetGuildBankItemLink(tabId, slotId);
Zerotorescue@95 247 local itemId = itemLink and addon:GetItemId(itemLink);
Zerotorescue@84 248 local itemCount = itemLink and select(2, GetGuildBankItemInfo(tabId, slotId));
Zerotorescue@84 249
Zerotorescue@84 250 if itemLink and itemId and itemCount and itemCount > 0 then
Zerotorescue@84 251 -- If there is actually an item in this slot
Zerotorescue@119 252 local containerItem;
Zerotorescue@84 253 if not itemCache[itemId] then
Zerotorescue@84 254 -- If this is the first time we see this item, make a new object
Zerotorescue@119 255 containerItem = addon.ContainerItem:New();
Zerotorescue@119 256 itemCache[itemId] = containerItem;
Zerotorescue@84 257 else
Zerotorescue@84 258 -- If we had this item in another slot too
Zerotorescue@119 259 containerItem = itemCache[itemId];
Zerotorescue@84 260 end
Zerotorescue@84 261
Zerotorescue@119 262 containerItem:AddLocation(tabId, slotId, itemCount);
Zerotorescue@84 263 end
Zerotorescue@84 264
Zerotorescue@84 265 -- Continue scanning a different slot
Zerotorescue@84 266 slotId = (slotId - 1);
Zerotorescue@80 267 end
Zerotorescue@80 268 end
Zerotorescue@80 269 end
Zerotorescue@110 270 elseif location == addon.Locations.Mailbox then
Zerotorescue@110 271 for mailIndex = 1, GetInboxNumItems() do
Zerotorescue@110 272 -- All mail items
Zerotorescue@110 273
Zerotorescue@110 274 for attachIndex = 1, ATTACHMENTS_MAX_RECEIVE do
Zerotorescue@110 275 -- All attachments
Zerotorescue@110 276
Zerotorescue@110 277 local itemLink = GetInboxItemLink(mailIndex, attachIndex);
Zerotorescue@110 278 local itemId = itemLink and addon:GetItemId(itemLink);
Zerotorescue@110 279 local itemCount = itemLink and select(3, GetInboxItem(mailIndex, attachIndex));
Zerotorescue@110 280
Zerotorescue@110 281 if itemLink and itemId and itemCount and itemCount > 0 then
Zerotorescue@119 282 local containerItem;
Zerotorescue@110 283 if not itemCache[itemId] then
Zerotorescue@110 284 -- If this is the first time we see this item, make a new object
Zerotorescue@119 285 containerItem = addon.ContainerItem:New();
Zerotorescue@119 286 itemCache[itemId] = containerItem;
Zerotorescue@110 287 else
Zerotorescue@110 288 -- If we had this item in another slot too
Zerotorescue@119 289 containerItem = itemCache[itemId];
Zerotorescue@110 290 end
Zerotorescue@110 291
Zerotorescue@119 292 containerItem:AddLocation(mailIndex, attachIndex, itemCount);
Zerotorescue@110 293 end
Zerotorescue@110 294 end
Zerotorescue@110 295 end
Zerotorescue@119 296 elseif location == addon.Locations.Merchant then
Zerotorescue@119 297 for itemIndex = 1, GetMerchantNumItems() do
Zerotorescue@119 298 -- All merchant items
Zerotorescue@119 299
Zerotorescue@119 300 local itemLink = GetMerchantItemLink(itemIndex);
Zerotorescue@119 301 local itemId = itemLink and addon:GetItemId(itemLink);
Zerotorescue@119 302 local _, _, vendorValue, quantity, numAvailable, _, extendedCost = GetMerchantItemInfo(itemIndex);
Zerotorescue@119 303
Zerotorescue@119 304 if itemLink and itemId and numAvailable ~= 0 and not extendedCost then
Zerotorescue@119 305 local containerItem;
Zerotorescue@119 306 if not itemCache[itemId] then
Zerotorescue@119 307 -- If this is the first time we see this item, make a new object
Zerotorescue@119 308 containerItem = addon.ContainerItem:New();
Zerotorescue@119 309 containerItem.price = (vendorValue / quantity); -- remember the price for this item. We assume it's the same for this entire item id
Zerotorescue@119 310
Zerotorescue@119 311 itemCache[itemId] = containerItem;
Zerotorescue@119 312 else
Zerotorescue@119 313 -- If we had this item in another slot too
Zerotorescue@119 314 containerItem = itemCache[itemId];
Zerotorescue@119 315 end
Zerotorescue@119 316
Zerotorescue@119 317 containerItem:AddLocation(1, itemIndex, numAvailable);
Zerotorescue@119 318 end
Zerotorescue@119 319 end
Zerotorescue@80 320 else
Zerotorescue@119 321 error("Invalid location provided for CacheLocation.");
Zerotorescue@80 322 end
Zerotorescue@80 323
Zerotorescue@80 324 if not remember then
Zerotorescue@80 325 -- Copy the table as clearing the cache wipes it empty (and tables are passed by reference)
Zerotorescue@80 326 local cacheCopy = CopyTable(itemCache);
Zerotorescue@80 327
Zerotorescue@80 328 self:ClearCache();
Zerotorescue@80 329
Zerotorescue@80 330 return cacheCopy;
Zerotorescue@80 331 end
Zerotorescue@80 332 end
Zerotorescue@80 333
Zerotorescue@80 334 function mod:Scan(location)
Zerotorescue@80 335 -- We might pause the scanning when we invoke moves ourself
Zerotorescue@80 336 if paused then
Zerotorescue@110 337 addon:Debug("Not scanning; paused...");
Zerotorescue@80 338 return;
Zerotorescue@80 339 end
Zerotorescue@80 340
Zerotorescue@80 341 local playerName = UnitName("player");
Zerotorescue@80 342
Zerotorescue@101 343 currentLocation = location;
Zerotorescue@80 344 self:CacheLocation(location, true);
Zerotorescue@80 345
Zerotorescue@110 346 -- Ensure previous queue isn't remaining
Zerotorescue@110 347 Mover:ResetQueue();
Zerotorescue@110 348
Zerotorescue@119 349 -- Restock = obtaining more, refill = merely moving local. IsRestock = are we buying/making more?
Zerotorescue@119 350 local isRestock = (location == addon.Locations.Merchant);
Zerotorescue@119 351
Zerotorescue@80 352 -- Go through all groups
Zerotorescue@80 353 for groupName, values in pairs(addon.db.profile.groups) do
Zerotorescue@119 354 -- Settings
Zerotorescue@80 355 local trackAt = addon:GetOptionByKey(groupName, "trackAtCharacters");
Zerotorescue@84 356 local localItemData = addon:GetOptionByKey(groupName, "localItemData");
Zerotorescue@123 357 local requiredItems, bonusQueue, minCraftingQueue, isRefillEnabled;
Zerotorescue@123 358 if isRestock then
Zerotorescue@123 359 requiredItems = addon:GetOptionByKey(groupName, "restockTarget");
Zerotorescue@123 360 bonusQueue = addon:GetOptionByKey(groupName, "bonusQueue");
Zerotorescue@123 361 minCraftingQueue = floor( addon:GetOptionByKey(groupName, "minCraftingQueue") * requiredItems ); -- If the minCraftingQueue is 5% and restockTarget is 60, this will result in 3
Zerotorescue@123 362 else
Zerotorescue@123 363 isRefillEnabled = addon:GetOptionByKey(groupName, "autoRefill");
Zerotorescue@123 364 requiredItems = addon:GetOptionByKey(groupName, "minLocalStock");
Zerotorescue@123 365 end
Zerotorescue@80 366
Zerotorescue@119 367 local isTracked = (trackAt and trackAt[playerName]); -- Is this character interested in this data?
Zerotorescue@119 368 local isConsideredLocal = (localItemData and localItemData[location]); -- if this location was checked as local storage, don't refill from it
Zerotorescue@119 369
Zerotorescue@123 370 if values.items and isTracked and (isRestock or isRefillEnabled) and not isConsideredLocal then
Zerotorescue@119 371 addon:Debug("Scanning |cff00ff00%s|r", groupName);
Zerotorescue@80 372
Zerotorescue@80 373 for itemId, _ in pairs(values.items) do
Zerotorescue@119 374 -- Find this item in the source
Zerotorescue@119 375 local containerItem = itemCache[itemId];
Zerotorescue@80 376
Zerotorescue@119 377 if containerItem then
Zerotorescue@119 378 -- Only do all the CPU intensive checks if this item is available
Zerotorescue@80 379
Zerotorescue@119 380 -- When restocking use the global item count, when refilling use the local
Zerotorescue@119 381 local currentItemCount = ((isRestock and addon:GetItemCount(itemId, groupName)) or addon:GetLocalItemCount(itemId, groupName));
Zerotorescue@119 382
Zerotorescue@119 383 -- Check if we have enough items local (but only do so if this location also has enough available)
Zerotorescue@119 384 local missingItems = (requiredItems - currentItemCount);
Zerotorescue@119 385
Zerotorescue@123 386 if isRestock and currentItemCount == 0 and bonusQueue and bonusQueue > 0 then
Zerotorescue@123 387 -- If we have none left and the bonus queue is enabled, modify the amount to be queued
Zerotorescue@123 388
Zerotorescue@123 389 missingItems = floor( ( missingItems * ( bonusQueue + 1 ) ) + .5 ); -- round
Zerotorescue@123 390 end
Zerotorescue@123 391
Zerotorescue@123 392 if missingItems > 0 and (not isRestock or missingItems >= minCraftingQueue) then
Zerotorescue@119 393 -- Check how many are available
Zerotorescue@119 394 local availableItems = ((containerItem.totalCount) or 0);
Zerotorescue@119 395 -- Calculate how many we'll be moving (less missing than available? use missing, otherwise use available)
Zerotorescue@119 396 -- -1 available items indicates unlimited amount, in that case we must cap at missing items
Zerotorescue@119 397 local moving = (((availableItems == -1 or missingItems <= availableItems) and missingItems) or availableItems);
Zerotorescue@80 398
Zerotorescue@119 399 if availableItems == -1 or availableItems > 0 then
Zerotorescue@119 400 addon:Debug("Insufficient %s but this location has %d (moving %d)", IdToItemLink(itemId), availableItems, moving);
Zerotorescue@119 401
Zerotorescue@119 402 Mover:AddMove(itemId, moving, missingItems, availableItems, containerItem.price);
Zerotorescue@119 403 end
Zerotorescue@80 404 end
Zerotorescue@80 405 end
Zerotorescue@80 406 end
Zerotorescue@80 407 end
Zerotorescue@80 408 end
Zerotorescue@80 409
Zerotorescue@80 410 self:ClearCache();
Zerotorescue@80 411
Zerotorescue@81 412 if Mover:HasMoves() then
Zerotorescue@101 413 if addon.db.profile.defaults.autoRefillSkipConfirm then
Zerotorescue@110 414 OnMoveAccept();
Zerotorescue@101 415 else
Zerotorescue@119 416 local moves = Mover:GetMoves();
Zerotorescue@110 417
Zerotorescue@106 418 -- This table is never copied, just referenced. It is the same for every row.
Zerotorescue@119 419 local columns;
Zerotorescue@119 420
Zerotorescue@119 421 if isRestock then
Zerotorescue@119 422 local totalCost = 0;
Zerotorescue@119 423 for _, move in pairs(moves) do
Zerotorescue@119 424 totalCost = (totalCost + (move.cost * move.num));
Zerotorescue@119 425 end
Zerotorescue@119 426 UseMerchantRestockST(totalCost);
Zerotorescue@119 427
Zerotorescue@119 428 columns = {
Zerotorescue@119 429 {
Zerotorescue@119 430 ["value"] = function(data, cols, realrow, column, table)
Zerotorescue@119 431 return IdToItemLink(data[realrow].rowData.itemId);
Zerotorescue@119 432 end,
Zerotorescue@119 433 }, -- item
Zerotorescue@119 434 {
Zerotorescue@119 435 ["value"] = function(data, cols, realrow, column, table)
Zerotorescue@119 436 return data[realrow].rowData.num;
Zerotorescue@119 437 end,
Zerotorescue@119 438 }, -- buying
Zerotorescue@119 439 {
Zerotorescue@119 440 ["value"] = function(data, cols, realrow, column, table)
Zerotorescue@119 441 return GetSmallCoinTextureString((data[realrow].rowData.cost * data[realrow].rowData.num));
Zerotorescue@119 442 end,
Zerotorescue@119 443 }, -- cost
Zerotorescue@119 444 };
Zerotorescue@119 445 else
Zerotorescue@119 446 UseStorageRefillST();
Zerotorescue@119 447
Zerotorescue@119 448 columns = {
Zerotorescue@119 449 {
Zerotorescue@119 450 ["value"] = function(data, cols, realrow, column, table)
Zerotorescue@119 451 return IdToItemLink(data[realrow].rowData.itemId);
Zerotorescue@119 452 end,
Zerotorescue@119 453 }, -- item
Zerotorescue@119 454 {
Zerotorescue@119 455 ["value"] = function(data, cols, realrow, column, table)
Zerotorescue@119 456 return data[realrow].rowData.num;
Zerotorescue@119 457 end,
Zerotorescue@119 458 }, -- moving
Zerotorescue@119 459 {
Zerotorescue@119 460 ["value"] = function(data, cols, realrow, column, table)
Zerotorescue@119 461 return addon:DisplayItemCount(data[realrow].rowData.available, data[realrow].rowData.missing); -- available / missing
Zerotorescue@119 462 end,
Zerotorescue@119 463 ["color"] = function(data, cols, realrow, column, table)
Zerotorescue@119 464 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@119 465 end,
Zerotorescue@119 466 }, -- missing / available
Zerotorescue@119 467 };
Zerotorescue@119 468 end
Zerotorescue@101 469
Zerotorescue@106 470 -- Store the list with rows in this
Zerotorescue@106 471 local data = {};
Zerotorescue@101 472
Zerotorescue@119 473 for i, move in pairs(moves) do
Zerotorescue@122 474 tinsert(data, {
Zerotorescue@106 475 ["rowData"] = move, -- this is not a key usually found in a row item and ignored by the library
Zerotorescue@101 476 ["cols"] = columns,
Zerotorescue@106 477 });
Zerotorescue@101 478 end
Zerotorescue@101 479
Zerotorescue@101 480 addon:SetMoverFrameData(data);
Zerotorescue@101 481 end
Zerotorescue@81 482 end
Zerotorescue@81 483 end
Zerotorescue@81 484
Zerotorescue@84 485
Zerotorescue@84 486
Zerotorescue@84 487 -- Events
Zerotorescue@84 488
Zerotorescue@84 489 -- Player bank
Zerotorescue@84 490
Zerotorescue@84 491 function mod:BANKFRAME_OPENED()
Zerotorescue@84 492 addon:Debug("Scanner:BANKFRAME_OPENED");
Zerotorescue@84 493
Zerotorescue@84 494 mod:RegisterEvent("BANKFRAME_CLOSED");
Zerotorescue@84 495
Zerotorescue@84 496 -- Scan once when the bank is opened, but no need to scan after
Zerotorescue@84 497 mod:Scan(addon.Locations.Bank);
Zerotorescue@84 498 end
Zerotorescue@84 499
Zerotorescue@84 500 function mod:BANKFRAME_CLOSED()
Zerotorescue@81 501 addon:Debug("Scanner:BANKFRAME_CLOSED");
Zerotorescue@81 502
Zerotorescue@89 503 self:ClearCache();
Zerotorescue@89 504
Zerotorescue@81 505 mod:UnregisterEvent("BANKFRAME_CLOSED");
Zerotorescue@81 506
Zerotorescue@137 507 if InventoriumItemMover then
Zerotorescue@137 508 InventoriumItemMover:Hide();
Zerotorescue@137 509 end
Zerotorescue@101 510 Mover:ResetQueue();
Zerotorescue@80 511 end
Zerotorescue@80 512
Zerotorescue@84 513 -- Guild bank
Zerotorescue@84 514
Zerotorescue@84 515 local tmrScanGuild, scanned;
Zerotorescue@84 516 function mod:GUILDBANKBAGSLOTS_CHANGED()
Zerotorescue@84 517 -- This event is spammed the first time the guild bank is opened
Zerotorescue@84 518 if not scanned then
Zerotorescue@84 519 self:CancelTimer(tmrScanGuild, true); -- silent
Zerotorescue@84 520 tmrScanGuild = self:ScheduleTimer("DoScanGuild", 1);
Zerotorescue@84 521 end
Zerotorescue@80 522 end
Zerotorescue@80 523
Zerotorescue@84 524 function mod:DoScanGuild()
Zerotorescue@84 525 if not scanned then
Zerotorescue@89 526 addon:Debug("Scanner:DoScanGuild");
Zerotorescue@84 527
Zerotorescue@84 528 scanned = true;
Zerotorescue@84 529
Zerotorescue@84 530 self:Scan(addon.Locations.Guild);
Zerotorescue@84 531 end
Zerotorescue@84 532 end
Zerotorescue@80 533
Zerotorescue@84 534 function mod:GUILDBANKFRAME_CLOSED()
Zerotorescue@81 535 addon:Debug("Scanner:GUILDBANKFRAME_CLOSED");
Zerotorescue@81 536
Zerotorescue@84 537 scanned = nil;
Zerotorescue@89 538 self:ClearCache();
Zerotorescue@81 539
Zerotorescue@84 540 self:UnregisterEvent("GUILDBANKFRAME_CLOSED");
Zerotorescue@84 541 self:UnregisterEvent("GUILDBANKBAGSLOTS_CHANGED");
Zerotorescue@84 542
Zerotorescue@84 543 self:CancelTimer(tmrScanGuild, true); -- silent
Zerotorescue@80 544
Zerotorescue@137 545 if InventoriumItemMover then
Zerotorescue@137 546 InventoriumItemMover:Hide();
Zerotorescue@137 547 end
Zerotorescue@101 548 Mover:ResetQueue();
Zerotorescue@80 549 end
Zerotorescue@80 550
Zerotorescue@84 551 function mod:GUILDBANKFRAME_OPENED()
Zerotorescue@81 552 addon:Debug("Scanner:GUILDBANKFRAME_OPENED");
Zerotorescue@81 553
Zerotorescue@84 554 scanned = nil;
Zerotorescue@80 555
Zerotorescue@84 556 -- Get the contents for every tab into our cache
Zerotorescue@84 557 for tabId = 1, GetNumGuildBankTabs() do
Zerotorescue@110 558 local _, _, isViewable, _, _, remainingWithdrawals = GetGuildBankTabInfo(tabId);
Zerotorescue@110 559
Zerotorescue@110 560 if isViewable and (remainingWithdrawals > 0 or remainingWithdrawals == -1) then
Zerotorescue@84 561 QueryGuildBankTab(tabId);
Zerotorescue@84 562 end
Zerotorescue@84 563 end
Zerotorescue@84 564
Zerotorescue@84 565 self:RegisterEvent("GUILDBANKFRAME_CLOSED");
Zerotorescue@84 566 self:RegisterEvent("GUILDBANKBAGSLOTS_CHANGED");
Zerotorescue@80 567 end
Zerotorescue@80 568
Zerotorescue@119 569 function mod:MERCHANT_SHOW()
Zerotorescue@119 570 addon:Debug("Scanner:MERCHANT_SHOW");
Zerotorescue@119 571
Zerotorescue@119 572 self:RegisterEvent("MERCHANT_CLOSED");
Zerotorescue@119 573
Zerotorescue@119 574 self:Scan(addon.Locations.Merchant);
Zerotorescue@119 575 end
Zerotorescue@119 576
Zerotorescue@119 577 function mod:MERCHANT_CLOSED()
Zerotorescue@119 578 addon:Debug("Scanner:MERCHANT_CLOSED");
Zerotorescue@119 579
Zerotorescue@119 580 self:ClearCache();
Zerotorescue@119 581
Zerotorescue@119 582 self:UnregisterEvent("MERCHANT_CLOSED");
Zerotorescue@119 583
Zerotorescue@137 584 if InventoriumItemMover then
Zerotorescue@137 585 InventoriumItemMover:Hide();
Zerotorescue@137 586 end
Zerotorescue@119 587 Mover:ResetQueue();
Zerotorescue@119 588 end
Zerotorescue@119 589
Zerotorescue@117 590 local previousMailCount;
Zerotorescue@117 591 function mod:MAIL_SHOW()
Zerotorescue@117 592 addon:Debug("Scanner:MAIL_SHOW");
Zerotorescue@117 593
Zerotorescue@117 594 self:RegisterEvent("MAIL_INBOX_UPDATE");
Zerotorescue@117 595 self:RegisterEvent("MAIL_CLOSED");
Zerotorescue@117 596
Zerotorescue@117 597 scanned = nil;
Zerotorescue@117 598 previousMailCount = nil;
Zerotorescue@117 599
Zerotorescue@117 600 self:Scan(addon.Locations.Mailbox);
Zerotorescue@117 601 end
Zerotorescue@110 602
Zerotorescue@117 603 function mod:MAIL_INBOX_UPDATE()
Zerotorescue@117 604 if not scanned then
Zerotorescue@117 605 addon:Debug("Scanner:MAIL_INBOX_UPDATE");
Zerotorescue@117 606
Zerotorescue@117 607 local current, total = GetInboxNumItems();
Zerotorescue@117 608
Zerotorescue@117 609 if not previousMailCount or current > previousMailCount then
Zerotorescue@117 610 -- New mail received
Zerotorescue@117 611
Zerotorescue@117 612 scanned = true;
Zerotorescue@117 613
Zerotorescue@117 614 self:Scan(addon.Locations.Mailbox);
Zerotorescue@117 615 end
Zerotorescue@117 616
Zerotorescue@117 617 -- Also remember the new mailcount when losing items, otherwise deleting item 50 and getting to 50 again wouldn't trigger a re-scan
Zerotorescue@117 618 previousMailCount = current;
Zerotorescue@117 619 else
Zerotorescue@117 620 addon:Debug("Scanner:MAIL_INBOX_UPDATE skipped, already scanned");
Zerotorescue@117 621 end
Zerotorescue@117 622 end
Zerotorescue@110 623
Zerotorescue@117 624 function mod:MAIL_CLOSED()
Zerotorescue@117 625 addon:Debug("Scanner:MAIL_CLOSED");
Zerotorescue@117 626
Zerotorescue@117 627 previousMailCount = nil;
Zerotorescue@117 628 scanned = nil;
Zerotorescue@117 629 self:ClearCache();
Zerotorescue@117 630
Zerotorescue@117 631 self:UnregisterEvent("MAIL_INBOX_UPDATE");
Zerotorescue@117 632 self:UnregisterEvent("MAIL_CLOSED");
Zerotorescue@117 633
Zerotorescue@137 634 if InventoriumItemMover then
Zerotorescue@137 635 InventoriumItemMover:Hide();
Zerotorescue@137 636 end
Zerotorescue@117 637 Mover:ResetQueue();
Zerotorescue@117 638 end
Zerotorescue@110 639
Zerotorescue@80 640 function mod:OnEnable()
Zerotorescue@80 641 -- Scan once when the bankframe is opened
Zerotorescue@84 642 self:RegisterEvent("BANKFRAME_OPENED");
Zerotorescue@84 643 self:RegisterEvent("GUILDBANKFRAME_OPENED");
Zerotorescue@117 644 self:RegisterEvent("MAIL_SHOW");
Zerotorescue@119 645 self:RegisterEvent("MERCHANT_SHOW");
Zerotorescue@80 646
Zerotorescue@80 647 Mover = addon:GetModule("Mover");
Zerotorescue@80 648 end
Zerotorescue@80 649
Zerotorescue@80 650 function mod:OnDisable()
Zerotorescue@80 651 Mover = nil;
Zerotorescue@101 652 currentLocation = nil;
Zerotorescue@101 653 paused = nil;
Zerotorescue@80 654
Zerotorescue@80 655 -- Bank
Zerotorescue@110 656 self:BANKFRAME_CLOSED();
Zerotorescue@84 657 self:UnregisterEvent("BANKFRAME_OPENED");
Zerotorescue@80 658
Zerotorescue@80 659 -- Guild
Zerotorescue@84 660 self:GUILDBANKFRAME_CLOSED();
Zerotorescue@84 661 self:UnregisterEvent("GUILDBANKFRAME_OPENED");
Zerotorescue@110 662
Zerotorescue@117 663 -- Mailbox
Zerotorescue@117 664 self:MAIL_CLOSED();
Zerotorescue@117 665 self:UnregisterEvent("MAIL_SHOW");
Zerotorescue@119 666
Zerotorescue@119 667 -- Merchant
Zerotorescue@119 668 self:MERCHANT_CLOSED();
Zerotorescue@119 669 self:UnregisterEvent("MERCHANT_SHOW");
Zerotorescue@80 670 end
Zerotorescue@80 671
Zerotorescue@80 672 function mod:Pause()
Zerotorescue@80 673 paused = true;
Zerotorescue@80 674 end
Zerotorescue@80 675
Zerotorescue@80 676 function mod:Unpause()
Zerotorescue@80 677 paused = nil;
Zerotorescue@80 678 end