Mercurial > wow > inventory
view Modules/Alerts.lua @ 184:679d3664849d
The stock alert should now properly scan immediately after a login.
Setting the stock scan speed at fast or higher now properly speeds things up when your FPS is below 100.
Renamed ?instant? speed to ?(Near) instant? and changed it to 100 steps per scan rather than everything at once.
author | Zerotorescue |
---|---|
date | Sun, 30 Jan 2011 20:53:13 +0100 |
parents | 26c750a10b14 |
children | 5cee31b1418a |
line wrap: on
line source
local addon = select(2, ...); local mod = addon:NewModule("Alerts", "AceEvent-3.0", "AceTimer-3.0"); local queue, cache = {}, {}; function mod:OnEnable() addon:Debug("Alerts:OnEnable"); -- Register our alert slash command -- /im alert addon:RegisterSlash(function(this) mod:Scan(true); end, { "a", "alert" }, "|Hfunction:InventoriumCommandHandler:alert|h|cff00fff7/im alert|r|h (or /im a) - Rescan the items within all tracked groups and show item alerts for those items missing."); mod:Scan(false); --[[if addon.db.profile.defaults.scanInterval["00Login"] then self:RegisterEvent("PLAYER_LOGIN", "Scan"); end if addon.db.profile.defaults.scanInterval["01Repeat5"] then self:ScheduleTimer("Scan", 5 * 60); elseif addon.db.profile.defaults.scanInterval["01Repeat10"] then self:ScheduleTimer("Scan", 10 * 60); elseif addon.db.profile.defaults.scanInterval["01Repeat15"] then self:ScheduleTimer("Scan", 15 * 60); elseif addon.db.profile.defaults.scanInterval["01Repeat30"] then self:ScheduleTimer("Scan", 30 * 60); elseif addon.db.profile.defaults.scanInterval["01Repeat60"] then self:ScheduleTimer("Scan", 60 * 60); elseif addon.db.profile.defaults.scanInterval["01Repeat120"] then self:ScheduleTimer("Scan", 120 * 60); end]] end local scanTypes = { Local = "local", Global = "global", }; function mod:Scan(verbal) addon:Debug("Alerts:Scan"); if verbal then addon:Print("Scanning items, the results will be presented to you in a moment. Please be patient."); end local playerName = UnitName("player"); table.wipe(queue); table.wipe(cache); -- Go through all groups for groupName, values in pairs(addon.db.profile.groups) do -- Settings local trackAt = addon:GetOptionByKey(groupName, "trackAtCharacters"); local dontAlertAt = addon:GetOptionByKey(groupName, "dontAlertAtCharacters"); local alertBelowLocalMinimum = addon:GetOptionByKey(groupName, "alertBelowLocalMinimum"); local minLocalStock = alertBelowLocalMinimum and addon:GetOptionByKey(groupName, "minLocalStock"); local alertBelowGlobalMinimum = addon:GetOptionByKey(groupName, "alertBelowGlobalMinimum"); local minGlobalStock = alertBelowGlobalMinimum and addon:GetOptionByKey(groupName, "minGlobalStock"); local isTracked = (trackAt and trackAt[playerName] and (not dontAlertAt or not dontAlertAt[playerName])); -- Is this character interested in this data and does it want alerts? if values.items and isTracked and (alertBelowLocalMinimum or alertBelowGlobalMinimum) then addon:Debug("Scanning |cff00ff00%s|r", groupName); local groupSettings = { ["name"] = groupName, ["minLocalStock"] = minLocalStock, ["minGlobalStock"] = minGlobalStock, }; for itemId, _ in pairs(values.items) do if alertBelowLocalMinimum then self:QeueueScan(groupSettings, itemId, scanTypes.Local); end if alertBelowGlobalMinimum then self:QeueueScan(groupSettings, itemId, scanTypes.Global); end end end end if self:HasQueue() then addon:Debug("Alerts:HasQueue, processing"); --addon:Debug(queue); self:ProcessScan(verbal); end end function mod:QeueueScan(groupSettings, itemId, scanType) table.insert(queue, { ["group"] = groupSettings, ["itemId"] = itemId, ["type"] = scanType, }); end function mod:HasQueue() return (#queue > 0); end function mod:ProcessScan(verbal) local nextScanDelay = (tonumber(addon.db.profile.defaults.scanInterval) or .1); local runs = (0.1 / nextScanDelay); -- 0.01 = 10, 0.05 = 2, 0.1 and smaller = 1 runs = (runs < 1 and 1) or runs; runs = (nextScanDelay == 0 and 100) or runs; for no = 1, runs do -- Get the last item added to the queue local thisItem = table.remove(queue, 1); if not thisItem then -- If no item exists then we processed everything, show summary self:ScanFinished(); return; end if thisItem.type == scanTypes.Global then -- Global scan local globalCount = addon:GetItemCount(thisItem.itemId, thisItem.group.name); if not cache[thisItem.itemId] then cache[thisItem.itemId] = { ["itemId"] = thisItem.itemId, -- needed later for displaying ["group"] = thisItem.group, ["globalCount"] = globalCount, }; else cache[thisItem.itemId].globalCount = globalCount; end elseif thisItem.type == scanTypes.Local then -- Local scan local localCount = addon:GetLocalItemCount(thisItem.itemId, thisItem.group.name); if not cache[thisItem.itemId] then cache[thisItem.itemId] = { ["itemId"] = thisItem.itemId, -- needed later for displaying ["group"] = thisItem.group, ["localCount"] = localCount, }; else cache[thisItem.itemId].globalCount = localCount; end end end self:ScheduleTimer(function() mod:ProcessScan(verbal); end, nextScanDelay); -- scan next item in nextScanDelay seconds end local function OnProceed() InventoriumCommandHandler("summary"); if InventoriumItemMover then InventoriumItemMover:Hide(); end end local function OnCancel() if InventoriumItemMover then InventoriumItemMover:Hide(); end end local function UseScanST() if not InventoriumItemMover then addon:CreateMoverFrame(); end local frame = InventoriumItemMover; -- both for speed as code-consistency -- Scrolling table with a list of items to be moved local scrollTableWidth = ( frame.frmMeasureDummy:GetWidth() - 30 ); -- adjust width by the scrollbar size local headers = { { ["name"] = "Item", ["width"] = (scrollTableWidth * .6), ["defaultsort"] = "asc", ["comparesort"] = function(this, aRow, bRow, column) local aName, _, aRarity = GetItemInfo(this:GetRow(aRow).rowData.itemId); local bName, _, bRarity = GetItemInfo(this:GetRow(bRow).rowData.itemId); local template = "%d%s"; aName = template:format((10 - (aRarity or 10)), (aName or ""):lower()); bName = template:format((10 - (bRarity or 10)), (bName or ""):lower()); if this.cols[column].sort == "dsc" then return aName > bName; else return aName < bName; end end, ["sort"] = "asc", -- when the data is set, use this column so sort the default data ["tooltipTitle"] = "Item", ["tooltip"] = "Click to sort the list by item quality then item name.", }, { ["name"] = "Local", ["width"] = (scrollTableWidth * .2), ["align"] = "RIGHT", ["defaultsort"] = "dsc", ["sortnext"] = 1, ["comparesort"] = function(this, aRow, bRow, column) local aAvailablePercent = (this:GetRow(aRow).rowData.localCount / this:GetRow(aRow).rowData.group.minLocalStock); local bAvailablePercent = (this:GetRow(bRow).rowData.localCount / this:GetRow(bRow).rowData.group.minLocalStock); if this.cols[column].sort == "dsc" then return aAvailablePercent > bAvailablePercent; else return aAvailablePercent < bAvailablePercent; end end, ["tooltipTitle"] = "Local Stock", ["tooltip"] = "Click to sort the list by the local stock percentage.", }, { ["name"] = "Global", ["width"] = (scrollTableWidth * .2), ["align"] = "RIGHT", ["defaultsort"] = "dsc", ["sortnext"] = 1, ["comparesort"] = function(this, aRow, bRow, column) local aAvailablePercent = (this:GetRow(aRow).rowData.globalCount / this:GetRow(aRow).rowData.group.minGlobalStock); local bAvailablePercent = (this:GetRow(bRow).rowData.globalCount / this:GetRow(bRow).rowData.group.minGlobalStock); if this.cols[column].sort == "dsc" then return aAvailablePercent > bAvailablePercent; else return aAvailablePercent < bAvailablePercent; end end, ["tooltipTitle"] = "Global Stock", ["tooltip"] = "Click to sort the list by the global stock percentage.", }, }; local proceedButton = { text = "Show in summary", tooltipTitle = "Show in Summary", tooltip = "Show the summary giving a more detailed list of missing items.", onClick = OnProceed, }; local cancelButton = { text = "Cancel", tooltipTitle = "Cancel", tooltip = "Close the window.", onClick = OnCancel, }; addon:SetMoverFrameSettings("Inventorium Stock Alert", "You have elected to receive an alert when the following items are under your minimum stock requirement:", proceedButton, cancelButton, headers); end function mod:ScanFinished() table.wipe(queue); --addon:Debug(cache); -- This table is never copied, just referenced. It is the same for every row. local missingRow = { { ["value"] = function(data, cols, realrow, column, table) return IdToItemLink(data[realrow].rowData.itemId); end, }, -- item { ["value"] = function(data, cols, realrow, column, table) return addon:DisplayItemCount(data[realrow].rowData.localCount or -4, data[realrow].rowData.group.minLocalStock); end, }, -- local { ["value"] = function(data, cols, realrow, column, table) return addon:DisplayItemCount(data[realrow].rowData.globalCount or -4, data[realrow].rowData.group.minGlobalStock); end, }, -- global }; -- Store the list with rows in this local missingList = {}; for itemId, info in pairs(cache) do if (info.globalCount and info.globalCount < info.group.minGlobalStock) or (info.localCount and info.localCount < info.group.minLocalStock) then -- Not enough global or not enough local tinsert(missingList, { ["rowData"] = info, -- this is not a key usually found in a row item and ignored by the library ["cols"] = missingRow, }); end end table.wipe(cache); -- no longer needed, all missing items are now stored in the missingList if #missingList > 0 then UseScanST(); addon:SetMoverFrameData(missingList); if verbal then addon:Print("Presenting the data..."); end elseif verbal then addon:Print("No items that you elected to be alerted about are below the selected stock thresholds."); end end