4 Commits

Author SHA1 Message Date
Brues 8268af915a energytick: let the five-second rule display as a separate bar or the old shade
The shading bar sat on top of the power bar's own fill and shrank from the
right as the window drained, which reads as part of the mana bar rather than
a countdown over it -- the same problem nameplate castbars solve by living
below the health bar instead of on it.

Show Five Second Rule Style now picks between that: a real StatusBar below
the power bar, backdrop and all, or the original translucent overlay for
anyone who prefers it. The style is read once at module load like the other
structural toggles here, not swapped live -- a /reload picks up a change.
Height and color are only meaningful for the separate-bar style, so the
GUI's Five Second Rule Height and the new appearance.castbar.fsrcolor picker
apply to it alone; the overlay is unchanged from before.

The sweep spark's own dim/solid signal (fsrEnd/fsrGain) is untouched by any
of this -- it keeps dimming through an unconfirmed window regardless of
which display, or none, is shown.

Energy/Mana Ticks -- including both five-second-rule settings -- moves from
Unit Frames > General to Unit Frames > Player, right after Powerbar: they
are C.unitframes.player-only, so General was never the right tab, and
Powerbar is the setting group they actually belong to.
2026-09-22 21:19:12 -05:00
Brues 1108746949 castbar: mark a cast that none of your interrupts can stop
ClassicAPI carries notInterruptible on C_Spell.UnitCastingInfo (arg 8) and
UnitChannelInfo (arg 7); both call sites already stepped over it positionally.
The target, focus and nameplate bars now paint it.

There is no shield art to hang on the icon -- this client ships three
CastingBar textures (Border, Flash, Spark), and Blizzard's shield arrived in
3.x -- so the state is carried by color instead: the bar and the icon's
border both take a new appearance.castbar.shieldcolor, which keeps it legible
on a bar configured without an icon. One api helper paints both so the two
modules cannot drift apart on it.

Dusty rose (.8,.45,.45) rather than a steel grey. Grey is the retail
convention, but pfUI's casting color is already a near-grey pale blue, so the
two separated on brightness alone and washed out against the bar texture. The
rose sits above failcolor in luminance and well below it in saturation, and
the two are further told apart by motion: a failed cast flashes the bar full
and fades, a shielded one fills normally and tints the icon border, which
failcolor never touches.

Not on the player's own bar. The flag is measured against the reader's own
interrupts and silences, so on your own cast it answers a question nobody
asked.

Stamped once at cast start, with the rest of the cast data, rather than
re-polled. ClassicAPI evaluates lazily from the caster's live auras but does
not yet fire the 3.3.5 UNIT_SPELLCAST_INTERRUPTIBLE / _NOT_INTERRUPTIBLE
change events, and polling per frame would undo the event-driven rework these
bars just got -- so a caster who bubbles mid-cast keeps the bar it started
with until the next one.

Two limits worth knowing when it stays dark. The value is relative to your own
kit -- with no interrupt and no silence known it is never reported, whatever
the cast -- and a creature's built-in interrupt immunity lives in
creature_template, which 1.12's SMSG_SPELL_START does not carry, so a boss
with that immunity reads interruptible while your kick still fails on it.
2026-09-13 15:19:42 -05:00
Brues 38b4100353 server agnostic <3 2026-09-12 04:36:27 -05:00
Brues f497c71523 Filter unit events to their units, rework energytick, drop macrotweak
Eight commits off classicapi_next.

ClassicAPI's RegisterUnitEvent registers for an event but only delivers it
when arg1 is one of the given units, so a handler for one unit stops waking
for every other one in the world. The 26 registrations whose unit set is
fixed at registration time now name it. The rule throughout is register the
superset and keep the handler's own check -- the filter narrows what arrives,
it does not decide what to act on. Guards that look unreachable stay put: the
filter applies only when arg1 is a string, so an event that fires with a
number or no argument is delivered as if plainly registered.

