mirror of
https://github.com/brues-code/pfUI.git
synced 2026-11-03 17:36:56 +00:00
Timer bars: buffwatch, loot roll, infobox and five-second rule drain from duration objects
Each bar hands its fill to StatusBar:SetTimerDuration instead of a per-frame SetValue. Buffwatch's time text moves to a duration text binding holding the cooldown formatter, now exposed as GetTimeFormatter (replacing GetColoredTimeString, whose only caller this was). The five-second rule's overlay style becomes a color-filled StatusBar too, so both styles share one path; energytick's OnUpdate keeps only the tick spark.
This commit is contained in:
+6
-5
@@ -196,9 +196,10 @@ function pfUI.api.GetAuraTimer(duration, expirationTime)
|
||||
return start, dur
|
||||
end
|
||||
|
||||
-- [ GetColoredTimeString ] --
|
||||
-- 'remaining' [number] the time in seconds that should be converted
|
||||
-- return [string] the time as cooldown numbers show it
|
||||
function pfUI.api.GetColoredTimeString(remaining)
|
||||
return GetFormatter():FormatNumber(remaining)
|
||||
-- [ GetTimeFormatter ] --
|
||||
-- The formatter cooldown numbers use, for other timers to show time the same
|
||||
-- way. Hold it rather than a copy: a settings change updates it in place.
|
||||
-- return [formatter] a NumericRuleFormatter
|
||||
function pfUI.api.GetTimeFormatter()
|
||||
return GetFormatter()
|
||||
end
|
||||
|
||||
+4
-9
@@ -834,10 +834,7 @@ function pfUI.api.CreateInfoBox(text, time, parent, height)
|
||||
end)
|
||||
|
||||
infobox:SetScript("OnUpdate", function()
|
||||
local time = infobox.lastshow + infobox.duration - GetTime()
|
||||
infobox.timeout:SetValue(time)
|
||||
|
||||
if GetTime() > infobox.lastshow + infobox.duration then
|
||||
if infobox.duration:HasExpired() then
|
||||
if not infobox.fade:IsPlaying() then infobox.fade:Play() end
|
||||
elseif MouseIsOverHitRect(this) then
|
||||
this:SetAlpha(max(0.4, this:GetAlpha() - .1))
|
||||
@@ -857,6 +854,8 @@ function pfUI.api.CreateInfoBox(text, time, parent, height)
|
||||
infobox.timeout = CreateFrame("StatusBar", nil, infobox)
|
||||
infobox.timeout:SetStatusBarTexture(pfUI.media["img:bar"])
|
||||
infobox.timeout:SetStatusBarColor(.3,1,.8,1)
|
||||
infobox.duration = C_DurationUtil.CreateDuration()
|
||||
infobox.timeout:SetTimerDuration(infobox.duration, Enum.StatusBarInterpolation.Immediate, Enum.StatusBarTimerDirection.RemainingTime)
|
||||
|
||||
infobox:ClearAllPoints()
|
||||
infobox.text:SetAllPoints(infobox)
|
||||
@@ -872,11 +871,7 @@ function pfUI.api.CreateInfoBox(text, time, parent, height)
|
||||
end
|
||||
|
||||
infobox.text:SetText(text)
|
||||
infobox.timeout:SetMinMaxValues(0, time)
|
||||
infobox.timeout:SetValue(time)
|
||||
|
||||
infobox.duration = time
|
||||
infobox.lastshow = GetTime()
|
||||
infobox.duration:SetTimeFromStart(GetTime(), time)
|
||||
|
||||
infobox:SetSize(infobox.text:GetStringWidth() + 50, height)
|
||||
infobox:SetParent(parent)
|
||||
|
||||
+24
-15
@@ -130,15 +130,14 @@ pfUI:RegisterModule("buffwatch", function ()
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
|
||||
local function StatusBarOnUpdate()
|
||||
local remaining = this.endtime - GetTime()
|
||||
this.bar:SetValue(remaining > 0 and remaining or 0)
|
||||
|
||||
if ( this.tick or 1) > GetTime() then return else this.tick = GetTime() + .1 end
|
||||
this.time:SetText(remaining > 0 and GetColoredTimeString(remaining) or "")
|
||||
-- an enabled text binding writes every frame, shown or not
|
||||
local function StatusBarOnShow()
|
||||
this.timer:Enable()
|
||||
this.parent:RefreshPosition()
|
||||
end
|
||||
|
||||
local function StatusBarRefreshParent()
|
||||
local function StatusBarOnHide()
|
||||
this.timer:Disable()
|
||||
this.parent:RefreshPosition()
|
||||
end
|
||||
|
||||
@@ -183,6 +182,16 @@ pfUI:RegisterModule("buffwatch", function ()
|
||||
frame.time:SetTextColor(1,1,1,1)
|
||||
frame.time:SetJustifyH("RIGHT")
|
||||
|
||||
-- the bar drains and the time counts down from this, engine-side
|
||||
frame.duration = C_DurationUtil.CreateDuration()
|
||||
frame.bar:SetTimerDuration(frame.duration, Enum.StatusBarInterpolation.Immediate, Enum.StatusBarTimerDirection.RemainingTime)
|
||||
frame.timer = C_DurationUtil.CreateDurationTextBinding()
|
||||
frame.timer:SetFontString(frame.time)
|
||||
frame.timer:SetFormatter(GetTimeFormatter())
|
||||
frame.timer:SetDuration(frame.duration)
|
||||
frame.timer:SetExpiredText("")
|
||||
frame.timer:SetZeroDurationText("")
|
||||
|
||||
frame.icon = frame:CreateTexture(nil, "OVERLAY")
|
||||
frame.icon:SetSize(height, height)
|
||||
frame.icon:SetPoint("LEFT", frame, "LEFT", 0, 0)
|
||||
@@ -195,9 +204,8 @@ pfUI:RegisterModule("buffwatch", function ()
|
||||
frame.stacks:SetJustifyV("CENTER")
|
||||
|
||||
frame.parent = parent
|
||||
frame:SetScript("OnUpdate", StatusBarOnUpdate)
|
||||
frame:SetScript("OnShow", StatusBarRefreshParent)
|
||||
frame:SetScript("OnHide", StatusBarRefreshParent)
|
||||
frame:SetScript("OnShow", StatusBarOnShow)
|
||||
frame:SetScript("OnHide", StatusBarOnHide)
|
||||
|
||||
frame:RegisterForClicks("LeftButtonUp", "RightButtonUp")
|
||||
frame:SetScript("OnClick", StatusBarOnClick)
|
||||
@@ -261,7 +269,6 @@ pfUI:RegisterModule("buffwatch", function ()
|
||||
frame.bars[bar].id = data[2]
|
||||
frame.bars[bar].unit = frame.unit
|
||||
frame.bars[bar].type = frame.type
|
||||
frame.bars[bar].endtime = GetTime() + ( data[1] > 0 and data[1] or -1 )
|
||||
|
||||
-- update max duration the cached remaining values is less than
|
||||
-- the real one, indicates a buff renewal
|
||||
@@ -313,10 +320,12 @@ pfUI:RegisterModule("buffwatch", function ()
|
||||
frame.bars[bar].icon:SetTexture(data[4])
|
||||
end
|
||||
|
||||
-- cache maxduration
|
||||
if frame.bars[bar].cacheMaxDuration ~= frame.durations[uuid][2] then
|
||||
frame.bars[bar].cacheMaxDuration = frame.durations[uuid][2]
|
||||
frame.bars[bar].bar:SetMinMaxValues(0, frame.durations[uuid][2])
|
||||
-- the bar spans the longest time left seen for this aura; one without
|
||||
-- a time left (threshold -1) shows an empty bar and no time
|
||||
if data[1] > 0 then
|
||||
frame.bars[bar].duration:SetTimeFromEnd(GetTime() + data[1], frame.durations[uuid][2])
|
||||
else
|
||||
frame.bars[bar].duration:Reset()
|
||||
end
|
||||
|
||||
-- set stacks
|
||||
|
||||
+28
-29
@@ -166,8 +166,8 @@ pfUI:RegisterModule("energytick", function()
|
||||
local cost = C_Spell.GetSpellPowerCost(arg3)
|
||||
cost = cost and cost[1]
|
||||
if cost and cost.type == Enum.PowerType.Mana and cost.cost > 0 then
|
||||
this.fsrSpell, this.fsrEnd = arg3, GetTime() + FIVE_SECOND_RULE
|
||||
this.fsrGain = nil
|
||||
this.fsrSpell, this.fsrGain = arg3, nil
|
||||
this.fsr:SetTimeFromStart(GetTime(), FIVE_SECOND_RULE)
|
||||
end
|
||||
return
|
||||
end
|
||||
@@ -175,7 +175,8 @@ pfUI:RegisterModule("energytick", function()
|
||||
-- Unit::Update won't expire the rule while the spending spell still channels
|
||||
if event == "UNIT_SPELLCAST_CHANNEL_STOP" and arg1 == "player" then
|
||||
if this.fsrSpell and this.fsrSpell == arg3 then
|
||||
this.fsrEnd, this.fsrGain = GetTime() + FIVE_SECOND_RULE, nil
|
||||
this.fsrGain = nil
|
||||
this.fsr:SetTimeFromStart(GetTime(), FIVE_SECOND_RULE)
|
||||
end
|
||||
return
|
||||
end
|
||||
@@ -189,7 +190,7 @@ pfUI:RegisterModule("energytick", function()
|
||||
-- only a gain can be the tick; a spend never touches the phase
|
||||
if diff > 0 and lockTick(this) then
|
||||
-- a tick inside the window proves regen continues through it
|
||||
if this.fsrEnd and this.fsrEnd > GetTime() then
|
||||
if this.fsr:IsActive() then
|
||||
this.fsrGain = true
|
||||
end
|
||||
end
|
||||
@@ -208,25 +209,15 @@ pfUI:RegisterModule("energytick", function()
|
||||
end
|
||||
this.tick = GetTime() + 0.020 -- ~50 FPS
|
||||
|
||||
-- five-second rule drains to nothing. The display is cosmetic and can be
|
||||
-- hidden on its own; the window itself (fsrEnd/fsrGain) keeps running
|
||||
-- either way -- it still dims the sweep spark below.
|
||||
local remaining = this.fsrEnd and (this.fsrEnd - GetTime()) or 0
|
||||
if this.mode == "MANA" and remaining > 0 then
|
||||
if C.unitframes.player.showfsr == "1" then
|
||||
if fsrOverlay then
|
||||
this.fsrbar:SetWidth(getBarWidth() * remaining / FIVE_SECOND_RULE)
|
||||
else
|
||||
this.fsrbar:SetValue(remaining)
|
||||
end
|
||||
this.fsrbar:Show()
|
||||
else
|
||||
this.fsrbar:Hide()
|
||||
end
|
||||
else
|
||||
this.fsrSpell, this.fsrEnd, this.fsrGain = nil, nil, nil
|
||||
this.fsrbar:Hide()
|
||||
-- five-second rule: fsrbar drains from this.fsr by itself. The display is
|
||||
-- cosmetic and can be hidden on its own; the window itself (fsr/fsrGain)
|
||||
-- keeps running either way -- it still dims the sweep spark below.
|
||||
local fsrUp = this.mode == "MANA" and this.fsr:IsActive()
|
||||
if not fsrUp and this.fsrSpell then
|
||||
this.fsrSpell, this.fsrGain = nil, nil
|
||||
this.fsr:Reset()
|
||||
end
|
||||
this.fsrbar:SetShown(fsrUp and C.unitframes.player.showfsr == "1")
|
||||
|
||||
if not this.start then
|
||||
this.spark:SetAlpha(0)
|
||||
@@ -249,7 +240,7 @@ pfUI:RegisterModule("energytick", function()
|
||||
end
|
||||
|
||||
-- dim while the rule is up and nothing has ticked inside it yet
|
||||
this.spark:SetAlpha((remaining > 0 and not this.fsrGain) and .4 or 1)
|
||||
this.spark:SetAlpha((fsrUp and not this.fsrGain) and .4 or 1)
|
||||
|
||||
if not C.unitframes.player.pheight then
|
||||
return
|
||||
@@ -259,19 +250,21 @@ pfUI:RegisterModule("energytick", function()
|
||||
this.spark:SetPoint("LEFT", pos - ((C.unitframes.player.pheight + 5) / 2), 0)
|
||||
end)
|
||||
|
||||
energytick.fsr = C_DurationUtil.CreateDuration()
|
||||
|
||||
if fsrOverlay then
|
||||
-- classic style: a translucent shade on top of the power bar's own fill
|
||||
energytick.fsrbar = energytick:CreateTexture(nil, "ARTWORK")
|
||||
energytick.fsrbar:SetColorTexture(1, 1, 1, .15)
|
||||
energytick.fsrbar:SetPoint("TOPLEFT", 0, 0)
|
||||
energytick.fsrbar:SetPoint("BOTTOMLEFT", 0, 0)
|
||||
-- classic style: a translucent shade on top of the power bar's own fill,
|
||||
-- under the spark
|
||||
energytick.fsrbar = CreateFrame("StatusBar", nil, pfUI.uf.player.power.bar)
|
||||
energytick.fsrbar:SetAllPoints(energytick)
|
||||
energytick.fsrbar:SetColorFill(1, 1, 1, .15)
|
||||
energytick:SetFrameLevel(energytick.fsrbar:GetFrameLevel() + 1)
|
||||
else
|
||||
-- a real bar below the power bar, not an overlay on top of it -- the same
|
||||
-- treatment nameplate castbars get relative to the health bar, so the
|
||||
-- window can't be mistaken for missing mana
|
||||
energytick.fsrbar = CreateFrame("StatusBar", nil, pfUI.uf.player)
|
||||
energytick.fsrbar:SetStatusBarTexture(cbtexture)
|
||||
energytick.fsrbar:SetMinMaxValues(0, FIVE_SECOND_RULE)
|
||||
energytick.fsrbar:SetPoint("TOPLEFT", pfUI.uf.player.power.bar, "BOTTOMLEFT", 0, -default_border * 2)
|
||||
energytick.fsrbar:SetPoint("TOPRIGHT", pfUI.uf.player.power.bar, "BOTTOMRIGHT", 0, -default_border * 2)
|
||||
energytick.fsrbar:SetHeight(tonumber(C.unitframes.player.fsrheight) or 4)
|
||||
@@ -279,8 +272,14 @@ pfUI:RegisterModule("energytick", function()
|
||||
CreateBackdrop(energytick.fsrbar, default_border)
|
||||
CreateBackdropShadow(energytick.fsrbar)
|
||||
end
|
||||
energytick.fsrbar:SetTimerDuration(energytick.fsr, Enum.StatusBarInterpolation.Immediate, Enum.StatusBarTimerDirection.RemainingTime)
|
||||
energytick.fsrbar:Hide()
|
||||
|
||||
-- the bar isn't parented to energytick, and OnUpdate stops with it
|
||||
energytick:SetScript("OnHide", function()
|
||||
this.fsrbar:Hide()
|
||||
end)
|
||||
|
||||
energytick.spark = energytick:CreateTexture(nil, "OVERLAY")
|
||||
energytick.spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark")
|
||||
energytick.spark:SetHeight(C.unitframes.player.pheight + 15)
|
||||
|
||||
+6
-10
@@ -238,17 +238,11 @@ pfUI:RegisterModule("roll", function ()
|
||||
f.time.bar = CreateFrame("StatusBar", "pfLootRollFrame" .. id .. "TimeBar", f.time)
|
||||
f.time.bar:SetAllPoints(f.time)
|
||||
f.time.bar:SetStatusBarTexture(pfUI.media["img:bar"])
|
||||
f.time.bar:SetMinMaxValues(0, 100)
|
||||
local r, g, b, a = GetStringColor(C.appearance.border.color)
|
||||
f.time.bar:SetStatusBarColor(r, g, b)
|
||||
f.time.bar:SetValue(20)
|
||||
f.time.bar:SetScript("OnUpdate", function()
|
||||
if not this:GetParent():GetParent().rollID then return end
|
||||
local left = GetLootRollTimeLeft(this:GetParent():GetParent().rollID)
|
||||
local min, max = this:GetMinMaxValues()
|
||||
if left < min or left > max then left = min end
|
||||
this:SetValue(left)
|
||||
end)
|
||||
-- drains by itself; UpdateLootRoll sets the roll's time span
|
||||
f.time.duration = C_DurationUtil.CreateDuration()
|
||||
f.time.bar:SetTimerDuration(f.time.duration, Enum.StatusBarInterpolation.Immediate, Enum.StatusBarTimerDirection.RemainingTime)
|
||||
|
||||
return f
|
||||
end
|
||||
@@ -299,7 +293,9 @@ pfUI:RegisterModule("roll", function ()
|
||||
pfUI.roll.frames[id].name.text:SetTextColor(color.r, color.g, color.b, 1)
|
||||
pfUI.roll.frames[id].icon.tex:SetTexture(texture)
|
||||
pfUI.roll.frames[id].backdrop:SetBackdropBorderColor(color.r, color.g, color.b)
|
||||
pfUI.roll.frames[id].time.bar:SetMinMaxValues(0, pfUI.roll.frames[id].rollTime)
|
||||
-- both in milliseconds
|
||||
local left = GetLootRollTimeLeft(pfUI.roll.frames[id].rollID)
|
||||
pfUI.roll.frames[id].time.duration:SetTimeFromEnd(GetTime() + left / 1000, pfUI.roll.frames[id].rollTime / 1000)
|
||||
|
||||
if C.loot.raritytimer == "1" then
|
||||
pfUI.roll.frames[id].time.bar:SetStatusBarColor(color.r, color.g, color.b, .5)
|
||||
|
||||
Reference in New Issue
Block a user