- Deleted LibGroupInSpecT-1.1.toc, LibStub.lua, and lib.xml files as they are no longer needed. - Updated localization files (deDE.lua, enUS.lua) to reflect the change from "Buff Ending" to "Aura Expiry". - Renamed BuffEndingAnnouncer module to AuraExpiry and updated references throughout the codebase. - Adjusted options and configuration to align with the new module name. - Updated readme to describe the new Aura Expiry feature instead of Buff Ending Announcer.
410 lines
15 KiB
Lua
410 lines
15 KiB
Lua
-- Modules/BuffEndingAnnouncer/BuffEndingAnnouncerOptions.lua
|
|
|
|
local ADDON_NAME = "HailMaryGuildTools"
|
|
local HMGT = LibStub("AceAddon-3.0"):GetAddon(ADDON_NAME)
|
|
if not HMGT then return end
|
|
local BEA = HMGT.AuraExpiry or HMGT.BuffEndingAnnouncer
|
|
if not BEA then return end
|
|
if not HMGT_Config or not HMGT_Config.RegisterOptionsProvider then return end
|
|
|
|
local L = LibStub("AceLocale-3.0"):GetLocale(ADDON_NAME, true) or {}
|
|
local AceConfigRegistry = LibStub("AceConfigRegistry-3.0")
|
|
local beaOptionsGroup
|
|
|
|
local function GetSpellName(spellId)
|
|
local sid = tonumber(spellId)
|
|
if not sid or sid <= 0 then return nil end
|
|
if C_Spell and type(C_Spell.GetSpellName) == "function" then
|
|
local name = C_Spell.GetSpellName(sid)
|
|
if type(name) == "string" and name ~= "" then
|
|
return name
|
|
end
|
|
end
|
|
if type(GetSpellInfo) == "function" then
|
|
local name = GetSpellInfo(sid)
|
|
if type(name) == "string" and name ~= "" then
|
|
return name
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
local function GetSpellIcon(spellId)
|
|
local sid = tonumber(spellId)
|
|
if not sid or sid <= 0 then return nil end
|
|
if HMGT_SpellData and type(HMGT_SpellData.GetSpellIcon) == "function" then
|
|
return HMGT_SpellData.GetSpellIcon(sid)
|
|
end
|
|
if C_Spell and type(C_Spell.GetSpellTexture) == "function" then
|
|
return C_Spell.GetSpellTexture(sid)
|
|
end
|
|
local _, _, icon = GetSpellInfo(sid)
|
|
return icon
|
|
end
|
|
|
|
local function RefreshTrackedGroup()
|
|
if not beaOptionsGroup or type(beaOptionsGroup.args) ~= "table" then
|
|
return
|
|
end
|
|
|
|
local fresh = BEA:BuildOptionsGroup()
|
|
local currentTracked = beaOptionsGroup.args.tracked
|
|
local freshTracked = fresh and fresh.args and fresh.args.tracked
|
|
if type(currentTracked) == "table" and type(freshTracked) == "table" then
|
|
currentTracked.name = freshTracked.name
|
|
currentTracked.order = freshTracked.order
|
|
currentTracked.inline = freshTracked.inline
|
|
currentTracked.childGroups = freshTracked.childGroups
|
|
currentTracked.args = freshTracked.args
|
|
end
|
|
end
|
|
|
|
local function NotifyOptionsChanged(rebuild)
|
|
if rebuild ~= false then
|
|
RefreshTrackedGroup()
|
|
end
|
|
AceConfigRegistry:NotifyChange(ADDON_NAME)
|
|
end
|
|
|
|
local function GetFilterState()
|
|
HMGT._beaSpellFilter = HMGT._beaSpellFilter or {
|
|
search = "",
|
|
}
|
|
return HMGT._beaSpellFilter
|
|
end
|
|
|
|
local function NormalizeSearchText(value)
|
|
local text = tostring(value or ""):lower()
|
|
text = text:gsub("^%s+", "")
|
|
text = text:gsub("%s+$", "")
|
|
return text
|
|
end
|
|
|
|
local function GetDraft()
|
|
HMGT._beaDraft = HMGT._beaDraft or {}
|
|
return HMGT._beaDraft
|
|
end
|
|
|
|
local function GetTrackedBuffLabel(entry)
|
|
local spellId = tonumber(entry and entry.spellId) or 0
|
|
local spellName = tostring(entry and entry.name or GetSpellName(spellId) or ("Spell " .. spellId))
|
|
local icon = GetSpellIcon(spellId)
|
|
local threshold = tonumber(entry and entry.threshold) or tonumber(BEA:GetDefaultThreshold()) or 0
|
|
if icon and icon ~= "" then
|
|
return string.format("|T%s:16:16:0:0|t %s (%ss)", tostring(icon), spellName, threshold)
|
|
end
|
|
return string.format("%s (%ss)", spellName, threshold)
|
|
end
|
|
|
|
local function BuildTrackedBuffLeaf(entry)
|
|
local spellId = tonumber(entry and entry.spellId) or 0
|
|
return {
|
|
type = "group",
|
|
name = GetTrackedBuffLabel(entry),
|
|
args = {
|
|
header = {
|
|
type = "header",
|
|
order = 1,
|
|
name = GetTrackedBuffLabel(entry),
|
|
},
|
|
spellInfo = {
|
|
type = "description",
|
|
order = 2,
|
|
width = "full",
|
|
name = string.format(
|
|
"|cffffd100Spell ID|r: %d\n|cffffd100%s|r: %s",
|
|
spellId,
|
|
L["OPT_BEA_COL_SPELL"] or "Spellname",
|
|
tostring(entry and entry.name or GetSpellName(spellId) or ("Spell " .. spellId))
|
|
),
|
|
},
|
|
threshold = {
|
|
type = "range",
|
|
order = 3,
|
|
min = 1,
|
|
max = 60,
|
|
step = 1,
|
|
width = "full",
|
|
name = L["OPT_BEA_COL_THRESHOLD"] or "Threshold",
|
|
get = function()
|
|
local current = BEA:GetTrackedBuffEntries()
|
|
for _, candidate in ipairs(current) do
|
|
if tonumber(candidate.spellId) == spellId then
|
|
return tonumber(candidate.threshold) or BEA:GetDefaultThreshold()
|
|
end
|
|
end
|
|
return tonumber(BEA:GetDefaultThreshold()) or 5
|
|
end,
|
|
set = function(_, val)
|
|
BEA:SetTrackedBuffThreshold(spellId, val)
|
|
NotifyOptionsChanged()
|
|
end,
|
|
},
|
|
remove = {
|
|
type = "execute",
|
|
order = 4,
|
|
width = "full",
|
|
name = REMOVE or (L["OPT_BEA_REMOVE"] or "Remove buff"),
|
|
confirm = function()
|
|
return string.format("%s?", tostring(entry and entry.name or GetSpellName(spellId) or ("Spell " .. spellId)))
|
|
end,
|
|
func = function()
|
|
local ok, info = BEA:RemoveTrackedBuff(spellId)
|
|
if ok then
|
|
HMGT:Print(string.format(L["OPT_BEA_MSG_REMOVED"] or "HMGT: buff removed: %s", tostring(info or spellId)))
|
|
else
|
|
HMGT:Print(L["OPT_BEA_MSG_NOT_FOUND"] or "HMGT: buff not found")
|
|
end
|
|
NotifyOptionsChanged()
|
|
end,
|
|
},
|
|
},
|
|
}
|
|
end
|
|
|
|
local function IsTrackedBuffVisible(entry)
|
|
local spellId = tonumber(entry and entry.spellId) or 0
|
|
if spellId <= 0 then
|
|
return false
|
|
end
|
|
|
|
local search = NormalizeSearchText(GetFilterState().search)
|
|
if search == "" then
|
|
return true
|
|
end
|
|
|
|
local haystack = table.concat({
|
|
tostring(entry and entry.name or GetSpellName(spellId) or ""),
|
|
tostring(spellId),
|
|
}, " "):lower()
|
|
|
|
return haystack:find(search, 1, true) ~= nil
|
|
end
|
|
|
|
local function CountVisibleEntries(entries)
|
|
local count = 0
|
|
for _, entry in ipairs(entries or {}) do
|
|
if IsTrackedBuffVisible(entry) then
|
|
count = count + 1
|
|
end
|
|
end
|
|
return count
|
|
end
|
|
|
|
function BEA:BuildOptionsGroup()
|
|
local draft = GetDraft()
|
|
local entries = self:GetTrackedBuffEntries()
|
|
|
|
local group = {
|
|
type = "group",
|
|
name = L["AE_NAME"] or L["BEA_NAME"] or "Aura Expiry",
|
|
order = 3,
|
|
childGroups = "tree",
|
|
args = {
|
|
general = {
|
|
type = "group",
|
|
order = 1,
|
|
name = L["OPT_BEA_SECTION_GENERAL"] or "General",
|
|
args = {
|
|
enabled = {
|
|
type = "toggle",
|
|
order = 1,
|
|
width = "full",
|
|
name = L["OPT_BEA_ENABLED"] or "Enable buff ending announcer",
|
|
desc = L["OPT_BEA_ENABLED_DESC"] or "Announce tracked buff countdowns in /say",
|
|
get = function()
|
|
return self:GetSettings().enabled == true
|
|
end,
|
|
set = function(_, val)
|
|
self:GetSettings().enabled = val and true or false
|
|
if val then
|
|
self:Enable()
|
|
else
|
|
self:Disable()
|
|
end
|
|
end,
|
|
},
|
|
defaultThreshold = {
|
|
type = "range",
|
|
order = 2,
|
|
min = 1,
|
|
max = 60,
|
|
step = 1,
|
|
width = "full",
|
|
name = L["OPT_BEA_DEFAULT_THRESHOLD"] or "Default threshold (sec)",
|
|
desc = L["OPT_BEA_DEFAULT_THRESHOLD_DESC"] or "Used when you add a new tracked buff",
|
|
get = function()
|
|
return tonumber(self:GetDefaultThreshold()) or 5
|
|
end,
|
|
set = function(_, val)
|
|
self:GetSettings().announceAtSec = math.floor((tonumber(val) or 5) + 0.5)
|
|
self:Refresh()
|
|
end,
|
|
},
|
|
},
|
|
},
|
|
tracked = {
|
|
type = "group",
|
|
order = 2,
|
|
name = string.format(
|
|
"%s (%d)",
|
|
L["OPT_BEA_SECTION_BUFFS"] or "Tracked buffs",
|
|
#entries
|
|
),
|
|
args = {
|
|
header = {
|
|
type = "header",
|
|
order = 1,
|
|
name = L["OPT_SPELL_BROWSER"] or "Spell Browser",
|
|
},
|
|
summary = {
|
|
type = "description",
|
|
order = 2,
|
|
width = "full",
|
|
name = function()
|
|
local currentEntries = BEA:GetTrackedBuffEntries()
|
|
return string.format(
|
|
"%s\n\n|cffffd100%s|r: %d\n|cffffd100%s|r: %d",
|
|
L["OPT_SPELL_BROWSER_DESC"] or "Filter tracked spells by name or Spell ID and apply quick actions to the visible results.",
|
|
L["OPT_SPELLS_VISIBLE"] or "Visible spells",
|
|
CountVisibleEntries(currentEntries),
|
|
L["OPT_BEA_SECTION_BUFFS"] or "Tracked buffs",
|
|
#currentEntries
|
|
)
|
|
end,
|
|
},
|
|
search = {
|
|
type = "input",
|
|
order = 3,
|
|
width = "full",
|
|
name = L["OPT_FILTER_SEARCH"] or "Search",
|
|
desc = L["OPT_FILTER_SEARCH_DESC"] or "Search by spell name or Spell ID",
|
|
get = function()
|
|
return GetFilterState().search or ""
|
|
end,
|
|
set = function(_, val)
|
|
GetFilterState().search = val or ""
|
|
NotifyOptionsChanged(false)
|
|
end,
|
|
},
|
|
resetFilters = {
|
|
type = "execute",
|
|
order = 4,
|
|
width = "full",
|
|
name = L["OPT_FILTER_RESET"] or "Reset filters",
|
|
func = function()
|
|
GetFilterState().search = ""
|
|
NotifyOptionsChanged(false)
|
|
end,
|
|
},
|
|
addGroup = {
|
|
type = "group",
|
|
order = 5,
|
|
inline = true,
|
|
name = L["OPT_BEA_CURRENT"] or "Current tracked buffs",
|
|
args = {
|
|
addSpellId = {
|
|
type = "input",
|
|
order = 1,
|
|
width = 0.9,
|
|
name = L["OPT_BEA_ADD_ID"] or "Add Spell ID",
|
|
get = function()
|
|
return tostring(draft.addSpellId or "")
|
|
end,
|
|
set = function(_, val)
|
|
draft.addSpellId = val
|
|
end,
|
|
},
|
|
addThreshold = {
|
|
type = "range",
|
|
order = 2,
|
|
min = 1,
|
|
max = 60,
|
|
step = 1,
|
|
width = 1.1,
|
|
name = L["OPT_BEA_ADD_THRESHOLD"] or "Threshold",
|
|
desc = L["OPT_BEA_ADD_THRESHOLD_DESC"] or "Countdown start in seconds for this buff",
|
|
get = function()
|
|
return tonumber(draft.addThreshold) or tonumber(self:GetDefaultThreshold()) or 5
|
|
end,
|
|
set = function(_, val)
|
|
draft.addThreshold = tonumber(val) or self:GetDefaultThreshold()
|
|
end,
|
|
},
|
|
addSpell = {
|
|
type = "execute",
|
|
order = 3,
|
|
width = "full",
|
|
name = L["OPT_BEA_ADD"] or "Add buff",
|
|
func = function()
|
|
local sid = tonumber(draft.addSpellId)
|
|
local threshold = tonumber(draft.addThreshold) or self:GetDefaultThreshold()
|
|
local ok, info = self:AddTrackedBuff(sid, threshold)
|
|
if ok then
|
|
draft.addSpellId = ""
|
|
draft.addThreshold = tonumber(self:GetDefaultThreshold()) or 5
|
|
HMGT:Print(string.format(L["OPT_BEA_MSG_ADDED"] or "HMGT: buff added: %s", tostring(info or sid)))
|
|
else
|
|
HMGT:Print(L["OPT_BEA_MSG_INVALID"] or "HMGT: invalid buff spell ID")
|
|
end
|
|
NotifyOptionsChanged()
|
|
end,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
if #entries == 0 then
|
|
group.args.tracked.args.empty = {
|
|
type = "description",
|
|
order = 10,
|
|
width = "full",
|
|
name = L["OPT_BEA_EMPTY"] or "No buffs configured.",
|
|
}
|
|
else
|
|
for index, entry in ipairs(entries) do
|
|
local key = "buff_" .. tostring(tonumber(entry.spellId) or index)
|
|
local leaf = BuildTrackedBuffLeaf(entry)
|
|
leaf.order = 10 + index
|
|
leaf.inline = true
|
|
leaf.name = " "
|
|
leaf.hidden = function()
|
|
return not IsTrackedBuffVisible(entry)
|
|
end
|
|
group.args.tracked.args[key] = leaf
|
|
end
|
|
|
|
group.args.tracked.args.noVisible = {
|
|
type = "description",
|
|
order = 1000,
|
|
width = "full",
|
|
hidden = function()
|
|
return CountVisibleEntries(BEA:GetTrackedBuffEntries()) > 0
|
|
end,
|
|
name = L["OPT_BEA_EMPTY"] or "No buffs configured.",
|
|
}
|
|
end
|
|
|
|
return group
|
|
end
|
|
|
|
function BEA:GetOptionsGroup()
|
|
if not beaOptionsGroup then
|
|
beaOptionsGroup = self:BuildOptionsGroup()
|
|
else
|
|
RefreshTrackedGroup()
|
|
end
|
|
return beaOptionsGroup
|
|
end
|
|
|
|
HMGT_Config:RegisterOptionsProvider("announcer.auraExpiry", function()
|
|
return {
|
|
path = "announcer",
|
|
order = 3,
|
|
group = BEA:GetOptionsGroup(),
|
|
}
|
|
end)
|