Mercurial > wow > inventory
view Modules/Alerts.lua @ 176:26c750a10b14
Renamed Inventorium debug channel to IMDebug (so it?s easier to recognize only IM changes, not from other addons), write /im d to register this new channel.
Implemented stock alerts.
Added ?don?t alert at characters? option which allows you to track groups at characters without being bothered about low stock.
You can change the speed of the stock alert at the extra config tab.
author | Zerotorescue |
---|---|
date | Sun, 30 Jan 2011 15:39:18 +0100 |
parents | |
children | 679d3664849d |
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."); self:RegisterEvent("PLAYER_LOGIN", function() mod:Scan(false); end); --[[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 thisItem = table.remove(queue, 1); if not thisItem then self:ScanFinished(); return; end if thisItem.type == scanTypes.Global then 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 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 local nextScanDelay = (tonumber(addon.db.profile.defaults.scanInterval) or .1); if nextScanDelay == 0 then mod:ProcessScan(verbal); else self:ScheduleTimer(function() mod:ProcessScan(verbal); end, nextScanDelay); -- scan next item in nextScanDelay seconds end 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