Frames whose unit changes at runtime own their subscriptions instead of
sorting events out per event. unitframes points them at the unitstr
UpdateVisibility already computes -- replacing a string concat, and on a miss
a second concat plus a UnitGUID call, for every frame on every unit event in
the world -- and a frame that is not in use drops its unit events entirely.
nameplates registers per plate against the plate's own token, which is also
the only workable shape: slots have no cap, so any nameplate1..N list would
have been a guess that fails in exactly the crowded scenes where plates
matter. marktracking names mark1 through mark8. A registration keeps its
kind, so none of these can be plain-registered first.

Both teardown paths PLAYER_LOGOUT guards -- the crash 132 -- now cover the
per-frame subscriptions: plates tear down rather than dispatching through
logout, and a unit frame takes itself off the visibility scan so it cannot
re-register what it just dropped.

marktracking also drops its once-a-second full rebuild, which ran for the
whole session whether or not a marker existed anywhere. The ticker is created
and cancelled with group membership. It is deliberately not keyed on a mark
being visible -- a marker on an out-of-range unit shows no row, and that is
the case the poll exists to catch.

nameplates gates the per-plate update against the floor across all four
throttle categories before classifying it, instead of running a GetAlpha, a
castbar IsShown, a cast lookup and up to two libthrottle:Get resolutions on
plates throttled to 10fps that were going to return anyway. Nothing that
would have updated can be turned away by a floor. The four throttles resolve
in CacheConfig, where config changes already land.

energytick sweeps the clock the server actually runs. There is one regen
timer for every power, re-armed every 2s by Player::RegenerateAll and never
touched by casting; the five-second rule changes what a tick pays, not when
it lands. The sweep is a free-running phase lock on that clock, so
Illumination refunds, potions and a Mana Spring totem on its own phase no
longer snap the spark mid-cycle, and an 80ms band keeps a correct tick from
hitching it at the wrap. The FSR window shades rather than predicting a share
of spirit the client cannot compute -- the Casting Regen item ladder is equip
auras absent from the buff list. The energy period is summed from
SPELL_AURA_MOD_ENERGY_REGEN_TIME across the spellbook and buffs, so Blade
Rush is found without GetTalentInfo(2, 16), an ordinal that does not fail
when the tree changes but reads another talent's rank.

