annotate Modules/Scanner.lua @ 225:2e4e52a589e5

Added onQueueStart and onQueueEnd events to crafting addon registering. GnomeWorks queue frame should automatically be closed before adding items to the queue and opened afterwards to speed this process up.
author Zerotorescue
date Mon, 07 Feb 2011 15:06:41 +0100
parents 07263a435f3c
children 24e71ed0a422
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@144 70 ["tooltipTitle"] = "Item",
Zerotorescue@144 71 ["tooltip"] = "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@144 79 ["tooltipTitle"] = "Moving",
Zerotorescue@144 80 ["tooltip"] = "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@144 98 ["tooltipTitle"] = "Item",
Zerotorescue@144 99 ["tooltip"] = "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@144 105 tooltipTitle = "Move Items",
Zerotorescue@144 106 tooltip = "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@144 111 tooltipTitle = "Cancel",
Zerotorescue@144 112 tooltip = "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@144 148 ["tooltipTitle"] = "Item",
Zerotorescue@144 149 ["tooltip"] = "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@144 157 ["tooltipTitle"] = "Buying",
Zerotorescue@144 158 ["tooltip"] = "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@144 166 ["tooltipTitle"] = "Cost",
Zerotorescue@144 167 ["tooltip"] = "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@144 173 tooltipTitle = "Purchase Items",
Zerotorescue@144 174 tooltip = "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@144 179 tooltipTitle = "Cancel",
Zerotorescue@144 180 tooltip = "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@218 357 local requiredItems, bonusQueue, priceThreshold, 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@218 361 priceThreshold = addon:GetOptionByKey(groupName, "priceThreshold");
Zerotorescue@123 362 minCraftingQueue = floor( addon:GetOptionByKey(groupName, "minCraftingQueue") * requiredItems ); -- If the minCraftingQueue is 5% and restockTarget is 60, this will result in 3
Zerotorescue@123 363 else
Zerotorescue@123 364 isRefillEnabled = addon:GetOptionByKey(groupName, "autoRefill");
Zerotorescue@123 365 requiredItems = addon:GetOptionByKey(groupName, "minLocalStock");
Zerotorescue@123 366 end
Zerotorescue@80 367
Zerotorescue@119 368 local isTracked = (trackAt and trackAt[playerName]); -- Is this character interested in this data?
Zerotorescue@119 369 local isConsideredLocal = (localItemData and localItemData[location]); -- if this location was checked as local storage, don't refill from it
Zerotorescue@119 370
Zerotorescue@123 371 if values.items and isTracked and (isRestock or isRefillEnabled) and not isConsideredLocal then
Zerotorescue@119 372 addon:Debug("Scanning |cff00ff00%s|r", groupName);
Zerotorescue@80 373
Zerotorescue@80 374 for itemId, _ in pairs(values.items) do
Zerotorescue@119 375 -- Find this item in the source
Zerotorescue@119 376 local containerItem = itemCache[itemId];
Zerotorescue@80 377
Zerotorescue@119 378 if containerItem then
Zerotorescue@119 379 -- Only do all the CPU intensive checks if this item is available
Zerotorescue@80 380
Zerotorescue@119 381 -- When restocking use the global item count, when refilling use the local
Zerotorescue@119 382 local currentItemCount = ((isRestock and addon:GetItemCount(itemId, groupName)) or addon:GetLocalItemCount(itemId, groupName));
Zerotorescue@119 383
Zerotorescue@119 384 -- Check if we have enough items local (but only do so if this location also has enough available)
Zerotorescue@119 385 local missingItems = (requiredItems - currentItemCount);
Zerotorescue@119 386
Zerotorescue@123 387 if isRestock and currentItemCount == 0 and bonusQueue and bonusQueue > 0 then
Zerotorescue@123 388 -- If we have none left and the bonus queue is enabled, modify the amount to be queued
Zerotorescue@123 389
Zerotorescue@123 390 missingItems = floor( ( missingItems * ( bonusQueue + 1 ) ) + .5 ); -- round
Zerotorescue@123 391 end
Zerotorescue@123 392
Zerotorescue@123 393 if missingItems > 0 and (not isRestock or missingItems >= minCraftingQueue) then
Zerotorescue@218 394
Zerotorescue@218 395 -- Get auction value when it is relevant
Zerotorescue@218 396 local value = (isRestock and priceThreshold ~= 0 and addon:GetAuctionValue(IdToItemLink(itemId), groupName));
Zerotorescue@80 397
Zerotorescue@218 398 if not isRestock or priceThreshold == 0 or value == -1 or value >= priceThreshold then
Zerotorescue@218 399 -- Check how many are available
Zerotorescue@218 400 local availableItems = ((containerItem.totalCount) or 0);
Zerotorescue@218 401 -- Calculate how many we'll be moving (less missing than available? use missing, otherwise use available)
Zerotorescue@218 402 -- -1 available items indicates unlimited amount, in that case we must cap at missing items
Zerotorescue@218 403 local moving = (((availableItems == -1 or missingItems <= availableItems) and missingItems) or availableItems);
Zerotorescue@119 404
Zerotorescue@218 405 if availableItems == -1 or availableItems > 0 then
Zerotorescue@218 406 addon:Debug("Insufficient %s but this location has %d (moving %d)", IdToItemLink(itemId), availableItems, moving);
Zerotorescue@218 407
Zerotorescue@218 408 Mover:AddMove(itemId, moving, missingItems, availableItems, containerItem.price);
Zerotorescue@218 409 end
Zerotorescue@119 410 end
Zerotorescue@80 411 end
Zerotorescue@80 412 end
Zerotorescue@80 413 end
Zerotorescue@80 414 end
Zerotorescue@80 415 end
Zerotorescue@80 416
Zerotorescue@80 417 self:ClearCache();
Zerotorescue@80 418
Zerotorescue@81 419 if Mover:HasMoves() then
Zerotorescue@101 420 if addon.db.profile.defaults.autoRefillSkipConfirm then
Zerotorescue@110 421 OnMoveAccept();
Zerotorescue@101 422 else
Zerotorescue@119 423 local moves = Mover:GetMoves();
Zerotorescue@110 424
Zerotorescue@106 425 -- This table is never copied, just referenced. It is the same for every row.
Zerotorescue@119 426 local columns;
Zerotorescue@119 427
Zerotorescue@119 428 if isRestock then
Zerotorescue@119 429 local totalCost = 0;
Zerotorescue@119 430 for _, move in pairs(moves) do
Zerotorescue@119 431 totalCost = (totalCost + (move.cost * move.num));
Zerotorescue@119 432 end
Zerotorescue@119 433 UseMerchantRestockST(totalCost);
Zerotorescue@119 434
Zerotorescue@119 435 columns = {
Zerotorescue@119 436 {
Zerotorescue@119 437 ["value"] = function(data, cols, realrow, column, table)
Zerotorescue@119 438 return IdToItemLink(data[realrow].rowData.itemId);
Zerotorescue@119 439 end,
Zerotorescue@119 440 }, -- item
Zerotorescue@119 441 {
Zerotorescue@119 442 ["value"] = function(data, cols, realrow, column, table)
Zerotorescue@119 443 return data[realrow].rowData.num;
Zerotorescue@119 444 end,
Zerotorescue@119 445 }, -- buying
Zerotorescue@119 446 {
Zerotorescue@119 447 ["value"] = function(data, cols, realrow, column, table)
Zerotorescue@119 448 return GetSmallCoinTextureString((data[realrow].rowData.cost * data[realrow].rowData.num));
Zerotorescue@119 449 end,
Zerotorescue@119 450 }, -- cost
Zerotorescue@119 451 };
Zerotorescue@119 452 else
Zerotorescue@119 453 UseStorageRefillST();
Zerotorescue@119 454
Zerotorescue@119 455 columns = {
Zerotorescue@119 456 {
Zerotorescue@119 457 ["value"] = function(data, cols, realrow, column, table)
Zerotorescue@119 458 return IdToItemLink(data[realrow].rowData.itemId);
Zerotorescue@119 459 end,
Zerotorescue@119 460 }, -- item
Zerotorescue@119 461 {
Zerotorescue@119 462 ["value"] = function(data, cols, realrow, column, table)
Zerotorescue@119 463 return data[realrow].rowData.num;
Zerotorescue@119 464 end,
Zerotorescue@119 465 }, -- moving
Zerotorescue@119 466 {
Zerotorescue@119 467 ["value"] = function(data, cols, realrow, column, table)
Zerotorescue@119 468 return addon:DisplayItemCount(data[realrow].rowData.available, data[realrow].rowData.missing); -- available / missing
Zerotorescue@119 469 end,
Zerotorescue@119 470 ["color"] = function(data, cols, realrow, column, table)
Zerotorescue@119 471 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 472 end,
Zerotorescue@119 473 }, -- missing / available
Zerotorescue@119 474 };
Zerotorescue@119 475 end
Zerotorescue@101 476
Zerotorescue@106 477 -- Store the list with rows in this
Zerotorescue@106 478 local data = {};
Zerotorescue@101 479
Zerotorescue@119 480 for i, move in pairs(moves) do
Zerotorescue@122 481 tinsert(data, {
Zerotorescue@106 482 ["rowData"] = move, -- this is not a key usually found in a row item and ignored by the library
Zerotorescue@101 483 ["cols"] = columns,
Zerotorescue@106 484 });
Zerotorescue@101 485 end
Zerotorescue@101 486
Zerotorescue@101 487 addon:SetMoverFrameData(data);
Zerotorescue@101 488 end
Zerotorescue@81 489 end
Zerotorescue@81 490 end
Zerotorescue@81 491
Zerotorescue@84 492
Zerotorescue@84 493
Zerotorescue@84 494 -- Events
Zerotorescue@84 495
Zerotorescue@84 496 -- Player bank
Zerotorescue@84 497
Zerotorescue@84 498 function mod:BANKFRAME_OPENED()
Zerotorescue@84 499 addon:Debug("Scanner:BANKFRAME_OPENED");
Zerotorescue@84 500
Zerotorescue@84 501 mod:RegisterEvent("BANKFRAME_CLOSED");
Zerotorescue@84 502
Zerotorescue@84 503 -- Scan once when the bank is opened, but no need to scan after
Zerotorescue@84 504 mod:Scan(addon.Locations.Bank);
Zerotorescue@84 505 end
Zerotorescue@84 506
Zerotorescue@84 507 function mod:BANKFRAME_CLOSED()
Zerotorescue@81 508 addon:Debug("Scanner:BANKFRAME_CLOSED");
Zerotorescue@81 509
Zerotorescue@89 510 self:ClearCache();
Zerotorescue@89 511
Zerotorescue@81 512 mod:UnregisterEvent("BANKFRAME_CLOSED");
Zerotorescue@81 513
Zerotorescue@137 514 if InventoriumItemMover then
Zerotorescue@137 515 InventoriumItemMover:Hide();
Zerotorescue@137 516 end
Zerotorescue@101 517 Mover:ResetQueue();
Zerotorescue@80 518 end
Zerotorescue@80 519
Zerotorescue@84 520 -- Guild bank
Zerotorescue@84 521
Zerotorescue@84 522 local tmrScanGuild, scanned;
Zerotorescue@84 523 function mod:GUILDBANKBAGSLOTS_CHANGED()
Zerotorescue@84 524 -- This event is spammed the first time the guild bank is opened
Zerotorescue@84 525 if not scanned then
Zerotorescue@84 526 self:CancelTimer(tmrScanGuild, true); -- silent
Zerotorescue@84 527 tmrScanGuild = self:ScheduleTimer("DoScanGuild", 1);
Zerotorescue@84 528 end
Zerotorescue@80 529 end
Zerotorescue@80 530
Zerotorescue@84 531 function mod:DoScanGuild()
Zerotorescue@84 532 if not scanned then
Zerotorescue@89 533 addon:Debug("Scanner:DoScanGuild");
Zerotorescue@84 534
Zerotorescue@84 535 scanned = true;
Zerotorescue@84 536
Zerotorescue@84 537 self:Scan(addon.Locations.Guild);
Zerotorescue@84 538 end
Zerotorescue@84 539 end
Zerotorescue@80 540
Zerotorescue@84 541 function mod:GUILDBANKFRAME_CLOSED()
Zerotorescue@81 542 addon:Debug("Scanner:GUILDBANKFRAME_CLOSED");
Zerotorescue@81 543
Zerotorescue@84 544 scanned = nil;
Zerotorescue@89 545 self:ClearCache();
Zerotorescue@81 546
Zerotorescue@84 547 self:UnregisterEvent("GUILDBANKFRAME_CLOSED");
Zerotorescue@84 548 self:UnregisterEvent("GUILDBANKBAGSLOTS_CHANGED");
Zerotorescue@84 549
Zerotorescue@84 550 self:CancelTimer(tmrScanGuild, true); -- silent
Zerotorescue@80 551
Zerotorescue@137 552 if InventoriumItemMover then
Zerotorescue@137 553 InventoriumItemMover:Hide();
Zerotorescue@137 554 end
Zerotorescue@101 555 Mover:ResetQueue();
Zerotorescue@80 556 end
Zerotorescue@80 557
Zerotorescue@84 558 function mod:GUILDBANKFRAME_OPENED()
Zerotorescue@81 559 addon:Debug("Scanner:GUILDBANKFRAME_OPENED");
Zerotorescue@81 560
Zerotorescue@84 561 scanned = nil;
Zerotorescue@80 562
Zerotorescue@84 563 -- Get the contents for every tab into our cache
Zerotorescue@84 564 for tabId = 1, GetNumGuildBankTabs() do
Zerotorescue@110 565 local _, _, isViewable, _, _, remainingWithdrawals = GetGuildBankTabInfo(tabId);
Zerotorescue@110 566
Zerotorescue@110 567 if isViewable and (remainingWithdrawals > 0 or remainingWithdrawals == -1) then
Zerotorescue@84 568 QueryGuildBankTab(tabId);
Zerotorescue@84 569 end
Zerotorescue@84 570 end
Zerotorescue@84 571
Zerotorescue@84 572 self:RegisterEvent("GUILDBANKFRAME_CLOSED");
Zerotorescue@84 573 self:RegisterEvent("GUILDBANKBAGSLOTS_CHANGED");
Zerotorescue@80 574 end
Zerotorescue@80 575
Zerotorescue@119 576 function mod:MERCHANT_SHOW()
Zerotorescue@119 577 addon:Debug("Scanner:MERCHANT_SHOW");
Zerotorescue@119 578
Zerotorescue@119 579 self:RegisterEvent("MERCHANT_CLOSED");
Zerotorescue@119 580
Zerotorescue@119 581 self:Scan(addon.Locations.Merchant);
Zerotorescue@119 582 end
Zerotorescue@119 583
Zerotorescue@119 584 function mod:MERCHANT_CLOSED()
Zerotorescue@119 585 addon:Debug("Scanner:MERCHANT_CLOSED");
Zerotorescue@119 586
Zerotorescue@119 587 self:ClearCache();
Zerotorescue@119 588
Zerotorescue@119 589 self:UnregisterEvent("MERCHANT_CLOSED");
Zerotorescue@119 590
Zerotorescue@137 591 if InventoriumItemMover then
Zerotorescue@137 592 InventoriumItemMover:Hide();
Zerotorescue@137 593 end
Zerotorescue@119 594 Mover:ResetQueue();
Zerotorescue@119 595 end
Zerotorescue@119 596
Zerotorescue@117 597 local previousMailCount;
Zerotorescue@117 598 function mod:MAIL_SHOW()
Zerotorescue@117 599 addon:Debug("Scanner:MAIL_SHOW");
Zerotorescue@117 600
Zerotorescue@117 601 self:RegisterEvent("MAIL_INBOX_UPDATE");
Zerotorescue@117 602 self:RegisterEvent("MAIL_CLOSED");
Zerotorescue@117 603
Zerotorescue@117 604 scanned = nil;
Zerotorescue@117 605 previousMailCount = nil;
Zerotorescue@117 606
Zerotorescue@117 607 self:Scan(addon.Locations.Mailbox);
Zerotorescue@117 608 end
Zerotorescue@110 609
Zerotorescue@117 610 function mod:MAIL_INBOX_UPDATE()
Zerotorescue@117 611 if not scanned then
Zerotorescue@117 612 addon:Debug("Scanner:MAIL_INBOX_UPDATE");
Zerotorescue@117 613
Zerotorescue@117 614 local current, total = GetInboxNumItems();
Zerotorescue@117 615
Zerotorescue@117 616 if not previousMailCount or current > previousMailCount then
Zerotorescue@117 617 -- New mail received
Zerotorescue@117 618
Zerotorescue@117 619 scanned = true;
Zerotorescue@117 620
Zerotorescue@117 621 self:Scan(addon.Locations.Mailbox);
Zerotorescue@117 622 end
Zerotorescue@117 623
Zerotorescue@117 624 -- 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 625 previousMailCount = current;
Zerotorescue@117 626 else
Zerotorescue@117 627 addon:Debug("Scanner:MAIL_INBOX_UPDATE skipped, already scanned");
Zerotorescue@117 628 end
Zerotorescue@117 629 end
Zerotorescue@110 630
Zerotorescue@117 631 function mod:MAIL_CLOSED()
Zerotorescue@117 632 addon:Debug("Scanner:MAIL_CLOSED");
Zerotorescue@117 633
Zerotorescue@117 634 previousMailCount = nil;
Zerotorescue@117 635 scanned = nil;
Zerotorescue@117 636 self:ClearCache();
Zerotorescue@117 637
Zerotorescue@117 638 self:UnregisterEvent("MAIL_INBOX_UPDATE");
Zerotorescue@117 639 self:UnregisterEvent("MAIL_CLOSED");
Zerotorescue@117 640
Zerotorescue@137 641 if InventoriumItemMover then
Zerotorescue@137 642 InventoriumItemMover:Hide();
Zerotorescue@137 643 end
Zerotorescue@117 644 Mover:ResetQueue();
Zerotorescue@117 645 end
Zerotorescue@110 646
Zerotorescue@80 647 function mod:OnEnable()
Zerotorescue@80 648 -- Scan once when the bankframe is opened
Zerotorescue@84 649 self:RegisterEvent("BANKFRAME_OPENED");
Zerotorescue@84 650 self:RegisterEvent("GUILDBANKFRAME_OPENED");
Zerotorescue@117 651 self:RegisterEvent("MAIL_SHOW");
Zerotorescue@119 652 self:RegisterEvent("MERCHANT_SHOW");
Zerotorescue@80 653
Zerotorescue@80 654 Mover = addon:GetModule("Mover");
Zerotorescue@80 655 end
Zerotorescue@80 656
Zerotorescue@80 657 function mod:OnDisable()
Zerotorescue@80 658 Mover = nil;
Zerotorescue@101 659 currentLocation = nil;
Zerotorescue@101 660 paused = nil;
Zerotorescue@80 661
Zerotorescue@80 662 -- Bank
Zerotorescue@110 663 self:BANKFRAME_CLOSED();
Zerotorescue@84 664 self:UnregisterEvent("BANKFRAME_OPENED");
Zerotorescue@80 665
Zerotorescue@80 666 -- Guild
Zerotorescue@84 667 self:GUILDBANKFRAME_CLOSED();
Zerotorescue@84 668 self:UnregisterEvent("GUILDBANKFRAME_OPENED");
Zerotorescue@110 669
Zerotorescue@117 670 -- Mailbox
Zerotorescue@117 671 self:MAIL_CLOSED();
Zerotorescue@117 672 self:UnregisterEvent("MAIL_SHOW");
Zerotorescue@119 673
Zerotorescue@119 674 -- Merchant
Zerotorescue@119 675 self:MERCHANT_CLOSED();
Zerotorescue@119 676 self:UnregisterEvent("MERCHANT_SHOW");
Zerotorescue@80 677 end
Zerotorescue@80 678
Zerotorescue@80 679 function mod:Pause()
Zerotorescue@80 680 paused = true;
Zerotorescue@80 681 end
Zerotorescue@80 682
Zerotorescue@80 683 function mod:Unpause()
Zerotorescue@80 684 paused = nil;
Zerotorescue@80 685 end