306 lines
9.9 KiB
Lua
306 lines
9.9 KiB
Lua
-- Modules/Tracker/SingleFrameTrackerBase.lua
|
|
-- Shared implementation for single-frame tracker modules.
|
|
|
|
local ADDON_NAME = "HailMaryGuildTools"
|
|
local HMGT = LibStub("AceAddon-3.0"):GetAddon(ADDON_NAME)
|
|
if not HMGT then return end
|
|
|
|
HMGT.SingleFrameTrackerBase = HMGT.SingleFrameTrackerBase or {}
|
|
local Base = HMGT.SingleFrameTrackerBase
|
|
|
|
local function GetDefaultGroupPlayers()
|
|
local players = {}
|
|
|
|
local ownName = HMGT:NormalizePlayerName(UnitName("player"))
|
|
local ownClass = select(2, UnitClass("player"))
|
|
table.insert(players, { name = ownName, class = ownClass, isOwn = true, unitId = "player" })
|
|
|
|
if IsInRaid() then
|
|
for i = 1, GetNumGroupMembers() do
|
|
local unitId = "raid" .. i
|
|
local name = HMGT:NormalizePlayerName(UnitName(unitId))
|
|
local class = select(2, UnitClass(unitId))
|
|
if name and name ~= ownName then
|
|
table.insert(players, { name = name, class = class, unitId = unitId })
|
|
end
|
|
end
|
|
elseif IsInGroup() then
|
|
for i = 1, GetNumGroupMembers() - 1 do
|
|
local unitId = "party" .. i
|
|
local name = HMGT:NormalizePlayerName(UnitName(unitId))
|
|
local class = select(2, UnitClass(unitId))
|
|
if name and name ~= ownName then
|
|
table.insert(players, { name = name, class = class, unitId = unitId })
|
|
end
|
|
end
|
|
end
|
|
|
|
return players
|
|
end
|
|
|
|
local function ResolveConfigValue(configValue, self)
|
|
if type(configValue) == "function" then
|
|
return configValue(self)
|
|
end
|
|
return configValue
|
|
end
|
|
|
|
local function EntryNeedsVisualTicker(entry)
|
|
if type(entry) ~= "table" then
|
|
return false
|
|
end
|
|
|
|
local remaining = tonumber(entry.remaining) or 0
|
|
if remaining > 0 then
|
|
return true
|
|
end
|
|
|
|
local maxCharges = tonumber(entry.maxCharges) or 0
|
|
local currentCharges = tonumber(entry.currentCharges)
|
|
if maxCharges > 0 and currentCharges ~= nil and currentCharges < maxCharges then
|
|
return true
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
function Base:Create(config)
|
|
local tracker = {
|
|
frame = nil,
|
|
updateTicker = nil,
|
|
lastEntryCount = 0,
|
|
}
|
|
|
|
function tracker:GetSettings()
|
|
return HMGT.db.profile[config.profileKey]
|
|
end
|
|
|
|
function tracker:GetDatabase()
|
|
return ResolveConfigValue(config.database, self) or {}
|
|
end
|
|
|
|
function tracker:GetTitle()
|
|
return ResolveConfigValue(config.title, self) or config.frameName
|
|
end
|
|
|
|
function tracker:GetDemoKey()
|
|
return ResolveConfigValue(config.demoKey, self) or config.profileKey
|
|
end
|
|
|
|
function tracker:GetCooldownInfoOpts()
|
|
return ResolveConfigValue(config.cooldownInfoOpts, self)
|
|
end
|
|
|
|
function tracker:GetGroupPlayers()
|
|
local custom = ResolveConfigValue(config.groupPlayersProvider, self)
|
|
if type(custom) == "table" then
|
|
return custom
|
|
end
|
|
return GetDefaultGroupPlayers()
|
|
end
|
|
|
|
function tracker:EnsureUpdateTicker()
|
|
if self.updateTicker then
|
|
return
|
|
end
|
|
self.updateTicker = C_Timer.NewTicker(0.1, function()
|
|
self:UpdateDisplay()
|
|
end)
|
|
end
|
|
|
|
function tracker:StopUpdateTicker()
|
|
if self.updateTicker then
|
|
self.updateTicker:Cancel()
|
|
self.updateTicker = nil
|
|
end
|
|
end
|
|
|
|
function tracker:SetUpdateTickerEnabled(enabled)
|
|
if enabled then
|
|
self:EnsureUpdateTicker()
|
|
else
|
|
self:StopUpdateTicker()
|
|
end
|
|
end
|
|
|
|
function tracker:Enable()
|
|
local s = self:GetSettings()
|
|
if not s.enabled and not s.demoMode and not s.testMode then return end
|
|
|
|
if not self.frame then
|
|
self.frame = HMGT.TrackerFrame:CreateTrackerFrame(config.frameName, s)
|
|
HMGT.TrackerFrame:SetTitle(self.frame, self:GetTitle())
|
|
end
|
|
|
|
if HMGT:IsVisibleForCurrentGroup(s) then
|
|
self.frame:Show()
|
|
else
|
|
self.frame:Hide()
|
|
end
|
|
self:UpdateDisplay()
|
|
end
|
|
|
|
function tracker:Disable()
|
|
self:StopUpdateTicker()
|
|
if self.frame then
|
|
self.frame:Hide()
|
|
end
|
|
end
|
|
|
|
function tracker:UpdateDisplay()
|
|
if not self.frame then
|
|
self:StopUpdateTicker()
|
|
return
|
|
end
|
|
|
|
local s = self:GetSettings()
|
|
local database = self:GetDatabase()
|
|
local cooldownInfoOpts = self:GetCooldownInfoOpts()
|
|
|
|
if s.testMode then
|
|
HMGT.TrackerFrame:SetLocked(self.frame, s.locked)
|
|
local entries = HMGT:GetOwnTestEntries(database, s, cooldownInfoOpts)
|
|
self.lastEntryCount = #entries
|
|
HMGT.TrackerFrame:UpdateFrame(self.frame, entries)
|
|
self.frame:Show()
|
|
local shouldTick = false
|
|
for _, entry in ipairs(entries) do
|
|
if EntryNeedsVisualTicker(entry) then
|
|
shouldTick = true
|
|
break
|
|
end
|
|
end
|
|
self:SetUpdateTickerEnabled(shouldTick)
|
|
return
|
|
end
|
|
|
|
if s.demoMode then
|
|
HMGT.TrackerFrame:SetLocked(self.frame, s.locked)
|
|
local entries = HMGT:GetDemoEntries(self:GetDemoKey(), database, s)
|
|
self.lastEntryCount = #entries
|
|
HMGT.TrackerFrame:UpdateFrame(self.frame, entries)
|
|
self.frame:Show()
|
|
self:SetUpdateTickerEnabled(#entries > 0)
|
|
return
|
|
end
|
|
|
|
if not s.enabled then
|
|
self.lastEntryCount = 0
|
|
self.frame:Hide()
|
|
self:StopUpdateTicker()
|
|
return
|
|
end
|
|
|
|
if not HMGT:IsVisibleForCurrentGroup(s) then
|
|
self.lastEntryCount = 0
|
|
self.frame:Hide()
|
|
self:StopUpdateTicker()
|
|
return
|
|
end
|
|
|
|
HMGT.TrackerFrame:SetLocked(self.frame, s.locked)
|
|
|
|
local entries = self:CollectEntries()
|
|
self.lastEntryCount = #entries
|
|
if HMGT.SortDisplayEntries then
|
|
HMGT:SortDisplayEntries(entries, config.profileKey)
|
|
end
|
|
|
|
HMGT.TrackerFrame:UpdateFrame(self.frame, entries)
|
|
self.frame:Show()
|
|
|
|
local shouldTick = false
|
|
for _, entry in ipairs(entries) do
|
|
if EntryNeedsVisualTicker(entry) then
|
|
shouldTick = true
|
|
break
|
|
end
|
|
end
|
|
self:SetUpdateTickerEnabled(shouldTick)
|
|
end
|
|
|
|
function tracker:CollectEntries()
|
|
local entries = {}
|
|
local s = self:GetSettings()
|
|
local database = self:GetDatabase()
|
|
local cooldownInfoOpts = self:GetCooldownInfoOpts()
|
|
local players = self:GetGroupPlayers()
|
|
|
|
for _, playerInfo in ipairs(players) do
|
|
repeat
|
|
local name = playerInfo.name
|
|
local pData = HMGT.playerData[name]
|
|
local class = pData and pData.class or playerInfo.class
|
|
local specIdx
|
|
if playerInfo.isOwn then
|
|
specIdx = GetSpecialization()
|
|
if not specIdx or specIdx == 0 then break end
|
|
else
|
|
specIdx = pData and pData.specIndex or nil
|
|
if not specIdx or tonumber(specIdx) <= 0 then break end
|
|
end
|
|
local talents = pData and pData.talents or {}
|
|
|
|
if not class then break end
|
|
|
|
local knownSpells = HMGT_SpellData.GetSpellsForSpec(class, specIdx, database)
|
|
|
|
for _, spellEntry in ipairs(knownSpells) do
|
|
if s.enabledSpells[spellEntry.spellId] ~= false then
|
|
local remaining, total, curCharges, maxCharges = HMGT:GetCooldownInfo(name, spellEntry.spellId, cooldownInfoOpts)
|
|
local isAvailabilitySpell = HMGT.IsAvailabilitySpell and HMGT:IsAvailabilitySpell(spellEntry)
|
|
local effectiveCd = HMGT_SpellData.GetEffectiveCooldown(spellEntry, talents)
|
|
local include = HMGT:ShouldDisplayEntry(s, remaining, curCharges, maxCharges, spellEntry)
|
|
local spellKnown = HMGT:IsTrackedSpellKnownForPlayer(name, spellEntry.spellId)
|
|
local hasPartialCharges = (tonumber(maxCharges) or 0) > 0
|
|
and (tonumber(curCharges) or tonumber(maxCharges) or 0) < (tonumber(maxCharges) or 0)
|
|
local hasActiveCd = ((remaining or 0) > 0) or hasPartialCharges
|
|
if not spellKnown and not hasActiveCd then
|
|
include = false
|
|
end
|
|
if isAvailabilitySpell and not spellKnown then
|
|
include = false
|
|
end
|
|
|
|
if not playerInfo.isOwn then
|
|
if isAvailabilitySpell and not HMGT:HasAvailabilityState(name, spellEntry.spellId) then
|
|
include = false
|
|
end
|
|
end
|
|
|
|
if include then
|
|
entries[#entries + 1] = {
|
|
playerName = name,
|
|
class = class,
|
|
spellEntry = spellEntry,
|
|
remaining = remaining,
|
|
total = total > 0 and total or effectiveCd,
|
|
currentCharges = curCharges,
|
|
maxCharges = maxCharges,
|
|
}
|
|
end
|
|
end
|
|
end
|
|
until true
|
|
end
|
|
|
|
return entries
|
|
end
|
|
|
|
return tracker
|
|
end
|
|
|
|
function Base:CreateModule(moduleName, config, ...)
|
|
if type(moduleName) ~= "string" or moduleName == "" then
|
|
return self:Create(config)
|
|
end
|
|
|
|
local module = HMGT:NewModule(moduleName, ...)
|
|
local tracker = self:Create(config)
|
|
for key, value in pairs(tracker) do
|
|
module[key] = value
|
|
end
|
|
HMGT[moduleName] = module
|
|
return module
|
|
end
|