initial commit v.2.1.0
This commit is contained in:
268
Modules/Tracker/TrackerDataProvider.lua
Normal file
268
Modules/Tracker/TrackerDataProvider.lua
Normal file
@@ -0,0 +1,268 @@
|
||||
local ADDON_NAME = "HailMaryGuildTools"
|
||||
local HMGT = LibStub("AceAddon-3.0"):GetAddon(ADDON_NAME)
|
||||
if not HMGT then return end
|
||||
|
||||
HMGT.TrackerDataProvider = HMGT.TrackerDataProvider or {}
|
||||
|
||||
local internals = HMGT.TrackerInternals or {}
|
||||
local SafeApiNumber = internals.SafeApiNumber
|
||||
local GetSpellChargesInfo = internals.GetSpellChargesInfo
|
||||
local GetSpellCooldownInfo = internals.GetSpellCooldownInfo
|
||||
|
||||
function HMGT:GetCooldownInfo(playerName, spellId, opts)
|
||||
opts = opts or {}
|
||||
local deferUntilEmpty = opts.deferChargeCooldownUntilEmpty and true or false
|
||||
local spellEntry = HMGT_SpellData.InterruptLookup[spellId]
|
||||
or HMGT_SpellData.CooldownLookup[spellId]
|
||||
local ownName = self:NormalizePlayerName(UnitName("player"))
|
||||
local isOwnPlayer = playerName == ownName
|
||||
local pData = isOwnPlayer and self.playerData[ownName] or nil
|
||||
local talents = pData and pData.talents or {}
|
||||
local effectiveCd = spellEntry and HMGT_SpellData.GetEffectiveCooldown(spellEntry, talents) or 0
|
||||
local knownMaxCharges, knownChargeDuration = 0, 0
|
||||
if spellEntry and isOwnPlayer then
|
||||
knownMaxCharges, knownChargeDuration = self:GetKnownChargeInfo(spellEntry, talents, spellId, effectiveCd)
|
||||
end
|
||||
|
||||
if self:IsAvailabilitySpell(spellEntry) then
|
||||
local normalizedName = self:NormalizePlayerName(playerName)
|
||||
if normalizedName == ownName then
|
||||
local current, max = self:GetOwnAvailabilityProgress(spellEntry)
|
||||
if (tonumber(max) or 0) > 0 then
|
||||
self:StoreAvailabilityState(ownName, spellId, current, max, spellEntry)
|
||||
return 0, 0, current, max
|
||||
end
|
||||
else
|
||||
local current, max = self:GetAvailabilityState(normalizedName, spellId)
|
||||
if (tonumber(max) or 0) > 0 then
|
||||
return 0, 0, current, max
|
||||
end
|
||||
end
|
||||
return 0, 0, nil, nil
|
||||
end
|
||||
|
||||
local cdData = self:GetActiveCooldown(playerName, spellId)
|
||||
|
||||
if isOwnPlayer and not (InCombatLockdown and InCombatLockdown()) then
|
||||
local charges, maxCharges, chargeStart, chargeDuration = nil, nil, nil, nil
|
||||
if GetSpellChargesInfo then
|
||||
charges, maxCharges, chargeStart, chargeDuration = GetSpellChargesInfo(spellId)
|
||||
end
|
||||
charges = SafeApiNumber and SafeApiNumber(charges, 0) or tonumber(charges) or 0
|
||||
maxCharges = SafeApiNumber and SafeApiNumber(maxCharges, 0) or tonumber(maxCharges) or 0
|
||||
chargeStart = SafeApiNumber and SafeApiNumber(chargeStart) or tonumber(chargeStart)
|
||||
chargeDuration = SafeApiNumber and SafeApiNumber(chargeDuration, 0) or tonumber(chargeDuration) or 0
|
||||
|
||||
if maxCharges > 0 then
|
||||
local tempChargeState = {
|
||||
currentCharges = charges,
|
||||
maxCharges = maxCharges,
|
||||
chargeStart = chargeStart,
|
||||
chargeDuration = chargeDuration,
|
||||
duration = chargeDuration,
|
||||
}
|
||||
local remaining, total, curCharges, maxChargeCount = self:ResolveChargeState(tempChargeState)
|
||||
self:StoreKnownChargeInfo(spellId, maxChargeCount, total > 0 and total or chargeDuration)
|
||||
if (curCharges or 0) < maxChargeCount and remaining <= 0 and GetSpellCooldownInfo then
|
||||
local cdStart, cdDuration = GetSpellCooldownInfo(spellId)
|
||||
if cdDuration > 0 then
|
||||
remaining = math.max(0, cdDuration - (GetTime() - cdStart))
|
||||
total = math.max(total or 0, cdDuration)
|
||||
end
|
||||
end
|
||||
if deferUntilEmpty and (curCharges or 0) > 0 then
|
||||
remaining = 0
|
||||
end
|
||||
return remaining, total, curCharges, maxChargeCount
|
||||
end
|
||||
|
||||
if GetSpellCooldownInfo then
|
||||
local cdStart, cdDuration = GetSpellCooldownInfo(spellId)
|
||||
cdStart = tonumber(cdStart) or 0
|
||||
cdDuration = tonumber(cdDuration) or 0
|
||||
if cdDuration > 0 then
|
||||
local remaining = math.max(0, cdDuration - (GetTime() - cdStart))
|
||||
remaining = math.max(0, math.min(cdDuration, remaining))
|
||||
if cdData and (tonumber(cdData.maxCharges) or 0) <= 0 then
|
||||
local cachedRemaining = (tonumber(cdData.duration) or 0) - (GetTime() - (tonumber(cdData.startTime) or GetTime()))
|
||||
cachedRemaining = math.max(0, math.min(tonumber(cdData.duration) or cachedRemaining, cachedRemaining))
|
||||
local cachedDuration = math.max(0, tonumber(cdData.duration) or 0)
|
||||
if cachedDuration > 2.0 and cachedRemaining > 2.0 and cdDuration < math.max(2.0, cachedDuration * 0.35) then
|
||||
return cachedRemaining, cachedDuration, nil, nil
|
||||
end
|
||||
end
|
||||
return remaining, cdDuration, nil, nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not cdData then
|
||||
if isOwnPlayer and knownMaxCharges > 1 then
|
||||
return 0, math.max(0, knownChargeDuration or effectiveCd or 0), knownMaxCharges, knownMaxCharges
|
||||
end
|
||||
return 0, 0, nil, nil
|
||||
end
|
||||
if (tonumber(cdData.maxCharges) or 0) > 0 then
|
||||
local remaining, chargeDur, charges, maxCharges = self:ResolveChargeState(cdData)
|
||||
self:StoreKnownChargeInfo(spellId, maxCharges, chargeDur)
|
||||
if deferUntilEmpty and charges > 0 then
|
||||
remaining = 0
|
||||
end
|
||||
return remaining, chargeDur, charges, maxCharges
|
||||
end
|
||||
if isOwnPlayer and knownMaxCharges > 1 then
|
||||
local remaining = (tonumber(cdData.duration) or 0) - (GetTime() - (tonumber(cdData.startTime) or GetTime()))
|
||||
remaining = math.max(0, math.min(tonumber(cdData.duration) or remaining, remaining))
|
||||
local currentCharges = knownMaxCharges
|
||||
if remaining > 0 then
|
||||
currentCharges = math.max(0, knownMaxCharges - 1)
|
||||
end
|
||||
if deferUntilEmpty and currentCharges > 0 then
|
||||
remaining = 0
|
||||
end
|
||||
return remaining, math.max(0, knownChargeDuration or effectiveCd or 0), currentCharges, knownMaxCharges
|
||||
end
|
||||
local remaining = cdData.duration - (GetTime() - cdData.startTime)
|
||||
remaining = math.max(0, math.min(cdData.duration, remaining))
|
||||
return remaining, cdData.duration, nil, nil
|
||||
end
|
||||
|
||||
function HMGT:ShouldDisplayEntry(settings, remaining, currentCharges, maxCharges, spellEntry)
|
||||
local rem = tonumber(remaining) or 0
|
||||
local cur = tonumber(currentCharges) or 0
|
||||
local max = tonumber(maxCharges) or 0
|
||||
local soon = tonumber(settings.readySoonSec) or 0
|
||||
local isAvailabilitySpell = spellEntry and self:IsAvailabilitySpell(spellEntry) or false
|
||||
local isReady
|
||||
|
||||
if isAvailabilitySpell then
|
||||
isReady = max > 0 and cur >= max
|
||||
else
|
||||
isReady = rem <= 0 or (max > 0 and cur > 0)
|
||||
end
|
||||
|
||||
if settings.showOnlyReady then
|
||||
return isReady
|
||||
end
|
||||
if soon > 0 then
|
||||
if isAvailabilitySpell then
|
||||
return isReady
|
||||
end
|
||||
return isReady or rem <= soon
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local DEFAULT_CATEGORY_PRIORITY = {
|
||||
interrupt = 1,
|
||||
lust = 2,
|
||||
defensive = 3,
|
||||
tank = 4,
|
||||
healing = 5,
|
||||
offensive = 6,
|
||||
utility = 7,
|
||||
cc = 8,
|
||||
}
|
||||
|
||||
local TRACKER_CATEGORY_PRIORITY = {
|
||||
interruptTracker = {
|
||||
interrupt = 1,
|
||||
defensive = 2,
|
||||
utility = 3,
|
||||
cc = 4,
|
||||
healing = 5,
|
||||
tank = 6,
|
||||
offensive = 7,
|
||||
lust = 8,
|
||||
},
|
||||
raidCooldownTracker = {
|
||||
lust = 1,
|
||||
defensive = 2,
|
||||
healing = 3,
|
||||
tank = 4,
|
||||
utility = 5,
|
||||
offensive = 6,
|
||||
cc = 7,
|
||||
interrupt = 8,
|
||||
},
|
||||
groupCooldownTracker = {
|
||||
tank = 1,
|
||||
defensive = 2,
|
||||
healing = 3,
|
||||
cc = 4,
|
||||
utility = 5,
|
||||
offensive = 6,
|
||||
lust = 7,
|
||||
interrupt = 8,
|
||||
},
|
||||
}
|
||||
|
||||
local function GetCategoryPriority(category, trackerKey)
|
||||
local cat = tostring(category or "utility")
|
||||
local trackerOrder = trackerKey and TRACKER_CATEGORY_PRIORITY[trackerKey]
|
||||
if trackerOrder and trackerOrder[cat] then
|
||||
return trackerOrder[cat]
|
||||
end
|
||||
local order = HMGT_SpellData and HMGT_SpellData.CategoryOrder
|
||||
if type(order) == "table" then
|
||||
for idx, key in ipairs(order) do
|
||||
if key == cat then
|
||||
return idx
|
||||
end
|
||||
end
|
||||
return #order + 10
|
||||
end
|
||||
return DEFAULT_CATEGORY_PRIORITY[cat] or 99
|
||||
end
|
||||
|
||||
function HMGT:SortDisplayEntries(entries, trackerKey)
|
||||
if type(entries) ~= "table" then return end
|
||||
table.sort(entries, function(a, b)
|
||||
local aRemaining = tonumber(a and a.remaining) or 0
|
||||
local bRemaining = tonumber(b and b.remaining) or 0
|
||||
local aActive = aRemaining > 0
|
||||
local bActive = bRemaining > 0
|
||||
if aActive ~= bActive then
|
||||
return aActive
|
||||
end
|
||||
|
||||
local aEntry = a and a.spellEntry
|
||||
local bEntry = b and b.spellEntry
|
||||
|
||||
local aPriority = tonumber(aEntry and aEntry.priority) or GetCategoryPriority(aEntry and aEntry.category, trackerKey)
|
||||
local bPriority = tonumber(bEntry and bEntry.priority) or GetCategoryPriority(bEntry and bEntry.category, trackerKey)
|
||||
if aPriority ~= bPriority then
|
||||
return aPriority < bPriority
|
||||
end
|
||||
|
||||
if aActive and aRemaining ~= bRemaining then
|
||||
return aRemaining < bRemaining
|
||||
end
|
||||
|
||||
local aTotal = tonumber(a and a.total)
|
||||
or tonumber(aEntry and HMGT_SpellData.GetBaseCooldown and HMGT_SpellData.GetBaseCooldown(aEntry))
|
||||
or tonumber(aEntry and aEntry.cooldown)
|
||||
or 0
|
||||
local bTotal = tonumber(b and b.total)
|
||||
or tonumber(bEntry and HMGT_SpellData.GetBaseCooldown and HMGT_SpellData.GetBaseCooldown(bEntry))
|
||||
or tonumber(bEntry and bEntry.cooldown)
|
||||
or 0
|
||||
if (not aActive) and aTotal ~= bTotal then
|
||||
return aTotal > bTotal
|
||||
end
|
||||
|
||||
if aRemaining ~= bRemaining then
|
||||
return aRemaining < bRemaining
|
||||
end
|
||||
|
||||
local aName = tostring(a and a.playerName or "")
|
||||
local bName = tostring(b and b.playerName or "")
|
||||
if aName ~= bName then
|
||||
return aName < bName
|
||||
end
|
||||
|
||||
local aSpell = tonumber(aEntry and aEntry.spellId) or 0
|
||||
local bSpell = tonumber(bEntry and bEntry.spellId) or 0
|
||||
return aSpell < bSpell
|
||||
end)
|
||||
end
|
||||
Reference in New Issue
Block a user