annotate Modules/Scanner.lua @ 131:a27948591159

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