Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 56 additions & 1 deletion EllesmereUICooldownManager/EUI_CooldownManager_Options.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3952,7 +3952,7 @@ initFrame:SetScript("OnEvent", function(self)
if tbbPanRow and tbbPanRow._refreshPreview then tbbPanRow._refreshPreview() end
C_Timer.After(0, function() EllesmereUI:RefreshPage() end)
end,
tooltip = "Show a glow on the bar when the remaining duration is in the pandemic window (last 30%)" },
tooltip = "Show a glow on the bar when the remaining duration is in the pandemic window (last 30%). Doesn't work for secret buff (Lifebloom on tank)" },
{ type = "label", text = "Pandemic Glow Preview" }); y = y - h

BuildPandemicPreview(tbbPanRow, tbbPandemicOff, SelectedTBB)
Expand Down Expand Up @@ -4004,6 +4004,61 @@ initFrame:SetScript("OnEvent", function(self)
end
end

-- Row 4: Pandemic Mark -- static line at the 30% threshold.
-- Lifebloom-only: its pandemic window is 30% of current duration,
-- Other auras pandemic off base duration so 30% mark can be inaccurate
-- Only really useful for secret buff on another target
do
local _bd0 = SelectedTBB()
local _lbName = C_Spell.GetSpellName(33763)
local _curName = _bd0 and _bd0.spellID and C_Spell.GetSpellName(_bd0.spellID)
if _lbName and _curName and _lbName == _curName then
local markRow
markRow, h = W:DualRow(parent, y,
{ type = "toggle", text = "Pandemic Mark",
getValue = function() local bd = SelectedTBB(); return bd and bd.pandemicMark end,
setValue = function(v)
local bd = SelectedTBB(); if not bd then return end
bd.pandemicMark = v; RefreshTBB(); EllesmereUI:RefreshPage()
end,
tooltip = "Draw a static line on the bar at the pandemic threshold (30%). Useful for Lifebloom on another target since glow doesn't work." },
{ type = "label", text = "" }); y = y - h
-- Inline swatch on the Pandemic Mark toggle (disabled when off).
do
local rgn = markRow._leftRegion
local ctrl = rgn._control
local markSwatch, updateMarkSwatch = EllesmereUI.BuildColorSwatch(
rgn, markRow:GetFrameLevel() + 3,
function()
local bd = SelectedTBB()
if not bd then return 1, 1, 0, 1 end
return bd.pandemicMarkR or 1, bd.pandemicMarkG or 1, bd.pandemicMarkB or 0, bd.pandemicMarkA or 1
end,
function(r, g, b, a)
local bd = SelectedTBB(); if not bd then return end
bd.pandemicMarkR, bd.pandemicMarkG, bd.pandemicMarkB, bd.pandemicMarkA = r, g, b, a; RefreshTBB()
end,
true, 20)
PP.Point(markSwatch, "RIGHT", ctrl, "LEFT", -8, 0)
local markBlock = CreateFrame("Frame", nil, markSwatch)
markBlock:SetAllPoints(); markBlock:SetFrameLevel(markSwatch:GetFrameLevel() + 10)
markBlock:EnableMouse(true)
markBlock:SetScript("OnEnter", function()
EllesmereUI.ShowWidgetTooltip(markSwatch, EllesmereUI.DisabledTooltip("Pandemic Mark"))
end)
markBlock:SetScript("OnLeave", function() EllesmereUI.HideWidgetTooltip() end)
local function UpdateMarkSwatchState()
local bd = SelectedTBB()
local off = not bd or not bd.pandemicMark
if off then markSwatch:SetAlpha(0.3); markBlock:Show()
else markSwatch:SetAlpha(1); markBlock:Hide() end
end
EllesmereUI.RegisterWidgetRefresh(function() updateMarkSwatch(); UpdateMarkSwatchState() end)
UpdateMarkSwatchState()
end
end
end

-- Ensure bar frames exist before showing placeholders
ns.BuildTrackedBuffBars()
UpdateTBBPlaceholder()
Expand Down
89 changes: 89 additions & 0 deletions EllesmereUICooldownManager/EllesmereUICdmBuffBars.lua
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,45 @@ end
-------------------------------------------------------------------------------
local _pandemicState = {} -- frame -> true when in pandemic
local _pandemicHooked = {} -- frame -> true once hooks are installed
-- cooldownID: true once Blizzard has ever fired pandemic for that cooldown.
-- Used to gate the computed fallback so we only compute pandemic for
-- spells Blizzard's CooldownViewer never flags (e.g. Lifebloom), leaving
-- Blizzard-handled spells on native behaviour.
local _blizzPandemicCD = {}
ns._pandemicState = _pandemicState

-- Pandemic refresh window (fraction of full duration remaining).
local PANDEMIC_THRESHOLD = 0.3

-- Fallback pandemic detection for auras Blizzard never pandemic-flags. The
-- player's own buff timing is not a secret value, so the refresh window can be
-- computed directly.
-- true -> in the pandemic window
-- false -> not in the window (clean read above threshold)
-- nil -> indeterminate, change nothing
local function ComputePandemicFallback(blzChild)
local iid = blzChild.auraInstanceID
local unit = blzChild.auraDataUnit
if not (iid and unit) then return nil end
local ok, ad = pcall(C_UnitAuras.GetAuraDataByAuraInstanceID, unit, iid)
if not ok or not ad then return nil end
local dur = ad.duration
local exp = ad.expirationTime
if not dur or not exp then return nil end
local isSec = issecretvalue
if isSec and (isSec(dur) or isSec(exp)) then return nil end
if dur <= 0 then return false end -- permanent / no-duration aura
return (exp - GetTime()) <= dur * PANDEMIC_THRESHOLD
end

function ns.HookPandemicState(frame)
if not frame or _pandemicHooked[frame] then return end
if not frame.ShowPandemicStateFrame then return end
_pandemicHooked[frame] = true
hooksecurefunc(frame, "ShowPandemicStateFrame", function(self)
_pandemicState[self] = true
local cd = self.cooldownID
if cd then _blizzPandemicCD[cd] = true end
-- Hide Blizzard's PandemicIcon unless "Blizzard Default" (-1).
-- Custom glow styles (>0) replace it; None (0/false) suppresses it.
local fc = ns._ecmeFC and ns._ecmeFC[self]
Expand Down Expand Up @@ -626,6 +657,45 @@ local function ApplyTBBTickMarks(sb, cfg, tickCache, isVert, tickParent)
end
ns.ApplyTBBTickMarks = ApplyTBBTickMarks

-- Static pandemic-threshold marker. A single line drawn at the pandemic
-- fraction of the bar's fill axis. Static, no valud read, secret-safe.
local function ApplyPandemicMark(sb, cfg, bar, isVert)
local t = bar._pandemicMark
if not cfg.pandemicMark then
if t then t:Hide() end
return
end
local parent = bar._tickOverlay or sb
if not t then
t = parent:CreateTexture(nil, "OVERLAY", nil, 7)
t:SetSnapToPixelGrid(false)
t:SetTexelSnappingBias(0)
bar._pandemicMark = t
end
t:SetColorTexture(cfg.pandemicMarkR or 1, cfg.pandemicMarkG or 1,
cfg.pandemicMarkB or 0, cfg.pandemicMarkA or 1)

local PP = EllesmereUI and EllesmereUI.PP
local barW, barH = sb:GetWidth(), sb:GetHeight()
if not barW or barW <= 0 or not barH or barH <= 0 then t:Hide(); return end
-- "30% remaining" boundary. reverseFill flips which end the fill drains
-- toward, so flip the line position to match.
local pos = cfg.reverseFill and (1 - PANDEMIC_THRESHOLD) or PANDEMIC_THRESHOLD
local thick = PP and PP.Scale(2) or 2
t:ClearAllPoints()
if isVert then
local off = PP and PP.Scale(barH * pos) or (barH * pos)
t:SetSize(barW, thick)
t:SetPoint("BOTTOMLEFT", sb, "BOTTOMLEFT", 0, off)
else
local off = PP and PP.Scale(barW * pos) or (barW * pos)
t:SetSize(thick, barH)
t:SetPoint("TOPLEFT", sb, "TOPLEFT", off, 0)
end
t:Show()
end
ns.ApplyPandemicMark = ApplyPandemicMark

-------------------------------------------------------------------------------
-- Apply Visual Settings
-------------------------------------------------------------------------------
Expand Down Expand Up @@ -892,6 +962,7 @@ local function ApplyTrackedBuffBarSettings(bar, cfg)
bar._tickOverlay = to
end
ApplyTBBTickMarks(sb, cfg, bar._threshTicks, isVert, bar._tickOverlay)
ApplyPandemicMark(sb, cfg, bar, isVert)
bar._ticksDirty = true
end

Expand Down Expand Up @@ -1562,6 +1633,23 @@ function ns.UpdateTrackedBuffBarTimers()
-- pandemic alerts in Blizzard CDM settings.
if _anyPandemic and cfg.pandemicGlow then
local inPandemic = blzChild and _pandemicState[blzChild]
-- Fallback for auras Blizzard never pandemic-flags
-- (e.g. Lifebloom): compute the refresh window
-- ourselves
if not inPandemic and blzChild then
local cd = blzChild.cooldownID
if not (cd and _blizzPandemicCD[cd]) then
local fb = ComputePandemicFallback(blzChild)
if fb == true then
inPandemic = true
elseif fb == nil and bar._pandemicGlowActive then
-- Indeterminate read - do nothing
-- A real expiry is caught
-- by the isActive=false branch below.
inPandemic = true
end
end
end
-- TBBs always show our glow (including Blizzard Default)
-- because Blizzard's native PandemicIcon is on the
-- hidden blzChild frame, not our visible TBB bar.
Expand Down Expand Up @@ -1594,6 +1682,7 @@ function ns.UpdateTrackedBuffBarTimers()
if bw and bw > 0 then
ApplyTBBTickMarks(sb, cfg, bar._threshTicks,
cfg.verticalOrientation, bar._tickOverlay)
ApplyPandemicMark(sb, cfg, bar, cfg.verticalOrientation)
bar._ticksDirty = nil
end
end
Expand Down
3 changes: 2 additions & 1 deletion Locales/_keys.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Auto-generated by .tools/extract-locale-keys.sh -- do not edit by hand.
# Canonical list of translatable English keys passed as string literals
# (273 unique). Regenerate after wrapping new strings. Keys passed as
# (275 unique). Regenerate after wrapping new strings. Keys passed as
# variables are not listed here -- use the in-game /euiloc harvester for
# the complete runtime set.
(Raid)
Expand Down Expand Up @@ -215,6 +215,7 @@ Select a Spec...
Select a bar
Select a talent...
Select which specs you want %1$s to be assigned to
Server Time
Settings
Shift + Left-Click Drag to permanently save a panel's position.
Show 'Not Needed' Reminder
Expand Down
Loading