mirror of
https://github.com/brues-code/pfUI.git
synced 2026-11-06 02:28:58 +00:00
Swing timer: bars fill from duration objects, drop the OnUpdate
Each bar fills itself from a duration object of the swing, a text binding counts it down, and the marker with its glows rides the fill's edge. One C_Timer per bar ends the swing, runs the melee grace and switches a hunter's reload to the deadzone. Colors update on the events that change them, ACTIONBAR_UPDATE_STATE standing in for the per-tick IsCurrentAction reconcile; a bar waiting past its grace hides on STOP_AUTOATTACK or leaving combat. The three bar builders become one. The Swing Timer throttle setting only paced the OnUpdate, so it goes.
This commit is contained in:
@@ -33,7 +33,6 @@ libthrottle.presetNames = {
|
|||||||
libthrottle.defaults = {
|
libthrottle.defaults = {
|
||||||
tooltip_cursor = "fastest",
|
tooltip_cursor = "fastest",
|
||||||
chat_tab = "custom",
|
chat_tab = "custom",
|
||||||
swingtimer = "custom",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Convert FPS to throttle delay in seconds
|
-- Convert FPS to throttle delay in seconds
|
||||||
@@ -156,7 +155,6 @@ libthrottle:SetScript("OnEvent", function()
|
|||||||
-- Set defaults for custom fields if missing
|
-- Set defaults for custom fields if missing
|
||||||
if not _G.pfUI_throttle.tooltip_cursor_custom then _G.pfUI_throttle.tooltip_cursor_custom = "10" end
|
if not _G.pfUI_throttle.tooltip_cursor_custom then _G.pfUI_throttle.tooltip_cursor_custom = "10" end
|
||||||
if not _G.pfUI_throttle.chat_tab_custom then _G.pfUI_throttle.chat_tab_custom = "10" end
|
if not _G.pfUI_throttle.chat_tab_custom then _G.pfUI_throttle.chat_tab_custom = "10" end
|
||||||
if not _G.pfUI_throttle.swingtimer_custom then _G.pfUI_throttle.swingtimer_custom = "50" end
|
|
||||||
|
|
||||||
this:UnregisterEvent("PLAYER_ENTERING_WORLD")
|
this:UnregisterEvent("PLAYER_ENTERING_WORLD")
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1788,67 +1788,6 @@ pfUI:RegisterModule("gui", function ()
|
|||||||
end, true)
|
end, true)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
CreateGUIEntry(T["Throttling"], T["Swing Timer"], function()
|
|
||||||
local swingCustom
|
|
||||||
|
|
||||||
CreateConfig(function()
|
|
||||||
if swingCustom and swingCustom.input then
|
|
||||||
local isCustom = pfUI.throttle:IsCustom("swingtimer")
|
|
||||||
if not isCustom then
|
|
||||||
swingCustom.input:EnableMouse(false)
|
|
||||||
swingCustom.input:EnableKeyboard(false)
|
|
||||||
swingCustom.input:ClearFocus()
|
|
||||||
swingCustom.input:SetTextColor(.5,.5,.5,1)
|
|
||||||
swingCustom.input:SetText(tostring(pfUI.throttle:GetFps("swingtimer")))
|
|
||||||
else
|
|
||||||
swingCustom.input:EnableMouse(true)
|
|
||||||
swingCustom.input:EnableKeyboard(true)
|
|
||||||
swingCustom.input:SetTextColor(.2,1,.8,1)
|
|
||||||
if _G.pfUI_throttle.swingtimer_custom then
|
|
||||||
swingCustom.input:SetText(_G.pfUI_throttle.swingtimer_custom)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end, T["Swing Timer Update Rate"], _G.pfUI_throttle, "swingtimer", "dropdown", {
|
|
||||||
"very_slow:" .. T["Very Slow"] .. " (2 FPS)",
|
|
||||||
"slow:" .. T["Slow"] .. " (5 FPS)",
|
|
||||||
"normal:" .. T["Normal"] .. " (10 FPS)",
|
|
||||||
"fast:" .. T["Fast"] .. " (20 FPS)",
|
|
||||||
"very_fast:" .. T["Very Fast"] .. " (30 FPS)",
|
|
||||||
"fastest:" .. T["Fastest"] .. " (50 FPS)",
|
|
||||||
"custom:" .. T["Custom"],
|
|
||||||
})
|
|
||||||
|
|
||||||
swingCustom = CreateConfig(nil, T["Custom FPS"], _G.pfUI_throttle, "swingtimer_custom")
|
|
||||||
|
|
||||||
local isCustom = pfUI.throttle:IsCustom("swingtimer")
|
|
||||||
if not isCustom then
|
|
||||||
swingCustom.input:EnableMouse(false)
|
|
||||||
swingCustom.input:EnableKeyboard(false)
|
|
||||||
swingCustom.input:SetTextColor(.5,.5,.5,1)
|
|
||||||
swingCustom.input:SetText(tostring(pfUI.throttle:GetFps("swingtimer")))
|
|
||||||
else
|
|
||||||
swingCustom.input:EnableMouse(true)
|
|
||||||
swingCustom.input:EnableKeyboard(true)
|
|
||||||
swingCustom.input:SetTextColor(.2,1,.8,1)
|
|
||||||
if _G.pfUI_throttle.swingtimer_custom then
|
|
||||||
swingCustom.input:SetText(_G.pfUI_throttle.swingtimer_custom)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Spacer before reset button
|
|
||||||
local spacer = CreateConfig(nil, " ", nil, nil, "header")
|
|
||||||
spacer:GetParent().objectCount = spacer:GetParent().objectCount - 1
|
|
||||||
spacer:SetHeight(10)
|
|
||||||
|
|
||||||
-- Reset to defaults button
|
|
||||||
CreateConfig(nil, T["Reset to Defaults"], nil, nil, "button", function()
|
|
||||||
pfUI.throttle:ResetToDefault("swingtimer")
|
|
||||||
_G.pfUI_throttle.swingtimer_custom = "50"
|
|
||||||
Reload()
|
|
||||||
end, true)
|
|
||||||
end)
|
|
||||||
|
|
||||||
CreateGUIEntry(T["Unit Frames"], T["General"], function()
|
CreateGUIEntry(T["Unit Frames"], T["General"], function()
|
||||||
CreateConfig(nil, T["Disable pfUI Unit Frames"], C.unitframes, "disable", "checkbox")
|
CreateConfig(nil, T["Disable pfUI Unit Frames"], C.unitframes, "disable", "checkbox")
|
||||||
CreateConfig(nil, T["Animate Health And Power Bars"], C.unitframes, "animatebars", "checkbox")
|
CreateConfig(nil, T["Animate Health And Power Bars"], C.unitframes, "animatebars", "checkbox")
|
||||||
|
|||||||
+230
-457
@@ -5,14 +5,16 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
local ON_SWING_QUEUED = 0
|
local ON_SWING_QUEUED = 0
|
||||||
local ON_SWING_QUEUE_POPPED = 1
|
local ON_SWING_QUEUE_POPPED = 1
|
||||||
|
|
||||||
|
-- seconds a melee bar stays full after its swing is due, to bridge the gap
|
||||||
|
-- until PLAYER_SWING arrives; it then hides unless auto attack goes on
|
||||||
|
local GRACE = 0.15
|
||||||
|
|
||||||
|
-- the last half second of a hunter's ranged swing, when moving cancels the shot
|
||||||
|
local DEADZONE = 0.5
|
||||||
|
|
||||||
-- Consolidate state into a table to avoid Lua 5.0 upvalue limit (32 max)
|
-- Consolidate state into a table to avoid Lua 5.0 upvalue limit (32 max)
|
||||||
local S = {
|
local S = {
|
||||||
mhTimer = 0, mhTimerMax = 1,
|
|
||||||
ohTimer = 0, ohTimerMax = 1,
|
|
||||||
raTimer = 0, raTimerMax = 1,
|
|
||||||
mhSpeed = 0, ohSpeed = 0, raSpeed = 0,
|
mhSpeed = 0, ohSpeed = 0, raSpeed = 0,
|
||||||
mhActive = false, ohActive = false, raActive = false,
|
|
||||||
lastMhMarkerX = -1, lastOhMarkerX = -1, lastRaMarkerX = -1,
|
|
||||||
autoAttackActive = false,
|
autoAttackActive = false,
|
||||||
inCombat = false,
|
inCombat = false,
|
||||||
hsQueued = false, cleaveQueued = false, maulQueued = false,
|
hsQueued = false, cleaveQueued = false, maulQueued = false,
|
||||||
@@ -21,7 +23,6 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
isDruid = false,
|
isDruid = false,
|
||||||
cachedHSSlots = {}, cachedCleaveSlots = {}, cachedMaulSlots = {},
|
cachedHSSlots = {}, cachedCleaveSlots = {}, cachedMaulSlots = {},
|
||||||
useSpellQueueEvent = false,
|
useSpellQueueEvent = false,
|
||||||
swingThrottle = 0,
|
|
||||||
onSwingCache = {},
|
onSwingCache = {},
|
||||||
outOfRange = {}, -- by Enum.PlayerSwingType
|
outOfRange = {}, -- by Enum.PlayerSwingType
|
||||||
}
|
}
|
||||||
@@ -70,196 +71,111 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
local rwR, rwG, rwB, rwA = ParseColor(C.unitframes.swingtimerrangedwarncolor, 0.9, 0.0, 0.0, 1)
|
local rwR, rwG, rwB, rwA = ParseColor(C.unitframes.swingtimerrangedwarncolor, 0.9, 0.0, 0.0, 1)
|
||||||
local orR, orG, orB = ParseColor(C.unitframes.swingtimeroutrangecolor, 0.5, 0.5, 0.5, 1)
|
local orR, orG, orB = ParseColor(C.unitframes.swingtimeroutrangecolor, 0.5, 0.5, 0.5, 1)
|
||||||
local isHunter = UnitClassBase("player") == "HUNTER"
|
local isHunter = UnitClassBase("player") == "HUNTER"
|
||||||
local mhDefaultR, mhDefaultG, mhDefaultB = mhR, mhG, mhB
|
|
||||||
|
|
||||||
|
-- the countdown text, cut down to tenths
|
||||||
|
local countdown = C_StringUtil.CreateNumericRuleFormatter()
|
||||||
|
countdown:AddBreakpoint({ threshold = 0, step = 0.1, rounding = Enum.NumericRuleFormatRounding.Down, format = "%.1f" })
|
||||||
|
|
||||||
|
-- the container keeps the public API
|
||||||
-- Create container frame
|
|
||||||
pfUI.swingtimer = CreateFrame("Frame", "pfSwingTimer", UIParent)
|
pfUI.swingtimer = CreateFrame("Frame", "pfSwingTimer", UIParent)
|
||||||
pfUI.swingtimer:SetFrameStrata("MEDIUM")
|
|
||||||
pfUI.swingtimer:Hide()
|
pfUI.swingtimer:Hide()
|
||||||
|
|
||||||
-- Mainhand bar
|
-- A bar fills by itself from `swing`, the time span of the whole swing, and
|
||||||
pfUI.swingtimer.mainhand = CreateFrame("StatusBar", "pfSwingTimerMainhand", UIParent)
|
-- its text binding counts it down. The marker and its glows ride the edge
|
||||||
pfUI.swingtimer.mainhand:SetPoint("BOTTOM", UIParent, "CENTER", -189, 103)
|
-- of the fill. `shown` is whether the config lets the bar show at all.
|
||||||
pfUI.swingtimer.mainhand:SetWidth(sw_width)
|
local function CreateSwingBar(name, label, shown)
|
||||||
pfUI.swingtimer.mainhand:SetHeight(sw_height)
|
local bar = CreateFrame("StatusBar", name, UIParent)
|
||||||
pfUI.swingtimer.mainhand:SetMinMaxValues(0, 1)
|
bar:SetWidth(sw_width)
|
||||||
pfUI.swingtimer.mainhand:SetValue(0)
|
bar:SetHeight(sw_height)
|
||||||
pfUI.swingtimer.mainhand:SetStatusBarTexture(sw_texture)
|
bar:SetStatusBarTexture(sw_texture)
|
||||||
pfUI.swingtimer.mainhand:SetStatusBarColor(mhR, mhG, mhB, mhA)
|
bar:Hide()
|
||||||
pfUI.swingtimer.mainhand:Hide()
|
bar.shown = shown
|
||||||
|
|
||||||
pfUI.swingtimer.mainhand.text = pfUI.swingtimer.mainhand:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
bar.swing = C_DurationUtil.CreateDuration()
|
||||||
pfUI.swingtimer.mainhand.text:SetPoint("CENTER", pfUI.swingtimer.mainhand, "CENTER", 0, 0)
|
bar:SetTimerDuration(bar.swing, Enum.StatusBarInterpolation.Immediate, Enum.StatusBarTimerDirection.ElapsedTime)
|
||||||
pfUI.swingtimer.mainhand.text:SetFont(pfUI.font_default, sw_fontsize, "OUTLINE")
|
|
||||||
pfUI.swingtimer.mainhand.text:SetTextColor(1, 1, 1, 1)
|
|
||||||
pfUI.swingtimer.mainhand.text:SetText("")
|
|
||||||
if not sw_showtext then pfUI.swingtimer.mainhand.text:Hide() end
|
|
||||||
|
|
||||||
pfUI.swingtimer.mainhand.label = pfUI.swingtimer.mainhand:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
bar.text = bar:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
||||||
pfUI.swingtimer.mainhand.label:SetPoint("RIGHT", pfUI.swingtimer.mainhand, "LEFT", -4, 0)
|
bar.text:SetPoint("CENTER", bar, "CENTER", 0, 0)
|
||||||
pfUI.swingtimer.mainhand.label:SetFont(pfUI.font_default, sw_fontsize, "OUTLINE")
|
bar.text:SetFont(pfUI.font_default, sw_fontsize, "OUTLINE")
|
||||||
pfUI.swingtimer.mainhand.label:SetTextColor(0.8, 0.8, 0.8, 1)
|
bar.text:SetTextColor(1, 1, 1, 1)
|
||||||
pfUI.swingtimer.mainhand.label:SetText(sw_showlabel and "MH" or "")
|
bar.text:SetShown(sw_showtext)
|
||||||
|
|
||||||
pfUI.swingtimer.mainhand.speed = pfUI.swingtimer.mainhand:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
bar.timer = C_DurationUtil.CreateDurationTextBinding()
|
||||||
pfUI.swingtimer.mainhand.speed:SetPoint("LEFT", pfUI.swingtimer.mainhand, "RIGHT", 4, 0)
|
bar.timer:SetFontString(bar.text)
|
||||||
pfUI.swingtimer.mainhand.speed:SetFont(pfUI.font_default, sw_fontsize, "OUTLINE")
|
bar.timer:SetDuration(bar.swing)
|
||||||
pfUI.swingtimer.mainhand.speed:SetTextColor(0.8, 0.8, 0.8, 1)
|
bar.timer:SetFormatter(countdown)
|
||||||
pfUI.swingtimer.mainhand.speed:SetText("")
|
|
||||||
if not sw_showspeed then pfUI.swingtimer.mainhand.speed:Hide() end
|
|
||||||
|
|
||||||
CreateBackdrop(pfUI.swingtimer.mainhand)
|
bar.label = bar:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
||||||
|
bar.label:SetPoint("RIGHT", bar, "LEFT", -4, 0)
|
||||||
|
bar.label:SetFont(pfUI.font_default, sw_fontsize, "OUTLINE")
|
||||||
|
bar.label:SetTextColor(0.8, 0.8, 0.8, 1)
|
||||||
|
bar.label:SetText(sw_showlabel and label or "")
|
||||||
|
|
||||||
|
bar.speed = bar:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
||||||
|
bar.speed:SetPoint("LEFT", bar, "RIGHT", 4, 0)
|
||||||
|
bar.speed:SetFont(pfUI.font_default, sw_fontsize, "OUTLINE")
|
||||||
|
bar.speed:SetTextColor(0.8, 0.8, 0.8, 1)
|
||||||
|
bar.speed:SetShown(sw_showspeed)
|
||||||
|
|
||||||
pfUI.swingtimer.mainhand.marker = pfUI.swingtimer.mainhand:CreateTexture(nil, "OVERLAY")
|
CreateBackdrop(bar)
|
||||||
pfUI.swingtimer.mainhand.marker:SetColorTexture(1, 1, 1, 1.0)
|
|
||||||
pfUI.swingtimer.mainhand.marker:SetWidth(2)
|
|
||||||
pfUI.swingtimer.mainhand.marker:SetHeight(sw_height)
|
|
||||||
pfUI.swingtimer.mainhand.marker:Hide()
|
|
||||||
|
|
||||||
-- Left glow: fades from transparent to white (right edge = marker)
|
bar.edge = CreateFrame("Frame", nil, bar)
|
||||||
pfUI.swingtimer.mainhand.markerGlowL = pfUI.swingtimer.mainhand:CreateTexture(nil, "OVERLAY")
|
bar.edge:SetAllPoints(bar)
|
||||||
pfUI.swingtimer.mainhand.markerGlowL:SetColorTexture(1, 1, 1, 1)
|
bar.edge:Hide()
|
||||||
pfUI.swingtimer.mainhand.markerGlowL:SetGradientAlpha("HORIZONTAL", 1, 1, 1, 0, 1, 1, 1, 0.35)
|
|
||||||
pfUI.swingtimer.mainhand.markerGlowL:SetWidth(10)
|
|
||||||
pfUI.swingtimer.mainhand.markerGlowL:SetHeight(sw_height)
|
|
||||||
pfUI.swingtimer.mainhand.markerGlowL:Hide()
|
|
||||||
|
|
||||||
-- Right glow: fades from white to transparent (left edge = marker)
|
bar.marker = bar.edge:CreateTexture(nil, "OVERLAY")
|
||||||
pfUI.swingtimer.mainhand.markerGlowR = pfUI.swingtimer.mainhand:CreateTexture(nil, "OVERLAY")
|
bar.marker:SetColorTexture(1, 1, 1, 1.0)
|
||||||
pfUI.swingtimer.mainhand.markerGlowR:SetColorTexture(1, 1, 1, 1)
|
bar.marker:SetWidth(2)
|
||||||
pfUI.swingtimer.mainhand.markerGlowR:SetGradientAlpha("HORIZONTAL", 1, 1, 1, 0.35, 1, 1, 1, 0)
|
bar.marker:SetHeight(sw_height)
|
||||||
pfUI.swingtimer.mainhand.markerGlowR:SetWidth(10)
|
bar.marker:SetPoint("CENTER", bar:GetStatusBarTexture(), "RIGHT")
|
||||||
pfUI.swingtimer.mainhand.markerGlowR:SetHeight(sw_height)
|
|
||||||
pfUI.swingtimer.mainhand.markerGlowR:Hide()
|
|
||||||
|
|
||||||
CreateBackdropShadow(pfUI.swingtimer.mainhand)
|
-- Left glow: fades from transparent to white (right edge = marker)
|
||||||
|
bar.markerGlowL = bar.edge:CreateTexture(nil, "OVERLAY")
|
||||||
|
bar.markerGlowL:SetColorTexture(1, 1, 1, 1)
|
||||||
|
bar.markerGlowL:SetGradientAlpha("HORIZONTAL", 1, 1, 1, 0, 1, 1, 1, 0.35)
|
||||||
|
bar.markerGlowL:SetWidth(10)
|
||||||
|
bar.markerGlowL:SetHeight(sw_height)
|
||||||
|
bar.markerGlowL:SetPoint("RIGHT", bar.marker, "LEFT", 0, 0)
|
||||||
|
|
||||||
-- Offhand bar
|
-- Right glow: fades from white to transparent (left edge = marker)
|
||||||
pfUI.swingtimer.offhand = CreateFrame("StatusBar", "pfSwingTimerOffhand", UIParent)
|
bar.markerGlowR = bar.edge:CreateTexture(nil, "OVERLAY")
|
||||||
pfUI.swingtimer.offhand:SetPoint("TOP", pfUI.swingtimer.mainhand, "BOTTOM", 0, -4)
|
bar.markerGlowR:SetColorTexture(1, 1, 1, 1)
|
||||||
pfUI.swingtimer.offhand:SetWidth(sw_width)
|
bar.markerGlowR:SetGradientAlpha("HORIZONTAL", 1, 1, 1, 0.35, 1, 1, 1, 0)
|
||||||
pfUI.swingtimer.offhand:SetHeight(sw_height)
|
bar.markerGlowR:SetWidth(10)
|
||||||
pfUI.swingtimer.offhand:SetMinMaxValues(0, 1)
|
bar.markerGlowR:SetHeight(sw_height)
|
||||||
pfUI.swingtimer.offhand:SetValue(0)
|
bar.markerGlowR:SetPoint("LEFT", bar.marker, "RIGHT", 0, 0)
|
||||||
pfUI.swingtimer.offhand:SetStatusBarTexture(sw_texture)
|
|
||||||
pfUI.swingtimer.offhand:SetStatusBarColor(ohR, ohG, ohB, ohA)
|
|
||||||
pfUI.swingtimer.offhand:Hide()
|
|
||||||
|
|
||||||
pfUI.swingtimer.offhand.text = pfUI.swingtimer.offhand:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
CreateBackdropShadow(bar)
|
||||||
pfUI.swingtimer.offhand.text:SetPoint("CENTER", pfUI.swingtimer.offhand, "CENTER", 0, 0)
|
return bar
|
||||||
pfUI.swingtimer.offhand.text:SetFont(pfUI.font_default, sw_fontsize, "OUTLINE")
|
end
|
||||||
pfUI.swingtimer.offhand.text:SetTextColor(1, 1, 1, 1)
|
|
||||||
pfUI.swingtimer.offhand.text:SetText("")
|
|
||||||
if not sw_showtext then pfUI.swingtimer.offhand.text:Hide() end
|
|
||||||
|
|
||||||
pfUI.swingtimer.offhand.label = pfUI.swingtimer.offhand:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
local mainhand = CreateSwingBar("pfSwingTimerMainhand", "MH", true)
|
||||||
pfUI.swingtimer.offhand.label:SetPoint("RIGHT", pfUI.swingtimer.offhand, "LEFT", -4, 0)
|
mainhand:SetPoint("BOTTOM", UIParent, "CENTER", -189, 103)
|
||||||
pfUI.swingtimer.offhand.label:SetFont(pfUI.font_default, sw_fontsize, "OUTLINE")
|
mainhand.showmarker = true
|
||||||
pfUI.swingtimer.offhand.label:SetTextColor(0.8, 0.8, 0.8, 1)
|
|
||||||
pfUI.swingtimer.offhand.label:SetText(sw_showlabel and "OH" or "")
|
|
||||||
|
|
||||||
pfUI.swingtimer.offhand.speed = pfUI.swingtimer.offhand:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
local offhand = CreateSwingBar("pfSwingTimerOffhand", "OH", sw_showoh)
|
||||||
pfUI.swingtimer.offhand.speed:SetPoint("LEFT", pfUI.swingtimer.offhand, "RIGHT", 4, 0)
|
offhand:SetPoint("TOP", mainhand, "BOTTOM", 0, -4)
|
||||||
pfUI.swingtimer.offhand.speed:SetFont(pfUI.font_default, sw_fontsize, "OUTLINE")
|
offhand.showmarker = true
|
||||||
pfUI.swingtimer.offhand.speed:SetTextColor(0.8, 0.8, 0.8, 1)
|
|
||||||
pfUI.swingtimer.offhand.speed:SetText("")
|
|
||||||
if not sw_showspeed then pfUI.swingtimer.offhand.speed:Hide() end
|
|
||||||
|
|
||||||
CreateBackdrop(pfUI.swingtimer.offhand)
|
|
||||||
|
|
||||||
|
|
||||||
pfUI.swingtimer.offhand.marker = pfUI.swingtimer.offhand:CreateTexture(nil, "OVERLAY")
|
|
||||||
pfUI.swingtimer.offhand.marker:SetColorTexture(1, 1, 1, 1.0)
|
|
||||||
pfUI.swingtimer.offhand.marker:SetWidth(2)
|
|
||||||
pfUI.swingtimer.offhand.marker:SetHeight(sw_height)
|
|
||||||
pfUI.swingtimer.offhand.marker:Hide()
|
|
||||||
|
|
||||||
-- Left glow: fades from transparent to white (right edge = marker)
|
|
||||||
pfUI.swingtimer.offhand.markerGlowL = pfUI.swingtimer.offhand:CreateTexture(nil, "OVERLAY")
|
|
||||||
pfUI.swingtimer.offhand.markerGlowL:SetColorTexture(1, 1, 1, 1)
|
|
||||||
pfUI.swingtimer.offhand.markerGlowL:SetGradientAlpha("HORIZONTAL", 1, 1, 1, 0, 1, 1, 1, 0.35)
|
|
||||||
pfUI.swingtimer.offhand.markerGlowL:SetWidth(10)
|
|
||||||
pfUI.swingtimer.offhand.markerGlowL:SetHeight(sw_height)
|
|
||||||
pfUI.swingtimer.offhand.markerGlowL:Hide()
|
|
||||||
|
|
||||||
-- Right glow: fades from white to transparent (left edge = marker)
|
|
||||||
pfUI.swingtimer.offhand.markerGlowR = pfUI.swingtimer.offhand:CreateTexture(nil, "OVERLAY")
|
|
||||||
pfUI.swingtimer.offhand.markerGlowR:SetColorTexture(1, 1, 1, 1)
|
|
||||||
pfUI.swingtimer.offhand.markerGlowR:SetGradientAlpha("HORIZONTAL", 1, 1, 1, 0.35, 1, 1, 1, 0)
|
|
||||||
pfUI.swingtimer.offhand.markerGlowR:SetWidth(10)
|
|
||||||
pfUI.swingtimer.offhand.markerGlowR:SetHeight(sw_height)
|
|
||||||
pfUI.swingtimer.offhand.markerGlowR:Hide()
|
|
||||||
|
|
||||||
CreateBackdropShadow(pfUI.swingtimer.offhand)
|
|
||||||
|
|
||||||
-- Ranged bar
|
|
||||||
-- Hunters fill from the center: the bar drains toward the middle during
|
-- Hunters fill from the center: the bar drains toward the middle during
|
||||||
-- the reload, then the auto shot deadzone grows back out in the warn color.
|
-- the reload, then the auto shot deadzone grows back out in the warn color.
|
||||||
pfUI.swingtimer.ranged = CreateFrame("StatusBar", "pfSwingTimerRanged", UIParent)
|
-- Each phase is a time span of its own on `phase`.
|
||||||
pfUI.swingtimer.ranged:SetPoint("BOTTOM", UIParent, "CENTER", -189, 83)
|
local ranged = CreateSwingBar("pfSwingTimerRanged", "Ra", sw_showranged)
|
||||||
pfUI.swingtimer.ranged:SetWidth(sw_width)
|
ranged:SetPoint("BOTTOM", UIParent, "CENTER", -189, 83)
|
||||||
pfUI.swingtimer.ranged:SetHeight(sw_height)
|
ranged:SetFillStyle(isHunter and "CENTER" or "STANDARD")
|
||||||
pfUI.swingtimer.ranged:SetMinMaxValues(0, 1)
|
ranged.showmarker = not isHunter
|
||||||
pfUI.swingtimer.ranged:SetValue(0)
|
if isHunter then
|
||||||
pfUI.swingtimer.ranged:SetStatusBarTexture(sw_texture)
|
ranged.phase = C_DurationUtil.CreateDuration()
|
||||||
pfUI.swingtimer.ranged:SetStatusBarColor(raR, raG, raB, raA)
|
ranged.timer:SetDuration(ranged.phase)
|
||||||
pfUI.swingtimer.ranged:SetFillStyle(isHunter and "CENTER" or "STANDARD")
|
end
|
||||||
pfUI.swingtimer.ranged:Hide()
|
|
||||||
|
|
||||||
pfUI.swingtimer.ranged.text = pfUI.swingtimer.ranged:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
pfUI.swingtimer.mainhand = mainhand
|
||||||
pfUI.swingtimer.ranged.text:SetPoint("CENTER", pfUI.swingtimer.ranged, "CENTER", 0, 0)
|
pfUI.swingtimer.offhand = offhand
|
||||||
pfUI.swingtimer.ranged.text:SetFont(pfUI.font_default, sw_fontsize, "OUTLINE")
|
pfUI.swingtimer.ranged = ranged
|
||||||
pfUI.swingtimer.ranged.text:SetTextColor(1, 1, 1, 1)
|
|
||||||
pfUI.swingtimer.ranged.text:SetText("")
|
|
||||||
if not sw_showtext then pfUI.swingtimer.ranged.text:Hide() end
|
|
||||||
|
|
||||||
pfUI.swingtimer.ranged.label = pfUI.swingtimer.ranged:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
UpdateMovable(mainhand)
|
||||||
pfUI.swingtimer.ranged.label:SetPoint("RIGHT", pfUI.swingtimer.ranged, "LEFT", -4, 0)
|
UpdateMovable(ranged)
|
||||||
pfUI.swingtimer.ranged.label:SetFont(pfUI.font_default, sw_fontsize, "OUTLINE")
|
|
||||||
pfUI.swingtimer.ranged.label:SetTextColor(0.8, 0.8, 0.8, 1)
|
|
||||||
pfUI.swingtimer.ranged.label:SetText(sw_showlabel and "Ra" or "")
|
|
||||||
|
|
||||||
pfUI.swingtimer.ranged.speed = pfUI.swingtimer.ranged:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
|
||||||
pfUI.swingtimer.ranged.speed:SetPoint("LEFT", pfUI.swingtimer.ranged, "RIGHT", 4, 0)
|
|
||||||
pfUI.swingtimer.ranged.speed:SetFont(pfUI.font_default, sw_fontsize, "OUTLINE")
|
|
||||||
pfUI.swingtimer.ranged.speed:SetTextColor(0.8, 0.8, 0.8, 1)
|
|
||||||
pfUI.swingtimer.ranged.speed:SetText("")
|
|
||||||
if not sw_showspeed then pfUI.swingtimer.ranged.speed:Hide() end
|
|
||||||
|
|
||||||
CreateBackdrop(pfUI.swingtimer.ranged)
|
|
||||||
|
|
||||||
|
|
||||||
pfUI.swingtimer.ranged.marker = pfUI.swingtimer.ranged:CreateTexture(nil, "OVERLAY")
|
|
||||||
pfUI.swingtimer.ranged.marker:SetColorTexture(1, 1, 1, 1.0)
|
|
||||||
pfUI.swingtimer.ranged.marker:SetWidth(2)
|
|
||||||
pfUI.swingtimer.ranged.marker:SetHeight(sw_height)
|
|
||||||
pfUI.swingtimer.ranged.marker:Hide()
|
|
||||||
|
|
||||||
-- Left glow: fades from transparent to white (right edge = marker)
|
|
||||||
pfUI.swingtimer.ranged.markerGlowL = pfUI.swingtimer.ranged:CreateTexture(nil, "OVERLAY")
|
|
||||||
pfUI.swingtimer.ranged.markerGlowL:SetColorTexture(1, 1, 1, 1)
|
|
||||||
pfUI.swingtimer.ranged.markerGlowL:SetGradientAlpha("HORIZONTAL", 1, 1, 1, 0, 1, 1, 1, 0.35)
|
|
||||||
pfUI.swingtimer.ranged.markerGlowL:SetWidth(10)
|
|
||||||
pfUI.swingtimer.ranged.markerGlowL:SetHeight(sw_height)
|
|
||||||
pfUI.swingtimer.ranged.markerGlowL:Hide()
|
|
||||||
|
|
||||||
-- Right glow: fades from white to transparent (left edge = marker)
|
|
||||||
pfUI.swingtimer.ranged.markerGlowR = pfUI.swingtimer.ranged:CreateTexture(nil, "OVERLAY")
|
|
||||||
pfUI.swingtimer.ranged.markerGlowR:SetColorTexture(1, 1, 1, 1)
|
|
||||||
pfUI.swingtimer.ranged.markerGlowR:SetGradientAlpha("HORIZONTAL", 1, 1, 1, 0.35, 1, 1, 1, 0)
|
|
||||||
pfUI.swingtimer.ranged.markerGlowR:SetWidth(10)
|
|
||||||
pfUI.swingtimer.ranged.markerGlowR:SetHeight(sw_height)
|
|
||||||
pfUI.swingtimer.ranged.markerGlowR:Hide()
|
|
||||||
|
|
||||||
CreateBackdropShadow(pfUI.swingtimer.ranged)
|
|
||||||
|
|
||||||
UpdateMovable(pfUI.swingtimer.mainhand)
|
|
||||||
UpdateMovable(pfUI.swingtimer.ranged)
|
|
||||||
|
|
||||||
-- OH weapon detection
|
|
||||||
-- OH weapon detection: slot 17 (off hand) accepts one-hand (13) and off-hand
|
-- OH weapon detection: slot 17 (off hand) accepts one-hand (13) and off-hand
|
||||||
-- weapons (22); main-hand-only (21) can never sit there.
|
-- weapons (22); main-hand-only (21) can never sit there.
|
||||||
local OH_WEAPON_TYPES = { [13]=true, [22]=true }
|
local OH_WEAPON_TYPES = { [13]=true, [22]=true }
|
||||||
@@ -276,60 +192,6 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
S.raSpeed = (rs and rs > 0) and rs or 0
|
S.raSpeed = (rs and rs > 0) and rs or 0
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Start* restart a countdown from a PLAYER_SWING reset. `remaining` can be
|
|
||||||
-- shorter than the weapon speed (parry haste, ranged wind-up), so the bar
|
|
||||||
-- length stays the full swing and the fill starts part-way along.
|
|
||||||
local function StartMH(remaining)
|
|
||||||
UpdateWeaponSpeeds()
|
|
||||||
pfUI.swingtimer.mhGraceAt = nil -- cancel any pending hide
|
|
||||||
S.mhTimerMax = math.max(S.mhSpeed, remaining)
|
|
||||||
S.mhTimer = remaining
|
|
||||||
S.mhActive = true
|
|
||||||
pfUI.swingtimer.mainhand:Show()
|
|
||||||
pfUI.swingtimer:Show()
|
|
||||||
end
|
|
||||||
|
|
||||||
local function StartOH(remaining)
|
|
||||||
UpdateWeaponSpeeds()
|
|
||||||
-- The off-hand attack time stays set with a shield equipped
|
|
||||||
if S.ohSpeed <= 0 then return end
|
|
||||||
pfUI.swingtimer.ohGraceAt = nil -- cancel any pending hide
|
|
||||||
S.ohTimerMax = math.max(S.ohSpeed, remaining)
|
|
||||||
S.ohTimer = remaining
|
|
||||||
S.ohActive = true
|
|
||||||
if sw_showoh then pfUI.swingtimer.offhand:Show() end
|
|
||||||
pfUI.swingtimer:Show()
|
|
||||||
end
|
|
||||||
|
|
||||||
local function StartRanged(remaining)
|
|
||||||
if not sw_showranged then return end
|
|
||||||
UpdateWeaponSpeeds()
|
|
||||||
if S.raSpeed <= 0 then return end
|
|
||||||
S.raTimerMax = math.max(S.raSpeed, remaining)
|
|
||||||
S.raTimer = remaining
|
|
||||||
S.raActive = true
|
|
||||||
|
|
||||||
pfUI.swingtimer.ranged:SetStatusBarColor(raR, raG, raB, raA)
|
|
||||||
pfUI.swingtimer.ranged:SetValue(isHunter and 1 or 0)
|
|
||||||
pfUI.swingtimer.ranged:Show()
|
|
||||||
pfUI.swingtimer:Show()
|
|
||||||
end
|
|
||||||
|
|
||||||
local function ResetAll()
|
|
||||||
S.mhActive = false
|
|
||||||
S.ohActive = false
|
|
||||||
S.raActive = false
|
|
||||||
S.mhTimer = 0
|
|
||||||
S.ohTimer = 0
|
|
||||||
S.raTimer = 0
|
|
||||||
pfUI.swingtimer.mhGraceAt = nil
|
|
||||||
pfUI.swingtimer.ohGraceAt = nil
|
|
||||||
pfUI.swingtimer.mainhand:Hide()
|
|
||||||
pfUI.swingtimer.offhand:Hide()
|
|
||||||
pfUI.swingtimer.ranged:Hide()
|
|
||||||
pfUI.swingtimer:Hide()
|
|
||||||
end
|
|
||||||
|
|
||||||
-- HS/Cleave/Maul helpers. Canonical rank-1 spellIDs resolve to the
|
-- HS/Cleave/Maul helpers. Canonical rank-1 spellIDs resolve to the
|
||||||
-- localized spell name once, so per-spell classification is rank- and
|
-- localized spell name once, so per-spell classification is rank- and
|
||||||
-- locale-independent without per-rank ID hardcoding (every rank of
|
-- locale-independent without per-rank ID hardcoding (every rank of
|
||||||
@@ -419,236 +281,139 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
return CheckQueuedAction(S.cachedHSSlots), CheckQueuedAction(S.cachedCleaveSlots)
|
return CheckQueuedAction(S.cachedHSSlots), CheckQueuedAction(S.cachedCleaveSlots)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- OnUpdate: countdown all timers with delta, then render
|
-- The bar colors follow the queued on-next-swing ability, the range state
|
||||||
pfUI.swingtimer:SetScript("OnUpdate", function()
|
-- and the hunter deadzone. Runs on the events that change any of them;
|
||||||
S.swingThrottle = S.swingThrottle + arg1
|
-- ACTIONBAR_UPDATE_STATE covers the IsCurrentAction reconcile.
|
||||||
local swingDelay = pfUI.throttle and pfUI.throttle:Get("swingtimer") or 0.02
|
local function UpdateColors()
|
||||||
if S.swingThrottle < swingDelay then return end
|
local r, g, b = mhR, mhG, mhB
|
||||||
local delta = S.swingThrottle
|
|
||||||
S.swingThrottle = 0
|
|
||||||
|
|
||||||
-- (out-of-combat hide handled naturally when timers expire)
|
|
||||||
|
|
||||||
local anyActive = false
|
|
||||||
|
|
||||||
-- Tick timers down. When a timer expires we give a short grace period before
|
|
||||||
-- hiding the bar, to bridge the 1-2 frame gap until PLAYER_SWING arrives.
|
|
||||||
-- If PLAYER_SWING arrives during the grace period it resets the timer
|
|
||||||
-- normally and the grace timer is cleared. If not (e.g. auto-attack was
|
|
||||||
-- turned off), the bar hides after the grace period ends.
|
|
||||||
local GRACE = 0.15 -- seconds to wait after timer hits 0 before hiding
|
|
||||||
|
|
||||||
if S.mhActive then
|
|
||||||
S.mhTimer = S.mhTimer - delta
|
|
||||||
if S.mhTimer <= 0 then
|
|
||||||
S.mhTimer = 0
|
|
||||||
if not pfUI.swingtimer.mhGraceAt then
|
|
||||||
pfUI.swingtimer.mhGraceAt = GetTime() + GRACE
|
|
||||||
elseif GetTime() >= pfUI.swingtimer.mhGraceAt then
|
|
||||||
pfUI.swingtimer.mhGraceAt = nil
|
|
||||||
if not S.inCombat or not S.autoAttackActive then
|
|
||||||
S.mhActive = false
|
|
||||||
pfUI.swingtimer.mainhand:Hide()
|
|
||||||
S.lastMhMarkerX = -1
|
|
||||||
pfUI.swingtimer.mainhand.marker:Hide()
|
|
||||||
pfUI.swingtimer.mainhand.markerGlowL:Hide()
|
|
||||||
pfUI.swingtimer.mainhand.markerGlowR:Hide()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if S.ohActive then
|
|
||||||
S.ohTimer = S.ohTimer - delta
|
|
||||||
if S.ohTimer <= 0 then
|
|
||||||
S.ohTimer = 0
|
|
||||||
if not pfUI.swingtimer.ohGraceAt then
|
|
||||||
pfUI.swingtimer.ohGraceAt = GetTime() + GRACE
|
|
||||||
elseif GetTime() >= pfUI.swingtimer.ohGraceAt then
|
|
||||||
pfUI.swingtimer.ohGraceAt = nil
|
|
||||||
if not S.inCombat or not S.autoAttackActive then
|
|
||||||
S.ohActive = false
|
|
||||||
pfUI.swingtimer.offhand:Hide()
|
|
||||||
S.lastOhMarkerX = -1
|
|
||||||
pfUI.swingtimer.offhand.marker:Hide()
|
|
||||||
pfUI.swingtimer.offhand.markerGlowL:Hide()
|
|
||||||
pfUI.swingtimer.offhand.markerGlowR:Hide()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if S.raActive then
|
|
||||||
S.raTimer = S.raTimer - delta
|
|
||||||
if S.raTimer <= 0 then
|
|
||||||
S.raTimer = 0
|
|
||||||
S.raActive = false
|
|
||||||
pfUI.swingtimer.ranged:Hide()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- HS/Cleave color
|
|
||||||
local curR, curG, curB = mhDefaultR, mhDefaultG, mhDefaultB
|
|
||||||
if sw_hsqueue then
|
if sw_hsqueue then
|
||||||
if S.isDruid and S.useSpellQueueEvent then
|
if S.isDruid and S.useSpellQueueEvent then
|
||||||
S.maulQueued, S.maulSeenCurrent =
|
S.maulQueued, S.maulSeenCurrent =
|
||||||
ReconcileQueued(S.maulQueued, S.cachedMaulSlots, S.maulSeenCurrent)
|
ReconcileQueued(S.maulQueued, S.cachedMaulSlots, S.maulSeenCurrent)
|
||||||
end
|
end
|
||||||
if S.maulQueued and S.isDruid then
|
if S.maulQueued and S.isDruid then
|
||||||
curR, curG, curB = 1.0, 0.55, 0.0 -- orange for druid maul queue
|
r, g, b = 1.0, 0.55, 0.0 -- orange for druid maul queue
|
||||||
elseif S.isWarrior then
|
elseif S.isWarrior then
|
||||||
local hs, cl = IsHSOrCleaveQueued()
|
local hs, cl = IsHSOrCleaveQueued()
|
||||||
if cl then
|
if cl then
|
||||||
curR, curG, curB = 0.2, 0.9, 0.2
|
r, g, b = 0.2, 0.9, 0.2
|
||||||
elseif hs then
|
elseif hs then
|
||||||
curR, curG, curB = 0.9, 0.9, 0.2
|
r, g, b = 0.9, 0.9, 0.2
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if S.outOfRange[MAINHAND] then r, g, b = orR, orG, orB end
|
||||||
|
mainhand:SetStatusBarColor(r, g, b, mhA)
|
||||||
|
|
||||||
-- Render MH
|
if S.outOfRange[OFFHAND] then
|
||||||
if S.outOfRange[MAINHAND] then
|
offhand:SetStatusBarColor(orR, orG, orB, ohA)
|
||||||
curR, curG, curB = orR, orG, orB
|
else
|
||||||
|
offhand:SetStatusBarColor(ohR, ohG, ohB, ohA)
|
||||||
end
|
end
|
||||||
|
|
||||||
if S.mhActive then
|
local a
|
||||||
local progress = 1 - (S.mhTimer / S.mhTimerMax)
|
if ranged.warn then
|
||||||
pfUI.swingtimer.mainhand:SetValue(progress)
|
r, g, b, a = rwR, rwG, rwB, rwA
|
||||||
if S.mhTimer <= 0 then
|
else
|
||||||
-- Timer expired: hide marker (no gap at right edge)
|
r, g, b, a = raR, raG, raB, raA
|
||||||
if S.lastMhMarkerX ~= -1 then
|
end
|
||||||
S.lastMhMarkerX = -1
|
if S.outOfRange[RANGED] then r, g, b = orR, orG, orB end
|
||||||
pfUI.swingtimer.mainhand.marker:Hide()
|
ranged:SetStatusBarColor(r, g, b, a)
|
||||||
pfUI.swingtimer.mainhand.markerGlowL:Hide()
|
end
|
||||||
pfUI.swingtimer.mainhand.markerGlowR:Hide()
|
|
||||||
end
|
local function StopBar(bar)
|
||||||
|
if bar.wake then bar.wake:Cancel() end
|
||||||
|
bar.wake, bar.active, bar.graced = nil, nil, nil
|
||||||
|
bar.timer:Disable()
|
||||||
|
bar:Hide()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- a melee bar that is due waits for the next swing; it hides after the
|
||||||
|
-- grace unless auto attack goes on, or on the event that stops it later
|
||||||
|
local function MeleeGrace(bar)
|
||||||
|
bar.graced = true
|
||||||
|
if not S.inCombat or not S.autoAttackActive then StopBar(bar) end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function MeleeDue(bar)
|
||||||
|
bar.edge:Hide()
|
||||||
|
bar.wake = C_Timer.NewTimer(GRACE, function() MeleeGrace(bar) end)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function RangedDue(bar)
|
||||||
|
StopBar(bar)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- the hunter's reload is over: the deadzone grows out in the warn color
|
||||||
|
local function HunterDeadzone(bar)
|
||||||
|
local finish = bar.swing:GetEndTime()
|
||||||
|
bar.phase:SetTimeFromEnd(finish, DEADZONE)
|
||||||
|
bar:SetTimerDuration(bar.phase, Enum.StatusBarInterpolation.Immediate, Enum.StatusBarTimerDirection.ElapsedTime)
|
||||||
|
bar.warn = true
|
||||||
|
UpdateColors()
|
||||||
|
bar.wake = C_Timer.NewTimer(finish - GetTime(), function() RangedDue(bar) end)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Restarts a bar from a PLAYER_SWING reset. `remaining` can be shorter than
|
||||||
|
-- the weapon speed (parry haste, ranged wind-up), so the bar length stays
|
||||||
|
-- the full swing and the fill starts part-way along.
|
||||||
|
local function StartBar(bar, remaining, speed, due)
|
||||||
|
if bar.wake then bar.wake:Cancel() end
|
||||||
|
local now = GetTime()
|
||||||
|
bar.swing:SetTimeFromEnd(now + remaining, math.max(speed, remaining))
|
||||||
|
bar.active, bar.graced, bar.warn = true, nil, nil
|
||||||
|
if speed > 0 then bar.speed:SetFormattedText("%.2f", speed) end
|
||||||
|
|
||||||
|
if bar.phase then
|
||||||
|
if remaining > DEADZONE then
|
||||||
|
bar.phase:SetTimeFromEnd(now + remaining - DEADZONE, math.max(speed, remaining) - DEADZONE)
|
||||||
|
bar:SetTimerDuration(bar.phase, Enum.StatusBarInterpolation.Immediate, Enum.StatusBarTimerDirection.RemainingTime)
|
||||||
|
bar.wake = C_Timer.NewTimer(remaining - DEADZONE, function() HunterDeadzone(bar) end)
|
||||||
else
|
else
|
||||||
local mhMarkerX = progress * sw_width
|
HunterDeadzone(bar)
|
||||||
if mhMarkerX < 1 then mhMarkerX = 1 end
|
|
||||||
if mhMarkerX > sw_width - 2 then mhMarkerX = sw_width - 2 end
|
|
||||||
if mhMarkerX ~= S.lastMhMarkerX then
|
|
||||||
S.lastMhMarkerX = mhMarkerX
|
|
||||||
pfUI.swingtimer.mainhand.marker:SetPoint("LEFT", pfUI.swingtimer.mainhand, "LEFT", mhMarkerX - 1, 0)
|
|
||||||
pfUI.swingtimer.mainhand.markerGlowL:SetPoint("RIGHT", pfUI.swingtimer.mainhand.marker, "LEFT", 0, 0)
|
|
||||||
pfUI.swingtimer.mainhand.markerGlowR:SetPoint("LEFT", pfUI.swingtimer.mainhand.marker, "RIGHT", 0, 0)
|
|
||||||
pfUI.swingtimer.mainhand.marker:Show()
|
|
||||||
pfUI.swingtimer.mainhand.markerGlowL:Show()
|
|
||||||
pfUI.swingtimer.mainhand.markerGlowR:Show()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
pfUI.swingtimer.mainhand:SetStatusBarColor(curR, curG, curB, mhA)
|
else
|
||||||
if sw_showtext then
|
bar.wake = C_Timer.NewTimer(remaining, function() due(bar) end)
|
||||||
pfUI.swingtimer.mainhand.text:SetFormattedText("%.1f", math.floor(S.mhTimer * 10) / 10)
|
|
||||||
end
|
|
||||||
if sw_showspeed and S.mhSpeed > 0 then
|
|
||||||
pfUI.swingtimer.mainhand.speed:SetFormattedText("%.2f", S.mhSpeed)
|
|
||||||
end
|
|
||||||
anyActive = true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Render OH
|
UpdateColors()
|
||||||
if sw_showoh and S.ohActive then
|
if bar.shown then
|
||||||
local progress = 1 - (S.ohTimer / S.ohTimerMax)
|
bar.edge:SetShown(bar.showmarker)
|
||||||
pfUI.swingtimer.offhand:SetValue(progress)
|
if sw_showtext then bar.timer:Enable() end
|
||||||
if S.outOfRange[OFFHAND] then
|
bar:Show()
|
||||||
pfUI.swingtimer.offhand:SetStatusBarColor(orR, orG, orB, ohA)
|
|
||||||
else
|
|
||||||
pfUI.swingtimer.offhand:SetStatusBarColor(ohR, ohG, ohB, ohA)
|
|
||||||
end
|
|
||||||
if S.ohTimer <= 0 then
|
|
||||||
if S.lastOhMarkerX ~= -1 then
|
|
||||||
S.lastOhMarkerX = -1
|
|
||||||
pfUI.swingtimer.offhand.marker:Hide()
|
|
||||||
pfUI.swingtimer.offhand.markerGlowL:Hide()
|
|
||||||
pfUI.swingtimer.offhand.markerGlowR:Hide()
|
|
||||||
end
|
|
||||||
else
|
|
||||||
local ohMarkerX = progress * sw_width
|
|
||||||
if ohMarkerX < 1 then ohMarkerX = 1 end
|
|
||||||
if ohMarkerX > sw_width - 2 then ohMarkerX = sw_width - 2 end
|
|
||||||
if ohMarkerX ~= S.lastOhMarkerX then
|
|
||||||
S.lastOhMarkerX = ohMarkerX
|
|
||||||
pfUI.swingtimer.offhand.marker:SetPoint("LEFT", pfUI.swingtimer.offhand, "LEFT", ohMarkerX - 1, 0)
|
|
||||||
pfUI.swingtimer.offhand.markerGlowL:SetPoint("RIGHT", pfUI.swingtimer.offhand.marker, "LEFT", 0, 0)
|
|
||||||
pfUI.swingtimer.offhand.markerGlowR:SetPoint("LEFT", pfUI.swingtimer.offhand.marker, "RIGHT", 0, 0)
|
|
||||||
pfUI.swingtimer.offhand.marker:Show()
|
|
||||||
pfUI.swingtimer.offhand.markerGlowL:Show()
|
|
||||||
pfUI.swingtimer.offhand.markerGlowR:Show()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if sw_showtext then
|
|
||||||
pfUI.swingtimer.offhand.text:SetFormattedText("%.1f", math.floor(S.ohTimer * 10) / 10)
|
|
||||||
end
|
|
||||||
if sw_showspeed and S.ohSpeed > 0 then
|
|
||||||
pfUI.swingtimer.offhand.speed:SetFormattedText("%.2f", S.ohSpeed)
|
|
||||||
end
|
|
||||||
anyActive = true
|
|
||||||
elseif not sw_showoh then
|
|
||||||
pfUI.swingtimer.offhand:Hide()
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Render Ranged
|
local function StartMH(remaining)
|
||||||
if sw_showranged and S.raActive then
|
UpdateWeaponSpeeds()
|
||||||
local remaining = S.raTimer
|
StartBar(mainhand, remaining, S.mhSpeed, MeleeDue)
|
||||||
local r, g, b, a = raR, raG, raB, raA
|
end
|
||||||
if isHunter then
|
|
||||||
local DEADZONE = 0.5
|
|
||||||
if remaining > DEADZONE then
|
|
||||||
pfUI.swingtimer.ranged:SetValue((remaining - DEADZONE) / (S.raTimerMax - DEADZONE))
|
|
||||||
else
|
|
||||||
r, g, b, a = rwR, rwG, rwB, rwA
|
|
||||||
pfUI.swingtimer.ranged:SetValue(1 - (remaining / DEADZONE))
|
|
||||||
end
|
|
||||||
if sw_showtext then
|
|
||||||
if remaining <= 0.5 then
|
|
||||||
pfUI.swingtimer.ranged.text:SetFormattedText("%.1f", math.floor(remaining * 10) / 10)
|
|
||||||
else
|
|
||||||
pfUI.swingtimer.ranged.text:SetFormattedText("%.1f", math.floor((remaining - 0.5) * 10) / 10)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
pfUI.swingtimer.ranged:SetValue(1 - (remaining / S.raTimerMax))
|
|
||||||
if sw_showtext then
|
|
||||||
pfUI.swingtimer.ranged.text:SetFormattedText("%.1f", math.floor(remaining * 10) / 10)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if S.outOfRange[RANGED] then
|
|
||||||
r, g, b = orR, orG, orB
|
|
||||||
end
|
|
||||||
pfUI.swingtimer.ranged:SetStatusBarColor(r, g, b, a)
|
|
||||||
if sw_showspeed and S.raSpeed > 0 then
|
|
||||||
pfUI.swingtimer.ranged.speed:SetFormattedText("%.2f", S.raSpeed)
|
|
||||||
end
|
|
||||||
local raProgress = 1 - (S.raTimer / S.raTimerMax)
|
|
||||||
local raMarkerX = raProgress * sw_width
|
|
||||||
if raMarkerX < 1 then raMarkerX = 1 end
|
|
||||||
if raMarkerX > sw_width - 2 then raMarkerX = sw_width - 2 end
|
|
||||||
if raMarkerX ~= S.lastRaMarkerX then
|
|
||||||
S.lastRaMarkerX = raMarkerX
|
|
||||||
if not isHunter then
|
|
||||||
pfUI.swingtimer.ranged.marker:SetPoint("LEFT", pfUI.swingtimer.ranged, "LEFT", raMarkerX - 1, 0)
|
|
||||||
pfUI.swingtimer.ranged.marker:Show()
|
|
||||||
pfUI.swingtimer.ranged.markerGlowL:SetPoint("RIGHT", pfUI.swingtimer.ranged.marker, "LEFT", 0, 0)
|
|
||||||
pfUI.swingtimer.ranged.markerGlowR:SetPoint("LEFT", pfUI.swingtimer.ranged.marker, "RIGHT", 0, 0)
|
|
||||||
pfUI.swingtimer.ranged.markerGlowL:Show()
|
|
||||||
pfUI.swingtimer.ranged.markerGlowR:Show()
|
|
||||||
else
|
|
||||||
pfUI.swingtimer.ranged.marker:Hide()
|
|
||||||
pfUI.swingtimer.ranged.markerGlowL:Hide()
|
|
||||||
pfUI.swingtimer.ranged.markerGlowR:Hide()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
anyActive = true
|
|
||||||
elseif not sw_showranged then
|
|
||||||
pfUI.swingtimer.ranged:Hide()
|
|
||||||
end
|
|
||||||
|
|
||||||
if not anyActive then
|
local function StartOH(remaining)
|
||||||
if not pfUI.swingtimer.mainhand:IsShown()
|
UpdateWeaponSpeeds()
|
||||||
and not pfUI.swingtimer.offhand:IsShown()
|
-- The off-hand attack time stays set with a shield equipped
|
||||||
and not pfUI.swingtimer.ranged:IsShown() then
|
if S.ohSpeed <= 0 then return end
|
||||||
this:Hide()
|
StartBar(offhand, remaining, S.ohSpeed, MeleeDue)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end)
|
local function StartRanged(remaining)
|
||||||
|
if not sw_showranged then return end
|
||||||
|
UpdateWeaponSpeeds()
|
||||||
|
if S.raSpeed <= 0 then return end
|
||||||
|
StartBar(ranged, remaining, S.raSpeed, RangedDue)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- melee bars waiting past their grace hide once auto attack stops
|
||||||
|
local function StopWaitingBars()
|
||||||
|
if mainhand.graced then StopBar(mainhand) end
|
||||||
|
if offhand.graced then StopBar(offhand) end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function ResetAll()
|
||||||
|
StopBar(mainhand)
|
||||||
|
StopBar(offhand)
|
||||||
|
StopBar(ranged)
|
||||||
|
end
|
||||||
|
|
||||||
local events = CreateFrame("Frame")
|
local events = CreateFrame("Frame")
|
||||||
events:RegisterEvent("PLAYER_SWING")
|
events:RegisterEvent("PLAYER_SWING")
|
||||||
@@ -658,6 +423,7 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
events:RegisterEvent("PLAYER_REGEN_DISABLED")
|
events:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||||
events:RegisterEvent("PLAYER_REGEN_ENABLED")
|
events:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||||
events:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
|
events:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
|
||||||
|
events:RegisterEvent("ACTIONBAR_UPDATE_STATE")
|
||||||
events:RegisterEvent("PLAYER_DEAD")
|
events:RegisterEvent("PLAYER_DEAD")
|
||||||
events:RegisterUnitEvent("UNIT_SPELLCAST_SENT", "player")
|
events:RegisterUnitEvent("UNIT_SPELLCAST_SENT", "player")
|
||||||
events:RegisterUnitEvent("UNIT_SPELLCAST_SUCCEEDED", "player")
|
events:RegisterUnitEvent("UNIT_SPELLCAST_SUCCEEDED", "player")
|
||||||
@@ -682,6 +448,7 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
-- arg1 = swingType, arg2 = isInRange, arg3 = checksRange; no check
|
-- arg1 = swingType, arg2 = isInRange, arg3 = checksRange; no check
|
||||||
-- (no target, nothing to attack, no weapon) is not out of range
|
-- (no target, nothing to attack, no weapon) is not out of range
|
||||||
S.outOfRange[arg1] = arg3 and not arg2
|
S.outOfRange[arg1] = arg3 and not arg2
|
||||||
|
UpdateColors()
|
||||||
|
|
||||||
elseif event == "UNIT_SPELLCAST_SENT" then
|
elseif event == "UNIT_SPELLCAST_SENT" then
|
||||||
-- arg4 = spellID: an on-next-swing ability (HS / Cleave / Maul) queued
|
-- arg4 = spellID: an on-next-swing ability (HS / Cleave / Maul) queued
|
||||||
@@ -689,6 +456,7 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
if kind then
|
if kind then
|
||||||
S.useSpellQueueEvent = true
|
S.useSpellQueueEvent = true
|
||||||
SetQueuedKind(kind)
|
SetQueuedKind(kind)
|
||||||
|
UpdateColors()
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif event == "UNIT_SPELLCAST_SUCCEEDED" then
|
elseif event == "UNIT_SPELLCAST_SUCCEEDED" then
|
||||||
@@ -696,6 +464,7 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
-- the queue, so drop the queued color
|
-- the queue, so drop the queued color
|
||||||
if IsOnSwingSpell(arg3) then
|
if IsOnSwingSpell(arg3) then
|
||||||
S.hsQueued = false; S.cleaveQueued = false; S.maulQueued = false
|
S.hsQueued = false; S.cleaveQueued = false; S.maulQueued = false
|
||||||
|
UpdateColors()
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif event == "SPELL_QUEUE_EVENT" then
|
elseif event == "SPELL_QUEUE_EVENT" then
|
||||||
@@ -707,12 +476,17 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
elseif eventCode == ON_SWING_QUEUE_POPPED then
|
elseif eventCode == ON_SWING_QUEUE_POPPED then
|
||||||
S.hsQueued = false; S.cleaveQueued = false; S.maulQueued = false
|
S.hsQueued = false; S.cleaveQueued = false; S.maulQueued = false
|
||||||
end
|
end
|
||||||
|
UpdateColors()
|
||||||
|
|
||||||
|
elseif event == "ACTIONBAR_UPDATE_STATE" then
|
||||||
|
if sw_hsqueue then UpdateColors() end
|
||||||
|
|
||||||
elseif event == "START_AUTOATTACK" then
|
elseif event == "START_AUTOATTACK" then
|
||||||
S.autoAttackActive = true
|
S.autoAttackActive = true
|
||||||
|
|
||||||
elseif event == "STOP_AUTOATTACK" then
|
elseif event == "STOP_AUTOATTACK" then
|
||||||
S.autoAttackActive = false
|
S.autoAttackActive = false
|
||||||
|
StopWaitingBars()
|
||||||
|
|
||||||
elseif event == "PLAYER_ENTERING_WORLD" then
|
elseif event == "PLAYER_ENTERING_WORLD" then
|
||||||
local class = UnitClassBase("player")
|
local class = UnitClassBase("player")
|
||||||
@@ -725,14 +499,8 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
-- arg1 = changed slot; only weapon slots (main/off/ranged) affect swing speed
|
-- arg1 = changed slot; only weapon slots (main/off/ranged) affect swing speed
|
||||||
if not INVSLOTS_EQUIPABLE_IN_COMBAT[arg1] then return end
|
if not INVSLOTS_EQUIPABLE_IN_COMBAT[arg1] then return end
|
||||||
UpdateWeaponSpeeds()
|
UpdateWeaponSpeeds()
|
||||||
if S.ohSpeed == 0 then
|
if S.ohSpeed == 0 then StopBar(offhand) end
|
||||||
S.ohActive = false
|
if S.raSpeed == 0 then StopBar(ranged) end
|
||||||
pfUI.swingtimer.offhand:Hide()
|
|
||||||
end
|
|
||||||
if S.raSpeed == 0 then
|
|
||||||
S.raActive = false
|
|
||||||
pfUI.swingtimer.ranged:Hide()
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif event == "ACTIONBAR_SLOT_CHANGED" then
|
elseif event == "ACTIONBAR_SLOT_CHANGED" then
|
||||||
RebuildQueueSlotCache()
|
RebuildQueueSlotCache()
|
||||||
@@ -746,12 +514,22 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
S.hsQueued = false
|
S.hsQueued = false
|
||||||
S.cleaveQueued = false
|
S.cleaveQueued = false
|
||||||
S.maulQueued = false
|
S.maulQueued = false
|
||||||
|
UpdateColors()
|
||||||
|
StopWaitingBars()
|
||||||
|
|
||||||
elseif event == "PLAYER_DEAD" then
|
elseif event == "PLAYER_DEAD" then
|
||||||
ResetAll()
|
ResetAll()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
local function Remaining(bar)
|
||||||
|
return bar.active and bar.swing:GetRemainingDuration() or 0
|
||||||
|
end
|
||||||
|
|
||||||
|
local function Progress(bar)
|
||||||
|
return bar.active and bar.swing:GetElapsedPercent() or 0
|
||||||
|
end
|
||||||
|
|
||||||
-- -------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------
|
||||||
-- Public API for external addons (e.g. SCRM)
|
-- Public API for external addons (e.g. SCRM)
|
||||||
-- Only available when the swingtimer module is loaded.
|
-- Only available when the swingtimer module is loaded.
|
||||||
@@ -763,9 +541,9 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
-- -------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------
|
||||||
pfUI.swingtimer.api = {
|
pfUI.swingtimer.api = {
|
||||||
-- Remaining time in seconds until next swing
|
-- Remaining time in seconds until next swing
|
||||||
GetMHTimer = function() return S.mhTimer end,
|
GetMHTimer = function() return Remaining(mainhand) end,
|
||||||
GetOHTimer = function() return S.ohTimer end,
|
GetOHTimer = function() return Remaining(offhand) end,
|
||||||
GetRangedTimer = function() return S.raTimer end,
|
GetRangedTimer = function() return Remaining(ranged) end,
|
||||||
|
|
||||||
-- Weapon speed (full swing duration in seconds)
|
-- Weapon speed (full swing duration in seconds)
|
||||||
GetMHSpeed = function() return S.mhSpeed end,
|
GetMHSpeed = function() return S.mhSpeed end,
|
||||||
@@ -773,20 +551,14 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
GetRangedSpeed = function() return S.raSpeed end,
|
GetRangedSpeed = function() return S.raSpeed end,
|
||||||
|
|
||||||
-- Whether each timer is currently running
|
-- Whether each timer is currently running
|
||||||
IsMHActive = function() return S.mhActive end,
|
IsMHActive = function() return mainhand.active == true end,
|
||||||
IsOHActive = function() return S.ohActive end,
|
IsOHActive = function() return offhand.active == true end,
|
||||||
IsRangedActive = function() return S.raActive end,
|
IsRangedActive = function() return ranged.active == true end,
|
||||||
|
|
||||||
-- Swing progress 0.0 (just reset) to 1.0 (about to swing)
|
-- Swing progress 0.0 (just reset) to 1.0 (about to swing)
|
||||||
GetMHProgress = function()
|
GetMHProgress = function() return Progress(mainhand) end,
|
||||||
return S.mhActive and S.mhTimerMax > 0 and (1 - S.mhTimer / S.mhTimerMax) or 0
|
GetOHProgress = function() return Progress(offhand) end,
|
||||||
end,
|
GetRangedProgress = function() return Progress(ranged) end,
|
||||||
GetOHProgress = function()
|
|
||||||
return S.ohActive and S.ohTimerMax > 0 and (1 - S.ohTimer / S.ohTimerMax) or 0
|
|
||||||
end,
|
|
||||||
GetRangedProgress = function()
|
|
||||||
return S.raActive and S.raTimerMax > 0 and (1 - S.raTimer / S.raTimerMax) or 0
|
|
||||||
end,
|
|
||||||
|
|
||||||
-- Warrior HS/Cleave queue state
|
-- Warrior HS/Cleave queue state
|
||||||
IsHSQueued = function() return S.hsQueued end,
|
IsHSQueued = function() return S.hsQueued end,
|
||||||
@@ -804,4 +576,5 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
if sw_showranged then EnableRangeCheck(RANGED) end
|
if sw_showranged then EnableRangeCheck(RANGED) end
|
||||||
|
|
||||||
UpdateWeaponSpeeds()
|
UpdateWeaponSpeeds()
|
||||||
end)
|
UpdateColors()
|
||||||
|
end)
|
||||||
|
|||||||
Reference in New Issue
Block a user