initial commit
This commit is contained in:
202
Modules/RaidTimeline/RaidTimelineBigWigs.lua
Normal file
202
Modules/RaidTimeline/RaidTimelineBigWigs.lua
Normal file
@@ -0,0 +1,202 @@
|
||||
local ADDON_NAME = "HailMaryGuildTools"
|
||||
local HMGT = LibStub("AceAddon-3.0"):GetAddon(ADDON_NAME)
|
||||
if not HMGT then return end
|
||||
|
||||
local RT = HMGT.RaidTimeline
|
||||
if not RT then return end
|
||||
|
||||
local function TrimText(value)
|
||||
local text = tostring(value or "")
|
||||
text = string.gsub(text, "^%s+", "")
|
||||
text = string.gsub(text, "%s+$", "")
|
||||
return text
|
||||
end
|
||||
|
||||
local function StripBarDisplayText(value)
|
||||
local text = tostring(value or "")
|
||||
text = string.gsub(text, "|T.-|t", "")
|
||||
text = string.gsub(text, "|c%x%x%x%x%x%x%x%x", "")
|
||||
text = string.gsub(text, "|r", "")
|
||||
return TrimText(text)
|
||||
end
|
||||
|
||||
local function NormalizeBossAbilityBarName(value)
|
||||
local text = TrimText(value)
|
||||
if text == "" then
|
||||
return ""
|
||||
end
|
||||
text = string.gsub(text, "%s*%(%d+%)%s*$", "")
|
||||
text = string.gsub(text, "%s*%([Cc]ount%)%s*$", "")
|
||||
text = string.gsub(text, "^%s*%[([A-Za-z])%]%s*", "%1 ")
|
||||
text = string.gsub(text, "%s*%[([A-Za-z])%]%s*$", " (%1)")
|
||||
text = string.gsub(text, "%s*%(([A-Za-z])%)%s*$", " (%1)")
|
||||
text = string.lower(text)
|
||||
return TrimText(text)
|
||||
end
|
||||
|
||||
local function EnsureBigWigsBridge()
|
||||
if RT._bigWigsBridgeRegistered == true then
|
||||
return true
|
||||
end
|
||||
if type(BigWigsLoader) ~= "table" or type(BigWigsLoader.RegisterMessage) ~= "function" then
|
||||
return false
|
||||
end
|
||||
|
||||
RT._bigWigsObservedBars = RT._bigWigsObservedBars or setmetatable({}, { __mode = "k" })
|
||||
RT._bigWigsReceiver = RT._bigWigsReceiver or {}
|
||||
|
||||
function RT._bigWigsReceiver:OnBigWigsBarCreated(_, plugin, bar, module, key, text, time)
|
||||
RT._bigWigsObservedBars[bar] = {
|
||||
plugin = plugin,
|
||||
module = module,
|
||||
key = key,
|
||||
createdText = tostring(text or ""),
|
||||
duration = tonumber(time) or 0,
|
||||
}
|
||||
end
|
||||
|
||||
function RT._bigWigsReceiver:OnBigWigsStopBar(_, plugin, module, text)
|
||||
local targetText = StripBarDisplayText(text)
|
||||
for bar, info in pairs(RT._bigWigsObservedBars) do
|
||||
local currentText = ""
|
||||
if type(bar) == "table" and type(bar.GetText) == "function" then
|
||||
currentText = StripBarDisplayText(bar:GetText())
|
||||
end
|
||||
if (info and info.plugin == plugin or not info or not info.plugin)
|
||||
and (currentText == targetText or StripBarDisplayText(info and info.createdText) == targetText) then
|
||||
RT._bigWigsObservedBars[bar] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
BigWigsLoader.RegisterMessage(RT._bigWigsReceiver, "BigWigs_BarCreated", "OnBigWigsBarCreated")
|
||||
BigWigsLoader.RegisterMessage(RT._bigWigsReceiver, "BigWigs_StopBar", "OnBigWigsStopBar")
|
||||
RT._bigWigsBridgeRegistered = true
|
||||
return true
|
||||
end
|
||||
|
||||
function RT:GetObservedBigWigsBars()
|
||||
local observed = {}
|
||||
if not EnsureBigWigsBridge() then
|
||||
return observed
|
||||
end
|
||||
|
||||
for bar, info in pairs(self._bigWigsObservedBars or {}) do
|
||||
local rawText = nil
|
||||
if type(bar) == "table" and type(bar.GetText) == "function" then
|
||||
rawText = bar:GetText()
|
||||
end
|
||||
rawText = StripBarDisplayText(rawText or (info and info.createdText) or "")
|
||||
local remaining = math.max(0, tonumber(bar and bar.remaining) or 0)
|
||||
if rawText ~= "" and remaining > 0 then
|
||||
observed[#observed + 1] = {
|
||||
rawText = rawText,
|
||||
normalizedName = NormalizeBossAbilityBarName(rawText),
|
||||
count = tonumber(string.match(rawText, "%((%d+)%)%s*$")) or 1,
|
||||
seconds = remaining,
|
||||
key = info and info.key or nil,
|
||||
}
|
||||
else
|
||||
self._bigWigsObservedBars[bar] = nil
|
||||
end
|
||||
end
|
||||
|
||||
return observed
|
||||
end
|
||||
|
||||
function RT:ProbeBossAbilityEntry(entryIndex, entry)
|
||||
if not self:IsLocalEditor() or not self.activeEncounterId or self:GetTriggerType(entry) ~= "bossAbility" then
|
||||
return
|
||||
end
|
||||
|
||||
local desiredRawName = TrimText(entry and entry.bossAbilityBarName or "")
|
||||
local desiredName = NormalizeBossAbilityBarName(desiredRawName)
|
||||
local desiredSelector = self:NormalizeCastCountSelector(entry and entry.castCount)
|
||||
local desiredSelectorText = self:FormatCastCountSelector(desiredSelector)
|
||||
if desiredName == "" then
|
||||
self:LogBossAbilityProbe(
|
||||
entryIndex,
|
||||
entry,
|
||||
"missing-bar-name",
|
||||
"RaidTimeline BigWigs probe encounter=%s slot=%s skipped=missing-bar-name",
|
||||
tostring(self.activeEncounterId),
|
||||
tostring(entryIndex)
|
||||
)
|
||||
return
|
||||
end
|
||||
|
||||
local bars = self:GetObservedBigWigsBars()
|
||||
if #bars == 0 then
|
||||
self:LogBossAbilityProbe(
|
||||
entryIndex,
|
||||
entry,
|
||||
"no-bars",
|
||||
"RaidTimeline BigWigs probe encounter=%s slot=%s target=%s normalized=%s selector=%s foundBar=false bars=0",
|
||||
tostring(self.activeEncounterId),
|
||||
tostring(entryIndex),
|
||||
tostring(desiredRawName),
|
||||
tostring(desiredName),
|
||||
tostring(desiredSelectorText)
|
||||
)
|
||||
return
|
||||
end
|
||||
|
||||
local seenNames = {}
|
||||
local foundName = false
|
||||
for _, observed in ipairs(bars) do
|
||||
seenNames[#seenNames + 1] = string.format("%s{key=%s}[%d]=%.1fs", tostring(observed.rawText), tostring(observed.key), tonumber(observed.count) or 1, tonumber(observed.seconds) or 0)
|
||||
if observed.normalizedName == desiredName then
|
||||
foundName = true
|
||||
if self:DoesCastCountSelectorMatch(desiredSelector, observed.count) then
|
||||
self:LogBossAbilityProbe(
|
||||
entryIndex,
|
||||
entry,
|
||||
string.format("match:%s:%s:%d", desiredName, tostring(desiredSelector), tonumber(observed.count) or 1),
|
||||
"RaidTimeline BigWigs probe encounter=%s slot=%s target=%s normalized=%s selector=%s foundBar=true countMatch=true observed=%s key=%s observedCount=%d remaining=%.1f",
|
||||
tostring(self.activeEncounterId),
|
||||
tostring(entryIndex),
|
||||
tostring(desiredRawName),
|
||||
tostring(desiredName),
|
||||
tostring(desiredSelectorText),
|
||||
tostring(observed.rawText),
|
||||
tostring(observed.key),
|
||||
tonumber(observed.count) or 1,
|
||||
tonumber(observed.seconds) or 0
|
||||
)
|
||||
self:TryDispatchBossAbilityEntry(entryIndex, entry, observed.count, observed.seconds)
|
||||
return
|
||||
end
|
||||
|
||||
self:LogBossAbilityProbe(
|
||||
entryIndex,
|
||||
entry,
|
||||
string.format("count-mismatch:%s:%d", desiredName, observed.count),
|
||||
"RaidTimeline BigWigs probe encounter=%s slot=%s target=%s normalized=%s selector=%s foundBar=true countMatch=false observed=%s key=%s observedCount=%d remaining=%.1f",
|
||||
tostring(self.activeEncounterId),
|
||||
tostring(entryIndex),
|
||||
tostring(desiredRawName),
|
||||
tostring(desiredName),
|
||||
tostring(desiredSelectorText),
|
||||
tostring(observed.rawText),
|
||||
tostring(observed.key),
|
||||
tonumber(observed.count) or 1,
|
||||
tonumber(observed.seconds) or 0
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
if not foundName then
|
||||
self:LogBossAbilityProbe(
|
||||
entryIndex,
|
||||
entry,
|
||||
string.format("name-miss:%s", desiredName),
|
||||
"RaidTimeline BigWigs probe encounter=%s slot=%s target=%s normalized=%s selector=%s foundBar=false bars=%s",
|
||||
tostring(self.activeEncounterId),
|
||||
tostring(entryIndex),
|
||||
tostring(desiredRawName),
|
||||
tostring(desiredName),
|
||||
tostring(desiredSelectorText),
|
||||
table.concat(seenNames, ", ")
|
||||
)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user