annotate Modules/Scanner.lua @ 119:dc6f405c1a5d

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