macrotweak is gone -- ClassicAPI 1.15 covers it -- with its config entry, its
GUI block, its translations in all eight locales, and actionbar's
ButtonMacroScan, the #showtooltip scanner that fed it.
2026-09-11 00:10:51 -05:00
7 changed files with 99 additions and 21 deletions
+1 -4
View File
@@ -1,13 +1,10 @@
# pfUI - ClassicAPI Edition # pfUI - ClassicAPI Edition
[![Octo WoW](https://img.shields.io/badge/Octo%20WoW-1.18.1-brightgreen.svg)](https://octowow.st/)
[![ClassicAPI](https://img.shields.io/badge/ClassicAPI-Required-purple.svg)](https://github.com/brues-code/ClassicAPI) [![ClassicAPI](https://img.shields.io/badge/ClassicAPI-Required-purple.svg)](https://github.com/brues-code/ClassicAPI)
[![Nampower](https://img.shields.io/badge/Nampower-Required-purple.svg)](https://github.com/brues-code/nampower) [![Nampower](https://img.shields.io/badge/Nampower-Required-purple.svg)](https://github.com/brues-code/nampower)
[![SuperWoW](https://img.shields.io/badge/SuperWoW-Optional-yellow.svg)](https://github.com/balakethelock/SuperWoW) [![SuperWoW](https://img.shields.io/badge/SuperWoW-Optional-yellow.svg)](https://github.com/balakethelock/SuperWoW)
[![UnitXP](https://img.shields.io/badge/UnitXP__SP3-Optional-yellow.svg)](https://github.com/brues-code/UnitXP_SP3) [![UnitXP](https://img.shields.io/badge/UnitXP__SP3-Optional-yellow.svg)](https://github.com/brues-code/UnitXP_SP3)
**A pfUI fork specifically optimized for ClassicAPI on [Octo WoW](https://octowow.st/)**
This version includes significant performance improvements and DLL-enhanced features. This version includes significant performance improvements and DLL-enhanced features.
## Installation ## Installation
@@ -18,7 +15,7 @@ This version includes significant performance improvements and DLL-enhanced feat
## DLL Enhancements ## DLL Enhancements
Since pfUI 6.0.0 includes integrations with client-side DLLs for enhanced functionality. These DLLs are permitted on Octo WoW: Since pfUI 6.0.0 includes integrations with client-side DLLs for enhanced functionality:
### [ClassicAPI](https://github.com/brues-code/ClassicAPI) ### [ClassicAPI](https://github.com/brues-code/ClassicAPI)
+26
View File
@@ -1333,6 +1333,32 @@ function pfUI.api.CreateBackdropShadow(f)
f.backdrop_shadow:SetBackdropBorderColor(0, 0, 0, tonumber(pfUI_config.appearance.border.shadow_intensity)) f.backdrop_shadow:SetBackdropBorderColor(0, 0, 0, tonumber(pfUI_config.appearance.border.shadow_intensity))
end end
-- [ Set Castbar Shield ]
-- Colors a castbar for a cast that none of the player's own interrupts or
-- silences can stop. The bar and the icon's border both take the shield color,
-- so the state still reads on a bar configured without an icon. Not shielded
-- restores the normal cast/channel color and the configured border.
-- 'bar' [frame] the castbar statusbar
-- 'icon' [frame] the icon frame, or nil for a bar without one
-- 'shielded' [bool] whether the cast is uninterruptible
-- 'isChannel' [bool] selects the unshielded color
function pfUI.api.SetCastbarShield(bar, icon, shielded, isChannel)
if shielded then
bar:SetStatusBarColor(pfUI.api.GetStringColor(C.appearance.castbar.shieldcolor))
else
bar:SetStatusBarColor(pfUI.api.GetStringColor(C.appearance.castbar[isChannel and "channelcolor" or "castbarcolor"]))
end
local iconborder = icon and icon.backdrop
if not iconborder then return end
if shielded then
iconborder:SetBackdropBorderColor(pfUI.api.GetStringColor(C.appearance.castbar.shieldcolor))
else
iconborder:SetBackdropBorderColor(pfUI.api.GetStringColor(C.appearance.border.color))
end
end
-- [ Bar Layout Options ] -- -- [ Bar Layout Options ] --
-- 'barsize' size of bar in number of buttons -- 'barsize' size of bar in number of buttons
-- returns: array of options as strings for pfUI.gui.bar -- returns: array of options as strings for pfUI.gui.bar
+5
View File
@@ -156,6 +156,8 @@ function pfUI:LoadConfig()
pfUI:UpdateConfig("appearance", "castbar", "castbarcolor", ".7,.7,.9,.8") pfUI:UpdateConfig("appearance", "castbar", "castbarcolor", ".7,.7,.9,.8")
pfUI:UpdateConfig("appearance", "castbar", "channelcolor", ".9,.9,.7,.8") pfUI:UpdateConfig("appearance", "castbar", "channelcolor", ".9,.9,.7,.8")
pfUI:UpdateConfig("appearance", "castbar", "failcolor", "1,.2,.2,.8") pfUI:UpdateConfig("appearance", "castbar", "failcolor", "1,.2,.2,.8")
pfUI:UpdateConfig("appearance", "castbar", "shieldcolor", ".8,.45,.45,.8")
pfUI:UpdateConfig("appearance", "castbar", "fsrcolor", ".9,.6,.2,.8")
pfUI:UpdateConfig("appearance", "castbar", "texture", "Interface\\AddOns\\pfUI\\img\\bar") pfUI:UpdateConfig("appearance", "castbar", "texture", "Interface\\AddOns\\pfUI\\img\\bar")
pfUI:UpdateConfig("appearance", "infight", "screen", "0") pfUI:UpdateConfig("appearance", "infight", "screen", "0")
pfUI:UpdateConfig("appearance", "infight", "aggro", "0") pfUI:UpdateConfig("appearance", "infight", "aggro", "0")
@@ -324,6 +326,9 @@ function pfUI:LoadConfig()
pfUI:UpdateConfig("unitframes", "player", "showRest", "0") pfUI:UpdateConfig("unitframes", "player", "showRest", "0")
pfUI:UpdateConfig("unitframes", "player", "energy", "1") pfUI:UpdateConfig("unitframes", "player", "energy", "1")
pfUI:UpdateConfig("unitframes", "player", "manatick", "0") pfUI:UpdateConfig("unitframes", "player", "manatick", "0")
pfUI:UpdateConfig("unitframes", "player", "showfsr", "1")
pfUI:UpdateConfig("unitframes", "player", "fsrheight", "4")
pfUI:UpdateConfig("unitframes", "player", "fsrstyle", "0")
pfUI:UpdateConfig("unitframes", "player", "display_haste", "0") pfUI:UpdateConfig("unitframes", "player", "display_haste", "0")
pfUI:UpdateConfig("unitframes", "player", "display_haste_color", "1,1,1,1") pfUI:UpdateConfig("unitframes", "player", "display_haste_color", "1,1,1,1")
pfUI:UpdateConfig("unitframes", "player", "display_spellpower", "1") pfUI:UpdateConfig("unitframes", "player", "display_spellpower", "1")
+8 -5
View File
@@ -86,7 +86,7 @@ pfUI:RegisterModule("castbar", function ()
-- Stamp the bar with cast data and render text/icon/lag once. OnUpdate -- Stamp the bar with cast data and render text/icon/lag once. OnUpdate
-- then animates the fill from this state without touching C_Spell. -- then animates the fill from this state without touching C_Spell.
local function StampBar(cb, name, tex, startMs, endMs, spellID, isChannel, delayMs, isTradeskill, rank) local function StampBar(cb, name, tex, startMs, endMs, spellID, isChannel, delayMs, isTradeskill, rank, noInterrupt)
cb.startTime = startMs cb.startTime = startMs
cb.endTime = endMs cb.endTime = endMs
cb.isChannel = isChannel cb.isChannel = isChannel
@@ -97,7 +97,10 @@ pfUI:RegisterModule("castbar", function ()
cb:SetAlpha(1) cb:SetAlpha(1)
cb.fadeout = nil cb.fadeout = nil
cb.bar:SetStatusBarColor(GetStringColor(C.appearance.castbar[isChannel and "channelcolor" or "castbarcolor"])) -- Shield an uninterruptible cast. Not on the player's own bar: the flag is
-- measured against the reader's own interrupts and silences, so on your own
-- cast it answers a question nobody asked.
SetCastbarShield(cb.bar, cb.icon, noInterrupt and cb.unitstr ~= "player", isChannel)
-- Rank: prefer the value the UNIT_SPELLCAST_* event delivered (arg5, passed -- Rank: prefer the value the UNIT_SPELLCAST_* event delivered (arg5, passed
-- through by RefreshBar). Only the retarget re-poll has no event in hand, so -- through by RefreshBar). Only the retarget re-poll has no event in hand, so
@@ -152,10 +155,10 @@ pfUI:RegisterModule("castbar", function ()
ClearBar(cb) ClearBar(cb)
return return
end end
local name, _, tex, startMs, endMs, isTradeskill, _, _, spellID, _, delayMs = C_Spell.UnitCastingInfo(query) local name, _, tex, startMs, endMs, isTradeskill, _, noInterrupt, spellID, _, delayMs = C_Spell.UnitCastingInfo(query)
local isChan local isChan
if not name then if not name then
name, _, tex, startMs, endMs, _, _, spellID = C_Spell.UnitChannelInfo(query) name, _, tex, startMs, endMs, _, noInterrupt, spellID = C_Spell.UnitChannelInfo(query)
isChan = true isChan = true
end end
-- Synthetic fallback for abilities the engine treats as instant-cast but -- Synthetic fallback for abilities the engine treats as instant-cast but
@@ -169,7 +172,7 @@ pfUI:RegisterModule("castbar", function ()
end end
end end
if name and startMs and endMs then if name and startMs and endMs then
StampBar(cb, name, tex, startMs, endMs, spellID, isChan, delayMs, isTradeskill, rank) StampBar(cb, name, tex, startMs, endMs, spellID, isChan, delayMs, isTradeskill, rank, noInterrupt)
else else
ClearBar(cb) ClearBar(cb)
end end
+44 -7
View File
@@ -89,6 +89,13 @@ pfUI:RegisterModule("energytick", function()
return C.unitframes.player.pwidth ~= "-1" and C.unitframes.player.pwidth or C.unitframes.player.width return C.unitframes.player.pwidth ~= "-1" and C.unitframes.player.pwidth or C.unitframes.player.width
end end
local rawborder, default_border = GetBorderSize("unitframes")
local cbtexture = pfUI.media[C.appearance.castbar.texture]
-- style is read once: switching it in the GUI needs a /reload, same as the
-- other structural (not cosmetic) toggles in this file
local fsrOverlay = C.unitframes.player.fsrstyle == "1"
-- was this gain the regen tick? if so, re-anchor the sweep on it -- was this gain the regen tick? if so, re-anchor the sweep on it
local function lockTick(frame) local function lockTick(frame)
local now, period = GetTime(), getAdjustedTickTimer() local now, period = GetTime(), getAdjustedTickTimer()
@@ -199,11 +206,21 @@ pfUI:RegisterModule("energytick", function()
end end
this.tick = GetTime() + 0.020 -- ~50 FPS this.tick = GetTime() + 0.020 -- ~50 FPS
-- five-second rule drains to nothing -- 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 local remaining = this.fsrEnd and (this.fsrEnd - GetTime()) or 0
if this.mode == "MANA" and remaining > 0 then if this.mode == "MANA" and remaining > 0 then
this.fsrbar:SetWidth(getBarWidth() * remaining / FIVE_SECOND_RULE) if C.unitframes.player.showfsr == "1" then
this.fsrbar:Show() 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 else
this.fsrSpell, this.fsrEnd, this.fsrGain = nil, nil, nil this.fsrSpell, this.fsrEnd, this.fsrGain = nil, nil, nil
this.fsrbar:Hide() this.fsrbar:Hide()
@@ -240,10 +257,26 @@ pfUI:RegisterModule("energytick", function()
this.spark:SetPoint("LEFT", pos - ((C.unitframes.player.pheight + 5) / 2), 0) this.spark:SetPoint("LEFT", pos - ((C.unitframes.player.pheight + 5) / 2), 0)
end) end)
energytick.fsrbar = energytick:CreateTexture(nil, "ARTWORK") if fsrOverlay then
energytick.fsrbar:SetTexture(1, 1, 1, .15) -- classic style: a translucent shade on top of the power bar's own fill
energytick.fsrbar:SetPoint("TOPLEFT", 0, 0) energytick.fsrbar = energytick:CreateTexture(nil, "ARTWORK")
energytick.fsrbar:SetPoint("BOTTOMLEFT", 0, 0) energytick.fsrbar:SetTexture(1, 1, 1, .15)
energytick.fsrbar:SetPoint("TOPLEFT", 0, 0)
energytick.fsrbar:SetPoint("BOTTOMLEFT", 0, 0)
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)
energytick.fsrbar:SetStatusBarColor(GetStringColor(C.appearance.castbar.fsrcolor))
CreateBackdrop(energytick.fsrbar, default_border)
CreateBackdropShadow(energytick.fsrbar)
end
energytick.fsrbar:Hide() energytick.fsrbar:Hide()
energytick.spark = energytick:CreateTexture(nil, "OVERLAY") energytick.spark = energytick:CreateTexture(nil, "OVERLAY")
@@ -256,6 +289,10 @@ pfUI:RegisterModule("energytick", function()
function pfUI.uf.player.UpdateConfig() function pfUI.uf.player.UpdateConfig()
energytick.spark:SetHeight(C.unitframes.player.pheight + 15) energytick.spark:SetHeight(C.unitframes.player.pheight + 15)
energytick.spark:SetWidth(C.unitframes.player.pheight + 5) energytick.spark:SetWidth(C.unitframes.player.pheight + 5)
if not fsrOverlay then
energytick.fsrbar:SetHeight(tonumber(C.unitframes.player.fsrheight) or 4)
energytick.fsrbar:SetStatusBarColor(GetStringColor(C.appearance.castbar.fsrcolor))
end
hookUpdateConfig(pfUI.uf.player) hookUpdateConfig(pfUI.uf.player)
end end
end) end)
+11 -2
View File
@@ -2072,8 +2072,6 @@ pfUI:RegisterModule("gui", function ()
CreateConfig(nil, T["Combopoint Width"], C.unitframes, "combowidth") CreateConfig(nil, T["Combopoint Width"], C.unitframes, "combowidth")
CreateConfig(nil, T["Combopoint Height"], C.unitframes, "comboheight") CreateConfig(nil, T["Combopoint Height"], C.unitframes, "comboheight")
CreateConfig(nil, T["Show Resting"], C.unitframes.player, "showRest", "checkbox") CreateConfig(nil, T["Show Resting"], C.unitframes.player, "showRest", "checkbox")
CreateConfig(nil, T["Enable Energy Ticks"], C.unitframes.player, "energy", "checkbox")
CreateConfig(nil, T["Enable Mana Ticks"], C.unitframes.player, "manatick", "checkbox")
CreateConfig(nil, T["Detect Enemy Buffs"], C.unitframes, "buffdetect", "checkbox", nil, nil, nil, nil) CreateConfig(nil, T["Detect Enemy Buffs"], C.unitframes, "buffdetect", "checkbox", nil, nil, nil, nil)
CreateConfig(nil, T["Raid Mark Icon Style"], C.unitframes, "blizzard_raidicons", "dropdown", function() return {"1:Original Blizzard", "0:pfUI Design"} end) CreateConfig(nil, T["Raid Mark Icon Style"], C.unitframes, "blizzard_raidicons", "dropdown", function() return {"1:Original Blizzard", "0:pfUI Design"} end)
@@ -2320,6 +2318,15 @@ pfUI:RegisterModule("gui", function ()
CreateConfig(U[c], T["Right Text Y Offset"], C.unitframes[c], "txtpowerrightoffy") CreateConfig(U[c], T["Right Text Y Offset"], C.unitframes[c], "txtpowerrightoffy")
CreateConfig(U[c], T["Power Bar Anchor"], C.unitframes[c], "panchor", "dropdown", pfUI.gui.dropdowns.uf_powerbar_position) CreateConfig(U[c], T["Power Bar Anchor"], C.unitframes[c], "panchor", "dropdown", pfUI.gui.dropdowns.uf_powerbar_position)
if c == "player" then
CreateConfig(nil, T["Energy/Mana Ticks"], nil, nil, "header")
CreateConfig(nil, T["Enable Energy Ticks"], C.unitframes[c], "energy", "checkbox")
CreateConfig(nil, T["Enable Mana Ticks"], C.unitframes[c], "manatick", "checkbox")
CreateConfig(nil, T["Show Five Second Rule"], C.unitframes[c], "showfsr", "checkbox")
CreateConfig(nil, T["Five Second Rule Style"], C.unitframes[c], "fsrstyle", "dropdown", function() return {"0:Separate Bar", "1:Overlay"} end)
CreateConfig(nil, T["Five Second Rule Height"], C.unitframes[c], "fsrheight")
end
CreateConfig(U[c], T["Combat Text"], nil, nil, "header") CreateConfig(U[c], T["Combat Text"], nil, nil, "header")
CreateConfig(U[c], T["Show Combat Text"], C.unitframes[c], "hitindicator", "checkbox") CreateConfig(U[c], T["Show Combat Text"], C.unitframes[c], "hitindicator", "checkbox")
CreateConfig(U[c], T["Combat Text Font"], C.unitframes[c], "hitindicatorfont", "dropdown", pfUI.gui.dropdowns.fonts) CreateConfig(U[c], T["Combat Text Font"], C.unitframes[c], "hitindicatorfont", "dropdown", pfUI.gui.dropdowns.fonts)
@@ -2792,6 +2799,8 @@ pfUI:RegisterModule("gui", function ()
CreateConfig(nil, T["Use Unit Fonts"], C.castbar, "use_unitfonts", "checkbox") CreateConfig(nil, T["Use Unit Fonts"], C.castbar, "use_unitfonts", "checkbox")
CreateConfig(nil, T["Casting Color"], C.appearance.castbar, "castbarcolor", "color") CreateConfig(nil, T["Casting Color"], C.appearance.castbar, "castbarcolor", "color")
CreateConfig(nil, T["Channeling Color"], C.appearance.castbar, "channelcolor", "color") CreateConfig(nil, T["Channeling Color"], C.appearance.castbar, "channelcolor", "color")
CreateConfig(nil, T["Uninterruptible Color"], C.appearance.castbar, "shieldcolor", "color")
CreateConfig(nil, T["Five Second Rule Color"], C.appearance.castbar, "fsrcolor", "color")
CreateConfig(nil, T["Castbar Texture"], C.appearance.castbar, "texture", "dropdown", pfUI.gui.dropdowns.uf_bartexture) CreateConfig(nil, T["Castbar Texture"], C.appearance.castbar, "texture", "dropdown", pfUI.gui.dropdowns.uf_bartexture)
CreateConfig(nil, T["Disable Blizzard Castbar"], C.castbar.player, "hide_blizz", "checkbox") CreateConfig(nil, T["Disable Blizzard Castbar"], C.castbar.player, "hide_blizz", "checkbox")
end) end)
+4 -3
View File
@@ -77,10 +77,10 @@ pfUI:RegisterModule("nameplates", function ()
-- vs channel itself. Never called per frame. -- vs channel itself. Never called per frame.
local function PollCastInfo(unit) local function PollCastInfo(unit)
if not unit then return nil end if not unit then return nil end
local name, _, texture, startMs, endMs, _, _, _, spellID = C_Spell.UnitCastingInfo(unit) local name, _, texture, startMs, endMs, _, _, noInterrupt, spellID = C_Spell.UnitCastingInfo(unit)
local isChannel local isChannel
if not name then if not name then
name, _, texture, startMs, endMs, _, _, spellID = C_Spell.UnitChannelInfo(unit) name, _, texture, startMs, endMs, _, noInterrupt, spellID = C_Spell.UnitChannelInfo(unit)
isChannel = true isChannel = true
end end
if not name or not startMs or not endMs then return nil end if not name or not startMs or not endMs then return nil end
@@ -92,6 +92,7 @@ pfUI:RegisterModule("nameplates", function ()
endTime = endMs / 1000, endTime = endMs / 1000,
duration = (endMs - startMs) / 1000, duration = (endMs - startMs) / 1000,
isChannel = isChannel, isChannel = isChannel,
noInterrupt = noInterrupt,
} }
end end
@@ -1751,7 +1752,7 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
-- Relative 0..duration range to avoid float precision loss with large -- Relative 0..duration range to avoid float precision loss with large
-- absolute timestamps. -- absolute timestamps.
nameplate.castbar:SetMinMaxValues(0, duration) nameplate.castbar:SetMinMaxValues(0, duration)
nameplate.castbar:SetStatusBarColor(GetStringColor(C.appearance.castbar[(isChannel and "channelcolor" or "castbarcolor")])) SetCastbarShield(nameplate.castbar, nameplate.castbar.icon, castInfo.noInterrupt, isChannel)
if castInfo.icon then if castInfo.icon then
nameplate.castbar.icon.tex:SetTexture(castInfo.icon) nameplate.castbar.icon.tex:SetTexture(castInfo.icon)
nameplate.castbar.icon.tex:SetTexCoord(.1,.9,.1,.9) nameplate.castbar.icon.tex:SetTexCoord(.1,.9,.1,.9)