mirror of
https://github.com/brues-code/pfUI.git
synced 2026-11-03 09:26:57 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee9bd9e31a | ||
|
|
df7c13651b | ||
|
|
646174fc60 | ||
|
|
1c1be19711 | ||
|
|
eb68642d21 | ||
|
|
d2088c455f | ||
|
|
9e2a89de62 | ||
|
|
1a6314aa60 | ||
|
|
70bfc1c443 | ||
|
|
d143e91f81 | ||
|
|
14ae659f2a | ||
|
|
9187155ea6 | ||
|
|
465e87d7d2 | ||
|
|
dd4ebda0a9 | ||
|
|
1abeafcec2 | ||
|
|
cde16e7fbe | ||
|
|
a376afb2d7 | ||
|
|
c8cc7bde79 | ||
|
|
d7e732981b | ||
|
|
2909679d62 | ||
|
|
f1c1bfd0c6 | ||
|
|
2a6bddd756 | ||
|
|
893524174c | ||
|
|
001e09c1b7 | ||
|
|
494f176f18 |
+1
-1
@@ -13,7 +13,7 @@ do
|
||||
-- on. There pfUI does load, and will throw wherever it reaches for something
|
||||
-- the installed DLL doesn't have yet -- the popup names the cause so those
|
||||
-- errors aren't a mystery.
|
||||
local PFUI_CLASSIC_API_MIN = 11813 -- (X*10000 + Y*100 + Z)
|
||||
local PFUI_CLASSIC_API_MIN = 11901 -- (X*10000 + Y*100 + Z)
|
||||
local PFUI_CLASSIC_API_LATEST = PFUI_CLASSIC_API_MIN
|
||||
local PFUI_CLASSIC_API_WEBSITE = "https://github.com/brues-code/ClassicAPI"
|
||||
local PFUI_CLASSIC_API_LATEST_URL = PFUI_CLASSIC_API_WEBSITE .. "/releases/latest"
|
||||
|
||||
@@ -23,7 +23,7 @@ Provides:
|
||||
- C_NamePlate - Event-driven nameplates (no more per-frame WorldFrame scanning) with real per-plate unit tokens and GUIDs
|
||||
- C_UnitAuras - Replaces over 3k lines of hand-rolled aura tracking
|
||||
- C_Spell - Replaces thousands of hardcoded spell names for each locale and powers castbar
|
||||
- Real cast bars - Actual cast/channel timing, spellID and interrupt state for any unit (C_Spell.UnitCastingInfo)
|
||||
- Real cast bars - Actual cast/channel timing, spellID and interrupt state for any unit (C_Spell.UnitCastingInfo), filled and counted down engine-side (UnitCastingDuration, StatusBar:SetTimerDuration, duration text bindings) with no Lua OnUpdate
|
||||
- Focus - A genuine `focus` unit plus `/focus` and `/clearfocus` (FocusUnit / ClearFocus)
|
||||
- C_EquipmentSet - Full Equipment Manager with GUID-tracked gear sets (tells apart duplicate/enchanted items)
|
||||
- Instant Bag Sorting - C_Container.MoveItem / SwapItems instead of cursor pickup/drop
|
||||
|
||||
+64
-27
@@ -992,28 +992,53 @@ function pfUI.api.GetBorderSize(pref)
|
||||
end
|
||||
end
|
||||
|
||||
-- The scale UIParent ends up with: one UI unit per screen pixel when pixel
|
||||
-- perfect, else the game's own. The game applies its scale only after the
|
||||
-- add-ons and their saved variables are loaded (CGGameUI::Initialize ends in
|
||||
-- OnDisplaySizeChanged), so at load time it is worked out from the same
|
||||
-- options and rules: uiScale while useUiScale is on and it is at least 0.64,
|
||||
-- else 768 over the window height kept within 0.9 and 1. Windows narrower
|
||||
-- than 4:3 cap either at 3/4 of their aspect.
|
||||
local function GetUIScale()
|
||||
if pfUI_config.global.pixelperfect == "1" then return PixelUtil.GetPixelToUIUnitFactor() end
|
||||
|
||||
local width, height = GetPhysicalScreenSize()
|
||||
local aspect = GetCVar("widescreen") == "1" and width / height or 4/3
|
||||
local function fit(scale)
|
||||
return aspect < 4/3 and math.min(scale, aspect * .75) or scale
|
||||
end
|
||||
|
||||
if GetCVar("useUiScale") == "1" then
|
||||
local scale = fit(tonumber(GetCVar("uiScale")))
|
||||
if scale >= .64 then return scale end
|
||||
end
|
||||
|
||||
return math.max(fit(height > 768 and 768 / height or 1), .9)
|
||||
end
|
||||
|
||||
-- [ UpdateUIScale ]
|
||||
-- Gives UIParent the pixel perfect scale when enabled, else leaves the game's
|
||||
-- own. The engine puts its own scale back on every window resize and scale
|
||||
-- option change, so this runs again on each UI_SCALE_CHANGED. Borders keep
|
||||
-- the pixel size they were built with, so a change of it offers a reload once.
|
||||
function pfUI.api.UpdateUIScale()
|
||||
if pfUI_config.global.pixelperfect == "1" then
|
||||
UIParent:SetScale(PixelUtil.GetPixelToUIUnitFactor())
|
||||
end
|
||||
|
||||
if not pfUI.pixel or pfUI.scaleprompt then return end
|
||||
if math.abs(PixelUtil.GetPixelToUIUnitFactor() / UIParent:GetScale() - pfUI.pixel) < .0001 then return end
|
||||
|
||||
pfUI.scaleprompt = true
|
||||
CreateQuestionDialog(T["The UI-Scale has changed. Reload the UI to redraw the borders?"], ReloadUI)
|
||||
end
|
||||
|
||||
-- [ GetPerfectPixel ]
|
||||
-- Returns a number that equals a real pixel on regular scaled frames.
|
||||
-- Respects the current UI-scale and calculates a real pixel based on
|
||||
-- the screen resolution and the 768px sized drawlayer.
|
||||
-- Returns the size of one physical pixel in UIParent units.
|
||||
function pfUI.api.GetPerfectPixel()
|
||||
if pfUI.pixel then return pfUI.pixel end
|
||||
|
||||
if pfUI_config.appearance.border.pixelperfect == "1" then
|
||||
local scale = GetCVar("useUiScale") == "1" and GetCVar("uiScale") or "1"
|
||||
local resolution = GetCVar("gxResolution")
|
||||
local _, _, screenwidth, screenheight = strfind(resolution, "(.+)x(.+)")
|
||||
|
||||
pfUI.pixel = 768 / screenheight / scale
|
||||
pfUI.pixel = pfUI.pixel > 1 and 1 or pfUI.pixel
|
||||
|
||||
-- autodetect and zoom for HiDPI displays
|
||||
if pfUI_config.appearance.border.hidpi == "1" then
|
||||
pfUI.pixel = pfUI.pixel < .5 and pfUI.pixel * 2 or pfUI.pixel
|
||||
end
|
||||
else
|
||||
pfUI.pixel = .7
|
||||
end
|
||||
pfUI.pixel = PixelUtil.GetPixelToUIUnitFactor() / GetUIScale()
|
||||
|
||||
pfUI.backdrop = {
|
||||
bgFile = "Interface\\BUTTONS\\WHITE8X8", tile = false, tileSize = 0,
|
||||
@@ -1158,8 +1183,11 @@ 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.
|
||||
-- so the state still reads on a bar configured without an icon. The fill also
|
||||
-- gets diagonal stripes, tiled at the image's own size so they keep their
|
||||
-- spacing as the fill grows or shrinks. They sit on OVERLAY, under the bar's
|
||||
-- text on the same layer. 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
|
||||
@@ -1171,6 +1199,18 @@ function pfUI.api.SetCastbarShield(bar, icon, shielded, isChannel)
|
||||
bar:SetStatusBarColor(pfUI.api.GetStringColor(C.appearance.castbar[isChannel and "channelcolor" or "castbarcolor"]))
|
||||
end
|
||||
|
||||
if shielded and not bar.shieldstripes then
|
||||
bar.shieldstripes = bar:CreateTexture(nil, "OVERLAY")
|
||||
bar.shieldstripes:SetTexture(pfUI.media["img:stripes"])
|
||||
bar.shieldstripes:SetHorizTile(true)
|
||||
bar.shieldstripes:SetVertTile(true)
|
||||
bar.shieldstripes:SetVertexColor(1, 1, 1, .3)
|
||||
bar.shieldstripes:SetAllPoints(bar:GetStatusBarTexture())
|
||||
end
|
||||
if bar.shieldstripes then
|
||||
bar.shieldstripes:SetShown(shielded)
|
||||
end
|
||||
|
||||
local iconborder = icon and icon.backdrop
|
||||
if not iconborder then return end
|
||||
|
||||
@@ -1364,10 +1404,10 @@ function pfUI.api.EnableAutohide(frame, timeout, combat)
|
||||
|
||||
if not frame.hover.fade then
|
||||
frame.hover.fade = frame:CreateAnimationGroup()
|
||||
frame.hover.fade:SetToFinalAlpha(true)
|
||||
local fade = frame.hover.fade:CreateAnimation("Alpha")
|
||||
fade:SetChange(-1)
|
||||
fade:SetDuration(1)
|
||||
frame.hover.fade:SetScript("OnFinished", function() frame:SetAlpha(0) end)
|
||||
end
|
||||
|
||||
if combat then
|
||||
@@ -1469,13 +1509,10 @@ end
|
||||
-- return object
|
||||
function pfUI.api.GetNoNameObject(frame, objtype, layer, arg1, arg2)
|
||||
-- A nil/non-frame parent otherwise dies on frame:GetRegions()/:GetChildren()
|
||||
-- below, and the traceback stops here — useless, since all callers share this
|
||||
-- line. pfUI shadows Lua's `error` (dropping the level arg and not throwing),
|
||||
-- so fold the caller frame in via debugstack to name the offending skin, then
|
||||
-- bail so we don't fall through and crash on frame:GetRegions() anyway.
|
||||
-- below, where the message would name this line, shared by every caller;
|
||||
-- level 2 names the offending skin instead.
|
||||
if type(frame) ~= "table" or not frame.GetRegions then
|
||||
error("GetNoNameObject: invalid parent frame\n" .. debugstack(2, 3, 0))
|
||||
return
|
||||
error("GetNoNameObject: invalid parent frame", 2)
|
||||
end
|
||||
|
||||
local arg1 = arg1 and gsub(arg1, "([%+%-%*%(%)%?%[%]%^])", "%%%1")
|
||||
|
||||
+83
-76
@@ -71,6 +71,7 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("buffs", nil, "debuffrowsize", "16")
|
||||
pfUI:UpdateConfig("buffs", nil, "textinside", "0")
|
||||
pfUI:UpdateConfig("buffs", nil, "fontsize", "-1")
|
||||
pfUI:UpdateConfig("buffs", nil, "timers", "both")
|
||||
|
||||
pfUI:UpdateConfig("buffbar", "pbuff", "enable", "0")
|
||||
pfUI:UpdateConfig("buffbar", "pbuff", "use_unitfonts", "0")
|
||||
@@ -128,9 +129,7 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("appearance", "border", "color", "0.2,0.2,0.2,1")
|
||||
pfUI:UpdateConfig("appearance", "border", "shadow", "0")
|
||||
pfUI:UpdateConfig("appearance", "border", "shadow_intensity", ".35")
|
||||
pfUI:UpdateConfig("appearance", "border", "pixelperfect", "1")
|
||||
pfUI:UpdateConfig("appearance", "border", "force_blizz", "0")
|
||||
pfUI:UpdateConfig("appearance", "border", "hidpi", "1")
|
||||
pfUI:UpdateConfig("appearance", "border", "default", "3")
|
||||
pfUI:UpdateConfig("appearance", "border", "nameplates", "-1")
|
||||
pfUI:UpdateConfig("appearance", "border", "actionbars", "-1")
|
||||
@@ -149,38 +148,9 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("cooldown", nil, "minutecolor", ".2,1,1,1")
|
||||
pfUI:UpdateConfig("cooldown", nil, "hourcolor", ".2,.5,1,1")
|
||||
pfUI:UpdateConfig("cooldown", nil, "daycolor", ".2,.2,1,1")
|
||||
pfUI:UpdateConfig("cooldown", "actionbar", "text", "1")
|
||||
pfUI:UpdateConfig("cooldown", "actionbar", "animation", "1")
|
||||
pfUI:UpdateConfig("cooldown", "actionbar", "reverse", "0")
|
||||
pfUI:UpdateConfig("cooldown", "bags", "text", "1")
|
||||
pfUI:UpdateConfig("cooldown", "bags", "animation", "1")
|
||||
pfUI:UpdateConfig("cooldown", "bags", "reverse", "0")
|
||||
pfUI:UpdateConfig("cooldown", "blizzard", "text", "1")
|
||||
pfUI:UpdateConfig("cooldown", "blizzard", "animation", "1")
|
||||
pfUI:UpdateConfig("cooldown", "blizzard", "reverse", "0")
|
||||
pfUI:UpdateConfig("cooldown", "unitframe", "text", "1")
|
||||
pfUI:UpdateConfig("cooldown", "unitframe", "animation", "0")
|
||||
pfUI:UpdateConfig("cooldown", "unitframe", "reverse", "1")
|
||||
pfUI:UpdateConfig("cooldown", "indicator", "text", "1")
|
||||
pfUI:UpdateConfig("cooldown", "indicator", "animation", "0")
|
||||
pfUI:UpdateConfig("cooldown", "indicator", "reverse", "0")
|
||||
pfUI:UpdateConfig("cooldown", "nameplate", "text", "1")
|
||||
pfUI:UpdateConfig("cooldown", "nameplate", "animation", "0")
|
||||
pfUI:UpdateConfig("cooldown", "nameplate", "reverse", "1")
|
||||
pfUI:UpdateConfig("cooldown", "buff", "text", "1")
|
||||
pfUI:UpdateConfig("cooldown", "buff", "animation", "1")
|
||||
pfUI:UpdateConfig("cooldown", "buff", "reverse", "1")
|
||||
pfUI:UpdateConfig("cooldown", "tooltip", "text", "1")
|
||||
pfUI:UpdateConfig("cooldown", "tooltip", "animation", "0")
|
||||
pfUI:UpdateConfig("cooldown", "tooltip", "reverse", "0")
|
||||
pfUI:UpdateConfig("cooldown", "totem", "text", "1")
|
||||
pfUI:UpdateConfig("cooldown", "totem", "animation", "1")
|
||||
pfUI:UpdateConfig("cooldown", "totem", "reverse", "1")
|
||||
pfUI:UpdateConfig("cooldown", "lossofcontrol", "text", "1")
|
||||
pfUI:UpdateConfig("cooldown", "lossofcontrol", "animation", "1")
|
||||
pfUI:UpdateConfig("cooldown", "lossofcontrol", "reverse", "0")
|
||||
pfUI:UpdateConfig("cooldown", "foreign", "text", "0")
|
||||
pfUI:UpdateConfig("cooldown", "foreign", "animation", "1")
|
||||
pfUI:UpdateConfig("cooldown", nil, "blizzard_timers", "both")
|
||||
pfUI:UpdateConfig("cooldown", nil, "lossofcontrol_timers", "both")
|
||||
pfUI:UpdateConfig("cooldown", nil, "foreign_timers", "sweep")
|
||||
|
||||
pfUI:UpdateConfig("appearance", "castbar", "castbarcolor", ".7,.7,.9,.8")
|
||||
pfUI:UpdateConfig("appearance", "castbar", "channelcolor", ".9,.9,.7,.8")
|
||||
@@ -207,6 +177,7 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("appearance", "bags", "autoSortOnOpen", "0")
|
||||
pfUI:UpdateConfig("appearance", "bags", "sortreverse", "0")
|
||||
pfUI:UpdateConfig("appearance", "bags", "sortprioreverse", "0")
|
||||
pfUI:UpdateConfig("appearance", "bags", "timers", "both")
|
||||
pfUI:UpdateConfig("appearance", "minimap", "size", "140")
|
||||
pfUI:UpdateConfig("appearance", "minimap", "arrowscale", "1")
|
||||
pfUI:UpdateConfig("appearance", "minimap", "zonetext", "off")
|
||||
@@ -564,6 +535,7 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("unitframes", unit, "debuffoffy", "0")
|
||||
pfUI:UpdateConfig("unitframes", unit, "debuffspacingx", "1")
|
||||
pfUI:UpdateConfig("unitframes", unit, "debuffspacingy", "1")
|
||||
pfUI:UpdateConfig("unitframes", unit, "aura_timers", "text")
|
||||
pfUI:UpdateConfig("unitframes", unit, "invert_healthbar", "0")
|
||||
pfUI:UpdateConfig("unitframes", unit, "verticalbar", "0")
|
||||
pfUI:UpdateConfig("unitframes", unit, "buff_indicator", "0")
|
||||
@@ -584,6 +556,7 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("unitframes", unit, "indicator_size", "10")
|
||||
pfUI:UpdateConfig("unitframes", unit, "indicator_spacing","1")
|
||||
pfUI:UpdateConfig("unitframes", unit, "indicator_pos", "TOPLEFT")
|
||||
pfUI:UpdateConfig("unitframes", unit, "indicator_timers", "text")
|
||||
|
||||
pfUI:UpdateConfig("unitframes", unit, "clickcast", "0")
|
||||
pfUI:UpdateConfig("unitframes", unit, "faderange", "0")
|
||||
@@ -702,6 +675,7 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("bars", nil, "oomcolor", ".2,.2,1,1")
|
||||
pfUI:UpdateConfig("bars", nil, "showna", "1")
|
||||
pfUI:UpdateConfig("bars", nil, "nacolor", ".3,.3,.3,1")
|
||||
pfUI:UpdateConfig("bars", nil, "procglow", "1")
|
||||
pfUI:UpdateConfig("bars", nil, "showequipped", "1")
|
||||
pfUI:UpdateConfig("bars", nil, "eqcolor", ".2,.8,.2,.2")
|
||||
pfUI:UpdateConfig("bars", nil, "shiftdrag", "1")
|
||||
@@ -714,6 +688,7 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("bars", nil, "count_color", ".2,1,.8,1")
|
||||
pfUI:UpdateConfig("bars", nil, "bind_size", "8")
|
||||
pfUI:UpdateConfig("bars", nil, "bind_color", "1,1,0,1")
|
||||
pfUI:UpdateConfig("bars", nil, "timers", "both")
|
||||
|
||||
pfUI:UpdateConfig("bars", "gryphons", "texture", "None")
|
||||
pfUI:UpdateConfig("bars", "gryphons", "color", ".6,.6,.6,1")
|
||||
@@ -727,6 +702,7 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("totems", nil, "iconsize", "26")
|
||||
pfUI:UpdateConfig("totems", nil, "spacing", "3")
|
||||
pfUI:UpdateConfig("totems", nil, "showbg", "0")
|
||||
pfUI:UpdateConfig("totems", nil, "timers", "both")
|
||||
|
||||
pfUI:UpdateConfig("panel", nil, "use_unitfonts", "0")
|
||||
pfUI:UpdateConfig("panel", nil, "hide_leftchat", "0")
|
||||
@@ -839,6 +815,7 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("tooltip", "statusbar", "texture", "Interface\\AddOns\\pfUI\\img\\bar")
|
||||
pfUI:UpdateConfig("tooltip", nil, "font_tooltip", "Interface\\AddOns\\pfUI\\fonts\\Myriad-Pro.ttf")
|
||||
pfUI:UpdateConfig("tooltip", nil, "font_tooltip_size", "12")
|
||||
pfUI:UpdateConfig("tooltip", nil, "aura_timers", "text")
|
||||
|
||||
-- Throttle Settings
|
||||
|
||||
@@ -963,6 +940,7 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("nameplates", nil, "glowcolor", "1,1,1,1")
|
||||
pfUI:UpdateConfig("nameplates", nil, "targetzoom", "0")
|
||||
pfUI:UpdateConfig("nameplates", nil, "targetzoomval", ".40")
|
||||
pfUI:UpdateConfig("nameplates", nil, "debuff_timers", "text")
|
||||
pfUI:UpdateConfig("nameplates", nil, "notargalpha", ".75")
|
||||
pfUI:UpdateConfig("nameplates", nil, "healthtexture", "Interface\\AddOns\\pfUI\\img\\bar")
|
||||
pfUI:UpdateConfig("nameplates", "name", "fontstyle", "OUTLINE")
|
||||
@@ -1436,9 +1414,32 @@ function pfUI:MigrateConfig()
|
||||
pfUI_config.unitframes.always2dportrait = nil
|
||||
end
|
||||
|
||||
-- migrate the scattered cooldown settings into the cooldown table; keyed
|
||||
-- on the old settings rather than the version, like the portrait style
|
||||
-- migrate the old cooldown settings into each feature's timers setting;
|
||||
-- keyed on the old settings rather than the version, like the portrait
|
||||
-- style. Reverse options are dropped: the direction follows what a
|
||||
-- cooldown times.
|
||||
local cooldown = pfUI_config.cooldown
|
||||
|
||||
-- 'mode' with its numbers and sweep replaced by 'text' and 'sweep' ("1" or
|
||||
-- "0"), each kept when nil
|
||||
local function timers(mode, text, sweep)
|
||||
local numbers = mode == "text" or mode == "both"
|
||||
local swipe = mode == "sweep" or mode == "both"
|
||||
if text then numbers = text == "1" end
|
||||
if sweep then swipe = sweep == "1" end
|
||||
|
||||
if numbers and swipe then return "both" end
|
||||
return numbers and "text" or swipe and "sweep" or "off"
|
||||
end
|
||||
|
||||
-- every unit frame's settings
|
||||
local function units(func)
|
||||
for _, unit in pairs(pfUI_config.unitframes) do
|
||||
if type(unit) == "table" and unit.aura_timers then func(unit) end
|
||||
end
|
||||
end
|
||||
|
||||
-- the shared look and the foreign and Blizzard toggles of appearance.cd
|
||||
local cd = pfUI_config.appearance.cd
|
||||
if cd then
|
||||
for _, entry in pairs({ "font", "font_size", "dynamicsize", "threshold", "milliseconds",
|
||||
@@ -1446,17 +1447,12 @@ function pfUI:MigrateConfig()
|
||||
cooldown[entry] = cd[entry] or cooldown[entry]
|
||||
end
|
||||
|
||||
cooldown.foreign.text = cd.foreign or cooldown.foreign.text
|
||||
if cd.hideanim then
|
||||
cooldown.foreign.animation = cd.hideanim == "1" and "0" or "1"
|
||||
end
|
||||
local sweep = cd.hideanim and (cd.hideanim == "1" and "0" or "1")
|
||||
cooldown.foreign_timers = timers(cooldown.foreign_timers, cd.foreign, sweep)
|
||||
|
||||
-- spellbook and character slots took the foreign sweep, and with the
|
||||
-- Blizzard toggle off the foreign numbers too
|
||||
cooldown.blizzard.animation = cooldown.foreign.animation
|
||||
if cd.blizzard == "0" then
|
||||
cooldown.blizzard.text = cooldown.foreign.text
|
||||
end
|
||||
cooldown.blizzard_timers = timers(cooldown.blizzard_timers, cd.blizzard == "0" and (cd.foreign or "0") or nil, sweep)
|
||||
|
||||
-- pfUI drew its own numbers before; the native countdown shows them
|
||||
-- only with this cvar on, which only the first-run setup sets
|
||||
@@ -1465,40 +1461,51 @@ function pfUI:MigrateConfig()
|
||||
pfUI_config.appearance.cd = nil
|
||||
end
|
||||
|
||||
local function move(config, old, kind, entry)
|
||||
if config[old] then
|
||||
cooldown[kind][entry] = config[old]
|
||||
config[old] = nil
|
||||
-- the options of each module
|
||||
local buffs, nameplates = pfUI_config.buffs, pfUI_config.nameplates
|
||||
buffs.timers = timers(buffs.timers, nil, buffs.cooldown_anim)
|
||||
nameplates.debuff_timers = timers(nameplates.debuff_timers, nameplates.debufftext, nameplates.debuffanim)
|
||||
if nameplates.debufftimers == "0" then nameplates.debuff_timers = "off" end
|
||||
|
||||
units(function(unit)
|
||||
unit.aura_timers = timers(unit.aura_timers, unit.cooldown_text, unit.cooldown_anim)
|
||||
unit.indicator_timers = timers(unit.indicator_timers, unit.indicator_time)
|
||||
unit.cooldown_text, unit.cooldown_anim, unit.cooldown_reverse, unit.indicator_time = nil, nil, nil, nil
|
||||
end)
|
||||
|
||||
pfUI_config.bars.cooldown_reverse = nil
|
||||
pfUI_config.appearance.bags.cooldown_reverse = nil
|
||||
pfUI_config.totems.cooldown_reverse = nil
|
||||
buffs.cooldown_anim, buffs.cooldown_reverse = nil, nil
|
||||
nameplates.debufftext, nameplates.debuffanim, nameplates.debreverse, nameplates.debufftimers = nil, nil, nil, nil
|
||||
|
||||
-- the cooldown kinds of Settings -> Cooldown, each with its numbers and
|
||||
-- sweep, into the setting that replaced it
|
||||
local kinds = {
|
||||
actionbar = { pfUI_config.bars, "timers" },
|
||||
bags = { pfUI_config.appearance.bags, "timers" },
|
||||
blizzard = { cooldown, "blizzard_timers" },
|
||||
nameplate = { nameplates, "debuff_timers" },
|
||||
buff = { buffs, "timers" },
|
||||
tooltip = { pfUI_config.tooltip, "aura_timers" },
|
||||
totem = { pfUI_config.totems, "timers" },
|
||||
lossofcontrol = { cooldown, "lossofcontrol_timers" },
|
||||
foreign = { cooldown, "foreign_timers" },
|
||||
unitframe = "aura_timers",
|
||||
indicator = "indicator_timers",
|
||||
}
|
||||
|
||||
for kind, target in pairs(kinds) do
|
||||
local old = cooldown[kind]
|
||||
if type(old) == "table" then
|
||||
if type(target) == "string" then
|
||||
units(function(unit) unit[target] = timers(unit[target], old.text, old.animation) end)
|
||||
else
|
||||
target[1][target[2]] = timers(target[1][target[2]], old.text, old.animation)
|
||||
end
|
||||
cooldown[kind] = nil
|
||||
end
|
||||
end
|
||||
|
||||
move(pfUI_config.bars, "cooldown_reverse", "actionbar", "reverse")
|
||||
move(pfUI_config.appearance.bags, "cooldown_reverse", "bags", "reverse")
|
||||
move(pfUI_config.buffs, "cooldown_anim", "buff", "animation")
|
||||
move(pfUI_config.buffs, "cooldown_reverse", "buff", "reverse")
|
||||
move(pfUI_config.totems, "cooldown_reverse", "totem", "reverse")
|
||||
move(pfUI_config.nameplates, "debufftext", "nameplate", "text")
|
||||
move(pfUI_config.nameplates, "debuffanim", "nameplate", "animation")
|
||||
move(pfUI_config.nameplates, "debreverse", "nameplate", "reverse")
|
||||
|
||||
if pfUI_config.nameplates.debufftimers == "0" then
|
||||
cooldown.nameplate.text, cooldown.nameplate.animation = "0", "0"
|
||||
end
|
||||
|
||||
-- one setting now covers every unit frame: the target frame's auras and
|
||||
-- the raid frames' indicators stand for the rest
|
||||
move(pfUI_config.unitframes.target, "cooldown_text", "unitframe", "text")
|
||||
move(pfUI_config.unitframes.target, "cooldown_anim", "unitframe", "animation")
|
||||
move(pfUI_config.unitframes.target, "cooldown_reverse", "unitframe", "reverse")
|
||||
move(pfUI_config.unitframes.raid, "indicator_time", "indicator", "text")
|
||||
|
||||
for _, unit in pairs(pfUI_config.unitframes) do
|
||||
if type(unit) == "table" then
|
||||
unit.cooldown_text, unit.cooldown_anim, unit.cooldown_reverse, unit.indicator_time = nil, nil, nil, nil
|
||||
end
|
||||
end
|
||||
|
||||
pfUI_config.nameplates.debufftimers = nil
|
||||
pfUI_config.bars.cd_size = nil
|
||||
|
||||
-- Remove "Show only own debuffs" from unitframes and nameplates
|
||||
|
||||
+42
-32
@@ -1,16 +1,20 @@
|
||||
-- load pfUI environment
|
||||
setfenv(1, pfUI:GetEnvironment())
|
||||
|
||||
-- Every pfUI cooldown is a Cooldown frame from CreateCooldown, made for one
|
||||
-- kind of timer. Settings -> Cooldown (C.cooldown) sets for each kind its
|
||||
-- countdown numbers, its sweep and the sweep's direction, and shares one font
|
||||
-- and one formatter between them all. The numbers are the frame's own
|
||||
-- countdown (ClassicAPI): the engine ticks them, gated by the
|
||||
-- countdownForCooldowns cvar. Other addons' Cooldown frames take the
|
||||
-- "foreign" settings as their timers start.
|
||||
-- Every pfUI cooldown is a Cooldown frame from CreateCooldown. The settings
|
||||
-- of the feature it belongs to pick its timers: none, numbers, sweep or both.
|
||||
-- Settings -> Cooldown (C.cooldown) sets one font and one formatter for them
|
||||
-- all. The numbers are the frame's own countdown (ClassicAPI): the engine
|
||||
-- ticks them, gated by the countdownForCooldowns cvar. Other addons' Cooldown
|
||||
-- frames take the "foreign" timers as their timers start.
|
||||
|
||||
-- kinds that time spells or items: no numbers for the global cooldown
|
||||
local spell = { actionbar = true, bags = true, blizzard = true, foreign = true }
|
||||
local function ShowNumbers(mode)
|
||||
return mode == "text" or mode == "both"
|
||||
end
|
||||
|
||||
local function ShowSweep(mode)
|
||||
return mode == "sweep" or mode == "both"
|
||||
end
|
||||
|
||||
-- every cooldown CreateCooldown made, for UpdateCooldowns
|
||||
local cooldowns = {}
|
||||
@@ -69,41 +73,41 @@ local function OnSizeChanged(cooldown, width, height)
|
||||
UpdateFont(cooldown, height)
|
||||
end
|
||||
|
||||
-- applies the settings of its kind to one of pfUI's cooldowns
|
||||
-- applies its timers setting to one of pfUI's cooldowns
|
||||
local function SetupCooldown(cooldown)
|
||||
local kind = cooldown.pfCooldownKind
|
||||
local config = C.cooldown[kind]
|
||||
local sweep = config.animation == "1" and not cooldown.pfTimeLeftOnly
|
||||
local mode = cooldown.pfCooldownConfig[cooldown.pfCooldownKey]
|
||||
local sweep = ShowSweep(mode) and not cooldown.pfTimeLeftOnly
|
||||
|
||||
cooldown:SetHideCountdownNumbers(config.text ~= "1")
|
||||
cooldown:SetHideCountdownNumbers(not ShowNumbers(mode))
|
||||
cooldown:SetDrawSwipe(sweep)
|
||||
cooldown:SetDrawBling(sweep)
|
||||
cooldown:SetReverse(config.reverse == "1")
|
||||
cooldown:SetMinimumCountdownDuration(spell[kind] and tonumber(C.cooldown.threshold) * 1000 or 0)
|
||||
cooldown:SetReverse(kind == "aura")
|
||||
cooldown:SetMinimumCountdownDuration(kind == "spell" and tonumber(C.cooldown.threshold) * 1000 or 0)
|
||||
cooldown:SetCountdownFormatter(GetFormatter())
|
||||
UpdateFont(cooldown, cooldown:GetParent():GetHeight())
|
||||
UpdateFont(cooldown, cooldown:GetParent():GetUnscaledHeight())
|
||||
end
|
||||
|
||||
-- applies the "foreign" settings to another addon's cooldown. They only take
|
||||
-- applies the "foreign" timers to another addon's cooldown. They only take
|
||||
-- the numbers or the sweep away, which the addon may have set up itself, so
|
||||
-- turning one back on needs a reload.
|
||||
local function SetupForeign(cooldown)
|
||||
local config = C.cooldown.foreign
|
||||
local mode = C.cooldown.foreign_timers
|
||||
|
||||
if config.animation ~= "1" then
|
||||
if not ShowSweep(mode) then
|
||||
cooldown:SetDrawSwipe(false)
|
||||
cooldown:SetDrawBling(false)
|
||||
end
|
||||
|
||||
-- omnicc's flag for cooldowns that want no numbers
|
||||
if config.text ~= "1" or cooldown.noCooldownCount then
|
||||
if not ShowNumbers(mode) or cooldown.noCooldownCount then
|
||||
cooldown:SetHideCountdownNumbers(true)
|
||||
return
|
||||
end
|
||||
|
||||
cooldown:SetMinimumCountdownDuration(tonumber(C.cooldown.threshold) * 1000)
|
||||
cooldown:SetCountdownFormatter(GetFormatter())
|
||||
UpdateFont(cooldown, (cooldown:GetParent() or cooldown):GetHeight())
|
||||
UpdateFont(cooldown, (cooldown:GetParent() or cooldown):GetUnscaledHeight())
|
||||
end
|
||||
|
||||
-- runs as a pfUI cooldown's timer starts: a timer with a total brings back
|
||||
@@ -129,17 +133,22 @@ hooksecurefunc("CooldownFrame_SetTimer", function(cooldown)
|
||||
end)
|
||||
|
||||
-- [ CreateCooldown ] --
|
||||
-- Creates one of pfUI's cooldowns: a Cooldown frame over all of 'parent'
|
||||
-- with the settings of its kind. Start it with CooldownFrame_SetTimer.
|
||||
-- Creates one of pfUI's cooldowns: a Cooldown frame over all of 'parent'.
|
||||
-- Start it with CooldownFrame_SetTimer.
|
||||
-- 'parent' [frame] the frame the cooldown covers
|
||||
-- 'kind' [string] what it times, a group of C.cooldown: actionbar,
|
||||
-- bags, blizzard, unitframe, indicator, nameplate,
|
||||
-- buff, tooltip, totem or lossofcontrol
|
||||
-- 'kind' [string] what it times: "spell" (spells and items: the sweep
|
||||
-- fills, no numbers for the global cooldown), "aura"
|
||||
-- (the sweep drains) or "timer" (the sweep fills)
|
||||
-- 'config' [table] the settings that hold its timers
|
||||
-- 'key' [string] the timers setting in 'config': "off", "text",
|
||||
-- "sweep" or "both"
|
||||
-- 'name' [string] optional frame name
|
||||
-- return [frame] the Cooldown frame
|
||||
function pfUI.api.CreateCooldown(parent, kind, name)
|
||||
function pfUI.api.CreateCooldown(parent, kind, config, key, name)
|
||||
local cooldown = CreateFrame("Cooldown", name, parent, "CooldownFrameTemplate")
|
||||
cooldown.pfCooldownKind = kind
|
||||
cooldown.pfCooldownConfig = config
|
||||
cooldown.pfCooldownKey = key
|
||||
cooldown:SetScript("OnSizeChanged", OnSizeChanged)
|
||||
table.insert(cooldowns, cooldown)
|
||||
SetupCooldown(cooldown)
|
||||
@@ -187,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
|
||||
|
||||
+5
-10
@@ -601,7 +601,7 @@ function pfUI.api.SkinDropDown(frame, cr, cg, cb, useSmall)
|
||||
|
||||
button:HookScript("OnClick", function()
|
||||
local DropDownListWidth = DropDownList1:GetWidth()
|
||||
local DropDownFrameWidth = frame.backdrop:GetWidth()
|
||||
local DropDownFrameWidth = frame.backdrop:GetUnscaledWidth()
|
||||
if DropDownListWidth < DropDownFrameWidth then
|
||||
local diff = DropDownFrameWidth - DropDownListWidth
|
||||
DropDownList1:SetWidth(DropDownList1:GetWidth() + diff)
|
||||
@@ -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)
|
||||
|
||||
+184
-198
@@ -362,7 +362,7 @@ pfUI.events:RegisterCallback("aggro:changed", function(_, old, new)
|
||||
if frame.aggro then
|
||||
local guid = UnitGUID(frame.label .. frame.id)
|
||||
if guid and (guid == old or guid == new) then
|
||||
frame.update_combat = true
|
||||
pfUI.uf:QueueUpdate(frame, "combat")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -498,10 +498,18 @@ function pfUI.uf:UpdateVisibility()
|
||||
self.chain = visibility ~= "hide" and unitstr:match("^(.+)target$") or nil
|
||||
if self.chain then
|
||||
local guid = UnitName(unitstr) and UnitGUID(unitstr)
|
||||
if guid ~= self.unitguid then self.update_full = true end
|
||||
if guid ~= self.unitguid then pfUI.uf:QueueUpdate(self, "full") end
|
||||
self.unitguid = guid
|
||||
self:RegisterUnitEvents(guid and CHAIN_TOKENS[unitstr] and unitstr or guid)
|
||||
else
|
||||
-- A pet frame's token gets the pet's unit events, but a new pet behind it
|
||||
-- (summoned, or remapped by raid.lua) comes with none of its own; the
|
||||
-- visibility timer's GUID compare turns it into the full refresh.
|
||||
if self.tick then
|
||||
local guid = UnitGUID(unitstr)
|
||||
if guid ~= self.unitguid then pfUI.uf:QueueUpdate(self, "full") end
|
||||
self.unitguid = guid
|
||||
end
|
||||
self:RegisterUnitEvents(visibility ~= "hide" and unitstr or nil)
|
||||
end
|
||||
self:RegisterChainEvents(self.chain)
|
||||
@@ -773,7 +781,6 @@ function pfUI.uf:UpdateConfig()
|
||||
if f.config.hitindicator == "1" then
|
||||
f.feedbackText:SetFont(pfUI.media[f.config.hitindicatorfont], f.config.hitindicatorsize, "OUTLINE")
|
||||
f.feedbackFontHeight = f.config.hitindicatorsize
|
||||
f.feedbackStartTime = GetTime()
|
||||
if f.config.portrait == "bar" or f.config.portrait == "off" then
|
||||
f.feedbackText:SetParent(f.texts)
|
||||
f.feedbackText:ClearAllPoints()
|
||||
@@ -785,6 +792,7 @@ function pfUI.uf:UpdateConfig()
|
||||
end
|
||||
f.combatfeedback = true
|
||||
else
|
||||
f.feedback:Stop()
|
||||
f.feedbackText:Hide()
|
||||
f.combatfeedback = nil
|
||||
end
|
||||
@@ -853,12 +861,16 @@ function pfUI.uf:UpdateConfig()
|
||||
f.incHeal.texture:SetVertexColor(cr, cg, cb, ca)
|
||||
f.incHeal:Hide()
|
||||
|
||||
if f.config.verticalbar == "0" then
|
||||
f.incHeal:ClearAllPoints()
|
||||
f.incHeal:SetPoint("TOPLEFT", f.hp.bar, "TOPLEFT", 0, 0)
|
||||
-- the bar texture covers only the fill, so a prediction anchored to it
|
||||
-- starts at the edge of the health and follows it as the bar animates.
|
||||
-- An inverted bar fills with the missing health, so it starts at the bar.
|
||||
f.incHeal:ClearAllPoints()
|
||||
if f.config.invert_healthbar == "1" then
|
||||
f.incHeal:SetPoint(f.config.verticalbar == "0" and "TOPLEFT" or "BOTTOM", f.hp.bar)
|
||||
elseif f.config.verticalbar == "0" then
|
||||
f.incHeal:SetPoint("TOPLEFT", f.hp.bar:GetStatusBarTexture(), "TOPRIGHT")
|
||||
else
|
||||
f.incHeal:ClearAllPoints()
|
||||
f.incHeal:SetPoint("BOTTOM", f.hp.bar, "BOTTOM", 0, 0)
|
||||
f.incHeal:SetPoint("BOTTOMLEFT", f.hp.bar:GetStatusBarTexture(), "TOPLEFT")
|
||||
end
|
||||
|
||||
f.ressIcon:SetFrameLevel(16)
|
||||
@@ -946,7 +958,7 @@ function pfUI.uf:UpdateConfig()
|
||||
f.buffs[i]:SetFrameLevel(12)
|
||||
f.buffs[i]:RegisterForClicks("RightButtonUp")
|
||||
|
||||
f.buffs[i].cd = f.buffs[i].cd or CreateCooldown(f.buffs[i], "unitframe", f.buffs[i]:GetName() .. "Cooldown")
|
||||
f.buffs[i].cd = f.buffs[i].cd or CreateCooldown(f.buffs[i], "aura", f.config, "aura_timers", f.buffs[i]:GetName() .. "Cooldown")
|
||||
f.buffs[i].cd:SetFrameLevel(14)
|
||||
|
||||
f.buffs[i].id = i
|
||||
@@ -999,7 +1011,7 @@ function pfUI.uf:UpdateConfig()
|
||||
f.debuffs[i]:RegisterForClicks("RightButtonUp")
|
||||
f.debuffs[i]:SetNormalTexture(nil)
|
||||
|
||||
f.debuffs[i].cd = f.debuffs[i].cd or CreateCooldown(f.debuffs[i], "unitframe", f.debuffs[i]:GetName() .. "Cooldown")
|
||||
f.debuffs[i].cd = f.debuffs[i].cd or CreateCooldown(f.debuffs[i], "aura", f.config, "aura_timers", f.debuffs[i]:GetName() .. "Cooldown")
|
||||
f.debuffs[i].cd:SetFrameLevel(14)
|
||||
|
||||
f.debuffs[i].id = i
|
||||
@@ -1031,6 +1043,8 @@ end
|
||||
function pfUI.uf.OnShow()
|
||||
RegisterShownEvents(this)
|
||||
pfUI.uf:RefreshUnit(this, "all")
|
||||
-- flags left from while the frame was off screen, and the portrait's model
|
||||
pfUI.uf:QueueUpdate(this)
|
||||
end
|
||||
|
||||
function pfUI.uf.OnHide()
|
||||
@@ -1047,7 +1061,6 @@ function pfUI.uf.OnEvent()
|
||||
if event == "PLAYER_LOGOUT" then
|
||||
this:UnregisterAllEvents()
|
||||
this:SetScript("OnEvent", nil)
|
||||
this:SetScript("OnUpdate", nil)
|
||||
-- the visibility timer keeps ticking, so leaving this frame on its list
|
||||
-- would have UpdateVisibility re-register the unit events we just
|
||||
-- dropped -- straight back into the crash 132 this branch prevents
|
||||
@@ -1063,13 +1076,13 @@ function pfUI.uf.OnEvent()
|
||||
event == "RAID_ROSTER_UPDATE" or
|
||||
event == "PLAYER_UPDATE_RESTING"
|
||||
then
|
||||
this.update_indicators = true
|
||||
pfUI.uf:QueueUpdate(this, "indicators")
|
||||
end
|
||||
|
||||
-- abort on broken unitframes (e.g focus)
|
||||
if not this.label then return end
|
||||
|
||||
-- a hidden frame runs no OnUpdate, so its unit coming into existence has to
|
||||
-- a hidden frame does not refresh, so its unit coming into existence has to
|
||||
-- show it from here
|
||||
if VISIBILITY_EVENTS[event] then
|
||||
this:UpdateVisibility()
|
||||
@@ -1077,11 +1090,11 @@ function pfUI.uf.OnEvent()
|
||||
|
||||
-- update regular frames
|
||||
if event == "PLAYER_ENTERING_WORLD" then
|
||||
this.update_full = true
|
||||
pfUI.uf:QueueUpdate(this, "full")
|
||||
-- Clear GUID tracking on zone change for full rebuild
|
||||
if pfUI.uf.ClearGuidTracking then pfUI.uf.ClearGuidTracking() end
|
||||
elseif this.label == "target" and event == "PLAYER_TARGET_CHANGED" then
|
||||
this.update_full = true
|
||||
pfUI.uf:QueueUpdate(this, "full")
|
||||
-- immediately update raid icon to avoid delay on target swap
|
||||
if this.raidIcon and this.config and this.config.raidicon == "1" then
|
||||
local raidIcon = UnitName("target") and GetRaidTargetIndex("target")
|
||||
@@ -1100,26 +1113,26 @@ function pfUI.uf.OnEvent()
|
||||
local oldGuid = pfUI.uf.guidTracker.frameToGuid[this]
|
||||
if newGuid ~= oldGuid then
|
||||
pfUI.uf.guidTracker.frameToGuid[this] = newGuid
|
||||
this.update_full = true
|
||||
pfUI.uf:QueueUpdate(this, "full")
|
||||
end
|
||||
else
|
||||
this.update_full = true
|
||||
pfUI.uf:QueueUpdate(this, "full")
|
||||
end
|
||||
elseif ( this.label == "raid" or this.label == "party" ) and event == "RAID_ROSTER_UPDATE" then
|
||||
-- Note: Smart GUID-based updates are handled in raid.lua OnUpdate
|
||||
-- Note: Smart GUID-based updates are handled in raid.lua UpdateRoster
|
||||
-- after frame IDs are reassigned. We don't set update_full here anymore
|
||||
-- for raid frames to avoid the freeze.
|
||||
if this.label == "party" then
|
||||
-- Party frames still need the old logic (no smart tracking yet)
|
||||
this.update_full = true
|
||||
pfUI.uf:QueueUpdate(this, "full")
|
||||
end
|
||||
-- Raid frames: update_full is set by raid.lua GUID tracker
|
||||
elseif this.label == "pet" and event == "UNIT_PET" then
|
||||
this.update_full = true
|
||||
pfUI.uf:QueueUpdate(this, "full")
|
||||
elseif this.label == "player" and (event == "PLAYER_AURAS_CHANGED" or event == "PLAYER_EQUIPMENT_CHANGED") then
|
||||
this.update_aura = true
|
||||
pfUI.uf:QueueUpdate(this, "aura")
|
||||
elseif this.label == "pet" and event == "UNIT_HAPPINESS" then
|
||||
this.update_full = true
|
||||
pfUI.uf:QueueUpdate(this, "full")
|
||||
elseif event == "UNIT_IN_RANGE_UPDATE" then
|
||||
-- registered for the frame's unit alone, and fired in the filter's lower
|
||||
-- case spelling, which a GUID's compare below would miss
|
||||
@@ -1131,224 +1144,180 @@ function pfUI.uf.OnEvent()
|
||||
-- GUID, so filtering on one of the two never wakes the frame twice.
|
||||
elseif arg1 and arg1 == this.eventunit then
|
||||
if event == "UNIT_PORTRAIT_UPDATE" or event == "UNIT_MODEL_CHANGED" then
|
||||
this.update_portrait = true
|
||||
pfUI.uf:QueueUpdate(this, "portrait")
|
||||
elseif event == "UNIT_AURA" then
|
||||
this.update_aura = true
|
||||
pfUI.uf:QueueUpdate(this, "aura")
|
||||
elseif event == "UNIT_AURA_DELTA" then
|
||||
-- an aura that only refreshed or restacked leaves every aura in its
|
||||
-- slot, so the icons need their timers and stacks, not a rebuild
|
||||
if arg2.isFullUpdate or arg2.addedAuraInstanceIDs or arg2.removedAuraInstanceIDs then
|
||||
this.update_aura = true
|
||||
pfUI.uf:QueueUpdate(this, "aura")
|
||||
else
|
||||
this.update_auratime = true
|
||||
pfUI.uf:QueueUpdate(this, "auratime")
|
||||
end
|
||||
elseif event == "UNIT_POWER_UPDATE" or event == "UNIT_MAXPOWER" then
|
||||
-- every power of the unit reports, a cat druid's mana regen too; redraw
|
||||
-- for the one the bar shows, and for mana under a druid mana bar
|
||||
local _, shown = UnitPowerType(arg1)
|
||||
if arg2 == shown or (arg2 == "MANA" and this.druidmana) then
|
||||
this.update_base = true
|
||||
pfUI.uf:QueueUpdate(this, "base")
|
||||
end
|
||||
elseif event == "UNIT_FACTION" then
|
||||
-- the PvP flag, the reaction colour and the tapped grey
|
||||
this.update_indicators = true
|
||||
this.update_base = true
|
||||
pfUI.uf:QueueUpdate(this, "indicators")
|
||||
pfUI.uf:QueueUpdate(this, "base")
|
||||
elseif event == "UNIT_FLAGS" then
|
||||
this.update_combat = true
|
||||
pfUI.uf:QueueUpdate(this, "combat")
|
||||
elseif event == "UNIT_DISTANCE_CHECK_UPDATE" then
|
||||
-- the portrait trades the question mark for the model, the frame fades
|
||||
-- by sight, and an attacker that left with the member is let go
|
||||
this.update_portrait = true
|
||||
this.update_combat = true
|
||||
pfUI.uf:QueueUpdate(this, "portrait")
|
||||
pfUI.uf:QueueUpdate(this, "combat")
|
||||
elseif event == "UNIT_CONNECTION" then
|
||||
this.update_full = true
|
||||
pfUI.uf:QueueUpdate(this, "full")
|
||||
elseif event == "UNIT_COMBAT" then
|
||||
-- every hit starts the fade over
|
||||
this.feedback:Stop()
|
||||
CombatFeedback_OnCombatEvent(arg2, arg3, arg4, arg5)
|
||||
this.feedback:Play()
|
||||
elseif event == "INCOMING_RESURRECT_CHANGED" then
|
||||
this.update_indicators = true
|
||||
pfUI.uf:QueueUpdate(this, "indicators")
|
||||
else
|
||||
this.update_base = true
|
||||
pfUI.uf:QueueUpdate(this, "base")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Local reference for performance
|
||||
local _GetTime = GetTime
|
||||
-- Drain the update flags the events set, then hand a 3D portrait its unit.
|
||||
-- A frame that is not on screen keeps its flags; OnShow flushes them.
|
||||
local function Flush(frame)
|
||||
frame.queued = nil
|
||||
if not frame:IsVisible() then return end
|
||||
|
||||
-- Global cached time for libpredict and other functions
|
||||
pfUI.uf.now = 0
|
||||
|
||||
-- ============================================================================
|
||||
-- OnUpdate - draining the event-set update flags, heal prediction, and the
|
||||
-- two polls no event replaces (a UnitXP range threshold, the pet frames).
|
||||
-- ============================================================================
|
||||
function pfUI.uf.OnUpdate()
|
||||
local now = _GetTime()
|
||||
pfUI.uf.now = now
|
||||
|
||||
-- update combat feedback (no throttle - needs immediate feedback)
|
||||
if this.feedbackText then CombatFeedback_OnUpdate(arg1) end
|
||||
|
||||
-- Throttle raid/party frames for performance
|
||||
if this.label == "raid" or this.label == "party" then
|
||||
if (this.throttleTick or 0) > now then
|
||||
return
|
||||
end
|
||||
this.throttleTick = now + 0.1 -- Default: 10 FPS
|
||||
end
|
||||
|
||||
if this.label then
|
||||
-- what no event reports: a UnitXP range threshold, and the pet frames
|
||||
-- (created with a tick)
|
||||
if this.rangepoll or this.tick then
|
||||
-- Validate tick value - it should be an interval (e.g. 0.5), not a timestamp
|
||||
local tickInterval = this.tick
|
||||
if tickInterval and tickInterval > 10 then
|
||||
-- tick is a timestamp, not an interval - ignore it
|
||||
tickInterval = nil
|
||||
end
|
||||
-- Reset lastTick if it's invalid (much larger than now, e.g. from corrupted state)
|
||||
if this.lastTick and this.lastTick > now + 10 then
|
||||
this.lastTick = nil
|
||||
end
|
||||
if not this.lastTick then this.lastTick = now + (tickInterval or .5) end
|
||||
if this.lastTick < now then
|
||||
local unitstr = this.label .. this.id
|
||||
this.lastTick = now + (tickInterval or .5)
|
||||
|
||||
if this.rangepoll then pfUI.uf:RefreshUnitState(this) end
|
||||
|
||||
-- A pet's full refresh rescans every aura and the portrait, so only
|
||||
-- do it when the unit behind the frame changes or once a second;
|
||||
-- other ticks refresh the bars only.
|
||||
if this.tick then
|
||||
local guid = UnitGUID(unitstr)
|
||||
if guid ~= this.tickGuid or (this.tickFull or 0) < now then
|
||||
this.tickGuid = guid
|
||||
this.tickFull = now + 1
|
||||
pfUI.uf:RefreshUnit(this, "all")
|
||||
else
|
||||
pfUI.uf:RefreshUnit(this, "base")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Heal Prediction (throttled to 0.1s for responsiveness)
|
||||
if libpredict and this.incHeal then
|
||||
if not this.lastHealTick then this.lastHealTick = now end
|
||||
if this.lastHealTick < now then
|
||||
this.lastHealTick = now + 0.1
|
||||
|
||||
local unit = this.label .. this.id
|
||||
local heal = libpredict:UnitGetIncomingHeals(unit)
|
||||
|
||||
local health, maxHealth = UnitHealth(unit), UnitHealthMax(unit)
|
||||
|
||||
if heal - health - maxHealth ~= this.predictstate then
|
||||
local overhealperc = tonumber(this.config.overhealperc)
|
||||
this.predictstate = heal - health - maxHealth
|
||||
|
||||
if heal > 0 and (health < maxHealth or overhealperc > 0 ) then
|
||||
local width = this.config.width
|
||||
local height = this.config.height
|
||||
|
||||
if this.config.verticalbar == "0" then
|
||||
local healthWidth = width * (health / maxHealth)
|
||||
local incWidth = width * heal / maxHealth
|
||||
if healthWidth + incWidth > width * (1+(overhealperc/100)) then
|
||||
incWidth = width * (1+overhealperc/100) - healthWidth
|
||||
end
|
||||
|
||||
if this.config.invert_healthbar == "1" then
|
||||
this.incHeal:SetWidth(incWidth)
|
||||
else
|
||||
this.incHeal:SetWidth(incWidth + healthWidth)
|
||||
end
|
||||
else
|
||||
local healthHeight = height * (health / maxHealth)
|
||||
local incHeight = height * heal / maxHealth
|
||||
if healthHeight + incHeight > height * (1+(overhealperc/100)) then
|
||||
incHeight = height * (1+overhealperc/100) - healthHeight
|
||||
end
|
||||
|
||||
if this.config.invert_healthbar == "1" then
|
||||
this.incHeal:SetHeight(incHeight)
|
||||
else
|
||||
this.incHeal:SetHeight(incHeight + healthHeight)
|
||||
end
|
||||
end
|
||||
|
||||
this.incHeal:Show()
|
||||
else
|
||||
this.incHeal:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
-- EVENT-BASED UPDATES (Health, Mana, Auras, etc.)
|
||||
-- ============================================================================
|
||||
|
||||
|
||||
-- process all queued unit events
|
||||
if this.update_full then
|
||||
if frame.update_full then
|
||||
-- process full updates, indicators and combat state included
|
||||
pfUI.uf:RefreshUnit(this, "all")
|
||||
pfUI.uf:RefreshUnit(frame, "all")
|
||||
|
||||
-- clear update caches
|
||||
this.update_full = nil
|
||||
this.update_base = nil
|
||||
this.update_aura = nil
|
||||
this.update_auratime = nil
|
||||
this.update_portrait = nil
|
||||
this.update_indicators = nil
|
||||
this.update_combat = nil
|
||||
frame.update_full = nil
|
||||
frame.update_base = nil
|
||||
frame.update_aura = nil
|
||||
frame.update_auratime = nil
|
||||
frame.update_portrait = nil
|
||||
frame.update_indicators = nil
|
||||
frame.update_combat = nil
|
||||
else
|
||||
if this.update_indicators then
|
||||
pfUI.uf:RefreshIndicators(this)
|
||||
this.update_indicators = nil
|
||||
if frame.update_indicators then
|
||||
pfUI.uf:RefreshIndicators(frame)
|
||||
frame.update_indicators = nil
|
||||
end
|
||||
|
||||
if this.update_combat then
|
||||
pfUI.uf:RefreshCombat(this)
|
||||
this.update_combat = nil
|
||||
if frame.update_combat then
|
||||
pfUI.uf:RefreshCombat(frame)
|
||||
frame.update_combat = nil
|
||||
end
|
||||
|
||||
-- process individual events; a rebuild re-times the icons as well
|
||||
if this.update_aura then
|
||||
pfUI.uf:RefreshUnit(this, "aura")
|
||||
this.update_aura = nil
|
||||
this.update_auratime = nil
|
||||
this.update_base = true
|
||||
elseif this.update_auratime then
|
||||
pfUI.uf:RefreshUnit(this, "auratime")
|
||||
this.update_auratime = nil
|
||||
if frame.update_aura then
|
||||
pfUI.uf:RefreshUnit(frame, "aura")
|
||||
frame.update_aura = nil
|
||||
frame.update_auratime = nil
|
||||
frame.update_base = true
|
||||
elseif frame.update_auratime then
|
||||
pfUI.uf:RefreshUnit(frame, "auratime")
|
||||
frame.update_auratime = nil
|
||||
end
|
||||
|
||||
if this.update_portrait then
|
||||
pfUI.uf:RefreshUnit(this, "portrait")
|
||||
this.update_portrait = nil
|
||||
this.update_base = true
|
||||
if frame.update_portrait then
|
||||
pfUI.uf:RefreshUnit(frame, "portrait")
|
||||
frame.update_portrait = nil
|
||||
frame.update_base = true
|
||||
end
|
||||
|
||||
if this.update_base then
|
||||
pfUI.uf:RefreshUnit(this, "base")
|
||||
this.update_base = nil
|
||||
if frame.update_base then
|
||||
pfUI.uf:RefreshUnit(frame, "base")
|
||||
frame.update_base = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- update portrait on first visible frame
|
||||
if this.portrait and this.portrait.model and this.portrait.model.update then
|
||||
this.portrait.model.lastUnit = UnitName(this.portrait.model.update)
|
||||
this.portrait.model:SetUnit(this.portrait.model.update)
|
||||
this.portrait.model:SetCamera(0)
|
||||
this.portrait.model.update = nil
|
||||
-- a model takes its unit only once it is on screen, so it waits for this
|
||||
local model = frame.portrait and frame.portrait.model
|
||||
if model and model.update then
|
||||
model.lastUnit = UnitName(model.update)
|
||||
model:SetUnit(model.update)
|
||||
model:SetCamera(0)
|
||||
model.update = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Flag `kind` ("full", "base", "aura", "auratime", "portrait", "indicators",
|
||||
-- "combat", or nil for none) for the frame's next flush, and schedule that
|
||||
-- flush: the next frame, or within 0.1s for the raid and party frames, which
|
||||
-- batch their bursts.
|
||||
function pfUI.uf:QueueUpdate(frame, kind)
|
||||
if kind then frame["update_" .. kind] = true end
|
||||
if frame.queued then return end
|
||||
frame.queued = true
|
||||
if frame.label == "raid" or frame.label == "party" then
|
||||
C_Timer.After(.1, function() Flush(frame) end)
|
||||
else
|
||||
RunNextFrame(function() Flush(frame) end)
|
||||
end
|
||||
end
|
||||
|
||||
-- Size the incoming-heal overlay from libpredict's heals and the unit's
|
||||
-- health. Runs with the bars (RefreshUnit "base") and when libpredict reports
|
||||
-- the heals on the unit changed.
|
||||
function pfUI.uf:RefreshIncomingHeal(frame)
|
||||
local unit = frame.label .. frame.id
|
||||
local heal = libpredict:UnitGetIncomingHeals(unit)
|
||||
local health, maxHealth = UnitHealth(unit), UnitHealthMax(unit)
|
||||
|
||||
if heal - health - maxHealth == frame.predictstate then return end
|
||||
frame.predictstate = heal - health - maxHealth
|
||||
|
||||
local overhealperc = tonumber(frame.config.overhealperc)
|
||||
if heal > 0 and (health < maxHealth or overhealperc > 0 ) then
|
||||
local width = frame.config.width
|
||||
local height = frame.config.height
|
||||
|
||||
if frame.config.verticalbar == "0" then
|
||||
local healthWidth = width * (health / maxHealth)
|
||||
local incWidth = width * heal / maxHealth
|
||||
if healthWidth + incWidth > width * (1+(overhealperc/100)) then
|
||||
incWidth = width * (1+overhealperc/100) - healthWidth
|
||||
end
|
||||
frame.incHeal:SetWidth(incWidth)
|
||||
else
|
||||
local healthHeight = height * (health / maxHealth)
|
||||
local incHeight = height * heal / maxHealth
|
||||
if healthHeight + incHeight > height * (1+(overhealperc/100)) then
|
||||
incHeight = height * (1+overhealperc/100) - healthHeight
|
||||
end
|
||||
frame.incHeal:SetHeight(incHeight)
|
||||
end
|
||||
|
||||
frame.incHeal:Show()
|
||||
else
|
||||
frame.incHeal:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
pfUI.events:RegisterCallback("libpredict:heals", function(_, target)
|
||||
for frame in pairs(visibilityframes) do
|
||||
if frame.namecache == target and frame:IsVisible() then
|
||||
pfUI.uf:RefreshIncomingHeal(frame)
|
||||
end
|
||||
end
|
||||
end, "unitframes")
|
||||
|
||||
-- A UnitXP range threshold has no event, so the frames fading by it poll.
|
||||
C_Timer.NewTicker(.5, function()
|
||||
for frame in pairs(visibilityframes) do
|
||||
if frame.rangepoll and frame:IsVisible() then pfUI.uf:RefreshUnitState(frame) end
|
||||
end
|
||||
end)
|
||||
|
||||
-- The unit events whose arg1 is the frame's OWN unit -- everything the OnEvent
|
||||
-- routes through its "UNIT_XXX Events" branch. These are not registered here:
|
||||
-- UpdateVisibility owns them, because it owns the frame's unit (below).
|
||||
@@ -1534,7 +1503,6 @@ function pfUI.uf:EnableScripts()
|
||||
f:SetScript("OnShow", pfUI.uf.OnShow)
|
||||
f:SetScript("OnHide", pfUI.uf.OnHide)
|
||||
f:SetScript("OnEvent", pfUI.uf.OnEvent)
|
||||
f:SetScript("OnUpdate", pfUI.uf.OnUpdate)
|
||||
|
||||
visibilityframes[f] = true
|
||||
end
|
||||
@@ -1606,11 +1574,11 @@ function pfUI.uf:CreateUnitFrame(unit, id, config, tick)
|
||||
f.glow = CreateFrame("Frame", nil, f)
|
||||
-- Pulse between .8 and .4 for good. The group only advances while the glow
|
||||
-- is shown, so a hidden glow costs nothing.
|
||||
f.glow:SetAlpha(.8)
|
||||
f.glow.pulse = f.glow:CreateAnimationGroup()
|
||||
f.glow.pulse:SetLooping("BOUNCE")
|
||||
local fade = f.glow.pulse:CreateAnimation("Alpha")
|
||||
fade:SetChange(-.4)
|
||||
fade:SetFromAlpha(.8)
|
||||
fade:SetToAlpha(.4)
|
||||
fade:SetDuration(1.3)
|
||||
fade:SetSmoothing("IN_OUT")
|
||||
f.glow.pulse:Play()
|
||||
@@ -1669,6 +1637,21 @@ function pfUI.uf:CreateUnitFrame(unit, id, config, tick)
|
||||
f.portrait.model.next = CreateFrame("PlayerModel", nil, nil)
|
||||
f.feedbackText = f:CreateFontString("pfHitIndicator" .. f.label .. f.id, "OVERLAY", "NumberFontNormalHuge")
|
||||
|
||||
-- Fade the combat feedback text in, hold it, and fade it out -- the timing
|
||||
-- of CombatFeedback_OnUpdate -- then hide it.
|
||||
f.feedback = f.feedbackText:CreateAnimationGroup()
|
||||
local fadein = f.feedback:CreateAnimation("Alpha")
|
||||
fadein:SetOrder(1)
|
||||
fadein:SetDuration(COMBATFEEDBACK_FADEINTIME)
|
||||
fadein:SetToAlpha(1)
|
||||
local fadeout = f.feedback:CreateAnimation("Alpha")
|
||||
fadeout:SetOrder(2)
|
||||
fadeout:SetStartDelay(COMBATFEEDBACK_HOLDTIME)
|
||||
fadeout:SetDuration(COMBATFEEDBACK_FADEOUTTIME)
|
||||
fadeout:SetFromAlpha(1)
|
||||
fadeout:SetToAlpha(0)
|
||||
f.feedback:SetScript("OnFinished", function() f.feedbackText:Hide() end)
|
||||
|
||||
if f.label == "raid" and mod(f.id, 5) == 1 then
|
||||
local group = math.ceil(f.id/5)
|
||||
f.group = f.group or f.hp.bar:CreateFontString("Status", "OVERLAY", "GameFontNormalSmall")
|
||||
@@ -2042,7 +2025,7 @@ function pfUI.uf:RefreshUnit(unit, component)
|
||||
local size
|
||||
|
||||
if disptype == "4" or disptype == "3" then
|
||||
size = unit.hp.bar:GetHeight() * tonumber(unit.config.debuff_ind_size)
|
||||
size = unit.hp.bar:GetUnscaledHeight() * tonumber(unit.config.debuff_ind_size)
|
||||
if size ~= indicator.size or disptype ~= indicator.disp or indipos ~= indicator.ipos then
|
||||
indicator:ClearAllPoints()
|
||||
indicator:SetPoint(indipos, 0, 0)
|
||||
@@ -2257,6 +2240,7 @@ function pfUI.uf:RefreshUnit(unit, component)
|
||||
unit.portrait.model.update = unitstr
|
||||
end
|
||||
end
|
||||
if unit.portrait.model.update then pfUI.uf:QueueUpdate(unit) end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2397,6 +2381,7 @@ function pfUI.uf:RefreshUnit(unit, component)
|
||||
|
||||
if unit.druidmana then pfUI.uf:UpdateDruidMana(unit) end
|
||||
|
||||
pfUI.uf:RefreshIncomingHeal(unit)
|
||||
pfUI.uf:RefreshUnitState(unit)
|
||||
end
|
||||
end
|
||||
@@ -2443,10 +2428,11 @@ function pfUI.uf:AddIcon(frame, pos, icon, timeleft, stacks, start, duration)
|
||||
local position = frame.config.indicator_pos or "TOPLEFT"
|
||||
local iconsize = tonumber(frame.config.indicator_size)
|
||||
local spacing = tonumber(frame.config.indicator_spacing)
|
||||
local config = frame.config
|
||||
|
||||
if not frame.hp then return end
|
||||
local frame = frame.hp.bar
|
||||
if pos > 6 or pos > ceil(frame:GetWidth() / iconsize) then return end
|
||||
if pos > 6 or pos > ceil(frame:GetUnscaledWidth() / iconsize) then return end
|
||||
|
||||
frame.icon = frame.icon or CreateFrame("Frame", nil, frame)
|
||||
|
||||
@@ -2461,7 +2447,7 @@ function pfUI.uf:AddIcon(frame, pos, icon, timeleft, stacks, start, duration)
|
||||
frame.icon[pos].stacks:SetJustifyH("RIGHT")
|
||||
frame.icon[pos].stacks:SetJustifyV("BOTTOM")
|
||||
|
||||
frame.icon[pos].cd = CreateCooldown(frame.icon[pos], "indicator")
|
||||
frame.icon[pos].cd = CreateCooldown(frame.icon[pos], "aura", config, "indicator_timers")
|
||||
frame.icon[pos].cd:SetFrameLevel(48)
|
||||
end
|
||||
|
||||
|
||||
Vendored
+1
-4
@@ -935,14 +935,11 @@ pfUI_profiles["Adapta"].new_module_positions = pfUI_profiles["Modern"].new_modul
|
||||
|
||||
|
||||
-- overwrite core profiles in userdata
|
||||
local profile_loader = CreateFrame("Frame")
|
||||
profile_loader:RegisterEvent("VARIABLES_LOADED")
|
||||
profile_loader:SetScript("OnEvent", function()
|
||||
EventUtil.RegisterOnceFrameEventAndCallback("VARIABLES_LOADED", function()
|
||||
pfUI_profiles["Modern"] = modern
|
||||
pfUI_profiles["Nostalgia"] = nostalgia
|
||||
pfUI_profiles["Legacy"] = legacy
|
||||
pfUI_profiles["Adapta"] = adapta
|
||||
pfUI_profiles["Light"] = light
|
||||
pfUI_profiles["Slim"] = slim
|
||||
this:UnregisterAllEvents()
|
||||
end)
|
||||
Vendored
+10
-11
@@ -8,7 +8,6 @@ pfUI_translation["deDE"] = {
|
||||
["Actionbar"] = nil,
|
||||
["Action Bar"] = nil,
|
||||
["Action Bar Border Size"] = nil,
|
||||
["Action Bars"] = nil,
|
||||
["Active Addons"] = nil,
|
||||
["Add button to the frame"] = nil,
|
||||
["Added button"] = nil,
|
||||
@@ -77,11 +76,11 @@ pfUI_translation["deDE"] = {
|
||||
["Bottom"] = nil,
|
||||
["Bottom Left"] = nil,
|
||||
["Bottom Right"] = nil,
|
||||
["Buff And Debuff Timers"] = nil,
|
||||
["Buffbar Height"] = nil,
|
||||
["Buffbar Width"] = nil,
|
||||
["Buff/Debuff Icons"] = nil,
|
||||
["Buff/Debuff Indicators"] = nil,
|
||||
["Buff Indicators"] = nil,
|
||||
["Buff Limit"] = nil,
|
||||
["Buff Position"] = nil,
|
||||
["Buffs"] = nil,
|
||||
@@ -106,6 +105,15 @@ pfUI_translation["deDE"] = {
|
||||
["Center Text"] = nil,
|
||||
["Center Text X Offset"] = nil,
|
||||
["Center Text Y Offset"] = nil,
|
||||
["Cooldown Timers"] = nil,
|
||||
["Debuff Timers"] = nil,
|
||||
["Duration Timers"] = nil,
|
||||
["Indicator Timers"] = nil,
|
||||
["Numbers"] = nil,
|
||||
["Numbers And Sweep"] = nil,
|
||||
["Sweep"] = nil,
|
||||
["Timers"] = nil,
|
||||
["Unit Buff Timers"] = nil,
|
||||
["|cff33ffccBlizzard: \"Interface Options\"|r\n\nDo you want me to set up the recommended Blizzard UI settings? This will enable settings that can be found in the Interface section of your client. Options like Buff Durations, Instant Quest Text, Auto Selfcast and others will be set."] = nil,
|
||||
["|cff33ffccChat: \"Channels\"|r\n\nDo you want me to setup the chat channels of your chatframes? This would set important or personal messages to the left chat and world channels and lootinformation to the right chat."] = nil,
|
||||
["|cff33ffccChat: \"Layout\"|r\n\nDo you want me to adjust the layout of your chatframes? This would make sure, that every window is placed on its dedicated position."] = nil,
|
||||
@@ -516,7 +524,6 @@ pfUI_translation["deDE"] = {
|
||||
["Name | Health Missing"] = nil,
|
||||
["Name (Linebreak) -Health Missing"] = nil,
|
||||
["Nameplate Border Size"] = nil,
|
||||
["Nameplate Debuffs"] = nil,
|
||||
["Nameplates"] = nil,
|
||||
["Nameplate Width"] = nil,
|
||||
["Name (Short)"] = nil,
|
||||
@@ -584,7 +591,6 @@ pfUI_translation["deDE"] = {
|
||||
["Pixel"] = nil,
|
||||
["Player"] = nil,
|
||||
["Player Buff Bar"] = nil,
|
||||
["Player Buffs"] = nil,
|
||||
["Player Castbar"] = nil,
|
||||
["Player Debuff Bar"] = nil,
|
||||
["Player SP/Haste Display"] = nil,
|
||||
@@ -651,7 +657,6 @@ pfUI_translation["deDE"] = {
|
||||
["Resting"] = nil,
|
||||
["Reveal Unexplored Areas"] = nil,
|
||||
["Switch to current zone"] = "Zur aktuellen Zone wechseln",
|
||||
["Reverse Sweep On"] = nil,
|
||||
["Right"] = nil,
|
||||
["Right Actionbar"] = nil,
|
||||
["Right Anchor"] = nil,
|
||||
@@ -733,7 +738,6 @@ pfUI_translation["deDE"] = {
|
||||
["Show Loot Icon"] = nil,
|
||||
["Show Macro Text"] = nil,
|
||||
["Show Meters By Default"] = nil,
|
||||
["Show Numbers On"] = nil,
|
||||
["Show On Friendly Units"] = nil,
|
||||
["Show On Hostile Units"] = nil,
|
||||
["Show Procs Indicators"] = nil,
|
||||
@@ -751,7 +755,6 @@ pfUI_translation["deDE"] = {
|
||||
["Show Spell Icon"] = nil,
|
||||
["Show Spell Name"] = nil,
|
||||
["Show Stacks"] = nil,
|
||||
["Show Sweep On"] = nil,
|
||||
["Show Tenths Below 5 Seconds"] = nil,
|
||||
["Show Text"] = nil,
|
||||
["Show Timer"] = nil,
|
||||
@@ -819,7 +822,6 @@ pfUI_translation["deDE"] = {
|
||||
["Tiny (PixelPerfect)"] = nil,
|
||||
["Toggle as Tank"] = nil,
|
||||
["Tooltip"] = nil,
|
||||
["Tooltip Auras"] = nil,
|
||||
["Tooltip Position"] = nil,
|
||||
["Tooltip Text Font"] = nil,
|
||||
["Tooltip Text Font Size"] = nil,
|
||||
@@ -831,13 +833,11 @@ pfUI_translation["deDE"] = {
|
||||
["Total Gold"] = nil,
|
||||
["Totem Direction"] = nil,
|
||||
["Totem Icons"] = nil,
|
||||
["Totems"] = nil,
|
||||
["Tracked Reputation"] = nil,
|
||||
["Tracking Icon Size"] = nil,
|
||||
["Trigger Actions On Key Down"] = nil,
|
||||
["UI-Scale"] = nil,
|
||||
["Unbuffed"] = nil,
|
||||
["Unit Frame Auras"] = nil,
|
||||
["Unit Frame Border Size"] = nil,
|
||||
["Unit Frame Layout"] = nil,
|
||||
["Unit Frames"] = nil,
|
||||
@@ -907,7 +907,6 @@ pfUI_translation["deDE"] = {
|
||||
["Chat Tab"] = "Chat Tab",
|
||||
["Libpredict"] = "Libpredict",
|
||||
["Panel Alignment"] = "Panel Ausrichtung",
|
||||
["Nameplate Update Rate"] = "Namensplaketten Aktualisierungsrate",
|
||||
["Target/Casting Plates"] = "Ziel/Cast Plaketten",
|
||||
["Tooltip Update Rate"] = "Tooltip Aktualisierungsrate",
|
||||
["Cursor Follow"] = "Cursor Folgen",
|
||||
|
||||
Vendored
+11
-11
@@ -8,7 +8,6 @@ pfUI_translation["enUS"] = {
|
||||
["Actionbar"] = nil,
|
||||
["Action Bar"] = nil,
|
||||
["Action Bar Border Size"] = nil,
|
||||
["Action Bars"] = nil,
|
||||
["Active Addons"] = nil,
|
||||
["Add button to the frame"] = nil,
|
||||
["Added button"] = nil,
|
||||
@@ -80,11 +79,11 @@ pfUI_translation["enUS"] = {
|
||||
["Bottom"] = nil,
|
||||
["Bottom Left"] = nil,
|
||||
["Bottom Right"] = nil,
|
||||
["Buff And Debuff Timers"] = nil,
|
||||
["Buffbar Height"] = nil,
|
||||
["Buffbar Width"] = nil,
|
||||
["Buff/Debuff Icons"] = nil,
|
||||
["Buff/Debuff Indicators"] = nil,
|
||||
["Buff Indicators"] = nil,
|
||||
["Buff Limit"] = nil,
|
||||
["Buff Position"] = nil,
|
||||
["Buffs"] = nil,
|
||||
@@ -113,6 +112,15 @@ pfUI_translation["enUS"] = {
|
||||
["Center Text"] = nil,
|
||||
["Center Text X Offset"] = nil,
|
||||
["Center Text Y Offset"] = nil,
|
||||
["Cooldown Timers"] = nil,
|
||||
["Debuff Timers"] = nil,
|
||||
["Duration Timers"] = nil,
|
||||
["Indicator Timers"] = nil,
|
||||
["Numbers"] = nil,
|
||||
["Numbers And Sweep"] = nil,
|
||||
["Sweep"] = nil,
|
||||
["Timers"] = nil,
|
||||
["Unit Buff Timers"] = nil,
|
||||
["|cff33ffccBlizzard: \"Interface Options\"|r\n\nDo you want me to set up the recommended Blizzard UI settings? This will enable settings that can be found in the Interface section of your client. Options like Buff Durations, Instant Quest Text, Auto Selfcast and others will be set."] = nil,
|
||||
["|cff33ffccChat: \"Channels\"|r\n\nDo you want me to setup the chat channels of your chatframes? This would set important or personal messages to the left chat and world channels and lootinformation to the right chat."] = nil,
|
||||
["|cff33ffccChat: \"Layout\"|r\n\nDo you want me to adjust the layout of your chatframes? This would make sure, that every window is placed on its dedicated position."] = nil,
|
||||
@@ -425,6 +433,7 @@ pfUI_translation["enUS"] = {
|
||||
["Highlight Out Of Mana Spells"] = nil,
|
||||
["Highlight New Items"] = nil,
|
||||
["Highlight Out Of Range Spells"] = nil,
|
||||
["Highlight Proc And Reactive Spells"] = nil,
|
||||
["Highlight Settings That Require Reload"] = nil,
|
||||
["Highlight Unusable Items"] = nil,
|
||||
["Hold [Shift] to use item."] = nil,
|
||||
@@ -533,7 +542,6 @@ pfUI_translation["enUS"] = {
|
||||
["Name | Health Missing"] = nil,
|
||||
["Name (Linebreak) -Health Missing"] = nil,
|
||||
["Nameplate Border Size"] = nil,
|
||||
["Nameplate Debuffs"] = nil,
|
||||
["Nameplates"] = nil,
|
||||
["Nameplate Width"] = nil,
|
||||
["Name (Short)"] = nil,
|
||||
@@ -606,7 +614,6 @@ pfUI_translation["enUS"] = {
|
||||
["Pixel"] = nil,
|
||||
["Player"] = nil,
|
||||
["Player Buff Bar"] = nil,
|
||||
["Player Buffs"] = nil,
|
||||
["Player Castbar"] = nil,
|
||||
["Player Debuff Bar"] = nil,
|
||||
["Player SP/Haste Display"] = nil,
|
||||
@@ -674,7 +681,6 @@ pfUI_translation["enUS"] = {
|
||||
["Reveal Unexplored Areas"] = nil,
|
||||
["Switch to current zone"] = nil,
|
||||
["Retrieving item information..."] = nil,
|
||||
["Reverse Sweep On"] = nil,
|
||||
["Right"] = nil,
|
||||
["Right Actionbar"] = nil,
|
||||
["Right Anchor"] = nil,
|
||||
@@ -756,7 +762,6 @@ pfUI_translation["enUS"] = {
|
||||
["Show Loot Icon"] = nil,
|
||||
["Show Macro Text"] = nil,
|
||||
["Show Meters By Default"] = nil,
|
||||
["Show Numbers On"] = nil,
|
||||
["Show On Friendly Units"] = nil,
|
||||
["Show On Hostile Units"] = nil,
|
||||
["Show Procs Indicators"] = nil,
|
||||
@@ -774,7 +779,6 @@ pfUI_translation["enUS"] = {
|
||||
["Show Spell Icon"] = nil,
|
||||
["Show Spell Name"] = nil,
|
||||
["Show Stacks"] = nil,
|
||||
["Show Sweep On"] = nil,
|
||||
["Show Tenths Below 5 Seconds"] = nil,
|
||||
["Show Text"] = nil,
|
||||
["Show Timer"] = nil,
|
||||
@@ -851,7 +855,6 @@ pfUI_translation["enUS"] = {
|
||||
["Tiny (PixelPerfect)"] = nil,
|
||||
["Toggle as Tank"] = nil,
|
||||
["Tooltip"] = nil,
|
||||
["Tooltip Auras"] = nil,
|
||||
["Tooltip Position"] = nil,
|
||||
["Tooltip Text Font"] = nil,
|
||||
["Tooltip Text Font Size"] = nil,
|
||||
@@ -863,13 +866,11 @@ pfUI_translation["enUS"] = {
|
||||
["Total Gold"] = nil,
|
||||
["Totem Direction"] = nil,
|
||||
["Totem Icons"] = nil,
|
||||
["Totems"] = nil,
|
||||
["Tracked Reputation"] = nil,
|
||||
["Tracking Icon Size"] = nil,
|
||||
["Trigger Actions On Key Down"] = nil,
|
||||
["UI-Scale"] = nil,
|
||||
["Unbuffed"] = nil,
|
||||
["Unit Frame Auras"] = nil,
|
||||
["Unit Frame Border Size"] = nil,
|
||||
["Unit Frame Layout"] = nil,
|
||||
["Unit Frames"] = nil,
|
||||
@@ -939,7 +940,6 @@ pfUI_translation["enUS"] = {
|
||||
["Chat Tab"] = nil,
|
||||
["Libpredict"] = nil,
|
||||
["Panel Alignment"] = nil,
|
||||
["Nameplate Update Rate"] = nil,
|
||||
["Target/Casting Plates"] = nil,
|
||||
["Tooltip Update Rate"] = nil,
|
||||
["Cursor Follow"] = nil,
|
||||
|
||||
Vendored
+10
-10
@@ -8,7 +8,6 @@ pfUI_translation["esES"] = {
|
||||
["Actionbar"] = "Barra de acción",
|
||||
["Action Bar"] = "Barra de acción",
|
||||
["Action Bar Border Size"] = "Tamaño del borde de la barra de acción",
|
||||
["Action Bars"] = nil,
|
||||
["Active Addons"] = "Accesorios activos",
|
||||
["Add button to the frame"] = "Añadir botón al marco",
|
||||
["Added button"] = "Botón añadido",
|
||||
@@ -77,11 +76,11 @@ pfUI_translation["esES"] = {
|
||||
["Bottom"] = "Inferior",
|
||||
["Bottom Left"] = "Inferior izquierda",
|
||||
["Bottom Right"] = "Inferior derecha",
|
||||
["Buff And Debuff Timers"] = nil,
|
||||
["Buffbar Height"] = "Altura de la barra de beneficios",
|
||||
["Buffbar Width"] = "Ancho de la barra de beneficios",
|
||||
["Buff/Debuff Icons"] = "Iconos de los beneficios/perjuicios",
|
||||
["Buff/Debuff Indicators"] = "Indicadores de beneficios/perjuicios",
|
||||
["Buff Indicators"] = nil,
|
||||
["Buff Limit"] = "Límite de beneficios",
|
||||
["Buff Position"] = "Posición de los beneficios",
|
||||
["Buffs"] = "Beneficios",
|
||||
@@ -106,6 +105,15 @@ pfUI_translation["esES"] = {
|
||||
["Center Text"] = "Centrar texto",
|
||||
["Center Text X Offset"] = nil,
|
||||
["Center Text Y Offset"] = nil,
|
||||
["Cooldown Timers"] = nil,
|
||||
["Debuff Timers"] = nil,
|
||||
["Duration Timers"] = nil,
|
||||
["Indicator Timers"] = nil,
|
||||
["Numbers"] = nil,
|
||||
["Numbers And Sweep"] = nil,
|
||||
["Sweep"] = nil,
|
||||
["Timers"] = nil,
|
||||
["Unit Buff Timers"] = nil,
|
||||
["|cff33ffccBlizzard: \"Interface Options\"|r\n\nDo you want me to set up the recommended Blizzard UI settings? This will enable settings that can be found in the Interface section of your client. Options like Buff Durations, Instant Quest Text, Auto Selfcast and others will be set."] = "|cff33ffccBlizzard: \"Opciones de la interfaz\"|r\n\n¿Prefieres usar la configuración IU recomendada de Blizzard? Se activarán algunas de las opciones que se encuentran en la sección Interfaz de tu cliente. Opciones como duración de buffs, texto de misión instantáneo, autolanzarse hechizos y otros serán activadas.",
|
||||
["|cff33ffccChat: \"Channels\"|r\n\nDo you want me to setup the chat channels of your chatframes? This would set important or personal messages to the left chat and world channels and lootinformation to the right chat."] = "|cff33ffccChat: \"Canales\"|r\n\n¿Quieres que configure los canales de chat para tu marco de chat? Los mensajes importantes o personales aparecerán en la ventana de chat izquierda y los canales del mundo e información del botín en la ventana de chat derecha.",
|
||||
["|cff33ffccChat: \"Layout\"|r\n\nDo you want me to adjust the layout of your chatframes? This would make sure, that every window is placed on its dedicated position."] = "|cff33ffccChat: \"Disposición\"|r\n\n¿Quieres que ajuste la disposición de los marcos de chat? De esta manera cada ventana estará en su posición correcta.",
|
||||
@@ -516,7 +524,6 @@ pfUI_translation["esES"] = {
|
||||
["Name | Health Missing"] = "Nombre | Falta de salud",
|
||||
["Name (Linebreak) -Health Missing"] = nil,
|
||||
["Nameplate Border Size"] = "Tamaño del borde de las placas de nombre",
|
||||
["Nameplate Debuffs"] = nil,
|
||||
["Nameplates"] = "Placas identificativas",
|
||||
["Nameplate Width"] = "Ancho de las placas identificativas",
|
||||
["Name (Short)"] = "Nombre (corto)",
|
||||
@@ -584,7 +591,6 @@ pfUI_translation["esES"] = {
|
||||
["Pixel"] = "Píxel",
|
||||
["Player"] = "Jugador",
|
||||
["Player Buff Bar"] = "Barra de beneficios del jugador",
|
||||
["Player Buffs"] = nil,
|
||||
["Player Castbar"] = "Barra de lanzamiento del jugador",
|
||||
["Player Debuff Bar"] = "Barra de perjuicios del jugador",
|
||||
["Player SP/Haste Display"] = nil,
|
||||
@@ -651,7 +657,6 @@ pfUI_translation["esES"] = {
|
||||
["Resting"] = "Descansando",
|
||||
["Reveal Unexplored Areas"] = "Mostrar áreas no exploradas",
|
||||
["Switch to current zone"] = "Ir a la zona actual",
|
||||
["Reverse Sweep On"] = nil,
|
||||
["Right"] = "Derecho",
|
||||
["Right Actionbar"] = "Barra de acción derecha",
|
||||
["Right Anchor"] = nil,
|
||||
@@ -733,7 +738,6 @@ pfUI_translation["esES"] = {
|
||||
["Show Loot Icon"] = "Mostrar icono de botín",
|
||||
["Show Macro Text"] = "Mostrar texto de macro",
|
||||
["Show Meters By Default"] = "Mostrar medidores por defecto",
|
||||
["Show Numbers On"] = nil,
|
||||
["Show On Friendly Units"] = "Mostrar en unidades amistosas",
|
||||
["Show On Hostile Units"] = "Mostrar en unidades enemigas",
|
||||
["Show Procs Indicators"] = "Mostrar indicadores de beneficios temporales activados",
|
||||
@@ -751,7 +755,6 @@ pfUI_translation["esES"] = {
|
||||
["Show Spell Icon"] = "Mostrar icono de hechizo",
|
||||
["Show Spell Name"] = nil,
|
||||
["Show Stacks"] = "Mostrar pilas",
|
||||
["Show Sweep On"] = nil,
|
||||
["Show Tenths Below 5 Seconds"] = nil,
|
||||
["Show Text"] = nil,
|
||||
["Show Timer"] = nil,
|
||||
@@ -819,7 +822,6 @@ pfUI_translation["esES"] = {
|
||||
["Tiny (PixelPerfect)"] = "Minúsculo (píxel perfecta)",
|
||||
["Toggle as Tank"] = "Alternar si eres el tanque",
|
||||
["Tooltip"] = "Descripción emergente",
|
||||
["Tooltip Auras"] = nil,
|
||||
["Tooltip Position"] = "Posición de la descripción emergente",
|
||||
["Tooltip Text Font"] = nil,
|
||||
["Tooltip Text Font Size"] = nil,
|
||||
@@ -831,13 +833,11 @@ pfUI_translation["esES"] = {
|
||||
["Total Gold"] = "Oro Total",
|
||||
["Totem Direction"] = "Dirección del tótem",
|
||||
["Totem Icons"] = "Iconos de los tótems",
|
||||
["Totems"] = nil,
|
||||
["Tracked Reputation"] = "Reputación rastreada",
|
||||
["Tracking Icon Size"] = "Tamaño del icono de rastreo",
|
||||
["Trigger Actions On Key Down"] = "Disparar acciones por presionar la tecla abajo",
|
||||
["UI-Scale"] = "Escala de IU",
|
||||
["Unbuffed"] = "Sin beneficios",
|
||||
["Unit Frame Auras"] = nil,
|
||||
["Unit Frame Border Size"] = "Tamaño del borde del marco de unidad",
|
||||
["Unit Frame Layout"] = "Disposición del Marco de unidad",
|
||||
["Unit Frames"] = "Marcos de unidad",
|
||||
|
||||
Vendored
+10
-10
@@ -8,7 +8,6 @@ pfUI_translation["frFR"] = {
|
||||
["Actionbar"] = "Barre d'action",
|
||||
["Action Bar"] = "Barre d'action",
|
||||
["Action Bar Border Size"] = "Taille de la bordure de la barre d'action",
|
||||
["Action Bars"] = nil,
|
||||
["Active Addons"] = "Addons Actif",
|
||||
["Add button to the frame"] = "Ajoute un bouton au cadre",
|
||||
["Added button"] = "Bouton ajouté",
|
||||
@@ -77,11 +76,11 @@ pfUI_translation["frFR"] = {
|
||||
["Bottom"] = "Bas",
|
||||
["Bottom Left"] = "Bas Gauche",
|
||||
["Bottom Right"] = "Bas Droit",
|
||||
["Buff And Debuff Timers"] = nil,
|
||||
["Buffbar Height"] = "Hauteur de la barre des Améliorations",
|
||||
["Buffbar Width"] = "Largeur de la barre des Améliorations",
|
||||
["Buff/Debuff Icons"] = "Icones de Améliorations/Affaiblissements",
|
||||
["Buff/Debuff Indicators"] = nil,
|
||||
["Buff Indicators"] = nil,
|
||||
["Buff Limit"] = "Limite des améliorations",
|
||||
["Buff Position"] = "Position des améliorations",
|
||||
["Buffs"] = "Buffs",
|
||||
@@ -106,6 +105,15 @@ pfUI_translation["frFR"] = {
|
||||
["Center Text"] = "Centrer le texte",
|
||||
["Center Text X Offset"] = nil,
|
||||
["Center Text Y Offset"] = nil,
|
||||
["Cooldown Timers"] = nil,
|
||||
["Debuff Timers"] = nil,
|
||||
["Duration Timers"] = nil,
|
||||
["Indicator Timers"] = nil,
|
||||
["Numbers"] = nil,
|
||||
["Numbers And Sweep"] = nil,
|
||||
["Sweep"] = nil,
|
||||
["Timers"] = nil,
|
||||
["Unit Buff Timers"] = nil,
|
||||
["|cff33ffccBlizzard: \"Interface Options\"|r\n\nDo you want me to set up the recommended Blizzard UI settings? This will enable settings that can be found in the Interface section of your client. Options like Buff Durations, Instant Quest Text, Auto Selfcast and others will be set."] = "|cff33ffccBlizzard: \"Options d'Interface\"|r\n\nVoulez-vous que le logiciel vous paramètre les options d'interface recommandées ? Si oui, cela va choisir les options d'interface par défaut de votre client. Les options comme la durée des améliorations, le texte instantané des quêtes, lancer sur soi par défaut et d'autres vont être activées.",
|
||||
["|cff33ffccChat: \"Channels\"|r\n\nDo you want me to setup the chat channels of your chatframes? This would set important or personal messages to the left chat and world channels and lootinformation to the right chat."] = "|cff33ffccChat: \"Canaux\"|r\n\nVoulez-vous que le logiciel vous paramètre les canaux de discussion dans votre fenêtre de chat ? En faisant ceci, les messages importants et personnels seront sur le chat de gauche, alors que les textes de butin ou autre informations diverses seront affichés sur le chat de droite.",
|
||||
["|cff33ffccChat: \"Layout\"|r\n\nDo you want me to adjust the layout of your chatframes? This would make sure, that every window is placed on its dedicated position."] = "|cff33ffccChat: \"Position\"|r\n\nVoulez-vous que le logiciel vous paramètre la position de la fenêtre de discussion ? Ceci permet d'optimiser et de placer correctement les fenêtres.",
|
||||
@@ -516,7 +524,6 @@ pfUI_translation["frFR"] = {
|
||||
["Name | Health Missing"] = "Nom | santé manquante",
|
||||
["Name (Linebreak) -Health Missing"] = nil,
|
||||
["Nameplate Border Size"] = "Taille de la bordure des barres de vie flottantes",
|
||||
["Nameplate Debuffs"] = nil,
|
||||
["Nameplates"] = "Barres de vie flottantes",
|
||||
["Nameplate Width"] = "Largeur des barres de vie flottantes",
|
||||
["Name (Short)"] = "Nom (Court)",
|
||||
@@ -584,7 +591,6 @@ pfUI_translation["frFR"] = {
|
||||
["Pixel"] = "Pixel",
|
||||
["Player"] = "Joueur",
|
||||
["Player Buff Bar"] = "Barre des Améliorations du Joueur",
|
||||
["Player Buffs"] = nil,
|
||||
["Player Castbar"] = "Barre d'incantation du Joueur",
|
||||
["Player Debuff Bar"] = "Barre des Affaiblissements du Joueur",
|
||||
["Player SP/Haste Display"] = nil,
|
||||
@@ -651,7 +657,6 @@ pfUI_translation["frFR"] = {
|
||||
["Resting"] = "Au Repos",
|
||||
["Reveal Unexplored Areas"] = "Révèle les zones non explorées",
|
||||
["Switch to current zone"] = "Aller à la zone actuelle",
|
||||
["Reverse Sweep On"] = nil,
|
||||
["Right"] = "Droit",
|
||||
["Right Actionbar"] = "Barre d'action droite",
|
||||
["Right Anchor"] = nil,
|
||||
@@ -733,7 +738,6 @@ pfUI_translation["frFR"] = {
|
||||
["Show Loot Icon"] = "Afficher l'icône du butin",
|
||||
["Show Macro Text"] = "Afficher le texte des macros",
|
||||
["Show Meters By Default"] = "Afficher les compteurs par défaut",
|
||||
["Show Numbers On"] = nil,
|
||||
["Show On Friendly Units"] = "Afficher sur les unités amicales",
|
||||
["Show On Hostile Units"] = "Afficher sur les unités hostiles",
|
||||
["Show Procs Indicators"] = "Afficher les indicateurs de Procs",
|
||||
@@ -751,7 +755,6 @@ pfUI_translation["frFR"] = {
|
||||
["Show Spell Icon"] = "Afficher l'icone des sorts",
|
||||
["Show Spell Name"] = nil,
|
||||
["Show Stacks"] = "Afficher les empilements",
|
||||
["Show Sweep On"] = nil,
|
||||
["Show Tenths Below 5 Seconds"] = nil,
|
||||
["Show Text"] = nil,
|
||||
["Show Timer"] = nil,
|
||||
@@ -819,7 +822,6 @@ pfUI_translation["frFR"] = {
|
||||
["Tiny (PixelPerfect)"] = "Minuscule (PixelParfait)",
|
||||
["Toggle as Tank"] = "Basculer en tant que tank",
|
||||
["Tooltip"] = "Infobulle",
|
||||
["Tooltip Auras"] = nil,
|
||||
["Tooltip Position"] = "Position de l'infobulle",
|
||||
["Tooltip Text Font"] = nil,
|
||||
["Tooltip Text Font Size"] = nil,
|
||||
@@ -831,13 +833,11 @@ pfUI_translation["frFR"] = {
|
||||
["Total Gold"] = "Or Total",
|
||||
["Totem Direction"] = "Direction des totems",
|
||||
["Totem Icons"] = "Icones des totems",
|
||||
["Totems"] = nil,
|
||||
["Tracked Reputation"] = nil,
|
||||
["Tracking Icon Size"] = "Taille de l'icône de suivi",
|
||||
["Trigger Actions On Key Down"] = "Déclencher des actions sur la touche enfoncée",
|
||||
["UI-Scale"] = "Echelle de l'interface",
|
||||
["Unbuffed"] = "Sans Améliorations",
|
||||
["Unit Frame Auras"] = nil,
|
||||
["Unit Frame Border Size"] = "Taille de la bordure des cadres d'unité",
|
||||
["Unit Frame Layout"] = "Position des cadres d'unité",
|
||||
["Unit Frames"] = "Cadres d'unités",
|
||||
|
||||
Vendored
+10
-10
@@ -8,7 +8,6 @@ pfUI_translation["koKR"] = {
|
||||
["Actionbar"] = "액션바",
|
||||
["Action Bar"] = nil,
|
||||
["Action Bar Border Size"] = "액션바 테두리 크기",
|
||||
["Action Bars"] = nil,
|
||||
["Active Addons"] = "애드온 활성화",
|
||||
["Add button to the frame"] = nil,
|
||||
["Added button"] = nil,
|
||||
@@ -77,11 +76,11 @@ pfUI_translation["koKR"] = {
|
||||
["Bottom"] = "아래",
|
||||
["Bottom Left"] = nil,
|
||||
["Bottom Right"] = nil,
|
||||
["Buff And Debuff Timers"] = nil,
|
||||
["Buffbar Height"] = nil,
|
||||
["Buffbar Width"] = nil,
|
||||
["Buff/Debuff Icons"] = nil,
|
||||
["Buff/Debuff Indicators"] = nil,
|
||||
["Buff Indicators"] = nil,
|
||||
["Buff Limit"] = "버프 한도",
|
||||
["Buff Position"] = "버프 위치",
|
||||
["Buffs"] = nil,
|
||||
@@ -106,6 +105,15 @@ pfUI_translation["koKR"] = {
|
||||
["Center Text"] = "가운데 텍스트",
|
||||
["Center Text X Offset"] = nil,
|
||||
["Center Text Y Offset"] = nil,
|
||||
["Cooldown Timers"] = nil,
|
||||
["Debuff Timers"] = nil,
|
||||
["Duration Timers"] = nil,
|
||||
["Indicator Timers"] = nil,
|
||||
["Numbers"] = nil,
|
||||
["Numbers And Sweep"] = nil,
|
||||
["Sweep"] = nil,
|
||||
["Timers"] = nil,
|
||||
["Unit Buff Timers"] = nil,
|
||||
["|cff33ffccBlizzard: \"Interface Options\"|r\n\nDo you want me to set up the recommended Blizzard UI settings? This will enable settings that can be found in the Interface section of your client. Options like Buff Durations, Instant Quest Text, Auto Selfcast and others will be set."] = "|cff33ffcc블리자드: \"인터페이스 옵션\"|r\n\n내가 권장하는 블리자드 UI 설정을 설치하길 원하십니까? 이렇게하면 클라이언트의 인터페이스 섹션에서 찾을 수 있는 설정이 활성화됩니다. 버프 기간, 인스턴트 퀘스트 텍스트, 자동 셀프 캐스트 및 기타 옵션이 설정됩니다.",
|
||||
["|cff33ffccChat: \"Channels\"|r\n\nDo you want me to setup the chat channels of your chatframes? This would set important or personal messages to the left chat and world channels and lootinformation to the right chat."] = "|cff33ffcc채팅: \"채널\"|r\n\n채팅 프레임의 채팅 채널을 설정하길 원하십니까? 그렇다면 왼쪽하단 채팅창에 중요하거나 개인적인 메시지가 표시됩니다. 그리고 오른쪽하단 채팅창에는 월드채널,룻팅정보가 표시됩니다.",
|
||||
["|cff33ffccChat: \"Layout\"|r\n\nDo you want me to adjust the layout of your chatframes? This would make sure, that every window is placed on its dedicated position."] = "|cff33ffcc채팅: \"레이아웃\"|r\n\n채팅 프레임의 레이아웃을 조정하길 원하십니까? 이렇게하면 모든 창을 전용 위치에 배치 할 수 있습니다.",
|
||||
@@ -516,7 +524,6 @@ pfUI_translation["koKR"] = {
|
||||
["Name | Health Missing"] = nil,
|
||||
["Name (Linebreak) -Health Missing"] = nil,
|
||||
["Nameplate Border Size"] = nil,
|
||||
["Nameplate Debuffs"] = nil,
|
||||
["Nameplates"] = "상바",
|
||||
["Nameplate Width"] = "상바 넓이",
|
||||
["Name (Short)"] = nil,
|
||||
@@ -584,7 +591,6 @@ pfUI_translation["koKR"] = {
|
||||
["Pixel"] = nil,
|
||||
["Player"] = "플레이어",
|
||||
["Player Buff Bar"] = nil,
|
||||
["Player Buffs"] = nil,
|
||||
["Player Castbar"] = nil,
|
||||
["Player Debuff Bar"] = nil,
|
||||
["Player SP/Haste Display"] = nil,
|
||||
@@ -651,7 +657,6 @@ pfUI_translation["koKR"] = {
|
||||
["Resting"] = "휴식",
|
||||
["Reveal Unexplored Areas"] = nil,
|
||||
["Switch to current zone"] = nil,
|
||||
["Reverse Sweep On"] = nil,
|
||||
["Right"] = "오른쪽",
|
||||
["Right Actionbar"] = nil,
|
||||
["Right Anchor"] = nil,
|
||||
@@ -733,7 +738,6 @@ pfUI_translation["koKR"] = {
|
||||
["Show Loot Icon"] = nil,
|
||||
["Show Macro Text"] = "매크로 텍스트 표시",
|
||||
["Show Meters By Default"] = nil,
|
||||
["Show Numbers On"] = nil,
|
||||
["Show On Friendly Units"] = nil,
|
||||
["Show On Hostile Units"] = nil,
|
||||
["Show Procs Indicators"] = nil,
|
||||
@@ -751,7 +755,6 @@ pfUI_translation["koKR"] = {
|
||||
["Show Spell Icon"] = nil,
|
||||
["Show Spell Name"] = nil,
|
||||
["Show Stacks"] = nil,
|
||||
["Show Sweep On"] = nil,
|
||||
["Show Tenths Below 5 Seconds"] = nil,
|
||||
["Show Text"] = nil,
|
||||
["Show Timer"] = nil,
|
||||
@@ -819,7 +822,6 @@ pfUI_translation["koKR"] = {
|
||||
["Tiny (PixelPerfect)"] = nil,
|
||||
["Toggle as Tank"] = nil,
|
||||
["Tooltip"] = "툴팁",
|
||||
["Tooltip Auras"] = nil,
|
||||
["Tooltip Position"] = "툴팁위치",
|
||||
["Tooltip Text Font"] = nil,
|
||||
["Tooltip Text Font Size"] = nil,
|
||||
@@ -831,13 +833,11 @@ pfUI_translation["koKR"] = {
|
||||
["Total Gold"] = "총 금",
|
||||
["Totem Direction"] = nil,
|
||||
["Totem Icons"] = nil,
|
||||
["Totems"] = nil,
|
||||
["Tracked Reputation"] = nil,
|
||||
["Tracking Icon Size"] = nil,
|
||||
["Trigger Actions On Key Down"] = nil,
|
||||
["UI-Scale"] = "UI-크기",
|
||||
["Unbuffed"] = nil,
|
||||
["Unit Frame Auras"] = nil,
|
||||
["Unit Frame Border Size"] = "유닛프레임 테두리 크기",
|
||||
["Unit Frame Layout"] = "유닛프레임 레이아웃",
|
||||
["Unit Frames"] = "유닛프레임",
|
||||
|
||||
Vendored
+10
-10
@@ -8,7 +8,6 @@ pfUI_translation["ruRU"] = {
|
||||
["Actionbar"] = "Панель действий",
|
||||
["Action Bar"] = "Панель действий",
|
||||
["Action Bar Border Size"] = "Размер границы панели действий",
|
||||
["Action Bars"] = nil,
|
||||
["Active Addons"] = "Активные аддоны",
|
||||
["Add button to the frame"] = "Добавить кнопку в окно",
|
||||
["Added button"] = "Добавлена кнопка",
|
||||
@@ -77,11 +76,11 @@ pfUI_translation["ruRU"] = {
|
||||
["Bottom"] = "Снизу",
|
||||
["Bottom Left"] = "Снизу слева",
|
||||
["Bottom Right"] = "Снизу справа",
|
||||
["Buff And Debuff Timers"] = nil,
|
||||
["Buffbar Height"] = "Высота панели баффов",
|
||||
["Buffbar Width"] = "Ширина панели баффов",
|
||||
["Buff/Debuff Icons"] = "Иконки баффов/дебаффов",
|
||||
["Buff/Debuff Indicators"] = "Индикаторы баффов/дебаффов",
|
||||
["Buff Indicators"] = nil,
|
||||
["Buff Limit"] = "Предел баффов",
|
||||
["Buff Position"] = "Расположение баффов",
|
||||
["Buffs"] = "Баффы",
|
||||
@@ -106,6 +105,15 @@ pfUI_translation["ruRU"] = {
|
||||
["Center Text"] = "Текст по центру",
|
||||
["Center Text X Offset"] = nil,
|
||||
["Center Text Y Offset"] = nil,
|
||||
["Cooldown Timers"] = nil,
|
||||
["Debuff Timers"] = nil,
|
||||
["Duration Timers"] = nil,
|
||||
["Indicator Timers"] = nil,
|
||||
["Numbers"] = nil,
|
||||
["Numbers And Sweep"] = nil,
|
||||
["Sweep"] = nil,
|
||||
["Timers"] = nil,
|
||||
["Unit Buff Timers"] = nil,
|
||||
["|cff33ffccBlizzard: \"Interface Options\"|r\n\nDo you want me to set up the recommended Blizzard UI settings? This will enable settings that can be found in the Interface section of your client. Options like Buff Durations, Instant Quest Text, Auto Selfcast and others will be set."] = "|cff33ffccBlizzard: \"Настройки интерфейса\"|r\n\nВы хотите, чтобы я установил рекомендуемые настройки пользовательского интерфейса Blizzard? Это позволит настроить параметры, которые можно найти в разделе \"Интерфейс\" вашего клиента. Будут установлены такие параметры, как Срок действия эффектов, Мгновенное отображение текста, Автовыбор себя и другие.",
|
||||
["|cff33ffccChat: \"Channels\"|r\n\nDo you want me to setup the chat channels of your chatframes? This would set important or personal messages to the left chat and world channels and lootinformation to the right chat."] = "|cff33ffccЧат: \"Каналы\"|r\n\nВы хотите, чтобы я настраивал каналы для вашего чата? Это установило бы важные или личные сообщения в левый чат, а мировые каналы и информацию о добыче в правый чат.",
|
||||
["|cff33ffccChat: \"Layout\"|r\n\nDo you want me to adjust the layout of your chatframes? This would make sure, that every window is placed on its dedicated position."] = "|cff33ffccЧат: \"Макет\"|r\n\nВы хотите, чтобы я скорректировал макет вашего чата? Это обеспечило бы уверенность, что каждое окно будет помещено в его выделенное положение.",
|
||||
@@ -516,7 +524,6 @@ pfUI_translation["ruRU"] = {
|
||||
["Name | Health Missing"] = "Имя | Отсутствующее здоровье",
|
||||
["Name (Linebreak) -Health Missing"] = "Имя (разрыв линии) -Отсутствует здоровье",
|
||||
["Nameplate Border Size"] = "Размер границы индикатора здоровья",
|
||||
["Nameplate Debuffs"] = nil,
|
||||
["Nameplates"] = "Индикаторы здоровья",
|
||||
["Nameplate Width"] = "Ширина индикатора здоровья",
|
||||
["Name (Short)"] = "Короткое имя",
|
||||
@@ -584,7 +591,6 @@ pfUI_translation["ruRU"] = {
|
||||
["Pixel"] = "пиксель",
|
||||
["Player"] = "Игрок",
|
||||
["Player Buff Bar"] = "Панель баффов игрока",
|
||||
["Player Buffs"] = nil,
|
||||
["Player Castbar"] = "Панель применения игрока",
|
||||
["Player Debuff Bar"] = "Панель дебаффов игрока",
|
||||
["Player SP/Haste Display"] = nil,
|
||||
@@ -651,7 +657,6 @@ pfUI_translation["ruRU"] = {
|
||||
["Resting"] = "Отдыхающий",
|
||||
["Reveal Unexplored Areas"] = "Показывать неисследованные области",
|
||||
["Switch to current zone"] = "Перейти к текущей зоне",
|
||||
["Reverse Sweep On"] = nil,
|
||||
["Right"] = "Справа",
|
||||
["Right Actionbar"] = "Правая",
|
||||
["Right Anchor"] = nil,
|
||||
@@ -733,7 +738,6 @@ pfUI_translation["ruRU"] = {
|
||||
["Show Loot Icon"] = "Показать иконку добычи",
|
||||
["Show Macro Text"] = "Показать текст макросов",
|
||||
["Show Meters By Default"] = "Показать счетчики по умолчанию",
|
||||
["Show Numbers On"] = nil,
|
||||
["Show On Friendly Units"] = "Показать на дружественных юнитах",
|
||||
["Show On Hostile Units"] = "Показать на вражеских юнитах",
|
||||
["Show Procs Indicators"] = "Показать проки (Procs)",
|
||||
@@ -751,7 +755,6 @@ pfUI_translation["ruRU"] = {
|
||||
["Show Spell Icon"] = "Показать иконку заклинания",
|
||||
["Show Spell Name"] = "Показать название заклинания",
|
||||
["Show Stacks"] = "Показать стаки",
|
||||
["Show Sweep On"] = nil,
|
||||
["Show Tenths Below 5 Seconds"] = nil,
|
||||
["Show Text"] = nil,
|
||||
["Show Timer"] = "Показать таймер",
|
||||
@@ -819,7 +822,6 @@ pfUI_translation["ruRU"] = {
|
||||
["Tiny (PixelPerfect)"] = "Крошечный (идеальный пиксель)",
|
||||
["Toggle as Tank"] = "Переключить как танк",
|
||||
["Tooltip"] = "Подсказка",
|
||||
["Tooltip Auras"] = nil,
|
||||
["Tooltip Position"] = "Расположение подсказки",
|
||||
["Tooltip Text Font"] = nil,
|
||||
["Tooltip Text Font Size"] = nil,
|
||||
@@ -831,13 +833,11 @@ pfUI_translation["ruRU"] = {
|
||||
["Total Gold"] = "Всего золота",
|
||||
["Totem Direction"] = "Направление тотемов",
|
||||
["Totem Icons"] = "Иконки тотемов",
|
||||
["Totems"] = nil,
|
||||
["Tracked Reputation"] = "Отслеживаемая репутация",
|
||||
["Tracking Icon Size"] = "Размер иконки отслеживания",
|
||||
["Trigger Actions On Key Down"] = "Активация действий при нажатии клавиши (а не ее отпускании)",
|
||||
["UI-Scale"] = "Масштаб пользовательского интерфейса",
|
||||
["Unbuffed"] = "Без баффа",
|
||||
["Unit Frame Auras"] = nil,
|
||||
["Unit Frame Border Size"] = "Размер границы окна юнита",
|
||||
["Unit Frame Layout"] = "Макет окна юнита",
|
||||
["Unit Frames"] = "Окна юнита",
|
||||
|
||||
Vendored
+10
-10
@@ -8,7 +8,6 @@ pfUI_translation["zhCN"] = {
|
||||
["Actionbar"] = "动作条",
|
||||
["Action Bar"] = "动作条",
|
||||
["Action Bar Border Size"] = "动作条边框大小",
|
||||
["Action Bars"] = nil,
|
||||
["Active Addons"] = "激活的插件",
|
||||
["Add button to the frame"] = "添加按钮到框架",
|
||||
["Added button"] = "已添加按钮",
|
||||
@@ -77,11 +76,11 @@ pfUI_translation["zhCN"] = {
|
||||
["Bottom"] = "底部",
|
||||
["Bottom Left"] = "左下方",
|
||||
["Bottom Right"] = "右下方",
|
||||
["Buff And Debuff Timers"] = nil,
|
||||
["Buffbar Height"] = "Buff条高度",
|
||||
["Buffbar Width"] = "Buff条宽度",
|
||||
["Buff/Debuff Icons"] = "Buff/Debuff图标",
|
||||
["Buff/Debuff Indicators"] = "Buff/Debuff指示器",
|
||||
["Buff Indicators"] = nil,
|
||||
["Buff Limit"] = "Buff总数量",
|
||||
["Buff Position"] = "Buff显示的位置",
|
||||
["Buffs"] = "Buff(增益)",
|
||||
@@ -106,6 +105,15 @@ pfUI_translation["zhCN"] = {
|
||||
["Center Text"] = "中间文字",
|
||||
["Center Text X Offset"] = "中心文本水平偏移量",
|
||||
["Center Text Y Offset"] = "中心文本垂直偏移量",
|
||||
["Cooldown Timers"] = nil,
|
||||
["Debuff Timers"] = nil,
|
||||
["Duration Timers"] = nil,
|
||||
["Indicator Timers"] = nil,
|
||||
["Numbers"] = nil,
|
||||
["Numbers And Sweep"] = nil,
|
||||
["Sweep"] = nil,
|
||||
["Timers"] = nil,
|
||||
["Unit Buff Timers"] = nil,
|
||||
["|cff33ffccBlizzard: \"Interface Options\"|r\n\nDo you want me to set up the recommended Blizzard UI settings? This will enable settings that can be found in the Interface section of your client. Options like Buff Durations, Instant Quest Text, Auto Selfcast and others will be set."] = "|cff33ffcc暴雪: \"界面选项\"|r\n\n你要我安装暴雪UI设置建议? 启用此设置可以在客户端的接口部分找到。 像buff持续时间选项,即时任务文本,自动施法和其他功能将被设置。",
|
||||
["|cff33ffccChat: \"Channels\"|r\n\nDo you want me to setup the chat channels of your chatframes? This would set important or personal messages to the left chat and world channels and lootinformation to the right chat."] = "|cff33ffcc聊天框架: \"聊天频道\"|r\n\n你想建立聊天框架中新的聊天频道? 这将设置重要或个人信息到左侧聊天。 和世界频道和信息到正确的聊天窗口。",
|
||||
["|cff33ffccChat: \"Layout\"|r\n\nDo you want me to adjust the layout of your chatframes? This would make sure, that every window is placed on its dedicated position."] = "|cff33ffcc聊天框架: \"聊天窗口布局\"|r\n\n你要我调整聊天框架的布局吗? 这将确保每个窗口都放在其专用位置上。",
|
||||
@@ -516,7 +524,6 @@ pfUI_translation["zhCN"] = {
|
||||
["Name | Health Missing"] = "名字 | 失去的生命值",
|
||||
["Name (Linebreak) -Health Missing"] = "名字 (换行符) -失去的生命值",
|
||||
["Nameplate Border Size"] = "姓名板边框尺寸",
|
||||
["Nameplate Debuffs"] = nil,
|
||||
["Nameplates"] = "姓名板",
|
||||
["Nameplate Width"] = "姓名板宽度",
|
||||
["Name (Short)"] = "名字 (短)",
|
||||
@@ -584,7 +591,6 @@ pfUI_translation["zhCN"] = {
|
||||
["Pixel"] = "像素",
|
||||
["Player"] = "玩家",
|
||||
["Player Buff Bar"] = "玩家Buffs条",
|
||||
["Player Buffs"] = nil,
|
||||
["Player Castbar"] = "玩家施法条",
|
||||
["Player Debuff Bar"] = "玩家Debuffs条",
|
||||
["Player SP/Haste Display"] = nil,
|
||||
@@ -651,7 +657,6 @@ pfUI_translation["zhCN"] = {
|
||||
["Resting"] = "休息中",
|
||||
["Reveal Unexplored Areas"] = "展示未勘探的地区",
|
||||
["Switch to current zone"] = nil,
|
||||
["Reverse Sweep On"] = nil,
|
||||
["Right"] = "右边",
|
||||
["Right Actionbar"] = "右侧动作条",
|
||||
["Right Anchor"] = "右锚点",
|
||||
@@ -734,7 +739,6 @@ pfUI_translation["zhCN"] = {
|
||||
["Show Loot Icon"] = "显示拾取权图标",
|
||||
["Show Macro Text"] = "显示宏的名字",
|
||||
["Show Meters By Default"] = "由默认显示其他接口表",
|
||||
["Show Numbers On"] = nil,
|
||||
["Show On Friendly Units"] = "显示友好单位姓名板",
|
||||
["Show On Hostile Units"] = "显示敌对单位姓名板",
|
||||
["Show Procs Indicators"] = "显示触发效果计时器",
|
||||
@@ -752,7 +756,6 @@ pfUI_translation["zhCN"] = {
|
||||
["Show Spell Icon"] = "显示技能图标",
|
||||
["Show Spell Name"] = "显示技能名称",
|
||||
["Show Stacks"] = "显示堆叠",
|
||||
["Show Sweep On"] = nil,
|
||||
["Show Tenths Below 5 Seconds"] = nil,
|
||||
["Show Text"] = "显示文本",
|
||||
["Show Timer"] = "显示计时器",
|
||||
@@ -820,7 +823,6 @@ pfUI_translation["zhCN"] = {
|
||||
["Tiny (PixelPerfect)"] = "极小(像素完美)",
|
||||
["Toggle as Tank"] = "切换成为坦克",
|
||||
["Tooltip"] = "信息提示框",
|
||||
["Tooltip Auras"] = nil,
|
||||
["Tooltip Position"] = "信息提示框位置",
|
||||
["Tooltip Text Font"] = "鼠标提示框字体",
|
||||
["Tooltip Text Font Size"] ="鼠标提示框字体大小",
|
||||
@@ -832,13 +834,11 @@ pfUI_translation["zhCN"] = {
|
||||
["Total Gold"] = "总黄金",
|
||||
["Totem Direction"] = "图腾方向",
|
||||
["Totem Icons"] = "图腾图标",
|
||||
["Totems"] = nil,
|
||||
["Tracked Reputation"] = "被追踪的声望",
|
||||
["Tracking Icon Size"] = "追踪图标大小",
|
||||
["Trigger Actions On Key Down"] = "按下即施法",
|
||||
["UI-Scale"] = "UI缩放比例",
|
||||
["Unbuffed"] = "该Buff缺失者",
|
||||
["Unit Frame Auras"] = nil,
|
||||
["Unit Frame Border Size"] = "头像边框大小",
|
||||
["Unit Frame Layout"] = "头像框架样式",
|
||||
["Unit Frames"] = "头像框架",
|
||||
|
||||
Vendored
+10
-10
@@ -8,7 +8,6 @@ pfUI_translation["zhTW"] = {
|
||||
["Actionbar"] = "動作條",
|
||||
["Action Bar"] = nil,
|
||||
["Action Bar Border Size"] = "動作條邊框大小",
|
||||
["Action Bars"] = nil,
|
||||
["Active Addons"] = "啟動的外掛程式",
|
||||
["Add button to the frame"] = nil,
|
||||
["Added button"] = nil,
|
||||
@@ -77,11 +76,11 @@ pfUI_translation["zhTW"] = {
|
||||
["Bottom"] = "底部",
|
||||
["Bottom Left"] = "左下方",
|
||||
["Bottom Right"] = "右下方",
|
||||
["Buff And Debuff Timers"] = nil,
|
||||
["Buffbar Height"] = "Buff高度",
|
||||
["Buffbar Width"] = "Buff寬度",
|
||||
["Buff/Debuff Icons"] = nil,
|
||||
["Buff/Debuff Indicators"] = nil,
|
||||
["Buff Indicators"] = nil,
|
||||
["Buff Limit"] = "Buff總數量",
|
||||
["Buff Position"] = "Buff顯示的位置",
|
||||
["Buffs"] = "Buff(增益)",
|
||||
@@ -106,6 +105,15 @@ pfUI_translation["zhTW"] = {
|
||||
["Center Text"] = "中間文字",
|
||||
["Center Text X Offset"] = nil,
|
||||
["Center Text Y Offset"] = nil,
|
||||
["Cooldown Timers"] = nil,
|
||||
["Debuff Timers"] = nil,
|
||||
["Duration Timers"] = nil,
|
||||
["Indicator Timers"] = nil,
|
||||
["Numbers"] = nil,
|
||||
["Numbers And Sweep"] = nil,
|
||||
["Sweep"] = nil,
|
||||
["Timers"] = nil,
|
||||
["Unit Buff Timers"] = nil,
|
||||
["|cff33ffccBlizzard: \"Interface Options\"|r\n\nDo you want me to set up the recommended Blizzard UI settings? This will enable settings that can be found in the Interface section of your client. Options like Buff Durations, Instant Quest Text, Auto Selfcast and others will be set."] = "|cff33ffcc暴雪: \"介面選項\"|r\n\n你要我安裝暴雪UI設置建議? 啟用此設置可以在用戶端的介面部分找到。 像buff持續時間選項,即時任務文本,自動施法和其他功能將被設置。",
|
||||
["|cff33ffccChat: \"Channels\"|r\n\nDo you want me to setup the chat channels of your chatframes? This would set important or personal messages to the left chat and world channels and lootinformation to the right chat."] = "|cff33ffcc聊天框架: \"聊天頻道\"|r\n\n你想建立聊天框架中新的聊天頻道? 這將設置重要或個人資訊到左側聊天。 和世界頻道和資訊到正確的聊天視窗。",
|
||||
["|cff33ffccChat: \"Layout\"|r\n\nDo you want me to adjust the layout of your chatframes? This would make sure, that every window is placed on its dedicated position."] = "|cff33ffcc聊天框架: \"聊天視窗佈局\"|r\n\n你要我調整聊天框架的佈局嗎? 這將確保每個視窗都放在其專用位置上。",
|
||||
@@ -516,7 +524,6 @@ pfUI_translation["zhTW"] = {
|
||||
["Name | Health Missing"] = nil,
|
||||
["Name (Linebreak) -Health Missing"] = nil,
|
||||
["Nameplate Border Size"] = nil,
|
||||
["Nameplate Debuffs"] = nil,
|
||||
["Nameplates"] = "姓名板",
|
||||
["Nameplate Width"] = "姓名板高度",
|
||||
["Name (Short)"] = "名字 (短)",
|
||||
@@ -584,7 +591,6 @@ pfUI_translation["zhTW"] = {
|
||||
["Pixel"] = nil,
|
||||
["Player"] = "玩家",
|
||||
["Player Buff Bar"] = nil,
|
||||
["Player Buffs"] = nil,
|
||||
["Player Castbar"] = nil,
|
||||
["Player Debuff Bar"] = nil,
|
||||
["Player SP/Haste Display"] = nil,
|
||||
@@ -651,7 +657,6 @@ pfUI_translation["zhTW"] = {
|
||||
["Resting"] = "休息中",
|
||||
["Reveal Unexplored Areas"] = "展示未勘探的地區",
|
||||
["Switch to current zone"] = nil,
|
||||
["Reverse Sweep On"] = nil,
|
||||
["Right"] = "右邊",
|
||||
["Right Actionbar"] = nil,
|
||||
["Right Anchor"] = nil,
|
||||
@@ -733,7 +738,6 @@ pfUI_translation["zhTW"] = {
|
||||
["Show Loot Icon"] = nil,
|
||||
["Show Macro Text"] = "顯示巨集的名字",
|
||||
["Show Meters By Default"] = "由默認顯示其他介面表",
|
||||
["Show Numbers On"] = nil,
|
||||
["Show On Friendly Units"] = nil,
|
||||
["Show On Hostile Units"] = nil,
|
||||
["Show Procs Indicators"] = nil,
|
||||
@@ -751,7 +755,6 @@ pfUI_translation["zhTW"] = {
|
||||
["Show Spell Icon"] = nil,
|
||||
["Show Spell Name"] = nil,
|
||||
["Show Stacks"] = nil,
|
||||
["Show Sweep On"] = nil,
|
||||
["Show Tenths Below 5 Seconds"] = nil,
|
||||
["Show Text"] = nil,
|
||||
["Show Timer"] = nil,
|
||||
@@ -819,7 +822,6 @@ pfUI_translation["zhTW"] = {
|
||||
["Tiny (PixelPerfect)"] = "極小(像素完美)",
|
||||
["Toggle as Tank"] = "切換成為坦克",
|
||||
["Tooltip"] = "滑鼠提示框",
|
||||
["Tooltip Auras"] = nil,
|
||||
["Tooltip Position"] = "滑鼠提示框位置",
|
||||
["Tooltip Text Font"] = nil,
|
||||
["Tooltip Text Font Size"] = nil,
|
||||
@@ -831,13 +833,11 @@ pfUI_translation["zhTW"] = {
|
||||
["Total Gold"] = "總金量",
|
||||
["Totem Direction"] = nil,
|
||||
["Totem Icons"] = nil,
|
||||
["Totems"] = nil,
|
||||
["Tracked Reputation"] = nil,
|
||||
["Tracking Icon Size"] = "追蹤圖示大小",
|
||||
["Trigger Actions On Key Down"] = nil,
|
||||
["UI-Scale"] = "UI縮放比例",
|
||||
["Unbuffed"] = "該Buff缺失者",
|
||||
["Unit Frame Auras"] = nil,
|
||||
["Unit Frame Border Size"] = "頭像邊框大小",
|
||||
["Unit Frame Layout"] = "頭像框架樣式",
|
||||
["Unit Frames"] = "頭像框架",
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
@@ -54,7 +54,6 @@
|
||||
<Include file="..\modules\gm.lua"/>
|
||||
<Include file="..\modules\mirrortimers.lua"/>
|
||||
<Include file="..\modules\feigndeath.lua"/>
|
||||
<Include file="..\modules\pixelperfect.lua"/>
|
||||
<Include file="..\modules\hdgraphic.lua"/>
|
||||
<Include file="..\modules\share.lua"/>
|
||||
<Include file="..\modules\tracking.lua"/>
|
||||
|
||||
+29
-15
@@ -36,6 +36,18 @@ local sentTargets = {} -- [castGUID] = target name of an own cast, from UNIT_
|
||||
local resOffers = {} -- [guid] = expiry of a landed resurrection the target has yet to accept
|
||||
local RES_OFFER_TIMEOUT = 60 -- the target's resurrect popup declines itself after 60s
|
||||
|
||||
-- Tell the listeners of "libpredict:heals" that the heals on `target` (a
|
||||
-- name) changed, and again at `expiry`, when a heal that is never stopped
|
||||
-- drops out of UnitGetIncomingHeals.
|
||||
local function HealsChanged(target, expiry)
|
||||
pfUI.events:TriggerEvent("libpredict:heals", target)
|
||||
if expiry then
|
||||
C_Timer.After(expiry - GetTime(), function()
|
||||
pfUI.events:TriggerEvent("libpredict:heals", target)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
-- Localized spell names resolved once from canonical rank-1 spellIDs.
|
||||
-- Every rank shares the same name, so per-rank comparisons elsewhere can
|
||||
-- be done against these constants without per-locale or per-rank tables.
|
||||
@@ -309,7 +321,7 @@ end
|
||||
local function RefreshResFrames(guid)
|
||||
for _, frame in pairs(pfUI.uf.frames) do
|
||||
if frame.unitstr and UnitGUID(frame.unitstr) == guid then
|
||||
frame.update_indicators = true
|
||||
pfUI.uf:QueueUpdate(frame, "indicators")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -439,7 +451,7 @@ function libpredict:ParseChatMessage(sender, msg)
|
||||
end
|
||||
elseif msgtype == "Hot" then
|
||||
-- Duplicate check: ignore same sender+target+spell within DUPLICATE_WINDOW
|
||||
local now = pfUI.uf.now or GetTime()
|
||||
local now = GetTime()
|
||||
local key = sender .. target .. heal
|
||||
if recentHots[key] and (now - recentHots[key]) < DUPLICATE_WINDOW then
|
||||
if libpredict.debug then
|
||||
@@ -484,11 +496,11 @@ function libpredict:Heal(sender, target, amount, duration, senderGuid)
|
||||
return
|
||||
end
|
||||
|
||||
local now = pfUI.uf.now or GetTime()
|
||||
local timeout = duration/1000 + now
|
||||
local timeout = duration/1000 + GetTime()
|
||||
heals[target] = heals[target] or {}
|
||||
heals[target][sender] = { amount, timeout }
|
||||
if senderGuid then healGuidToName[senderGuid] = sender end
|
||||
HealsChanged(target, timeout)
|
||||
end
|
||||
|
||||
-- Debug flag
|
||||
@@ -512,7 +524,7 @@ function libpredict:Hot(sender, target, spell, duration, startTime, source, rank
|
||||
local existingRank = tonumber(existing.rank) or 0
|
||||
local newRank = tonumber(rank) or 0
|
||||
|
||||
local now = pfUI.uf.now or GetTime()
|
||||
local now = GetTime()
|
||||
local existingTimeleft = (existing.start + existing.duration) - now
|
||||
|
||||
-- If existing HoT is still active and has higher rank, don't overwrite
|
||||
@@ -525,7 +537,7 @@ function libpredict:Hot(sender, target, spell, duration, startTime, source, rank
|
||||
end
|
||||
end
|
||||
|
||||
local now = pfUI.uf.now or GetTime()
|
||||
local now = GetTime()
|
||||
hots[target][spell].duration = duration
|
||||
hots[target][spell].start = startTime or now
|
||||
hots[target][spell].rank = rank -- Store rank for protection
|
||||
@@ -544,7 +556,7 @@ function libpredict:Hot(sender, target, spell, duration, startTime, source, rank
|
||||
if pfUI and pfUI.uf and pfUI.uf.frames then
|
||||
for _, frame in pairs(pfUI.uf.frames) do
|
||||
if frame.namecache == target then
|
||||
frame.update_aura = true
|
||||
pfUI.uf:QueueUpdate(frame, "aura")
|
||||
if libpredict.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(" |cff00ff00-> Frame update triggered for " .. (frame:GetName() or "?") .. "|r")
|
||||
end
|
||||
@@ -558,6 +570,7 @@ function libpredict:HealStop(sender)
|
||||
for tsender in pairs(heals[ttarget]) do
|
||||
if sender == tsender then
|
||||
heals[ttarget][tsender] = nil
|
||||
HealsChanged(ttarget)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -573,6 +586,7 @@ function libpredict:HealDelay(sender, delay)
|
||||
for tsender, amount in pairs(heals[target]) do
|
||||
if sender == tsender then
|
||||
amount[2] = amount[2] + delay
|
||||
HealsChanged(target, amount[2])
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -588,7 +602,7 @@ function libpredict:UnitGetIncomingHeals(unit)
|
||||
if not heals[name] then
|
||||
return sumheal
|
||||
else
|
||||
local now = pfUI.uf.now or GetTime()
|
||||
local now = GetTime()
|
||||
for sender, amount in pairs(heals[name]) do
|
||||
if amount[2] <= now then
|
||||
heals[name][sender] = nil
|
||||
@@ -720,7 +734,7 @@ hooksecurefunc("CastSpell", function(id, bookType)
|
||||
|
||||
if effect == REJUVENATION then
|
||||
local target = spell_queue[3]
|
||||
local now = pfUI.uf.now or GetTime()
|
||||
local now = GetTime()
|
||||
local key = "Reju" .. target
|
||||
|
||||
-- Cooldown-Check
|
||||
@@ -737,7 +751,7 @@ hooksecurefunc("CastSpell", function(id, bookType)
|
||||
libpredict.sender:SendHealCommMsg("Reju/"..target.."/"..rejuvDuration.."/"..rankStr.."/")
|
||||
elseif effect == RENEW then
|
||||
local target = spell_queue[3]
|
||||
local now = pfUI.uf.now or GetTime()
|
||||
local now = GetTime()
|
||||
local key = "Renew" .. target
|
||||
|
||||
-- Cooldown-Check
|
||||
@@ -783,7 +797,7 @@ hooksecurefunc("CastSpellByName", function(effect, target)
|
||||
|
||||
if effect == REJUVENATION then
|
||||
local hotTarget = target or default
|
||||
local now = pfUI.uf.now or GetTime()
|
||||
local now = GetTime()
|
||||
local key = "Reju" .. hotTarget
|
||||
|
||||
-- Cooldown-Check
|
||||
@@ -800,7 +814,7 @@ hooksecurefunc("CastSpellByName", function(effect, target)
|
||||
libpredict.sender:SendHealCommMsg("Reju/"..hotTarget.."/"..rejuvDuration.."/"..rankStr.."/")
|
||||
elseif effect == RENEW then
|
||||
local hotTarget = target or default
|
||||
local now = pfUI.uf.now or GetTime()
|
||||
local now = GetTime()
|
||||
local key = "Renew" .. hotTarget
|
||||
|
||||
-- Cooldown-Check
|
||||
@@ -843,7 +857,7 @@ hooksecurefunc("UseAction", function(slot, target, selfcast)
|
||||
|
||||
if effect == REJUVENATION then
|
||||
local hotTarget = spell_queue[3]
|
||||
local now = pfUI.uf.now or GetTime()
|
||||
local now = GetTime()
|
||||
local key = "Reju" .. hotTarget
|
||||
|
||||
-- Cooldown-Check
|
||||
@@ -860,7 +874,7 @@ hooksecurefunc("UseAction", function(slot, target, selfcast)
|
||||
libpredict.sender:SendHealCommMsg("Reju/"..hotTarget.."/"..rejuvDuration.."/"..rankStr.."/")
|
||||
elseif effect == RENEW then
|
||||
local hotTarget = spell_queue[3]
|
||||
local now = pfUI.uf.now or GetTime()
|
||||
local now = GetTime()
|
||||
local key = "Renew" .. hotTarget
|
||||
|
||||
-- Cooldown-Check
|
||||
@@ -1083,7 +1097,7 @@ function libpredict:GetHotDuration(unit, spell)
|
||||
|
||||
-- FALLBACK: the HealComm/cast-fed table, for HoTs C_UnitAuras has no timer for
|
||||
local start, duration, timeleft
|
||||
local now = pfUI.uf.now or GetTime()
|
||||
local now = GetTime()
|
||||
|
||||
local unitName = UnitName(unit)
|
||||
local unitdata = hots[unitName]
|
||||
|
||||
+1
-11
@@ -31,10 +31,8 @@ libthrottle.presetNames = {
|
||||
|
||||
-- Default throttle categories
|
||||
libthrottle.defaults = {
|
||||
nameplates_castbar = "custom",
|
||||
tooltip_cursor = "fastest",
|
||||
chat_tab = "custom",
|
||||
swingtimer = "custom",
|
||||
}
|
||||
|
||||
-- Convert FPS to throttle delay in seconds
|
||||
@@ -141,8 +139,7 @@ function libthrottle:ResetAllToDefaults()
|
||||
end
|
||||
|
||||
-- Initialize - set defaults if config doesn't exist
|
||||
libthrottle:SetScript("OnEvent", function()
|
||||
if event == "PLAYER_ENTERING_WORLD" then
|
||||
EventUtil.RegisterOnceFrameEventAndCallback("PLAYER_ENTERING_WORLD", function()
|
||||
if not _G.pfUI_throttle then
|
||||
_G.pfUI_throttle = {}
|
||||
end
|
||||
@@ -155,16 +152,9 @@ libthrottle:SetScript("OnEvent", function()
|
||||
end
|
||||
|
||||
-- Set defaults for custom fields if missing
|
||||
if not _G.pfUI_throttle.nameplates_castbar_custom then _G.pfUI_throttle.nameplates_castbar_custom = "100" 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.swingtimer_custom then _G.pfUI_throttle.swingtimer_custom = "50" end
|
||||
|
||||
this:UnregisterEvent("PLAYER_ENTERING_WORLD")
|
||||
end
|
||||
end)
|
||||
|
||||
libthrottle:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
|
||||
-- Export to pfUI namespace for easier access
|
||||
pfUI.throttle = libthrottle
|
||||
|
||||
+45
-66
@@ -2,20 +2,17 @@
|
||||
setfenv(1, pfUI:GetEnvironment())
|
||||
|
||||
--[[ libunitscan ]]--
|
||||
-- A pfUI library that remembers the class, level and guild of every player it
|
||||
-- sees: in the friends, guild, raid and party rosters, in /who results, and as
|
||||
-- target, mouseover or nameplate. The data is persisted within pfUI_playerDB,
|
||||
-- for the places that only have a player's name, such as chat links and
|
||||
-- offline friends. Anything with a unit reads the unit itself instead.
|
||||
-- A pfUI library that remembers the level of every player it sees: in the
|
||||
-- friends, guild, raid and party rosters, in /who results, and as target,
|
||||
-- mouseover or nameplate. The levels are persisted within pfUI_playerDB, for
|
||||
-- the places that only have a player's name, such as chat links and offline
|
||||
-- friends. Anything with a unit reads the unit itself instead. A player's
|
||||
-- class comes from C_PlayerCache.GetPlayerInfoByName, not from here.
|
||||
--
|
||||
-- External functions:
|
||||
-- GetUnitInfo(name)
|
||||
-- Returns information of the given player name. Returns nil if the player
|
||||
-- was never seen.
|
||||
--
|
||||
-- class[String] - The class of the player
|
||||
-- level[Number] - The level of the player
|
||||
-- guild[String] - The guild name of the player
|
||||
-- GetPlayerLevel(name)
|
||||
-- Returns the last seen level of the given player name, or nil if it was
|
||||
-- never seen.
|
||||
--
|
||||
|
||||
-- return instantly when another libunitscan is already active
|
||||
@@ -23,33 +20,33 @@ if pfUI.api.libunitscan then return end
|
||||
|
||||
local players = {}
|
||||
|
||||
-- Feed (guid, name, classToken) into ClassicAPI's persistent name
|
||||
-- cache when the unit's GUID is resolvable. Roster-style packets
|
||||
-- (party / raid / inspect on glance) carry class inline, so the
|
||||
-- engine often doesn't issue a separate name query and the DLL's
|
||||
-- NameCache hook never fires for them — this is where we close that gap.
|
||||
local function RememberByUnit(unit, name, class)
|
||||
if not (name and class) then return end
|
||||
-- Feed a unit into ClassicAPI's persistent name cache. Roster-style packets
|
||||
-- (party / raid / inspect on glance) carry class inline, so the engine often
|
||||
-- doesn't issue a separate name query and the DLL's NameCache hook never
|
||||
-- fires for them — this is where we close that gap.
|
||||
local function RememberByUnit(unit)
|
||||
local guid = UnitGUID(unit)
|
||||
if not guid then return end
|
||||
C_PlayerCache.RememberPlayer(guid, name, class, UnitRace(unit), UnitSex(unit))
|
||||
local _, race = UnitRace(unit)
|
||||
C_PlayerCache.RememberPlayer(guid, UnitName(unit), UnitClassBase(unit), race, UnitSex(unit) - 2)
|
||||
end
|
||||
|
||||
function GetUnitInfo(name)
|
||||
local ret = players[name]
|
||||
if ret then
|
||||
return ret.class, ret.level, ret.guild
|
||||
function GetPlayerLevel(name)
|
||||
local entry = players[name]
|
||||
return entry and entry.level
|
||||
end
|
||||
|
||||
-- UnitLevel returns -1 for unknown levels, don't overwrite known values
|
||||
local function AddLevel(name, level)
|
||||
if not name or not level or level <= 0 then return end
|
||||
local entry = players[name]
|
||||
if entry then
|
||||
entry.level = level
|
||||
else
|
||||
players[name] = { level = level }
|
||||
end
|
||||
end
|
||||
|
||||
local function AddData(name, class, level, guild)
|
||||
if not name then return end
|
||||
players[name] = players[name] or {}
|
||||
players[name].class = class or players[name].class
|
||||
players[name].level = level or players[name].level
|
||||
players[name].guild = guild or players[name].guild
|
||||
end
|
||||
|
||||
local libunitscan = CreateFrame("Frame", "pfUnitScan", UIParent)
|
||||
libunitscan:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
libunitscan:RegisterEvent("FRIENDLIST_UPDATE")
|
||||
@@ -68,58 +65,45 @@ libunitscan:SetScript("OnEvent", function()
|
||||
players = pfUI_playerDB
|
||||
|
||||
-- update own character details
|
||||
local name = UnitName("player")
|
||||
local class = UnitClassBase("player")
|
||||
local level = UnitLevel("player")
|
||||
local guild = GetGuildInfo("player")
|
||||
AddData(name, class, level, guild)
|
||||
RememberByUnit("player", name, class)
|
||||
AddLevel(UnitName("player"), UnitLevel("player"))
|
||||
RememberByUnit("player")
|
||||
|
||||
elseif event == "FRIENDLIST_UPDATE" then
|
||||
for i = 1, GetNumFriends() do
|
||||
local info = C_FriendList.GetFriendInfoByIndex(i)
|
||||
if info then
|
||||
local level = info.level > 0 and info.level or nil
|
||||
AddData(info.name, info.classFilename, level)
|
||||
AddLevel(info.name, info.level)
|
||||
end
|
||||
end
|
||||
|
||||
elseif event == "GUILD_ROSTER_UPDATE" then
|
||||
local guild = GetGuildInfo("player")
|
||||
local name, class, level, _
|
||||
local name, level, _
|
||||
for i = 1, GetNumGuildMembers() do
|
||||
name, _, _, level, class = GetGuildRosterInfo(i)
|
||||
class = L["class"][class] or nil
|
||||
AddData(name, class, level, guild)
|
||||
name, _, _, level = GetGuildRosterInfo(i)
|
||||
AddLevel(name, level)
|
||||
end
|
||||
|
||||
elseif event == "RAID_ROSTER_UPDATE" then
|
||||
local name, class, level, unit, _
|
||||
local name, level, _
|
||||
for i = 1, GetNumRaidMembers() do
|
||||
unit = "raid" .. i
|
||||
name, _, _, level, class = GetRaidRosterInfo(i)
|
||||
class = L["class"][class] or nil
|
||||
AddData(name, class, level)
|
||||
RememberByUnit(unit, name, class)
|
||||
name, _, _, level = GetRaidRosterInfo(i)
|
||||
AddLevel(name, level)
|
||||
RememberByUnit("raid" .. i)
|
||||
end
|
||||
|
||||
elseif event == "PARTY_MEMBERS_CHANGED" then
|
||||
local name, class, level, unit, guild
|
||||
local unit
|
||||
for i = 1, GetNumPartyMembers() do
|
||||
unit = "party" .. i
|
||||
class = UnitClassBase(unit)
|
||||
name = UnitName(unit)
|
||||
level = UnitLevel(unit)
|
||||
guild = GetGuildInfo(unit)
|
||||
AddData(name, class, level, guild)
|
||||
RememberByUnit(unit, name, class)
|
||||
AddLevel(UnitName(unit), UnitLevel(unit))
|
||||
RememberByUnit(unit)
|
||||
end
|
||||
|
||||
elseif event == "WHO_LIST_UPDATE" or event == "CHAT_MSG_SYSTEM" then
|
||||
for i = 1, C_FriendList.GetNumWhoResults() do
|
||||
local info = C_FriendList.GetWhoInfo(i)
|
||||
if info then
|
||||
AddData(info.fullName, info.filename, info.level, info.fullGuildName)
|
||||
AddLevel(info.fullName, info.level)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -128,13 +112,8 @@ libunitscan:SetScript("OnEvent", function()
|
||||
or event == "NAME_PLATE_UNIT_ADDED" and arg1
|
||||
or "mouseover"
|
||||
if UnitIsPlayer(scan) then
|
||||
local name = UnitName(scan)
|
||||
local class = UnitClassBase(scan)
|
||||
-- UnitLevel returns -1 for unknown levels, don't overwrite known values
|
||||
local level = UnitLevel(scan)
|
||||
level = level > 0 and level or nil
|
||||
AddData(name, class, level, GetGuildInfo(scan))
|
||||
RememberByUnit(scan, name, class)
|
||||
AddLevel(UnitName(scan), UnitLevel(scan))
|
||||
RememberByUnit(scan)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
+339
-256
@@ -9,7 +9,7 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
local rawborder, border = GetBorderSize("actionbars")
|
||||
local bpad = rawborder > 1 and border - GetPerfectPixel() or GetPerfectPixel()
|
||||
|
||||
local eventcache = { } -- contains a list of events that shall be processed later -> [event] = true
|
||||
local passcache = { } -- contains the passes over the visible buttons that shall run later -> [pass] = true
|
||||
local updatecache = { } -- contains a list of buttons slots that shall be refreshed later -> [slot] = true
|
||||
local buttoncache = { } -- contains a list of all buttons ever created -> [slot] = frame
|
||||
|
||||
@@ -54,18 +54,21 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
if f.Hide then f:Hide() end
|
||||
end
|
||||
|
||||
-- also abbreviate mouse buttons
|
||||
local OrigGetBindingText = GetBindingText
|
||||
local function GetBindingText(msg, mod, abbrev)
|
||||
local txt = OrigGetBindingText(msg, mod, abbrev)
|
||||
if abbrev then
|
||||
txt = string.gsub(txt, _G[string.format("%s%s", mod, "BUTTON3")], "MB3")
|
||||
txt = string.gsub(txt, _G[string.format("%s%s", mod, "BUTTON4")], "MB4")
|
||||
txt = string.gsub(txt, _G[string.format("%s%s", mod, "BUTTON5")], "MB5")
|
||||
txt = string.gsub(txt, _G[string.format("%s%s", mod, "MOUSEWHEELDOWN")], "MWD")
|
||||
txt = string.gsub(txt, _G[string.format("%s%s", mod, "MOUSEWHEELUP")], "MWU")
|
||||
-- the abbreviated text of the key bound to a command, mouse buttons included
|
||||
local mouse_abbrevs = {
|
||||
[_G.KEY_BUTTON3] = "MB3",
|
||||
[_G.KEY_BUTTON4] = "MB4",
|
||||
[_G.KEY_BUTTON5] = "MB5",
|
||||
[_G.KEY_MOUSEWHEELDOWN] = "MWD",
|
||||
[_G.KEY_MOUSEWHEELUP] = "MWU",
|
||||
}
|
||||
|
||||
local function GetKeybindText(command)
|
||||
local text = GetBindingText(GetBindingKey(command), "KEY_", 1)
|
||||
for name, abbrev in pairs(mouse_abbrevs) do
|
||||
text = text:gsub(name, abbrev)
|
||||
end
|
||||
return txt
|
||||
return text
|
||||
end
|
||||
|
||||
kill(MainMenuBar)
|
||||
@@ -83,33 +86,34 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
_G.SHOW_MULTI_ACTIONBAR_3 = nil
|
||||
_G.SHOW_MULTI_ACTIONBAR_4 = nil
|
||||
|
||||
-- events that provide special updater functions
|
||||
local special_events = {
|
||||
["ACTIONBAR_UPDATE_COOLDOWN"] = true,
|
||||
["ACTIONBAR_UPDATE_USABLE"] = true,
|
||||
["ACTIONBAR_UPDATE_STATE"] = true,
|
||||
-- events that refresh one part of every visible button -> [event] = pass.
|
||||
-- Page changes only touch the main bar, whose pager handles them.
|
||||
local pass_events = {
|
||||
["ACTIONBAR_UPDATE_COOLDOWN"] = "cooldown",
|
||||
-- action slots take ACTION_USABLE_CHANGED; the stance buttons still
|
||||
-- need a pass on this one
|
||||
["ACTIONBAR_UPDATE_USABLE"] = "stance",
|
||||
["ACTIONBAR_UPDATE_STATE"] = "state",
|
||||
-- the active border of attack, auto repeat and tradeskill actions
|
||||
["PLAYER_ENTER_COMBAT"] = "state",
|
||||
["PLAYER_LEAVE_COMBAT"] = "state",
|
||||
["START_AUTOREPEAT_SPELL"] = "state",
|
||||
["STOP_AUTOREPEAT_SPELL"] = "state",
|
||||
["CRAFT_SHOW"] = "state",
|
||||
["CRAFT_CLOSE"] = "state",
|
||||
["TRADE_SKILL_SHOW"] = "state",
|
||||
["TRADE_SKILL_CLOSE"] = "state",
|
||||
-- fires on every ammo shot / consumable use, but only counts, equipped
|
||||
-- state, cooldowns and usability can change from it
|
||||
["UNIT_INVENTORY_CHANGED"] = true,
|
||||
["UNIT_INVENTORY_CHANGED"] = "inventory",
|
||||
-- the keybind text of every button, shown or not
|
||||
["UPDATE_BINDINGS"] = "bindings",
|
||||
}
|
||||
|
||||
-- events that are shared across all buttons
|
||||
-- events that refresh every button
|
||||
local global_events = {
|
||||
-- slot/button updates
|
||||
["PLAYER_ENTERING_WORLD"] = true,
|
||||
["ACTIONBAR_SLOT_CHANGED"] = true,
|
||||
["UPDATE_BINDINGS"] = true,
|
||||
["ACTIONBAR_PAGE_CHANGED"] = true,
|
||||
["UPDATE_BONUS_ACTIONBAR"] = true,
|
||||
["CRAFT_SHOW"] = true,
|
||||
["CRAFT_CLOSE"] = true,
|
||||
["TRADE_SKILL_SHOW"] = true,
|
||||
["TRADE_SKILL_CLOSE"] = true,
|
||||
["PLAYER_ENTER_COMBAT"] = true,
|
||||
["PLAYER_LEAVE_COMBAT"] = true,
|
||||
-- auto repeat action
|
||||
["START_AUTOREPEAT_SPELL"] = true,
|
||||
["STOP_AUTOREPEAT_SPELL"] = true,
|
||||
}
|
||||
|
||||
-- events that are used for the aura/shapeshift bar
|
||||
@@ -394,37 +398,85 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
self.equipped:SetShown(IsEquippedAction(sid) and C.bars.showequipped == "1")
|
||||
end
|
||||
|
||||
local start, duration, enable, castable, autocast, token
|
||||
local grid, sid, id, bar, active, texture, _
|
||||
-- the keybind text, which an empty hidden button hides as well. The binding
|
||||
-- itself is only read on UPDATE_BINDINGS (the "bindings" pass).
|
||||
local function ButtonKeybindUpdate(self)
|
||||
self.keybind:SetText(not self.hide and self.binding or "")
|
||||
end
|
||||
|
||||
-- the active border of current, attack and auto repeat actions, which the
|
||||
-- "statechange" animation follows. A full update applies it unconditionally.
|
||||
local function ButtonActiveUpdate(self, active, force)
|
||||
if active then
|
||||
if not self.isactive and C.bars.animmode == "statechange" then
|
||||
PlayButtonAnimation(self)
|
||||
end
|
||||
|
||||
if force or not self.isactive then
|
||||
self.backdrop:SetBackdropBorderColor(cr,cg,cb,1)
|
||||
self.active:Show()
|
||||
self.isactive = true
|
||||
end
|
||||
elseif force or self.isactive then
|
||||
self.backdrop:SetBackdropBorderColor(er,eg,eb,ea)
|
||||
self.active:Hide()
|
||||
self.isactive = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- the pulsing border of a spell whose proc glow is lit
|
||||
local function ButtonProcShow(self, glow)
|
||||
if glow then
|
||||
if not self.proc:IsShown() then
|
||||
self.proc:Show()
|
||||
self.proc.pulse:Play()
|
||||
end
|
||||
elseif self.proc:IsShown() then
|
||||
self.proc.pulse:Stop()
|
||||
self.proc:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
-- the spell an action slot casts, directly or through a macro, and its
|
||||
-- proc glow. The glow events name that spell.
|
||||
local function ButtonProcUpdate(self)
|
||||
local kind, id, spellid, _
|
||||
if C.bars.procglow == "1" then
|
||||
kind, id = GetActionInfo(self.id)
|
||||
if kind == "spell" then
|
||||
spellid = id
|
||||
elseif kind == "macro" then
|
||||
_, _, spellid = GetMacroSpell(id)
|
||||
end
|
||||
end
|
||||
|
||||
self.spellid = spellid
|
||||
ButtonProcShow(self, spellid and IsSpellOverlayed(spellid))
|
||||
end
|
||||
|
||||
local castable, autocast, token
|
||||
local grid, sid, active, texture, _
|
||||
local function ButtonSlotUpdate(self)
|
||||
if not self then return end
|
||||
self = self or this
|
||||
sid = self.id -- 1 to 120
|
||||
|
||||
-- reset shared variables
|
||||
castable, autocast, token = nil, nil, nil
|
||||
|
||||
-- set the own ID for compatibility to some vanilla addons
|
||||
self:SetID(self.id)
|
||||
self:SetID(sid)
|
||||
|
||||
grid = self.bar == 12 and showgrid_pet or showgrid
|
||||
|
||||
if self.bar == 11 then
|
||||
-- stance button
|
||||
bar = self.bar
|
||||
id = sid
|
||||
texture, _, active = GetShapeshiftFormInfo(id)
|
||||
texture, _, active = GetShapeshiftFormInfo(sid)
|
||||
elseif self.bar == 12 then
|
||||
-- pet button
|
||||
bar = self.bar
|
||||
id = sid
|
||||
_, _, texture, token, active, castable, autocast = GetPetActionInfo(id)
|
||||
_, _, texture, token, active, castable, autocast = GetPetActionInfo(sid)
|
||||
texture = token and _G[texture] or texture
|
||||
else
|
||||
active = IsCurrentAction(sid) or IsAutoRepeatAction(sid)
|
||||
texture = GetActionTexture(sid)
|
||||
bar = GetActiveBar()
|
||||
id = self.bar == 1 and self.slot or sid-((self.bar)-1)*12
|
||||
end
|
||||
|
||||
if not self.showempty and self.backdrop and not texture and grid == 0 then
|
||||
@@ -435,19 +487,6 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
self.hide = nil
|
||||
end
|
||||
|
||||
-- active border
|
||||
if active then
|
||||
if C.bars.animmode == "statechange" and not self.active:IsShown() then
|
||||
PlayButtonAnimation(self)
|
||||
end
|
||||
|
||||
self.backdrop:SetBackdropBorderColor(cr,cg,cb,1)
|
||||
self.active:Show()
|
||||
else
|
||||
self.backdrop:SetBackdropBorderColor(er,eg,eb,ea)
|
||||
self.active:Hide()
|
||||
end
|
||||
|
||||
ButtonInventoryUpdate(self)
|
||||
|
||||
if self.bar ~= 11 and self.bar ~= 12 then
|
||||
@@ -457,6 +496,8 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
else
|
||||
self.macro:SetText("")
|
||||
end
|
||||
|
||||
ButtonProcUpdate(self)
|
||||
end
|
||||
|
||||
-- icon
|
||||
@@ -481,14 +522,8 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
self.autocastable:SetShown(castable and C.bars.showcastable == "1")
|
||||
end
|
||||
|
||||
-- keybinds
|
||||
if not self.hide and self.bar == 1 and self.bar ~= 11 and self.bar ~= 12 then
|
||||
self.keybind:SetText(GetBindingText(GetBindingKey("ACTIONBUTTON"..id), "KEY_", 1))
|
||||
elseif not self.hide and buttontypes[self.bar] then
|
||||
self.keybind:SetText(GetBindingText(GetBindingKey(buttontypes[self.bar]..id), "KEY_", 1))
|
||||
else
|
||||
self.keybind:SetText("")
|
||||
end
|
||||
ButtonActiveUpdate(self, active, true)
|
||||
ButtonKeybindUpdate(self)
|
||||
end
|
||||
|
||||
local sid, usable, oom, _
|
||||
@@ -498,8 +533,9 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
|
||||
if self.bar == 11 then
|
||||
_, _, _, usable = GetShapeshiftFormInfo(sid)
|
||||
oom = nil
|
||||
elseif self.bar == 12 then
|
||||
usable = true
|
||||
usable, oom = true, nil
|
||||
else
|
||||
usable, oom = IsUsableAction(sid)
|
||||
end
|
||||
@@ -528,25 +564,22 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
end
|
||||
end
|
||||
|
||||
local function ButtonRangeUpdate(self)
|
||||
self = self or this
|
||||
-- Keeps the range check of the slot a shown action button displays
|
||||
-- enabled, so ACTION_RANGE_CHECK_UPDATE reports it. Each button holds its
|
||||
-- own enable, as the client counts them per slot. An enable fires the
|
||||
-- event with the current state, so a new slot starts in range until then.
|
||||
local function ButtonRangeWatch(button)
|
||||
local slot = C.bars.glowrange == "1" and button.bar <= 10 and button:IsVisible() and button.id or nil
|
||||
if slot == button.rangeslot then return end
|
||||
|
||||
-- update range display
|
||||
if C.bars.glowrange == "1" and self.bar ~= 11 and self.bar ~= 12 and HasAction(self.id) and ActionHasRange(self.id) and IsActionInRange(self.id) == 0 then
|
||||
if not self.outofrange then
|
||||
self.outofrange = true
|
||||
ButtonUsableUpdate(self)
|
||||
end
|
||||
elseif self.outofrange then
|
||||
self.outofrange = nil
|
||||
ButtonUsableUpdate(self)
|
||||
end
|
||||
if button.rangeslot then C_ActionBar.EnableActionRangeCheck(button.rangeslot, false) end
|
||||
if slot then C_ActionBar.EnableActionRangeCheck(slot, true) end
|
||||
button.rangeslot = slot
|
||||
button.outofrange = nil
|
||||
end
|
||||
|
||||
local start, duration, enable
|
||||
local function ButtonCooldownUpdate(button)
|
||||
if not button then return end
|
||||
|
||||
if button.bar == 11 then
|
||||
start, duration, enable = GetShapeshiftFormCooldown(button.id)
|
||||
elseif button.bar == 12 then
|
||||
@@ -556,183 +589,205 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
end
|
||||
|
||||
-- Nil-protect: GetActionCooldown can return nil during macro parsing/indexing
|
||||
if start and duration then
|
||||
CooldownFrame_SetTimer(button.cd, start, duration, enable or 1)
|
||||
end
|
||||
if not start or not duration then return end
|
||||
enable = enable or 1
|
||||
|
||||
-- most buttons keep their cooldown through a cooldown event
|
||||
if start == button.cdstart and duration == button.cdduration and enable == button.cdenable then return end
|
||||
button.cdstart, button.cdduration, button.cdenable = start, duration, enable
|
||||
|
||||
CooldownFrame_SetTimer(button.cd, start, duration, enable)
|
||||
end
|
||||
|
||||
local _, active
|
||||
local function ButtonIsActiveUpdate(button)
|
||||
if not button then return end
|
||||
|
||||
if button.bar == 11 then
|
||||
_, _, active, _ = GetShapeshiftFormInfo(button.id)
|
||||
_, _, active = GetShapeshiftFormInfo(button.id)
|
||||
elseif button.bar == 12 then
|
||||
_, _, _, _, active, _, _ = GetPetActionInfo(button.id)
|
||||
_, _, _, _, active = GetPetActionInfo(button.id)
|
||||
else
|
||||
active = IsCurrentAction(button.id) or IsAutoRepeatAction(button.id)
|
||||
end
|
||||
|
||||
-- active border
|
||||
if active then
|
||||
if not button.border_active then
|
||||
button.backdrop:SetBackdropBorderColor(cr,cg,cb,1)
|
||||
button.border_active = true
|
||||
end
|
||||
|
||||
button.active:Show()
|
||||
else
|
||||
if button.border_active then
|
||||
button.backdrop:SetBackdropBorderColor(er,eg,eb,ea)
|
||||
button.border_active = nil
|
||||
end
|
||||
|
||||
button.active:Hide()
|
||||
end
|
||||
ButtonActiveUpdate(button, active)
|
||||
end
|
||||
|
||||
|
||||
-- everything of a button; the slot update covers its active state
|
||||
local function ButtonFullUpdate(button)
|
||||
if not button then return end
|
||||
|
||||
ButtonSlotUpdate(button)
|
||||
ButtonRangeUpdate(button)
|
||||
ButtonUsableUpdate(button)
|
||||
ButtonCooldownUpdate(button)
|
||||
ButtonIsActiveUpdate(button)
|
||||
end
|
||||
|
||||
local function BarsEvent(self)
|
||||
self = self or this
|
||||
-- the pfActionBar frame handles the events of every button; its array part
|
||||
-- holds the bar frames, bars[1] to bars[12]
|
||||
local bars = CreateFrame("Frame", "pfActionBar", UIParent)
|
||||
|
||||
-- Updates wait for the next frame, so the events of one frame share one
|
||||
-- pass. Passes and full updates skip hidden bars, which catch up as they
|
||||
-- show (BarShowHide). The shown buttons of a bar are its first `count` ones.
|
||||
local scheduled
|
||||
|
||||
-- calls func on the buttons that show a slot: its own button and the main
|
||||
-- bar button paged to it
|
||||
local function ForSlotButtons(slot, func, a1)
|
||||
local button = buttoncache[slot]
|
||||
if button then func(button, a1) end
|
||||
|
||||
local page = bars[1][1].id - 1
|
||||
local paged = slot > page and slot <= page + 12 and bars[1][slot - page]
|
||||
if paged and paged ~= button then func(paged, a1) end
|
||||
end
|
||||
|
||||
-- the range watch follows hidden buttons too, so a hidden bar lets go of
|
||||
-- its slots
|
||||
local function SlotButtonUpdate(button)
|
||||
ButtonRangeWatch(button)
|
||||
if button:IsVisible() then pfUI.bars.ButtonFullUpdate(button) end
|
||||
end
|
||||
|
||||
local function Flush()
|
||||
scheduled = nil
|
||||
|
||||
local inventory, cooldown, state = passcache.inventory, passcache.cooldown, passcache.state
|
||||
local stance, bindings = passcache.stance, passcache.bindings
|
||||
table.wipe(passcache)
|
||||
|
||||
if inventory or cooldown or state then
|
||||
for i = 1, 12 do
|
||||
local bar = bars[i]
|
||||
if bar:IsVisible() then
|
||||
for j = 1, bar.count do
|
||||
local button = bar[j]
|
||||
if inventory then ButtonInventoryUpdate(button) end
|
||||
if inventory or cooldown then ButtonCooldownUpdate(button) end
|
||||
if inventory then ButtonUsableUpdate(button) end
|
||||
if state then ButtonIsActiveUpdate(button) end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if stance and not inventory and bars[11]:IsVisible() then
|
||||
for j = 1, bars[11].count do
|
||||
ButtonUsableUpdate(bars[11][j])
|
||||
end
|
||||
end
|
||||
|
||||
-- the keybinds of hidden buttons as well, as they don't catch up on them
|
||||
if bindings then
|
||||
for _, button in pairs(buttoncache) do
|
||||
button.binding = GetKeybindText(button.bindcommand)
|
||||
ButtonKeybindUpdate(button)
|
||||
end
|
||||
end
|
||||
|
||||
for slot in pairs(updatecache) do
|
||||
updatecache[slot] = nil
|
||||
ForSlotButtons(slot, SlotButtonUpdate)
|
||||
end
|
||||
end
|
||||
|
||||
local function Schedule()
|
||||
if scheduled then return end
|
||||
scheduled = true
|
||||
RunNextFrame(Flush)
|
||||
end
|
||||
|
||||
-- queues a full update of the button in a slot
|
||||
local function QueueSlot(slot)
|
||||
updatecache[slot] = true
|
||||
Schedule()
|
||||
end
|
||||
|
||||
-- queues a pass over the visible buttons
|
||||
local function QueuePass(pass)
|
||||
passcache[pass] = true
|
||||
Schedule()
|
||||
end
|
||||
|
||||
-- passes skip hidden bars, so a bar refreshes its buttons as it shows;
|
||||
-- as it hides, its buttons let go of their range checks
|
||||
local function BarShowHide()
|
||||
local offset = (this:GetID() - 1) * 12
|
||||
for j = 1, this.count do
|
||||
QueueSlot(offset + j)
|
||||
end
|
||||
end
|
||||
|
||||
local function ButtonRangeEvent(button, outofrange)
|
||||
if button.rangeslot ~= arg1 or button.outofrange == outofrange then return end
|
||||
button.outofrange = outofrange
|
||||
ButtonUsableUpdate(button)
|
||||
end
|
||||
|
||||
local function ButtonUsableEvent(button)
|
||||
if button:IsVisible() then ButtonUsableUpdate(button) end
|
||||
end
|
||||
|
||||
local function BarsEvent()
|
||||
-- slot, isInRange, checksRange of a slot a button watches
|
||||
if event == "ACTION_RANGE_CHECK_UPDATE" then
|
||||
ForSlotButtons(arg1, ButtonRangeEvent, arg3 and not arg2 or nil)
|
||||
return
|
||||
end
|
||||
|
||||
-- the slots whose usable state changed
|
||||
if event == "ACTION_USABLE_CHANGED" then
|
||||
for _, change in ipairs(arg1) do
|
||||
ForSlotButtons(change.slot, ButtonUsableEvent)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- the spell whose glow started or ended; each rank has its own event
|
||||
if event == "SPELL_ACTIVATION_OVERLAY_GLOW_SHOW" or event == "SPELL_ACTIVATION_OVERLAY_GLOW_HIDE" then
|
||||
local glow = IsSpellOverlayed(arg1)
|
||||
for _, button in pairs(buttoncache) do
|
||||
if button.spellid == arg1 then ButtonProcShow(button, glow) end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- refresh only specific slots
|
||||
if event == "ACTIONBAR_SLOT_CHANGED" and arg1 and arg1 ~= 0 then
|
||||
updatecache[arg1] = true
|
||||
QueueSlot(arg1)
|
||||
return
|
||||
end
|
||||
|
||||
-- run special refresh functions on next update
|
||||
if special_events[event] then
|
||||
eventcache[event] = true
|
||||
-- refresh one part of every visible button
|
||||
if pass_events[event] then
|
||||
QueuePass(pass_events[event])
|
||||
return
|
||||
end
|
||||
|
||||
-- handle aura events
|
||||
-- auras and forms change the stance buttons
|
||||
if aura_events[event] then
|
||||
for j=1,12 do
|
||||
if self[11] and self[11][j] then
|
||||
updatecache[self[11][j].slot] = true
|
||||
end
|
||||
for j = 1, bars[11].count do
|
||||
QueueSlot(bars[11][j].slot)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- handle pet events
|
||||
if pet_events[event] then
|
||||
for j=1,12 do
|
||||
if self[12] and self[12][j] then
|
||||
updatecache[self[12][j].slot] = true
|
||||
end
|
||||
for j = 1, bars[12].count do
|
||||
QueueSlot(bars[12][j].slot)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- handle global events
|
||||
for id in pairs(buttoncache) do
|
||||
updatecache[id] = true
|
||||
end
|
||||
end
|
||||
|
||||
local self, button, unlock
|
||||
-- Main update loop with throttle for performance optimization
|
||||
local function BarsUpdate(self)
|
||||
self = self or this
|
||||
|
||||
-- Throttle for performance
|
||||
if (this.tick_main or 0) > GetTime() then return end
|
||||
this.tick_main = GetTime() + 0.025
|
||||
|
||||
if pfUI.unlock then
|
||||
-- update all bars when entering unlock
|
||||
if pfUI.unlock:IsShown() ~= unlock then
|
||||
pfUI.bars:UpdateConfig()
|
||||
unlock = pfUI.unlock:IsShown()
|
||||
end
|
||||
end
|
||||
|
||||
-- The cached passes below only touch visible buttons. Hidden ones (other
|
||||
-- pages, hidden bars) are flagged stale and get a full update once the
|
||||
-- range pass sees them visible again.
|
||||
|
||||
-- run cached inventory changes (ammo, reagents, consumables)
|
||||
if eventcache["UNIT_INVENTORY_CHANGED"] then
|
||||
eventcache["UNIT_INVENTORY_CHANGED"] = nil
|
||||
for id, button in pairs(buttoncache) do
|
||||
if button:IsVisible() then
|
||||
ButtonInventoryUpdate(button)
|
||||
ButtonCooldownUpdate(button)
|
||||
ButtonUsableUpdate(button)
|
||||
else
|
||||
button.stale = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- run cached usable usable actions
|
||||
if eventcache["ACTIONBAR_UPDATE_USABLE"] then
|
||||
eventcache["ACTIONBAR_UPDATE_USABLE"] = nil
|
||||
for id, button in pairs(buttoncache) do
|
||||
if button:IsVisible() then ButtonUsableUpdate(button) else button.stale = true end
|
||||
end
|
||||
end
|
||||
|
||||
-- run cached cooldown events
|
||||
if eventcache["ACTIONBAR_UPDATE_COOLDOWN"] then
|
||||
eventcache["ACTIONBAR_UPDATE_COOLDOWN"] = nil
|
||||
for id, button in pairs(buttoncache) do
|
||||
if button:IsVisible() then ButtonCooldownUpdate(button) else button.stale = true end
|
||||
end
|
||||
end
|
||||
|
||||
-- run cached action state events
|
||||
if eventcache["ACTIONBAR_UPDATE_STATE"] then
|
||||
eventcache["ACTIONBAR_UPDATE_STATE"] = nil
|
||||
for id, button in pairs(buttoncache) do
|
||||
if button:IsVisible() then ButtonIsActiveUpdate(button) else button.stale = true end
|
||||
end
|
||||
end
|
||||
|
||||
for id in pairs(updatecache) do
|
||||
-- run updates based on slot
|
||||
pfUI.bars.ButtonFullUpdate(buttoncache[id])
|
||||
|
||||
-- run updates on paging actionbar if required
|
||||
for i=1,12 do
|
||||
if pfUI.bars[1][i].id == id then
|
||||
pfUI.bars.ButtonFullUpdate(pfUI.bars[1][i])
|
||||
end
|
||||
end
|
||||
|
||||
-- clear update cache
|
||||
updatecache[id] = nil
|
||||
end
|
||||
|
||||
if ( this.tick or .2) > GetTime() then return else this.tick = GetTime() + .2 end
|
||||
|
||||
for id, button in pairs(buttoncache) do
|
||||
if button.stale and button:IsVisible() then
|
||||
-- catch up on updates skipped while hidden
|
||||
button.stale = nil
|
||||
ButtonFullUpdate(button)
|
||||
elseif button:IsShown() then
|
||||
ButtonRangeUpdate(button)
|
||||
-- refresh every button and its keybind
|
||||
if global_events[event] then
|
||||
QueuePass("bindings")
|
||||
for slot in pairs(buttoncache) do
|
||||
QueueSlot(slot)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- create the main event and update handler for pfUI actionbars
|
||||
local bars = CreateFrame("Frame", "pfActionBar", UIParent)
|
||||
|
||||
-- The only unit events in the tables above; both concern the player alone.
|
||||
-- A registration keeps its kind, so these have to go in unit-filtered from
|
||||
-- the start -- RegisterUnitEvent over a plain registration stays plain.
|
||||
@@ -750,17 +805,18 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
end
|
||||
end
|
||||
|
||||
for event in pairs(special_events) do RegisterBarEvent(event) end
|
||||
for event in pairs(pass_events) do RegisterBarEvent(event) end
|
||||
for event in pairs(global_events) do RegisterBarEvent(event) end
|
||||
for event in pairs(aura_events) do RegisterBarEvent(event) end
|
||||
for event in pairs(pet_events) do RegisterBarEvent(event) end
|
||||
bars:RegisterEvent("ACTION_RANGE_CHECK_UPDATE")
|
||||
bars:RegisterEvent("ACTION_USABLE_CHANGED")
|
||||
bars:RegisterEvent("SPELL_ACTIVATION_OVERLAY_GLOW_SHOW")
|
||||
bars:RegisterEvent("SPELL_ACTIVATION_OVERLAY_GLOW_HIDE")
|
||||
|
||||
-- refresh actionbar buttons on event
|
||||
bars:SetScript("OnEvent", BarsEvent)
|
||||
|
||||
-- update actionbar buttons
|
||||
bars:SetScript("OnUpdate", BarsUpdate)
|
||||
|
||||
-- enable bar paging via secure functions
|
||||
local function EnablePaging(bar)
|
||||
if not bar.pager then
|
||||
@@ -776,9 +832,8 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
|
||||
local active = GetActiveBar()
|
||||
for i=1,12 do
|
||||
local id = i + (active-1)*12
|
||||
bar[i].id = id
|
||||
updatecache[i] = true
|
||||
bar[i].id = i + (active-1)*12
|
||||
QueueSlot(i)
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -1006,8 +1061,11 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
-- set a static slot
|
||||
f.slot = id
|
||||
|
||||
-- the binding command of the button, fixed on the paged main bar too
|
||||
f.bindcommand = (bar == 1 and "ACTIONBUTTON" or buttontypes[bar]) .. button
|
||||
|
||||
-- cooldown
|
||||
f.cd = CreateCooldown(f, "actionbar", f:GetName() .. "Cooldown")
|
||||
f.cd = CreateCooldown(f, "spell", C.bars, "timers", f:GetName() .. "Cooldown")
|
||||
|
||||
-- icon
|
||||
f.icon = f:CreateTexture(button_name .. "Icon", "BACKGROUND")
|
||||
@@ -1065,6 +1123,23 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
f.active:SetAllPoints()
|
||||
f.active:Hide()
|
||||
|
||||
-- proc glow
|
||||
if bar ~= 11 and bar ~= 12 then
|
||||
f.proc = CreateFrame("Frame", nil, f)
|
||||
f.proc:SetBackdrop(backdrop_highlight)
|
||||
f.proc:SetBackdropBorderColor(1,.8,.2,1)
|
||||
f.proc:SetAllPoints()
|
||||
f.proc:Hide()
|
||||
|
||||
f.proc.pulse = f.proc:CreateAnimationGroup()
|
||||
f.proc.pulse:SetLooping("BOUNCE")
|
||||
local fade = f.proc.pulse:CreateAnimation("Alpha")
|
||||
fade:SetFromAlpha(1)
|
||||
fade:SetToAlpha(.3)
|
||||
fade:SetDuration(.5)
|
||||
fade:SetSmoothing("IN_OUT")
|
||||
end
|
||||
|
||||
-- add to buttoncache
|
||||
buttoncache[id] = f
|
||||
end
|
||||
@@ -1168,6 +1243,7 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
|
||||
-- don't process empty bars
|
||||
if buttons == 0 then
|
||||
bars[i].count = 0
|
||||
bars[i]:Hide()
|
||||
return
|
||||
end
|
||||
@@ -1186,6 +1262,11 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
local init = not bars[i]
|
||||
bars[i] = bars[i] or CreateFrame("Frame", "pfActionBar" .. barnames[i], UIParent)
|
||||
bars[i]:SetID(i)
|
||||
bars[i].count = buttons
|
||||
if init then
|
||||
bars[i]:SetScript("OnShow", BarShowHide)
|
||||
if i <= 10 then bars[i]:SetScript("OnHide", BarShowHide) end
|
||||
end
|
||||
|
||||
-- autohide
|
||||
if autohide == "1" then
|
||||
@@ -1201,18 +1282,12 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
-- only show when pet actions exists
|
||||
bars[i]:SetShown(PetHasActionBar() or pfUI.unlock and pfUI.unlock:IsShown())
|
||||
|
||||
-- show/hide petbar on petbar updates
|
||||
-- show/hide petbar on petbar updates; the pet events of the
|
||||
-- pfActionBar frame refresh its buttons
|
||||
if init then
|
||||
bars[i]:RegisterEvent("PET_BAR_UPDATE")
|
||||
bars[i]:SetScript("OnEvent", function()
|
||||
-- hide obsolete buttons
|
||||
for i=1, NUM_PET_ACTION_SLOTS do
|
||||
if not PetHasActionBar() and bars[12][i] then
|
||||
bars[12][i]:Hide()
|
||||
end
|
||||
end
|
||||
-- refresh layout
|
||||
CreateActionBar(12)
|
||||
this:SetShown(PetHasActionBar() or pfUI.unlock and pfUI.unlock:IsShown())
|
||||
end)
|
||||
end
|
||||
|
||||
@@ -1270,7 +1345,7 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
end
|
||||
|
||||
-- refresh button
|
||||
updatecache[bars[i][j].slot] = true
|
||||
QueueSlot(bars[i][j].slot)
|
||||
end
|
||||
|
||||
for j=buttons+1,12 do
|
||||
@@ -1303,25 +1378,27 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
elseif i == 12 then -- pet
|
||||
bars[i]:SetPoint("BOTTOM", bars[6], "TOP", 0, 3*border)
|
||||
|
||||
-- make stance bar dodge by default
|
||||
bars[i]:SetScript("OnShow", function()
|
||||
if pfUI.unlock and pfUI.unlock:IsShown() then return end
|
||||
if bars[11] and bars[11]:IsShown() then
|
||||
bars[11]:ClearAllPoints()
|
||||
bars[11]:SetPoint("BOTTOM", bars[12], "TOP", 0, 3*border)
|
||||
UpdateMovable(bars[11], true)
|
||||
end
|
||||
end)
|
||||
if init then
|
||||
-- make stance bar dodge by default
|
||||
bars[i]:HookScript("OnShow", function()
|
||||
if pfUI.unlock and pfUI.unlock:IsShown() then return end
|
||||
if bars[11] and bars[11]:IsShown() then
|
||||
bars[11]:ClearAllPoints()
|
||||
bars[11]:SetPoint("BOTTOM", bars[12], "TOP", 0, 3*border)
|
||||
UpdateMovable(bars[11], true)
|
||||
end
|
||||
end)
|
||||
|
||||
-- restore old stance bar position
|
||||
bars[i]:SetScript("OnHide", function()
|
||||
if pfUI.unlock and pfUI.unlock:IsShown() then return end
|
||||
if bars[11] and bars[11]:IsShown() then
|
||||
bars[11]:ClearAllPoints()
|
||||
bars[11]:SetPoint("BOTTOM", bars[6], "TOP", 0, 3*border)
|
||||
UpdateMovable(bars[11], true)
|
||||
end
|
||||
end)
|
||||
-- restore old stance bar position
|
||||
bars[i]:SetScript("OnHide", function()
|
||||
if pfUI.unlock and pfUI.unlock:IsShown() then return end
|
||||
if bars[11] and bars[11]:IsShown() then
|
||||
bars[11]:ClearAllPoints()
|
||||
bars[11]:SetPoint("BOTTOM", bars[6], "TOP", 0, 3*border)
|
||||
UpdateMovable(bars[11], true)
|
||||
end
|
||||
end)
|
||||
end
|
||||
else -- others
|
||||
bars[i]:SetPoint("TOP", 0, -i*50)
|
||||
end
|
||||
@@ -1382,7 +1459,7 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
|
||||
-- create actionbars
|
||||
pfUI.bars = bars
|
||||
pfUI.bars.update = updatecache
|
||||
pfUI.bars.QueueSlot = QueueSlot
|
||||
pfUI.bars.buttons = buttoncache
|
||||
pfUI.bars.ButtonFullUpdate = ButtonFullUpdate
|
||||
pfUI.bars.ButtonEnter = ButtonEnter
|
||||
@@ -1392,13 +1469,13 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
if not typ then
|
||||
showgrid = state
|
||||
|
||||
for id in pairs(buttoncache) do
|
||||
updatecache[id] = true
|
||||
for slot in pairs(buttoncache) do
|
||||
QueueSlot(slot)
|
||||
end
|
||||
elseif typ == "PET" then
|
||||
showgrid_pet = state
|
||||
for slot=133,142 do
|
||||
updatecache[slot] = true
|
||||
QueueSlot(slot)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1411,6 +1488,12 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
|
||||
pfUI.bars:UpdateConfig()
|
||||
|
||||
-- update all bars when entering or leaving unlock mode
|
||||
if pfUI.unlock then
|
||||
pfUI.unlock:HookScript("OnShow", function() pfUI.bars:UpdateConfig() end)
|
||||
pfUI.unlock:HookScript("OnHide", function() pfUI.bars:UpdateConfig() end)
|
||||
end
|
||||
|
||||
-- Localize custom keybinds for additional actionbars (see Bindings.xml)
|
||||
local names = {
|
||||
["PAGING"] = T["Paging Actionbar"],
|
||||
@@ -1492,7 +1575,7 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
if newID then
|
||||
reagent_counts[newID] = reagent_counts[newID] or C_Item.GetItemCount(newID)
|
||||
end
|
||||
updatecache[slot] = true
|
||||
QueueSlot(slot)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1502,7 +1585,7 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
reagent_counts[itemID] = C_Item.GetItemCount(itemID)
|
||||
end
|
||||
for slot in pairs(reagent_slots) do
|
||||
updatecache[slot] = true
|
||||
QueueSlot(slot)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
+31
-17
@@ -89,42 +89,56 @@ pfUI:RegisterModule("bags", function ()
|
||||
|
||||
pfUI.bag.delay = { UpdateBag = {} }
|
||||
|
||||
pfUI.bag:SetScript("OnUpdate", function()
|
||||
-- update delayed ones every 0.1s
|
||||
if ( this.tick or 1) > GetTime() then return else this.tick = GetTime() + .1 end
|
||||
-- run the updates queued by events, batched into one pass per 0.1s
|
||||
local function FlushDelayed()
|
||||
local delay = pfUI.bag.delay
|
||||
delay.pending = nil
|
||||
|
||||
if this.delay.RefreshSpells then
|
||||
this.delay.RefreshSpells = nil
|
||||
if delay.RefreshSpells then
|
||||
delay.RefreshSpells = nil
|
||||
pfUI.bag:RefreshSpells()
|
||||
end
|
||||
|
||||
if this.delay.CheckFullUpdate then
|
||||
this.delay.CheckFullUpdate = nil
|
||||
if delay.CheckFullUpdate then
|
||||
delay.CheckFullUpdate = nil
|
||||
pfUI.bag:CheckFullUpdate()
|
||||
end
|
||||
|
||||
if this.delay.UpdateCooldowns then
|
||||
this.delay.UpdateCooldowns = nil
|
||||
if delay.UpdateCooldowns then
|
||||
delay.UpdateCooldowns = nil
|
||||
pfUI.bag:UpdateCooldowns()
|
||||
end
|
||||
|
||||
if this.delay.UpdateItemLock then
|
||||
this.delay.UpdateItemLock = nil
|
||||
if delay.UpdateItemLock then
|
||||
delay.UpdateItemLock = nil
|
||||
pfUI.bag:UpdateItemLock()
|
||||
end
|
||||
|
||||
if this.delay.UpdateSearch then
|
||||
this.delay.UpdateSearch = nil
|
||||
if delay.UpdateSearch then
|
||||
delay.UpdateSearch = nil
|
||||
pfUI.bag:UpdateSearch()
|
||||
end
|
||||
|
||||
for bag in pairs(this.delay.UpdateBag) do
|
||||
this.delay.UpdateBag[bag] = nil
|
||||
for bag in pairs(delay.UpdateBag) do
|
||||
delay.UpdateBag[bag] = nil
|
||||
pfUI.bag:UpdateBag(bag)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local function ScheduleFlush()
|
||||
if pfUI.bag.delay.pending then return end
|
||||
pfUI.bag.delay.pending = true
|
||||
C_Timer.After(.1, FlushDelayed)
|
||||
end
|
||||
|
||||
function pfUI.bag:QueueBagUpdate(bag)
|
||||
self.delay.UpdateBag[bag] = true
|
||||
ScheduleFlush()
|
||||
end
|
||||
|
||||
pfUI.bag:SetScript("OnEvent", function()
|
||||
ScheduleFlush()
|
||||
|
||||
if event == "PLAYER_ENTERING_WORLD" then
|
||||
pfUI.bag:CreateBags()
|
||||
pfUI.bag.right:Hide()
|
||||
@@ -415,7 +429,7 @@ pfUI:RegisterModule("bags", function ()
|
||||
-- reaches it after that
|
||||
local slotframe = pfUI.bags[bag].slots[slot].frame
|
||||
local cdname = slotframe:GetName() .. "Cooldown"
|
||||
slotframe.cd = CreateCooldown(slotframe, "bags", cdname)
|
||||
slotframe.cd = CreateCooldown(slotframe, "spell", C.appearance.bags, "timers", cdname)
|
||||
_G[cdname] = slotframe.cd
|
||||
|
||||
if not pfUI.bags[bag].slots[slot].frame.backdrop then
|
||||
|
||||
+1
-1
@@ -152,7 +152,7 @@ pfUI:RegisterModule("buff", function ()
|
||||
|
||||
-- the sweep and the duration numbers (the template covers the button and
|
||||
-- starts hidden); RefreshBuffButton starts its timer
|
||||
buff.cd = CreateCooldown(buff, "buff", buttonName .. "Cooldown")
|
||||
buff.cd = CreateCooldown(buff, "aura", C.buffs, "timers", buttonName .. "Cooldown")
|
||||
buff.cd:SetFrameLevel(buff:GetFrameLevel() + 1)
|
||||
buff.overlay:SetFrameLevel(buff:GetFrameLevel() + 2)
|
||||
|
||||
|
||||
+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
|
||||
|
||||
+122
-161
@@ -5,37 +5,68 @@ pfUI:RegisterModule("castbar", function ()
|
||||
local rawborder, default_border = GetBorderSize("unitframes")
|
||||
local cbtexture = pfUI.media[C.appearance.castbar.texture]
|
||||
|
||||
-- Helper function for castbar timer formatting
|
||||
local function FormatCastbarTime(value)
|
||||
if C.unitframes.castbardecimals == "1" then
|
||||
-- 1 decimal, round half up (matches Blizzard spellbook display)
|
||||
return string.format("%.1f", floor(value * 10 + 0.5) / 10)
|
||||
else
|
||||
-- 2 decimals (default)
|
||||
return string.format("%.2f", value)
|
||||
end
|
||||
-- Castbar timer text: 1 decimal rounded half up (matches Blizzard spellbook
|
||||
-- display), or 2 decimals (default)
|
||||
local formatter = C_StringUtil.CreateNumericRuleFormatter()
|
||||
if C.unitframes.castbardecimals == "1" then
|
||||
formatter:AddBreakpoint({ threshold = 0, step = .1, format = "%.1f" })
|
||||
else
|
||||
formatter:AddBreakpoint({ threshold = 0, format = "%.2f" })
|
||||
end
|
||||
|
||||
-- Clear cast state on the bar and start the fade-out. On a normal end the bar
|
||||
-- is left at its current fill (a completed cast is already ~full; nothing
|
||||
-- snaps to full, which used to flash for a frame when the next cast stamped
|
||||
-- the bar). When `failed` is set for a cast that was actually in progress, the
|
||||
-- bar flashes full red before fading — the cancelled-cast indicator.
|
||||
-- "cur / max": a cast counts up, a channel counts down
|
||||
local castText = {
|
||||
{ property = Enum.DurationTextBindingProperty.ElapsedDuration, formatter = formatter },
|
||||
{ property = Enum.DurationTextBindingProperty.TotalDuration, formatter = formatter },
|
||||
}
|
||||
local channelText = {
|
||||
{ property = Enum.DurationTextBindingProperty.RemainingDuration, formatter = formatter },
|
||||
{ property = Enum.DurationTextBindingProperty.TotalDuration, formatter = formatter },
|
||||
}
|
||||
|
||||
-- The bar's fill and timer text both follow cb.duration on their own; only
|
||||
-- the pushback total in front of the text needs a refresh.
|
||||
local function UpdateTimerText(cb)
|
||||
if not cb.showtimer then return end
|
||||
local prefix = ""
|
||||
if cb.delay > 0 then
|
||||
prefix = "|cffffaaaa" .. (cb.isChannel and "-" or "+") .. formatter:FormatNumber(cb.delay) .. " |r "
|
||||
end
|
||||
cb.timer:SetTextFormat(prefix .. "{} / {}", cb.isChannel and channelText or castText)
|
||||
cb.timer:Enable()
|
||||
end
|
||||
|
||||
-- STOP doesn't arrive for every cast (a synthetic cast has none, a remote
|
||||
-- unit's can be missed out of range), so the bar also clears at its end time.
|
||||
local function ArmExpiry(cb)
|
||||
if cb.expiry then cb.expiry:Cancel() end
|
||||
cb.expiry = C_Timer.NewTimer(cb.duration:GetRemainingDuration(), cb.onExpire)
|
||||
end
|
||||
|
||||
-- Clear cast state on the bar and start the fade-out. The fill freezes where
|
||||
-- the cast stopped (SetMinMaxValues drops the timer). When `failed` is set for
|
||||
-- a cast that was actually in progress, the bar flashes full red before
|
||||
-- fading — the cancelled-cast indicator.
|
||||
local function ClearBar(cb, failed)
|
||||
local wasActive = cb.endTime ~= nil
|
||||
cb.startTime, cb.endTime, cb.isChannel = nil, nil, nil
|
||||
if cb.expiry then cb.expiry:Cancel() end
|
||||
cb.expiry = nil
|
||||
cb.timer:Disable()
|
||||
if cb.active then
|
||||
cb.bar:SetMinMaxValues(0, 1)
|
||||
if failed then
|
||||
cb.bar:SetStatusBarColor(GetStringColor(C.appearance.castbar.failcolor))
|
||||
cb.bar:SetValue(1)
|
||||
else
|
||||
cb.bar:SetValue(cb.isChannel and cb.duration:GetRemainingPercent() or cb.duration:GetElapsedPercent())
|
||||
end
|
||||
end
|
||||
cb.active, cb.isChannel = nil, nil
|
||||
cb.activeName, cb.spellID = nil, nil
|
||||
cb.isTradeskill = nil
|
||||
cb.tradeskillTotal, cb.tradeskillCompleted, cb.tradeskillSpellID = nil, nil, nil
|
||||
cb.tradeskillSingleMs, cb.currentCraftStart = nil, nil
|
||||
cb.lastMax = nil
|
||||
cb.tradeskillSingle = nil
|
||||
cb.delay = 0
|
||||
if failed and wasActive then
|
||||
cb.bar:SetStatusBarColor(GetStringColor(C.appearance.castbar.failcolor))
|
||||
cb.bar:SetMinMaxValues(0, 1)
|
||||
cb.bar:SetValue(1)
|
||||
end
|
||||
if cb.bar.spark then cb.bar.spark:Hide() end
|
||||
if cb.craftbar then cb.craftbar:Hide() end
|
||||
if cb:IsShown() and not cb.fade:IsPlaying() then cb.fade:Play() end
|
||||
end
|
||||
|
||||
@@ -55,40 +86,35 @@ pfUI:RegisterModule("castbar", function ()
|
||||
-- fills continuously across the chain instead of resetting per craft.
|
||||
-- Also arms the per-craft spark — a thin marker that crosses the bar once
|
||||
-- per craft (so it moves N× faster than the main fill on an N-stack).
|
||||
local function EnterTradeskillMerge(cb, startMs, endMs, count)
|
||||
local function EnterTradeskillMerge(cb, count)
|
||||
local start, single = cb.duration:GetStartTime(), cb.duration:GetTotalDuration()
|
||||
cb.tradeskillTotal = count
|
||||
cb.tradeskillCompleted = 0
|
||||
cb.tradeskillSpellID = cb.spellID
|
||||
local single = endMs - startMs
|
||||
cb.tradeskillSingleMs = single
|
||||
cb.currentCraftStart = startMs
|
||||
local mergedEnd = startMs + single * count
|
||||
cb.endTime = mergedEnd
|
||||
local duration = (mergedEnd - startMs) / 1000
|
||||
cb.bar:SetMinMaxValues(0, duration)
|
||||
cb.lastMax = duration
|
||||
if cb.bar.spark then cb.bar.spark:Show() end
|
||||
cb.tradeskillSingle = single
|
||||
cb.craft:SetTimeFromStart(start, single)
|
||||
cb.duration:SetTimeFromStart(start, single * count)
|
||||
ArmExpiry(cb)
|
||||
cb.craftbar:Show()
|
||||
UpdateTradeskillLabel(cb)
|
||||
end
|
||||
|
||||
-- Mark the start of craft 2..N within an active merge (called from the
|
||||
-- UNIT_SPELLCAST_START handler). Resets the per-craft spark to the left
|
||||
-- edge of the bar.
|
||||
-- UNIT_SPELLCAST_START handler) and re-fit the bar's end to the crafts left.
|
||||
local function StartTradeskillCraft(cb)
|
||||
cb.currentCraftStart = GetTime() * 1000
|
||||
local remaining = cb.tradeskillTotal - (cb.tradeskillCompleted or 0)
|
||||
cb.endTime = cb.currentCraftStart + cb.tradeskillSingleMs * remaining
|
||||
local duration = (cb.endTime - cb.startTime) / 1000
|
||||
cb.bar:SetMinMaxValues(0, duration)
|
||||
cb.lastMax = duration
|
||||
local now = GetTime()
|
||||
local remaining = cb.tradeskillTotal - cb.tradeskillCompleted
|
||||
cb.craft:SetTimeFromStart(now, cb.tradeskillSingle)
|
||||
cb.duration:SetTimeSpan(cb.duration:GetStartTime(), now + cb.tradeskillSingle * remaining)
|
||||
ArmExpiry(cb)
|
||||
UpdateTradeskillLabel(cb)
|
||||
end
|
||||
|
||||
-- Stamp the bar with cast data and render text/icon/lag once. OnUpdate
|
||||
-- then animates the fill from this state without touching C_Spell.
|
||||
-- Stamp the bar with cast data and render text/icon/lag once. From here the
|
||||
-- bar's timer and text binding follow cb.duration without any Lua.
|
||||
local function StampBar(cb, name, tex, startMs, endMs, spellID, isChannel, delayMs, isTradeskill, rank, noInterrupt)
|
||||
cb.startTime = startMs
|
||||
cb.endTime = endMs
|
||||
cb.duration:SetTimeSpan(startMs / 1000, endMs / 1000)
|
||||
cb.active = true
|
||||
cb.isChannel = isChannel
|
||||
cb.spellID = spellID
|
||||
cb.activeName = name
|
||||
@@ -124,27 +150,18 @@ pfUI:RegisterModule("castbar", function ()
|
||||
cb.icon:Hide()
|
||||
end
|
||||
|
||||
local duration = (endMs - startMs) / 1000
|
||||
if cb.showlag then
|
||||
local _, _, lag = GetNetStats()
|
||||
cb.bar.lag:SetWidth(math.min(cb:GetWidth(), cb:GetWidth() / duration * (lag/1000)))
|
||||
cb.bar.lag:SetWidth(math.min(cb:GetWidth(), cb:GetWidth() / cb.duration:GetTotalDuration() * (lag/1000)))
|
||||
cb.bar.lag:Show()
|
||||
else
|
||||
cb.bar.lag:Hide()
|
||||
end
|
||||
|
||||
cb.bar:SetMinMaxValues(0, duration)
|
||||
cb.lastMax = duration
|
||||
|
||||
-- Prime the fill on this frame. StampBar otherwise leaves the previous
|
||||
-- value in place (ClearBar, run on the prior cast's STOP, leaves it full),
|
||||
-- so the bar would flash full for the frame between here and the next
|
||||
-- OnUpdate tick. Reset the throttle too so the timer text updates promptly.
|
||||
local nowSec = GetTime()
|
||||
local cur = isChannel and (endMs / 1000 - nowSec) or (nowSec - startMs / 1000)
|
||||
if cur < 0 then cur = 0 elseif cur > duration then cur = duration end
|
||||
cb.bar:SetValue(cur)
|
||||
cb.tick = 0
|
||||
cb.bar:SetTimerDuration(cb.duration, Enum.StatusBarInterpolation.Immediate,
|
||||
isChannel and Enum.StatusBarTimerDirection.RemainingTime or Enum.StatusBarTimerDirection.ElapsedTime)
|
||||
UpdateTimerText(cb)
|
||||
ArmExpiry(cb)
|
||||
end
|
||||
|
||||
-- One-shot poll: read C_Spell for the bar's unit, stamp or clear. Called
|
||||
@@ -186,6 +203,10 @@ pfUI:RegisterModule("castbar", function ()
|
||||
cb:SetFrameLevel(8)
|
||||
|
||||
cb.unitstr = unitstr
|
||||
cb.delay = 0
|
||||
cb.duration = C_DurationUtil.CreateDuration()
|
||||
cb.craft = C_DurationUtil.CreateDuration() -- the current craft of a tradeskill merge
|
||||
cb.onExpire = function() ClearBar(cb) end
|
||||
|
||||
-- icon
|
||||
cb.icon = CreateFrame("Frame", nil, cb)
|
||||
@@ -210,7 +231,7 @@ pfUI:RegisterModule("castbar", function ()
|
||||
CreateBackdropShadow(cb.bar)
|
||||
|
||||
-- text left
|
||||
cb.bar.left = cb.bar:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
||||
cb.bar.left = cb.bar:CreateFontString("Status", "OVERLAY", "GameFontNormal")
|
||||
cb.bar.left:ClearAllPoints()
|
||||
cb.bar.left:SetPoint("TOPLEFT", cb.bar, "TOPLEFT", 3 + C.castbar[unitstr].txtleftoffx, C.castbar[unitstr].txtleftoffy)
|
||||
cb.bar.left:SetPoint("BOTTOMRIGHT", cb.bar, "BOTTOMRIGHT", -3 + C.castbar[unitstr].txtleftoffx, C.castbar[unitstr].txtleftoffy)
|
||||
@@ -221,7 +242,7 @@ pfUI:RegisterModule("castbar", function ()
|
||||
cb.bar.left:SetJustifyH(C.castbar[unitstr].namealign or "LEFT")
|
||||
|
||||
-- text right
|
||||
cb.bar.right = cb.bar:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
||||
cb.bar.right = cb.bar:CreateFontString("Status", "OVERLAY", "GameFontNormal")
|
||||
cb.bar.right:ClearAllPoints()
|
||||
cb.bar.right:SetPoint("TOPLEFT", cb.bar, "TOPLEFT", 3 + C.castbar[unitstr].txtrightoffx, C.castbar[unitstr].txtrightoffy)
|
||||
cb.bar.right:SetPoint("BOTTOMRIGHT", cb.bar, "BOTTOMRIGHT", -3 + C.castbar[unitstr].txtrightoffx, C.castbar[unitstr].txtrightoffy)
|
||||
@@ -231,6 +252,10 @@ pfUI:RegisterModule("castbar", function ()
|
||||
cb.bar.right:SetFont(font, font_size, "OUTLINE")
|
||||
cb.bar.right:SetJustifyH(C.castbar[unitstr].timealign or "RIGHT")
|
||||
|
||||
cb.timer = C_DurationUtil.CreateDurationTextBinding()
|
||||
cb.timer:SetFontString(cb.bar.right)
|
||||
cb.timer:SetDuration(cb.duration)
|
||||
|
||||
cb.bar.lag = cb.bar:CreateTexture(nil, "OVERLAY")
|
||||
cb.bar.lag:SetPoint("TOPRIGHT", cb.bar, "TOPRIGHT", 0, 0)
|
||||
cb.bar.lag:SetPoint("BOTTOMRIGHT", cb.bar, "BOTTOMRIGHT", 0, 0)
|
||||
@@ -238,88 +263,29 @@ pfUI:RegisterModule("castbar", function ()
|
||||
|
||||
-- Per-craft progress spark for tradeskill merge — a thin vertical line
|
||||
-- that crosses the bar once per craft in the chain (so on a 5-stack it
|
||||
-- moves 5x faster than the main fill). Position is updated by OnUpdate
|
||||
-- while a merge is active; hidden otherwise.
|
||||
cb.bar.spark = cb.bar:CreateTexture(nil, "OVERLAY")
|
||||
cb.bar.spark:SetColorTexture(1, 1, 1, 0.8)
|
||||
cb.bar.spark:SetWidth(2)
|
||||
cb.bar.spark:SetPoint("TOP", cb.bar, "TOPLEFT", 0, 0)
|
||||
cb.bar.spark:SetPoint("BOTTOM", cb.bar, "BOTTOMLEFT", 0, 0)
|
||||
cb.bar.spark:Hide()
|
||||
-- moves 5x faster than the main fill). It rides the edge of an invisible
|
||||
-- fill that follows cb.craft, shown while a merge is active, and snaps
|
||||
-- back to the left each time StartTradeskillCraft restarts the craft.
|
||||
cb.craftbar = CreateFrame("StatusBar", nil, cb.bar)
|
||||
cb.craftbar:SetAllPoints(cb.bar)
|
||||
cb.craftbar:SetColorFill(1, 1, 1, 0)
|
||||
cb.craftbar:SetTimerDuration(cb.craft, Enum.StatusBarInterpolation.Immediate, Enum.StatusBarTimerDirection.ElapsedTime)
|
||||
cb.craftbar:Hide()
|
||||
|
||||
-- Fade-out after a cast ends. The bar is hidden while idle, so its OnUpdate
|
||||
-- only runs during a cast; unlock mode keeps it shown for dragging.
|
||||
local function unlocked() return cb.drag and cb.drag:IsShown() end
|
||||
cb.craftbar.spark = cb.craftbar:CreateTexture(nil, "OVERLAY")
|
||||
cb.craftbar.spark:SetColorTexture(1, 1, 1, 0.8)
|
||||
cb.craftbar.spark:SetWidth(2)
|
||||
cb.craftbar.spark:SetPoint("TOPRIGHT", cb.craftbar:GetStatusBarTexture(), "TOPRIGHT")
|
||||
cb.craftbar.spark:SetPoint("BOTTOMRIGHT", cb.craftbar:GetStatusBarTexture(), "BOTTOMRIGHT")
|
||||
|
||||
-- Fade-out after a cast ends. The bar is hidden while idle; unlock mode
|
||||
-- keeps it shown for dragging.
|
||||
cb.fade = cb:CreateAnimationGroup()
|
||||
local fade = cb.fade:CreateAnimation("Alpha")
|
||||
fade:SetChange(-1)
|
||||
fade:SetDuration(.4)
|
||||
cb.fade:SetScript("OnFinished", function()
|
||||
if not unlocked() then cb:Hide() end
|
||||
end)
|
||||
|
||||
-- OnUpdate animates the bar fill. All state transitions (cast start/stop/interrupt, channel start/stop,
|
||||
-- pushback) come from the event handler below — we never poll C_Spell
|
||||
-- here.
|
||||
cb:SetScript("OnUpdate", function()
|
||||
if (this.tick or 0) > GetTime() then return end
|
||||
this.tick = GetTime() + 0.020 -- ~50 FPS
|
||||
|
||||
if unlocked() then
|
||||
this.fade:Stop()
|
||||
return
|
||||
end
|
||||
|
||||
if this.fade:IsPlaying() then return end
|
||||
|
||||
if not this.endTime then
|
||||
this:Hide()
|
||||
return
|
||||
end
|
||||
|
||||
-- Non-player bars: if the unit disappears (target died / detarget),
|
||||
-- drop the bar immediately.
|
||||
if this.unitstr ~= "player" and not UnitExists(this.unitstr) then
|
||||
ClearBar(this)
|
||||
return
|
||||
end
|
||||
|
||||
local now = GetTime()
|
||||
local endSec = this.endTime / 1000
|
||||
if now >= endSec then
|
||||
ClearBar(this)
|
||||
return
|
||||
end
|
||||
|
||||
local startSec = this.startTime / 1000
|
||||
local max = endSec - startSec
|
||||
local cur = this.isChannel and (endSec - now) or (now - startSec)
|
||||
if cur > max then cur = max end
|
||||
if cur < 0 then cur = 0 end
|
||||
|
||||
this.bar:SetValue(cur)
|
||||
|
||||
-- Per-craft spark for a tradeskill merge: position by (now - current
|
||||
-- craft's start) / single-craft duration, clamped to [0, 1]. Snaps back
|
||||
-- to the left edge each time StartTradeskillCraft fires for craft N+1.
|
||||
if this.tradeskillTotal and this.tradeskillSingleMs and this.currentCraftStart then
|
||||
local craftElapsed = now * 1000 - this.currentCraftStart
|
||||
local p = craftElapsed / this.tradeskillSingleMs
|
||||
if p < 0 then p = 0 elseif p > 1 then p = 1 end
|
||||
local x = p * this.bar:GetWidth() - 1
|
||||
this.bar.spark:ClearAllPoints()
|
||||
this.bar.spark:SetPoint("TOP", this.bar, "TOPLEFT", x, 0)
|
||||
this.bar.spark:SetPoint("BOTTOM", this.bar, "BOTTOMLEFT", x, 0)
|
||||
end
|
||||
|
||||
if this.showtimer then
|
||||
if (this.delay or 0) > 0 then
|
||||
local prefix = "|cffffaaaa" .. (this.isChannel and "-" or "+") .. FormatCastbarTime(this.delay) .. " |r "
|
||||
this.bar.right:SetText(prefix .. FormatCastbarTime(cur) .. " / " .. FormatCastbarTime(max))
|
||||
else
|
||||
this.bar.right:SetText(FormatCastbarTime(cur) .. " / " .. FormatCastbarTime(max))
|
||||
end
|
||||
end
|
||||
if not (cb.drag and cb.drag:IsShown()) then cb:Hide() end
|
||||
end)
|
||||
|
||||
-- Cast lifecycle, entirely on ClassicAPI's UNIT_SPELLCAST_* events. They
|
||||
@@ -383,7 +349,7 @@ pfUI:RegisterModule("castbar", function ()
|
||||
RefreshBar(this, arg5)
|
||||
if this.isTradeskill and (this.pendingTradeskillCount or 0) > 1
|
||||
and C.castbar.player.mergetradeskill == "1" then
|
||||
EnterTradeskillMerge(this, this.startTime, this.endTime, this.pendingTradeskillCount)
|
||||
EnterTradeskillMerge(this, this.pendingTradeskillCount)
|
||||
end
|
||||
this.pendingTradeskillCount = nil
|
||||
end
|
||||
@@ -392,7 +358,7 @@ pfUI:RegisterModule("castbar", function ()
|
||||
-- count and clear when the chain is done. A no-op for normal casts,
|
||||
-- which are cleared by UNIT_SPELLCAST_STOP.
|
||||
if this.tradeskillTotal and arg3 == this.tradeskillSpellID then
|
||||
this.tradeskillCompleted = (this.tradeskillCompleted or 0) + 1
|
||||
this.tradeskillCompleted = this.tradeskillCompleted + 1
|
||||
if this.tradeskillCompleted >= this.tradeskillTotal then
|
||||
ClearBar(this)
|
||||
else
|
||||
@@ -412,35 +378,30 @@ pfUI:RegisterModule("castbar", function ()
|
||||
elseif event == "UNIT_SPELLCAST_FAILED" or event == "UNIT_SPELLCAST_INTERRUPTED" then
|
||||
ClearBar(this, true)
|
||||
elseif event == "UNIT_SPELLCAST_INTERRUPTIBLE" or event == "UNIT_SPELLCAST_NOT_INTERRUPTIBLE" then
|
||||
if this.endTime then
|
||||
if this.active then
|
||||
SetCastbarShield(this.bar, this.icon, event == "UNIT_SPELLCAST_NOT_INTERRUPTIBLE", this.isChannel)
|
||||
end
|
||||
elseif event == "UNIT_SPELLCAST_DELAYED" or event == "UNIT_SPELLCAST_CHANNEL_UPDATE" then
|
||||
-- Pushback: a cast delayed later or a channel shortened. Following
|
||||
-- Quartz, re-poll just the times and accumulate the shift into a running
|
||||
-- Quartz, re-read just the times and accumulate the shift into a running
|
||||
-- this.delay for the +/- indicator, rather than a full restamp (which
|
||||
-- would reset that total and re-render icon/text). ClassicAPI moves
|
||||
-- endMs (SpellDelayed_h bumps g_cast.endMs; the MSG_CHANNEL_UPDATE
|
||||
-- co-hook rewrites g_channel.endMs) while startMs stays put, so we diff
|
||||
-- endMs. delay is a positive magnitude; OnUpdate signs it "+" for casts
|
||||
-- and "-" for channels. Skipped during a tradeskill merge.
|
||||
if this.endTime and not this.tradeskillTotal then
|
||||
local startMs, endMs
|
||||
-- would reset that total and re-render icon/text). Pushback moves the
|
||||
-- end time while the start stays put, so we diff the end. delay is a
|
||||
-- positive magnitude; UpdateTimerText signs it "+" for casts and "-"
|
||||
-- for channels. Skipped during a tradeskill merge.
|
||||
if this.active and not this.tradeskillTotal then
|
||||
local duration
|
||||
if this.isChannel then
|
||||
local _, _, _, s, e = C_Spell.UnitChannelInfo(unit)
|
||||
startMs, endMs = s, e
|
||||
duration = UnitChannelDuration(unit)
|
||||
else
|
||||
local _, _, _, s, e = C_Spell.UnitCastingInfo(unit)
|
||||
startMs, endMs = s, e
|
||||
duration = UnitCastingDuration(unit)
|
||||
end
|
||||
if startMs and endMs then
|
||||
local shift = this.isChannel and (this.endTime - endMs) or (endMs - this.endTime)
|
||||
this.delay = (this.delay or 0) + shift / 1000
|
||||
this.startTime = startMs
|
||||
this.endTime = endMs
|
||||
local newDuration = (endMs - startMs) / 1000
|
||||
this.bar:SetMinMaxValues(0, newDuration)
|
||||
this.lastMax = newDuration
|
||||
if duration then
|
||||
local shift = duration:GetEndTime() - this.duration:GetEndTime()
|
||||
this.delay = this.delay + (this.isChannel and -shift or shift)
|
||||
this.duration:Assign(duration)
|
||||
UpdateTimerText(this)
|
||||
ArmExpiry(this)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
+2
-14
@@ -701,12 +701,6 @@ pfUI:RegisterModule("chat", function ()
|
||||
local r,g,b = GetStringColor(C.chat.text.unknowncolor)
|
||||
local unknowncolorhex = rgbhex(r,g,b)
|
||||
|
||||
local function GetPlayerLevel(name)
|
||||
if not pfUI_playerDB then return nil end
|
||||
if not pfUI_playerDB[name] then return nil end
|
||||
return pfUI_playerDB[name].level
|
||||
end
|
||||
|
||||
-- the sender of the line AddMessage is reading, from its chat event
|
||||
local lineSender, lineSenderClass, lineSenderRace, lineSenderSex
|
||||
|
||||
@@ -727,10 +721,7 @@ pfUI:RegisterModule("chat", function ()
|
||||
else
|
||||
_, class, _, raceKey, sex = C_PlayerCache.GetPlayerInfoByName(real)
|
||||
end
|
||||
if not class then
|
||||
class = GetUnitInfo(real)
|
||||
end
|
||||
if class and class ~= UNKNOWN then
|
||||
if class then
|
||||
color = "|c" .. PFUI_CLASS_COLORS[class].colorStr
|
||||
if C.chat.text.factionicons == "1" then
|
||||
icon = GetFactionIcon(raceKey)
|
||||
@@ -745,11 +736,8 @@ pfUI:RegisterModule("chat", function ()
|
||||
|
||||
local suffix = ""
|
||||
local level = C.chat.text.playerlevel == "1" and GetPlayerLevel(real)
|
||||
if level and level > 0 then
|
||||
if level then
|
||||
suffix = " " .. rgbhex(GetDifficultyColor(level)) .. level .. "|r"
|
||||
elseif level then
|
||||
-- Show ?? for unknown levels (e.g. -1 from UnitLevel)
|
||||
suffix = " |cffff0000??|r"
|
||||
end
|
||||
|
||||
if color == "" and suffix == "" then return link end
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
pfUI:RegisterModule("chatcopy", function ()
|
||||
local f = CreateFrame("Frame")
|
||||
f:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
f:SetScript("OnEvent", function()
|
||||
EventUtil.RegisterOnceFrameEventAndCallback("PLAYER_ENTERING_WORLD", function()
|
||||
if not pfUI.chat then return end
|
||||
|
||||
local button = CreateFrame("Button", "pfChatCopyButton", pfUI.chat.left.panelTop)
|
||||
@@ -99,7 +97,5 @@ pfUI:RegisterModule("chatcopy", function ()
|
||||
|
||||
frame.scroll = scroll
|
||||
end
|
||||
|
||||
this:UnregisterAllEvents()
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -2509,13 +2509,7 @@ pfUI:RegisterModule("combatlog", function ()
|
||||
local buttonName, button, textWidth;
|
||||
local buttonIndex = 1;
|
||||
-- subtract the width of the dropdown button
|
||||
local clogleft, clogright = COMBATLOG:GetRight(), COMBATLOG:GetLeft();
|
||||
local maxWidth;
|
||||
if ( clogleft and clogright ) then
|
||||
maxWidth = (COMBATLOG:GetRight()-COMBATLOG:GetLeft())-31; --Hacky hacky because GetWidth goes crazy when it is docked
|
||||
else
|
||||
maxWidth = COMBATLOG:GetWidth() - 31;
|
||||
end
|
||||
local maxWidth = COMBATLOG:GetUnscaledWidth() - 31;
|
||||
|
||||
local additionalFilterButton = CombatLogQuickButtonFrame.AdditionalFilterButton;
|
||||
|
||||
|
||||
+12
-9
@@ -30,15 +30,15 @@ pfUI:RegisterModule("easteregg", function ()
|
||||
scene.dtext:SetPoint("TOP", 0, -430)
|
||||
scene.dtext:SetText(info and info .. "\n\n" .. exit or exit)
|
||||
|
||||
-- Fade the night in by playing a fade-out backwards. The scene keeps an
|
||||
-- alpha of 1, which comes back when the fade ends.
|
||||
-- Fade the night in. The scene keeps an alpha of 1, which comes back
|
||||
-- when the fade ends.
|
||||
scene.dusk = scene:CreateAnimationGroup()
|
||||
local fade = scene.dusk:CreateAnimation("Alpha")
|
||||
fade:SetChange(-1)
|
||||
fade:SetToAlpha(1)
|
||||
fade:SetDuration(.8)
|
||||
|
||||
scene:SetScript("OnShow", function()
|
||||
this.dusk:Play(true)
|
||||
this.dusk:Play()
|
||||
end)
|
||||
|
||||
-- start over on the next AFK
|
||||
@@ -159,7 +159,7 @@ pfUI:RegisterModule("easteregg", function ()
|
||||
halloween.text:SetTextColor(1, .5, 0)
|
||||
|
||||
-- Candlelight glows in from the screen edges. It flickers in uneven
|
||||
-- steps of { duration, change } that end where they began, so the loop
|
||||
-- steps of { duration, alpha } that end where they began, so the loop
|
||||
-- never jumps.
|
||||
local candle = CreateFrame("Frame", nil, halloween)
|
||||
candle:SetAllPoints()
|
||||
@@ -169,16 +169,19 @@ pfUI:RegisterModule("easteregg", function ()
|
||||
candle.flicker = candle:CreateAnimationGroup()
|
||||
candle.flicker:SetLooping("REPEAT")
|
||||
local steps = {
|
||||
{ .18, -.25 }, { .09, .1 }, { .22, -.2 }, { .14, .3 }, { .3, -.1 },
|
||||
{ .11, -.15 }, { .2, .2 }, { .16, -.3 }, { .26, .25 }, { .12, .15 },
|
||||
{ .18, .75 }, { .09, .85 }, { .22, .65 }, { .14, .95 }, { .3, .85 },
|
||||
{ .11, .7 }, { .2, .9 }, { .16, .6 }, { .26, .85 }, { .12, 1 },
|
||||
}
|
||||
local from = 1
|
||||
for order, step in ipairs(steps) do
|
||||
local duration, change = unpack(step)
|
||||
local duration, alpha = unpack(step)
|
||||
local fade = candle.flicker:CreateAnimation("Alpha")
|
||||
fade:SetOrder(order)
|
||||
fade:SetDuration(duration)
|
||||
fade:SetChange(change)
|
||||
fade:SetFromAlpha(from)
|
||||
fade:SetToAlpha(alpha)
|
||||
fade:SetSmoothing("IN_OUT")
|
||||
from = alpha
|
||||
end
|
||||
|
||||
-- Once the night has fallen, undead rise along the bottom one after
|
||||
|
||||
+79
-84
@@ -84,11 +84,6 @@ pfUI:RegisterModule("energytick", function()
|
||||
return
|
||||
end
|
||||
|
||||
-- inside the module body on purpose: C is on pfUI.env, not _G
|
||||
local function getBarWidth()
|
||||
return C.unitframes.player.pwidth ~= "-1" and C.unitframes.player.pwidth or C.unitframes.player.width
|
||||
end
|
||||
|
||||
local rawborder, default_border = GetBorderSize("unitframes")
|
||||
local cbtexture = pfUI.media[C.appearance.castbar.texture]
|
||||
|
||||
@@ -128,8 +123,13 @@ pfUI:RegisterModule("energytick", function()
|
||||
return true
|
||||
end
|
||||
|
||||
local energytick = CreateFrame("Frame", nil, pfUI.uf.player.power.bar)
|
||||
-- the bar sweeps its fill over one tick period from a duration object; the
|
||||
-- fill is invisible and carries the spark on its edge
|
||||
local energytick = CreateFrame("StatusBar", nil, pfUI.uf.player.power.bar)
|
||||
energytick:SetAllPoints(pfUI.uf.player.power.bar)
|
||||
energytick:SetColorFill(1, 1, 1, 0)
|
||||
energytick.sweep = C_DurationUtil.CreateDuration()
|
||||
energytick:SetTimerDuration(energytick.sweep, Enum.StatusBarInterpolation.Immediate, Enum.StatusBarTimerDirection.ElapsedTime)
|
||||
energytick:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
energytick:RegisterUnitEvent("UNIT_DISPLAYPOWER", "player")
|
||||
energytick:RegisterUnitEvent("UNIT_POWER_UPDATE", "player")
|
||||
@@ -138,21 +138,61 @@ pfUI:RegisterModule("energytick", function()
|
||||
energytick:RegisterEvent("SPELLS_CHANGED")
|
||||
energytick:RegisterEvent("PLAYER_AURAS_CHANGED")
|
||||
|
||||
-- the spark hides until a tick is seen, and dims while the rule is up and
|
||||
-- nothing has ticked inside it yet
|
||||
local function UpdateRule()
|
||||
local fsrUp = energytick.mode == "MANA" and energytick.fsr:IsActive()
|
||||
energytick.fsrbar:SetShown(fsrUp and energytick:IsShown() and C.unitframes.player.showfsr == "1")
|
||||
energytick.spark:SetAlpha(not energytick.start and 0 or (fsrUp and not energytick.fsrGain) and .4 or 1)
|
||||
end
|
||||
|
||||
-- the window closed without being re-armed
|
||||
local function RuleEnd()
|
||||
energytick.fsrSpell, energytick.fsrGain = nil, nil
|
||||
energytick.fsr:Reset()
|
||||
UpdateRule()
|
||||
end
|
||||
|
||||
local function ArmRule()
|
||||
energytick.fsr:SetTimeFromStart(GetTime(), FIVE_SECOND_RULE)
|
||||
if energytick.ruletimer then energytick.ruletimer:Cancel() end
|
||||
energytick.ruletimer = C_Timer.NewTimer(FIVE_SECOND_RULE, RuleEnd)
|
||||
end
|
||||
|
||||
-- sweeps the period that holds now and wakes at its end. Rolls over by
|
||||
-- whole periods, not from now: restarting bakes timer overshoot into the
|
||||
-- phase as drift the lock then has to chase. Runs only while shown; a
|
||||
-- hidden bar keeps its phase and catches up as it shows.
|
||||
local Sweep
|
||||
local function Wrap() Sweep() end
|
||||
function Sweep()
|
||||
if energytick.wrap then energytick.wrap:Cancel() end
|
||||
if not energytick.start or not energytick:IsShown() then return end
|
||||
|
||||
local now = GetTime()
|
||||
while now - energytick.start >= energytick.max do
|
||||
energytick.start = energytick.start + energytick.max * math.floor((now - energytick.start) / energytick.max)
|
||||
energytick.max = getAdjustedTickTimer()
|
||||
end
|
||||
|
||||
energytick.sweep:SetTimeFromStart(energytick.start, energytick.max)
|
||||
energytick.wrap = C_Timer.NewTimer(energytick.start + energytick.max - now, Wrap)
|
||||
end
|
||||
|
||||
energytick:SetScript("OnEvent", function()
|
||||
if UnitPowerType("player") == Enum.PowerType.Mana and C.unitframes.player.manatick == "1" then
|
||||
this.mode = "MANA"
|
||||
this:Show()
|
||||
elseif UnitPowerType("player") == Enum.PowerType.Energy and C.unitframes.player.energy == "1" then
|
||||
this.mode = "ENERGY"
|
||||
this:Show()
|
||||
else
|
||||
this.mode = nil
|
||||
this:Hide()
|
||||
end
|
||||
|
||||
-- mana regen stops showing at full mana
|
||||
this:SetShown(this.mode and not (this.mode == "MANA" and UnitPower("player") >= UnitPowerMax("player")))
|
||||
|
||||
if event == "SPELLS_CHANGED" or event == "PLAYER_AURAS_CHANGED" then
|
||||
energyRegenTimeMod = nil
|
||||
return
|
||||
end
|
||||
|
||||
-- a shift swaps the power the gains are measured on
|
||||
@@ -166,18 +206,17 @@ 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
|
||||
ArmRule()
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- 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
|
||||
ArmRule()
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- only the shown power: a cat druid's mana regen is not an energy gain
|
||||
@@ -189,89 +228,31 @@ 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
|
||||
|
||||
-- phase is kept while hidden; OnUpdate catches up by whole periods
|
||||
if this.mode == "MANA" and power >= UnitPowerMax("player") then
|
||||
this:Hide()
|
||||
Sweep()
|
||||
end
|
||||
end
|
||||
|
||||
UpdateRule()
|
||||
end)
|
||||
|
||||
energytick:SetScript("OnUpdate", function()
|
||||
-- Throttle for performance
|
||||
if (this.tick or 0) > GetTime() then
|
||||
return
|
||||
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()
|
||||
end
|
||||
|
||||
if not this.start then
|
||||
this.spark:SetAlpha(0)
|
||||
return
|
||||
end
|
||||
|
||||
if this.mode == "MANA" and UnitPower("player") >= UnitPowerMax("player") then
|
||||
this.spark:SetAlpha(0)
|
||||
return
|
||||
end
|
||||
|
||||
this.current = GetTime() - this.start
|
||||
|
||||
-- roll over by whole periods, not from now: restarting bakes frame
|
||||
-- overshoot into the phase as drift the lock then has to chase
|
||||
if this.current > this.max then
|
||||
this.start = this.start + this.max * math.floor(this.current / this.max)
|
||||
this.max = getAdjustedTickTimer()
|
||||
this.current = GetTime() - this.start
|
||||
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)
|
||||
|
||||
if not C.unitframes.player.pheight then
|
||||
return
|
||||
end
|
||||
|
||||
local pos = getBarWidth() * (this.current / this.max)
|
||||
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,13 +260,27 @@ 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, so it follows it by hand
|
||||
energytick:SetScript("OnShow", function()
|
||||
Sweep()
|
||||
UpdateRule()
|
||||
end)
|
||||
|
||||
energytick:SetScript("OnHide", function()
|
||||
Sweep()
|
||||
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)
|
||||
energytick.spark:SetWidth(C.unitframes.player.pheight + 5)
|
||||
energytick.spark:SetBlendMode("ADD")
|
||||
energytick.spark:SetPoint("CENTER", energytick:GetStatusBarTexture(), "RIGHT")
|
||||
energytick.spark:SetAlpha(0)
|
||||
|
||||
local hookUpdateConfig = pfUI.uf.player.UpdateConfig
|
||||
function pfUI.uf.player.UpdateConfig()
|
||||
|
||||
@@ -768,11 +768,13 @@ pfUI:RegisterModule("equipmentmanager", function()
|
||||
-- Popout arrows follow the EM sidecar by default. With the
|
||||
-- "Always Show Equipment Slot Flyouts" option they follow the paperdoll
|
||||
-- instead, so gear can be swapped without opening the equipment manager.
|
||||
-- IsVisible, not IsShown: closing CharacterFrame fires OnHide on both
|
||||
-- without clearing their own shown flags.
|
||||
local function PopoutsActive()
|
||||
if C.character.inventory.equipflyout == "1" then
|
||||
return PaperDollFrame:IsShown()
|
||||
return PaperDollFrame:IsVisible()
|
||||
end
|
||||
return frame:IsShown()
|
||||
return frame:IsVisible()
|
||||
end
|
||||
|
||||
function UpdatePopouts()
|
||||
|
||||
+13
-26
@@ -136,17 +136,19 @@ pfUI:RegisterModule("firstrun", function ()
|
||||
local f = CreateFirstRunPage()
|
||||
f.text:SetText(T["A new installation of |cff33ffccpf|rUI ships with 4 prebuilt design profiles. Click below if you wish to load one of these profiles."])
|
||||
|
||||
local function LoadProfile(name)
|
||||
_G["pfUI_config"] = CopyTable(pfUI_profiles[name])
|
||||
pfUI_init.selected_profile = name
|
||||
pfUI:LoadConfig()
|
||||
ReloadUI()
|
||||
end
|
||||
|
||||
f.Modern = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
|
||||
f.Modern:SetSize(120, 20)
|
||||
f.Modern:SetPoint("BOTTOM", -65, 100)
|
||||
f.Modern:SetTextColor(1,1,1)
|
||||
f.Modern:SetText("Modern")
|
||||
f.Modern:SetScript("OnClick", function()
|
||||
_G["pfUI_config"] = CopyTable(pfUI_profiles["Modern"])
|
||||
pfUI_init.selected_profile = "Modern"
|
||||
pfUI:LoadConfig()
|
||||
ReloadUI()
|
||||
end)
|
||||
f.Modern:SetScript("OnClick", function() LoadProfile("Modern") end)
|
||||
SkinButton(f.Modern)
|
||||
|
||||
f.Nostalgia = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
|
||||
@@ -154,12 +156,7 @@ pfUI:RegisterModule("firstrun", function ()
|
||||
f.Nostalgia:SetPoint("BOTTOM", 65, 100)
|
||||
f.Nostalgia:SetTextColor(1,1,1)
|
||||
f.Nostalgia:SetText("Nostalgia")
|
||||
f.Nostalgia:SetScript("OnClick", function()
|
||||
_G["pfUI_config"] = CopyTable(pfUI_profiles["Nostalgia"])
|
||||
pfUI_init.selected_profile = "Nostalgia"
|
||||
pfUI:LoadConfig()
|
||||
ReloadUI()
|
||||
end)
|
||||
f.Nostalgia:SetScript("OnClick", function() LoadProfile("Nostalgia") end)
|
||||
SkinButton(f.Nostalgia)
|
||||
|
||||
f.Legacy = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
|
||||
@@ -167,12 +164,7 @@ pfUI:RegisterModule("firstrun", function ()
|
||||
f.Legacy:SetPoint("BOTTOM", 65, 75)
|
||||
f.Legacy:SetTextColor(1,1,1)
|
||||
f.Legacy:SetText("Legacy")
|
||||
f.Legacy:SetScript("OnClick", function()
|
||||
_G["pfUI_config"] = CopyTable(pfUI_profiles["Legacy"])
|
||||
pfUI_init.selected_profile = "Legacy"
|
||||
pfUI:LoadConfig()
|
||||
ReloadUI()
|
||||
end)
|
||||
f.Legacy:SetScript("OnClick", function() LoadProfile("Legacy") end)
|
||||
SkinButton(f.Legacy)
|
||||
|
||||
f.Slim = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
|
||||
@@ -180,12 +172,7 @@ pfUI:RegisterModule("firstrun", function ()
|
||||
f.Slim:SetPoint("BOTTOM", -65, 75)
|
||||
f.Slim:SetTextColor(1,1,1)
|
||||
f.Slim:SetText("Slim")
|
||||
f.Slim:SetScript("OnClick", function()
|
||||
_G["pfUI_config"] = CopyTable(pfUI_profiles["Slim"])
|
||||
pfUI_init.selected_profile = "Slim"
|
||||
pfUI:LoadConfig()
|
||||
ReloadUI()
|
||||
end)
|
||||
f.Slim:SetScript("OnClick", function() LoadProfile("Slim") end)
|
||||
SkinButton(f.Slim)
|
||||
|
||||
f.Slider = CreateFrame("Slider", "pfFirstRunWizardScaleSlider", f, "OptionsSliderTemplate")
|
||||
@@ -196,14 +183,14 @@ pfUI:RegisterModule("firstrun", function ()
|
||||
f.Slider:SetSize(240, 20)
|
||||
f.Slider:SetPoint("BOTTOM", 0, 50)
|
||||
f.Slider:SetOrientation('HORIZONTAL')
|
||||
f.Slider:SetMinMaxValues(0.5, 2.0)
|
||||
-- the game drops a uiScale under 0.64 for its automatic scale at login
|
||||
f.Slider:SetMinMaxValues(0.64, 2.0)
|
||||
f.Slider:SetValue(UIParent:GetScale())
|
||||
|
||||
f.Slider:SetScript("OnMouseUp", function()
|
||||
local scale = round(this:GetValue(),2)
|
||||
SetCVar("uiScale", scale)
|
||||
SetCVar("useUiScale", 1)
|
||||
UIParent:SetScale(scale)
|
||||
this:SetValue(scale)
|
||||
end)
|
||||
|
||||
|
||||
+43
-172
@@ -78,7 +78,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
|
||||
-- basic frame
|
||||
local frame = CreateFrame("Frame", nil, this)
|
||||
frame:SetWidth(this.parent:GetRight()-this.parent:GetLeft()-20)
|
||||
frame:SetWidth(this.parent:GetUnscaledWidth()-20)
|
||||
frame:SetHeight(22)
|
||||
frame:SetPoint("TOPLEFT", this, "TOPLEFT", 5, (this.objectCount*-23)-5)
|
||||
|
||||
@@ -130,7 +130,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
category = {}
|
||||
category[config] = tostring(GetCVar(config))
|
||||
ufunc = function()
|
||||
SetCVar(this:GetParent().config, this:GetParent().category[config])
|
||||
SetCVar(config, category[config])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -881,14 +881,6 @@ pfUI:RegisterModule("gui", function ()
|
||||
"35:35",
|
||||
"40:40",
|
||||
},
|
||||
["scaling"] = {
|
||||
"0:" .. T["Off"],
|
||||
"4:" .. T["Huge (PixelPerfect)"],
|
||||
"5:" .. T["Large"],
|
||||
"6:" .. T["Medium"],
|
||||
"7:" .. T["Small"],
|
||||
"8:" .. T["Tiny (PixelPerfect)"],
|
||||
},
|
||||
["abbrevnum"] = {
|
||||
"0:" .. T["Full Numbers (4250)"],
|
||||
"1:" .. T["Abbreviate 2 Decimals (4.25k)"],
|
||||
@@ -981,6 +973,12 @@ pfUI:RegisterModule("gui", function ()
|
||||
"BOTTOMRIGHT:" .. T["Bottom Right"],
|
||||
"off:" .. T["Disabled"]
|
||||
},
|
||||
["cooldown_timers"] = {
|
||||
"off:" .. T["None"],
|
||||
"text:" .. T["Numbers"],
|
||||
"sweep:" .. T["Sweep"],
|
||||
"both:" .. T["Numbers And Sweep"]
|
||||
},
|
||||
["uf_debuff_indicator"] = {
|
||||
"0:" .. T["Disabled"],
|
||||
"1:" .. T["Legacy"],
|
||||
@@ -1502,7 +1500,24 @@ pfUI:RegisterModule("gui", function ()
|
||||
|
||||
CreateConfig(nil, T["Settings"], nil, nil, "header")
|
||||
CreateConfig(nil, T["Language"], C.global, "language", "dropdown", pfUI.gui.dropdowns.languages)
|
||||
CreateConfig(U["pixelperfect"], T["Enable UI-Scale"], C.global, "pixelperfect", "dropdown", pfUI.gui.dropdowns.scaling)
|
||||
-- the game's own scale options, as in its Video Options; the list keeps
|
||||
-- a value set there that is none of these steps
|
||||
CreateConfig(nil, T["Use UI-Scale"], "CVAR", "useUiScale", "checkbox")
|
||||
CreateConfig(nil, T["UI-Scale"], "CVAR", "uiScale", "dropdown", function()
|
||||
local current = GetCVar("uiScale")
|
||||
local values, found = {}, nil
|
||||
for _, scale in ipairs({ .64, .65, .7, .75, .8, .85, .9, .95, 1, 1.1, 1.2, 1.3, 1.4, 1.5 }) do
|
||||
if math.abs(scale - tonumber(current)) < .001 then
|
||||
found = true
|
||||
table.insert(values, current .. ":" .. scale)
|
||||
else
|
||||
table.insert(values, tostring(scale))
|
||||
end
|
||||
end
|
||||
if not found then table.insert(values, 1, current .. ":" .. round(tonumber(current), 2)) end
|
||||
return values
|
||||
end)
|
||||
CreateConfig(nil, string.format(T["Pixel Perfect UI-Scale: %s (Overrides UI-Scale)"], round(PixelUtil.GetPixelToUIUnitFactor(), 2)), C.global, "pixelperfect", "checkbox")
|
||||
CreateConfig(nil, T["Use Original Game Fonts"], C.global, "font_blizzard", "checkbox")
|
||||
CreateConfig(nil, T["Enable Region Compatible Font"], C.global, "force_region", "checkbox")
|
||||
CreateConfig(nil, T["Standard Text Font"], C.global, "font_default", "dropdown", pfUI.gui.dropdowns.fonts)
|
||||
@@ -1579,8 +1594,6 @@ pfUI:RegisterModule("gui", function ()
|
||||
CreateConfig(nil, T["Frame Shadow Intensity"], C.appearance.border, "shadow_intensity", "dropdown", pfUI.gui.dropdowns.uf_debuff_indicator_size)
|
||||
CreateConfig(nil) -- spacer
|
||||
CreateConfig(nil, T["Force Blizzard Borders (|cffffaaaaExperimental|r)"], C.appearance.border, "force_blizz", "checkbox")
|
||||
CreateConfig(nil, T["Enable Pixel Perfect Borders"], C.appearance.border, "pixelperfect", "checkbox")
|
||||
CreateConfig(nil, T["Scale Border On HiDPI Displays"], C.appearance.border, "hidpi", "checkbox")
|
||||
CreateConfig(nil) -- spacer
|
||||
CreateConfig(nil, T["Global Border Size"], C.appearance.border, "default", "dropdown", pfUI.gui.dropdowns.border)
|
||||
CreateConfig(nil, T["Action Bar Border Size"], C.appearance.border, "actionbars", "dropdown", pfUI.gui.dropdowns.border)
|
||||
@@ -1597,23 +1610,6 @@ pfUI:RegisterModule("gui", function ()
|
||||
end)
|
||||
|
||||
CreateGUIEntry(T["Settings"], T["Cooldown"], function()
|
||||
-- every kind of cooldown CreateCooldown makes, as C.cooldown groups.
|
||||
-- Other addons' cooldowns only lose numbers or sweep (see
|
||||
-- api/cooldown.lua), so giving them back takes a reload
|
||||
local kinds = {
|
||||
{ "actionbar", T["Action Bars"] },
|
||||
{ "bags", T["Bags"] },
|
||||
{ "blizzard", T["Spellbook And Character"] },
|
||||
{ "unitframe", T["Unit Frame Auras"] },
|
||||
{ "indicator", T["Buff Indicators"] },
|
||||
{ "nameplate", T["Nameplate Debuffs"] },
|
||||
{ "buff", T["Player Buffs"] },
|
||||
{ "tooltip", T["Tooltip Auras"] },
|
||||
{ "totem", T["Totems"] },
|
||||
{ "lossofcontrol", T["Loss Of Control"] },
|
||||
{ "foreign", T["Other Addons"] },
|
||||
}
|
||||
|
||||
CreateConfig(nil, COUNTDOWN_FOR_COOLDOWNS_TEXT, "CVAR", "countdownForCooldowns", "checkbox")
|
||||
CreateConfig(UpdateCooldowns, T["Font"], C.cooldown, "font", "dropdown", pfUI.gui.dropdowns.fonts)
|
||||
CreateConfig(nil, T["Font Size"], C.cooldown, "font_size")
|
||||
@@ -1626,22 +1622,14 @@ pfUI:RegisterModule("gui", function ()
|
||||
CreateConfig(UpdateCooldowns, T["Cooldown Color (Hours)"], C.cooldown, "hourcolor", "color")
|
||||
CreateConfig(UpdateCooldowns, T["Cooldown Color (Days)"], C.cooldown, "daycolor", "color")
|
||||
|
||||
CreateConfig(nil, T["Show Numbers On"], nil, nil, "header")
|
||||
for _, kind in ipairs(kinds) do
|
||||
CreateConfig(kind[1] ~= "foreign" and UpdateCooldowns or nil, kind[2], C.cooldown[kind[1]], "text", "checkbox")
|
||||
end
|
||||
|
||||
CreateConfig(nil, T["Show Sweep On"], nil, nil, "header")
|
||||
for _, kind in ipairs(kinds) do
|
||||
CreateConfig(kind[1] ~= "foreign" and UpdateCooldowns or nil, kind[2], C.cooldown[kind[1]], "animation", "checkbox")
|
||||
end
|
||||
|
||||
CreateConfig(nil, T["Reverse Sweep On"], nil, nil, "header")
|
||||
for _, kind in ipairs(kinds) do
|
||||
if kind[1] ~= "foreign" then
|
||||
CreateConfig(UpdateCooldowns, kind[2], C.cooldown[kind[1]], "reverse", "checkbox")
|
||||
end
|
||||
end
|
||||
-- the timers of cooldowns no other page covers. Other addons' cooldowns
|
||||
-- only lose numbers or sweep (see api/cooldown.lua), so giving them
|
||||
-- back takes a reload
|
||||
local timers = pfUI.gui.dropdowns.cooldown_timers
|
||||
CreateConfig(nil, T["Timers"], nil, nil, "header")
|
||||
CreateConfig(UpdateCooldowns, T["Spellbook And Character"], C.cooldown, "blizzard_timers", "dropdown", timers)
|
||||
CreateConfig(UpdateCooldowns, T["Loss Of Control"], C.cooldown, "lossofcontrol_timers", "dropdown", timers)
|
||||
CreateConfig(nil, T["Other Addons"], C.cooldown, "foreign_timers", "dropdown", timers)
|
||||
end)
|
||||
|
||||
CreateGUIEntry(T["Settings"], T["Screenshot"], function()
|
||||
@@ -1665,71 +1653,6 @@ pfUI:RegisterModule("gui", function ()
|
||||
end)
|
||||
|
||||
-- Throttling Menu
|
||||
CreateGUIEntry(T["Throttling"], T["Nameplates"], function()
|
||||
local header = CreateConfig(nil, T["Nameplate Update Rate"], nil, nil, "header")
|
||||
header:GetParent().objectCount = header:GetParent().objectCount - 1
|
||||
header:SetHeight(20)
|
||||
|
||||
local castbarCustom
|
||||
|
||||
CreateConfig(function()
|
||||
if castbarCustom and castbarCustom.input then
|
||||
local isCustom = pfUI.throttle:IsCustom("nameplates_castbar")
|
||||
if not isCustom then
|
||||
castbarCustom.input:EnableMouse(false)
|
||||
castbarCustom.input:EnableKeyboard(false)
|
||||
castbarCustom.input:ClearFocus()
|
||||
castbarCustom.input:SetTextColor(.5,.5,.5,1)
|
||||
castbarCustom.input:SetText(tostring(pfUI.throttle:GetFps("nameplates_castbar")))
|
||||
else
|
||||
castbarCustom.input:EnableMouse(true)
|
||||
castbarCustom.input:EnableKeyboard(true)
|
||||
castbarCustom.input:SetTextColor(.2,1,.8,1)
|
||||
if _G.pfUI_throttle.nameplates_castbar_custom then
|
||||
castbarCustom.input:SetText(_G.pfUI_throttle.nameplates_castbar_custom)
|
||||
end
|
||||
end
|
||||
end
|
||||
end, T["Castbar Plates"], _G.pfUI_throttle, "nameplates_castbar", "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"],
|
||||
})
|
||||
|
||||
castbarCustom = CreateConfig(nil, T["Custom FPS"], _G.pfUI_throttle, "nameplates_castbar_custom")
|
||||
|
||||
local isCustom = pfUI.throttle:IsCustom("nameplates_castbar")
|
||||
if not isCustom then
|
||||
castbarCustom.input:EnableMouse(false)
|
||||
castbarCustom.input:EnableKeyboard(false)
|
||||
castbarCustom.input:SetTextColor(.5,.5,.5,1)
|
||||
castbarCustom.input:SetText(tostring(pfUI.throttle:GetFps("nameplates_castbar")))
|
||||
else
|
||||
castbarCustom.input:EnableMouse(true)
|
||||
castbarCustom.input:EnableKeyboard(true)
|
||||
castbarCustom.input:SetTextColor(.2,1,.8,1)
|
||||
if _G.pfUI_throttle.nameplates_castbar_custom then
|
||||
castbarCustom.input:SetText(_G.pfUI_throttle.nameplates_castbar_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("nameplates_castbar")
|
||||
_G.pfUI_throttle.nameplates_castbar_custom = "100"
|
||||
Reload()
|
||||
end, true)
|
||||
end)
|
||||
|
||||
CreateGUIEntry(T["Throttling"], T["Tooltips"], function()
|
||||
local header = CreateConfig(nil, T["Tooltip Update Rate"], nil, nil, "header")
|
||||
header:GetParent().objectCount = header:GetParent().objectCount - 1
|
||||
@@ -1865,67 +1788,6 @@ pfUI:RegisterModule("gui", function ()
|
||||
end, true)
|
||||
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()
|
||||
CreateConfig(nil, T["Disable pfUI Unit Frames"], C.unitframes, "disable", "checkbox")
|
||||
CreateConfig(nil, T["Animate Health And Power Bars"], C.unitframes, "animatebars", "checkbox")
|
||||
@@ -2206,6 +2068,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
CreateConfig(U[c], T["Automatic Class Text Color"], C.unitframes[c], "classcolor", "checkbox")
|
||||
|
||||
CreateConfig(U[c], T["Buffs"], nil, nil, "header")
|
||||
CreateConfig(UpdateCooldowns, T["Buff And Debuff Timers"], C.unitframes[c], "aura_timers", "dropdown", pfUI.gui.dropdowns.cooldown_timers)
|
||||
CreateConfig(U[c], T["Buff Position"], C.unitframes[c], "buffs", "dropdown", pfUI.gui.dropdowns.uf_buff_position)
|
||||
CreateConfig(U[c], T["Buff Size"], C.unitframes[c], "buffsize")
|
||||
CreateConfig(U[c], T["Buff Limit"], C.unitframes[c], "bufflimit")
|
||||
@@ -2239,6 +2102,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
CreateConfig(U[c], T["Buff/Debuff Indicators"], nil, nil, "header")
|
||||
CreateConfig(U[c], T["Enable Indicators"], C.unitframes[c], "buff_indicator", "checkbox")
|
||||
CreateConfig(U[c], T["Show Stacks"], C.unitframes[c], "indicator_stacks", "checkbox")
|
||||
CreateConfig(UpdateCooldowns, T["Indicator Timers"], C.unitframes[c], "indicator_timers", "dropdown", pfUI.gui.dropdowns.cooldown_timers)
|
||||
CreateConfig(U[c], T["Indicator Size"], C.unitframes[c], "indicator_size")
|
||||
CreateConfig(U[c], T["Indicator Spacing"], C.unitframes[c], "indicator_spacing", "dropdown", pfUI.gui.dropdowns.spacing)
|
||||
CreateConfig(U[c], T["Indicator Position"], C.unitframes[c], "indicator_pos", "dropdown", pfUI.gui.dropdowns.positions)
|
||||
@@ -2325,6 +2189,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
CreateConfig(nil, T["Bagslots Per Row"], C.appearance.bags, "bagrowlength")
|
||||
CreateConfig(nil, T["Bankslots Per Row"], C.appearance.bags, "bankrowlength")
|
||||
CreateConfig(nil, T["Item Slot Size"], C.appearance.bags, "icon_size")
|
||||
CreateConfig(UpdateCooldowns, T["Cooldown Timers"], C.appearance.bags, "timers", "dropdown", pfUI.gui.dropdowns.cooldown_timers)
|
||||
CreateConfig(nil, T["Auto Sell Grey Items"], C.global, "autosell", "checkbox")
|
||||
CreateConfig(nil, T["Auto Repair Items"], C.global, "autorepair", "checkbox")
|
||||
CreateConfig(nil, T["Auto Sort When Opening Bags"], C.appearance.bags, "autoSortOnOpen", "checkbox")
|
||||
@@ -2373,6 +2238,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
CreateConfig(U["buff"], T["Number Of Weapon Buffs Per Row"], C.buffs, "wepbuffrowsize")
|
||||
CreateConfig(U["buff"], T["Number Of Buffs Per Row"], C.buffs, "buffrowsize")
|
||||
CreateConfig(U["buff"], T["Number Of Debuffs Per Row"], C.buffs, "debuffrowsize")
|
||||
CreateConfig(UpdateCooldowns, T["Duration Timers"], C.buffs, "timers", "dropdown", pfUI.gui.dropdowns.cooldown_timers)
|
||||
CreateConfig(U["buff"], T["Show Duration Inside Buff"], C.buffs, "textinside", "checkbox")
|
||||
CreateConfig(U["buff"], T["Stack Count Font Size"], C.buffs, "fontsize")
|
||||
end)
|
||||
@@ -2382,6 +2248,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
CreateConfig(U["totems"], T["Icon Size"], C.totems, "iconsize")
|
||||
CreateConfig(U["totems"], T["Spacing"], C.totems, "spacing", "dropdown", pfUI.gui.dropdowns.spacing)
|
||||
CreateConfig(U["totems"], T["Show Background"], C.totems, "showbg", "checkbox")
|
||||
CreateConfig(UpdateCooldowns, T["Duration Timers"], C.totems, "timers", "dropdown", pfUI.gui.dropdowns.cooldown_timers)
|
||||
end)
|
||||
|
||||
CreateGUIEntry(T["Buffs"], T["Player Buff Bar"], function()
|
||||
@@ -2448,6 +2315,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
CreateConfig(U["bars"], T["Self Cast: Right Click"], C.bars, "rightself", "checkbox")
|
||||
CreateConfig(U["bars"], T["Button Animation"], C.bars, "animation", "dropdown", pfUI.gui.dropdowns.actionbuttonanimations)
|
||||
CreateConfig(U["bars"], T["Button Animation Trigger"], C.bars, "animmode", "dropdown", pfUI.gui.dropdowns.animationmode)
|
||||
CreateConfig(UpdateCooldowns, T["Cooldown Timers"], C.bars, "timers", "dropdown", pfUI.gui.dropdowns.cooldown_timers)
|
||||
CreateConfig(U["bars"], T["Show Animation On Hidden Bars"], C.bars, "animalways", "checkbox")
|
||||
CreateConfig(U["bars"], T["Show Reagent Count"], C.bars, "reagents", "checkbox")
|
||||
CreateConfig(U["bars"], T["Highlight Equipped Items"], C.bars, "showequipped", "checkbox")
|
||||
@@ -2458,6 +2326,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
CreateConfig(U["bars"], T["Out Of Mana Color"], C.bars, "oomcolor", "color")
|
||||
CreateConfig(U["bars"], T["Highlight Not Usable Spells"], C.bars, "showna", "checkbox")
|
||||
CreateConfig(U["bars"], T["Not Usable Color"], C.bars, "nacolor", "color")
|
||||
CreateConfig(U["bars"], T["Highlight Proc And Reactive Spells"], C.bars, "procglow", "checkbox")
|
||||
CreateConfig(U["bars"], T["Lock Actionbars"], "UVAR", "LOCK_ACTIONBAR", "checkbox")
|
||||
CreateConfig(U["bars"], T["Always Allow Drag Via Shift Key"], C.bars, "shiftdrag", "checkbox")
|
||||
|
||||
@@ -2677,6 +2546,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
CreateConfig(nil, T["Always Show Health In Percent"], C.tooltip, "alwaysperc", "checkbox")
|
||||
CreateConfig(nil, T["Show Movement Speed"], C.tooltip, "movespeed", "checkbox")
|
||||
CreateConfig(nil, T["Show Unit Buffs"], C.tooltip, "showbuffs", "checkbox")
|
||||
CreateConfig(UpdateCooldowns, T["Unit Buff Timers"], C.tooltip, "aura_timers", "dropdown", pfUI.gui.dropdowns.cooldown_timers)
|
||||
CreateConfig(nil, T["Show Unit IDs"], C.tooltip, "unitid", "checkbox")
|
||||
end)
|
||||
|
||||
@@ -2840,6 +2710,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
CreateConfig(U["nameplates"], T["Debuff Icon Offset"], C.nameplates, "debuffoffset")
|
||||
CreateConfig(U["nameplates"], T["Debuff Icon Size"], C.nameplates, "debuffsize")
|
||||
CreateConfig(U["nameplates"], T["Show Debuff Stacks"], C.nameplates.debuffs, "showstacks", "checkbox")
|
||||
CreateConfig(UpdateCooldowns, T["Debuff Timers"], C.nameplates, "debuff_timers", "dropdown", pfUI.gui.dropdowns.cooldown_timers)
|
||||
|
||||
CreateConfig(U["nameplates"], T["Filter Mode"], C.nameplates.debuffs, "filter", "dropdown", pfUI.gui.dropdowns.buffbarfilter)
|
||||
CreateConfig(U["nameplates"], T["Blacklist"], C.nameplates.debuffs, "blacklist", "list")
|
||||
|
||||
@@ -34,7 +34,7 @@ pfUI:RegisterModule("lossofcontrol", function ()
|
||||
frame.icon.tex = frame.icon:CreateTexture(nil, "ARTWORK")
|
||||
HandleIcon(frame.icon, frame.icon.tex)
|
||||
|
||||
frame.cd = CreateCooldown(frame.icon, "lossofcontrol")
|
||||
frame.cd = CreateCooldown(frame.icon, "timer", C.cooldown, "lossofcontrol_timers")
|
||||
frame.cd:SetAllPoints(frame.icon.tex)
|
||||
|
||||
frame.label = frame:CreateFontString(nil, "OVERLAY")
|
||||
|
||||
@@ -41,7 +41,7 @@ pfUI:RegisterModule("marktracking", function ()
|
||||
|
||||
local function ShortenName(name, row)
|
||||
if not name or name == "" then return "" end
|
||||
local barWidth = row.health:GetWidth()
|
||||
local barWidth = row.health:GetUnscaledWidth()
|
||||
if barWidth < 1 then barWidth = BAR_WIDTH end
|
||||
local available = barWidth - 4
|
||||
if rm_showpct then available = available - 32 end
|
||||
|
||||
+4
-3
@@ -111,15 +111,16 @@ pfUI:RegisterModule("minimap", function ()
|
||||
|
||||
-- Blink ten times between .9 and .1, then hide
|
||||
local highlight = this.highlight
|
||||
highlight:SetAlpha(.9)
|
||||
highlight.blink = highlight:CreateAnimationGroup()
|
||||
for i = 1, 10 do
|
||||
local down = highlight.blink:CreateAnimation("Alpha")
|
||||
down:SetChange(-.8)
|
||||
down:SetFromAlpha(.9)
|
||||
down:SetToAlpha(.1)
|
||||
down:SetDuration(.3)
|
||||
down:SetOrder(i * 2 - 1)
|
||||
local up = highlight.blink:CreateAnimation("Alpha")
|
||||
up:SetChange(.8)
|
||||
up:SetFromAlpha(.1)
|
||||
up:SetToAlpha(.9)
|
||||
up:SetDuration(.3)
|
||||
up:SetOrder(i * 2)
|
||||
end
|
||||
|
||||
@@ -3,20 +3,53 @@ pfUI:RegisterModule("mirrortimers", function ()
|
||||
local fontsize = tonumber(C.global.font_size)
|
||||
local height = fontsize * 1.3
|
||||
|
||||
-- The value of a mirror timer moves by `scale` per second: breath drains at
|
||||
-- -1, and refills faster than that. A running bar fills from a duration
|
||||
-- object that spans the whole bar at that rate, and its text binding shows
|
||||
-- the value as m:ss. A paused bar holds its value.
|
||||
local function Sync(frame)
|
||||
local value = GetMirrorTimerProgress(frame.timer) / 1000
|
||||
local max, scale = frame.maxvalue, frame.scale
|
||||
local label = frame.label:GetText() or ""
|
||||
|
||||
if frame.paused or scale == 0 then
|
||||
frame.statusbar:SetMinMaxValues(0, max)
|
||||
frame.statusbar:SetValue(value)
|
||||
frame.binding:Disable()
|
||||
frame.text:SetFormattedText("%s (%d:%02d)", label, value / 60, value % 60)
|
||||
return
|
||||
end
|
||||
|
||||
-- the shown value is the seconds of the duration times the rate
|
||||
local rate = math.abs(scale)
|
||||
local property
|
||||
if scale < 0 then
|
||||
frame.duration:SetTimeFromEnd(GetTime() + value / rate, max / rate)
|
||||
frame.statusbar:SetTimerDuration(frame.duration, Enum.StatusBarInterpolation.Immediate, Enum.StatusBarTimerDirection.RemainingTime)
|
||||
property = Enum.DurationTextBindingProperty.RemainingDuration
|
||||
else
|
||||
frame.duration:SetTimeFromEnd(GetTime() + (max - value) / rate, max / rate)
|
||||
frame.statusbar:SetTimerDuration(frame.duration, Enum.StatusBarInterpolation.Immediate, Enum.StatusBarTimerDirection.ElapsedTime)
|
||||
property = Enum.DurationTextBindingProperty.ElapsedDuration
|
||||
end
|
||||
|
||||
local Down = Enum.NumericRuleFormatRounding.Down
|
||||
frame.clock:SetBreakpoints({
|
||||
{ threshold = 0, format = "%d:%02d", components = {
|
||||
{ div = 60 / rate, step = 1, rounding = Down },
|
||||
{ div = 1 / rate, mod = 60, step = 1, rounding = Down },
|
||||
} },
|
||||
})
|
||||
frame.binding:SetTextFormat(label .. " ({})", { { property = property, formatter = frame.clock } })
|
||||
frame.binding:Enable()
|
||||
end
|
||||
|
||||
for i = 1, MIRRORTIMER_NUMTIMERS do
|
||||
local frame = _G["MirrorTimer"..i]
|
||||
frame:GetRegions():Hide()
|
||||
frame:SetWidth(200)
|
||||
frame:SetHeight(height)
|
||||
frame:SetScript("OnUpdate", function()
|
||||
if this.paused or not this.timer then return end
|
||||
MirrorTimerFrame_OnUpdate(this, arg1)
|
||||
|
||||
local text = this.label:GetText()
|
||||
if text and this.value then
|
||||
this.text:SetText(format("%s (%d:%02d)", text, this.value/60, this.value - math.floor(this.value/60)*60))
|
||||
end
|
||||
end)
|
||||
frame:SetScript("OnUpdate", nil)
|
||||
|
||||
frame:ClearAllPoints()
|
||||
frame:SetPoint("TOP", UIParent, "TOP", 0, -120-(i-1)*(height + 10))
|
||||
@@ -38,5 +71,34 @@ pfUI:RegisterModule("mirrortimers", function ()
|
||||
frame.text = frame:CreateFontString(nil, "OVERLAY")
|
||||
frame.text:SetFont(font, fontsize, "OUTLINE")
|
||||
frame.text:SetPoint("CENTER", frame.statusbar, "CENTER", 0, 0)
|
||||
|
||||
frame.duration = C_DurationUtil.CreateDuration()
|
||||
frame.clock = C_StringUtil.CreateNumericRuleFormatter()
|
||||
frame.binding = C_DurationUtil.CreateDurationTextBinding()
|
||||
frame.binding:SetFontString(frame.text)
|
||||
frame.binding:SetDuration(frame.duration)
|
||||
|
||||
-- the stock handler has already set the pause state
|
||||
frame:HookScript("OnEvent", function()
|
||||
if event == "MIRROR_TIMER_PAUSE" and this:IsShown() and arg1 == this.timer then
|
||||
Sync(this)
|
||||
end
|
||||
end)
|
||||
|
||||
frame:HookScript("OnHide", function()
|
||||
this.binding:Disable()
|
||||
end)
|
||||
end
|
||||
|
||||
-- the stock function picks the bar and sets its timer, scale and pause state
|
||||
hooksecurefunc("MirrorTimer_Show", function(timer, _, maxvalue)
|
||||
for i = 1, MIRRORTIMER_NUMTIMERS do
|
||||
local frame = _G["MirrorTimer"..i]
|
||||
if frame:IsShown() and frame.timer == timer then
|
||||
frame.maxvalue = maxvalue / 1000
|
||||
Sync(frame)
|
||||
return
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
+100
-126
@@ -82,7 +82,6 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
local threatMemory = {} -- guid -> true once the mob targeted the player
|
||||
local raidGuidCache = {} -- guid -> name of the player's group
|
||||
local offtanks = {}
|
||||
local activeCasts = {} -- overlay -> true while its castbar sweeps
|
||||
local zooming = {} -- overlay -> true while its target zoom animates
|
||||
local auraSlots = {} -- reusable GetAuraSlots buffer for the per-plate aura scan
|
||||
local targetGuid
|
||||
@@ -100,6 +99,7 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
-- Config caching
|
||||
-- ============================================================================
|
||||
local cfg = {}
|
||||
local castFormatter = C_StringUtil.CreateNumericRuleFormatter()
|
||||
local debufffilter, debufflist
|
||||
|
||||
local function DebuffFilterPopulate()
|
||||
@@ -158,7 +158,13 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
cfg.showguildname = N.showguildname == "1"
|
||||
cfg.abbrevname = C.unitframes.abbrevname == "1"
|
||||
cfg.friendclassnamec = N.friendclassnamec == "1"
|
||||
cfg.castbardecimals = C.unitframes.castbardecimals == "1"
|
||||
-- the plate castbars' text bindings hold this formatter, so they pick the
|
||||
-- change up on their next tick
|
||||
if C.unitframes.castbardecimals == "1" then
|
||||
castFormatter:SetBreakpoints({ { threshold = 0, step = .1, rounding = Enum.NumericRuleFormatRounding.Down, format = "%.1f" } })
|
||||
else
|
||||
castFormatter:SetBreakpoints({ { threshold = 0, format = "%.2f" } })
|
||||
end
|
||||
cfg.fullhealth = N.fullhealth == "1"
|
||||
cfg.keeptarget = N.target == "1"
|
||||
cfg.critters = N.critters == "1"
|
||||
@@ -187,8 +193,6 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
cfg.rightclick = N.rightclick == "1"
|
||||
cfg.hlr, cfg.hlg, cfg.hlb, cfg.hla = GetStringColor(N.highlightcolor)
|
||||
cfg.br, cfg.bg, cfg.bb, cfg.ba = GetStringColor(C.appearance.border.color)
|
||||
-- sweep rate of the castbars on plates other than the target's
|
||||
cfg.throttle_castbar = pfUI.throttle:Get("nameplates_castbar")
|
||||
|
||||
local c = combatstate
|
||||
c.CASTING.r, c.CASTING.g, c.CASTING.b, c.CASTING.a = GetStringColor(N.combatcasting)
|
||||
@@ -227,22 +231,23 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
-- One-shot C_Spell poll. Builds the cast struct for a UNIT_SPELLCAST_* event
|
||||
-- (the payload carries no timing) and seeds a plate that binds while its unit
|
||||
-- is already mid-cast (its START fired before the plate existed). Picks cast
|
||||
-- vs channel itself.
|
||||
-- vs channel itself. A cast whose start was never seen has no duration.
|
||||
local function PollCastInfo(unit)
|
||||
local name, _, texture, startMs, endMs, _, _, noInterrupt, spellID = C_Spell.UnitCastingInfo(unit)
|
||||
local isChannel
|
||||
if not name then
|
||||
name, _, texture, startMs, endMs, _, noInterrupt, spellID = C_Spell.UnitChannelInfo(unit)
|
||||
local name, _, texture, _, _, _, _, noInterrupt, spellID = C_Spell.UnitCastingInfo(unit)
|
||||
local duration, isChannel
|
||||
if name then
|
||||
duration = UnitCastingDuration(unit)
|
||||
else
|
||||
name, _, texture, _, _, _, noInterrupt, spellID = C_Spell.UnitChannelInfo(unit)
|
||||
duration = name and UnitChannelDuration(unit)
|
||||
isChannel = true
|
||||
end
|
||||
if not name or not startMs or not endMs then return nil end
|
||||
if not duration then return nil end
|
||||
return {
|
||||
spellName = name,
|
||||
spellID = spellID,
|
||||
icon = texture,
|
||||
startTime = startMs / 1000,
|
||||
endTime = endMs / 1000,
|
||||
duration = (endMs - startMs) / 1000,
|
||||
duration = duration,
|
||||
isChannel = isChannel,
|
||||
noInterrupt = noInterrupt,
|
||||
}
|
||||
@@ -279,7 +284,7 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
local mobTargetGuid = UnitGUID(target)
|
||||
local hasTarget = mobTargetGuid and mobTargetGuid ~= NULL_GUID
|
||||
local info = castState[guid]
|
||||
local isCasting = info and info.endTime > GetTime()
|
||||
local isCasting = info and not info.duration:HasExpired()
|
||||
local targetingPlayer = hasTarget and UnitIsUnit(target, "player")
|
||||
|
||||
if targetingPlayer then
|
||||
@@ -487,8 +492,7 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
local elite = UnitClassification(unit)
|
||||
if level <= 0 then
|
||||
if plate.player then
|
||||
local _, dblevel = GetUnitInfo(plate.rawname)
|
||||
if dblevel and dblevel > 0 then level = dblevel end
|
||||
level = GetPlayerLevel(plate.rawname) or level
|
||||
else
|
||||
-- UnitLevel answers -1 exactly where the engine shows the skull: a
|
||||
-- world boss, or a hostile ten or more levels above the player
|
||||
@@ -671,7 +675,8 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
local function CreateDebuffIcon(plate, index)
|
||||
local icon = CreateFrame("Frame", plate.platename.."Debuff"..index, plate)
|
||||
icon:Hide()
|
||||
icon:SetFrameLevel(4)
|
||||
-- relative: a raised target plate can grow icons too
|
||||
icon:SetFrameLevel(plate.health:GetFrameLevel())
|
||||
|
||||
icon.icon = icon:CreateTexture(nil, "BACKGROUND")
|
||||
icon.icon:SetColorTexture(.3,1,.8,1)
|
||||
@@ -683,8 +688,8 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
icon.stacks:SetJustifyV("BOTTOM")
|
||||
icon.stacks:SetTextColor(1,1,0)
|
||||
|
||||
icon.cd = CreateCooldown(icon, "nameplate", plate.platename.."Debuff"..index.."Cooldown")
|
||||
icon.cd:SetFrameLevel(6)
|
||||
icon.cd = CreateCooldown(icon, "aura", C.nameplates, "debuff_timers", plate.platename.."Debuff"..index.."Cooldown")
|
||||
icon.cd:SetFrameLevel(icon:GetFrameLevel() + 2)
|
||||
|
||||
plate.debuffs[index] = icon
|
||||
end
|
||||
@@ -799,16 +804,26 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
plate:SetAlpha(alpha)
|
||||
end
|
||||
|
||||
local function UpdateStrata(plate)
|
||||
local strata = plate.istarget and "LOW" or "BACKGROUND"
|
||||
if plate.strata == strata then return end
|
||||
plate.strata = strata
|
||||
plate:SetFrameStrata(strata)
|
||||
-- The engine's plates draw in the world frame's stratum, under every UI
|
||||
-- stratum, and the overlay inherits it; a SetFrameStrata would lift it into
|
||||
-- the UI's and over the chat. The target rises above the other plates by
|
||||
-- level instead: raise the engine frame, then re-parent the overlay, which
|
||||
-- moves its whole subtree to the new parent level.
|
||||
local TARGET_RAISE = 20
|
||||
|
||||
local function UpdateStacking(plate)
|
||||
local raised = plate.istarget and true or nil
|
||||
if plate.raised == raised then return end
|
||||
plate.raised = raised
|
||||
local parent = plate.parent
|
||||
parent:SetFrameLevel(plate.baselevel + (raised and TARGET_RAISE or 0))
|
||||
-- SetParent does nothing for the same parent, so it goes through nil
|
||||
plate:SetParent(nil)
|
||||
plate:SetParent(parent)
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
-- Animation driver: castbar sweeps and the target zoom. Shown only while
|
||||
-- something moves.
|
||||
-- Animation driver: the target zoom. Shown only while a plate zooms.
|
||||
-- ============================================================================
|
||||
local driver = CreateFrame("Frame", nil, UIParent)
|
||||
driver:Hide()
|
||||
@@ -829,98 +844,8 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
driver:Show()
|
||||
end
|
||||
|
||||
-- Skip SetText when the rounded value hasn't changed since last frame.
|
||||
-- `string.format("%.2f", ...)` allocates a fresh string every call; this
|
||||
-- gate compares cheap integers and only formats when the displayed value
|
||||
-- would actually differ. Reset via lastEndTime-changed branch below.
|
||||
local function SetCastbarText(castbar, remaining)
|
||||
local rounded
|
||||
if cfg.castbardecimals then
|
||||
rounded = floor(remaining * 10)
|
||||
if castbar.lastTextTick ~= rounded then
|
||||
castbar.lastTextTick = rounded
|
||||
castbar.text:SetText(rounded / 10)
|
||||
end
|
||||
else
|
||||
rounded = floor(remaining * 100)
|
||||
if castbar.lastTextTick ~= rounded then
|
||||
castbar.lastTextTick = rounded
|
||||
castbar.text:SetFormattedText("%.2f", remaining)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function UpdateCastbar(plate, info, now)
|
||||
local castbar = plate.castbar
|
||||
local duration = info.duration
|
||||
if castbar.lastEndTime ~= info.endTime then
|
||||
castbar.lastEndTime = info.endTime
|
||||
castbar.lastTextTick = nil
|
||||
-- Relative 0..duration range to avoid float precision loss with large
|
||||
-- absolute timestamps.
|
||||
castbar:SetMinMaxValues(0, duration)
|
||||
SetCastbarShield(castbar, castbar.icon, info.noInterrupt, info.isChannel)
|
||||
if info.icon then
|
||||
castbar.icon.tex:SetTexture(info.icon)
|
||||
castbar.icon.tex:SetTexCoord(.1,.9,.1,.9)
|
||||
end
|
||||
castbar.spell:SetText(cfg.spellname and info.spellName or "")
|
||||
end
|
||||
|
||||
local value = info.isChannel and (info.endTime - now) or (now - info.startTime)
|
||||
if value < 0 then value = 0 elseif value > duration then value = duration end
|
||||
castbar:SetValue(value)
|
||||
SetCastbarText(castbar, info.endTime - now)
|
||||
if not castbar.isShown then
|
||||
castbar.isShown = true
|
||||
castbar:Show()
|
||||
end
|
||||
end
|
||||
|
||||
function HideCast(plate)
|
||||
activeCasts[plate] = nil
|
||||
local castbar = plate.castbar
|
||||
if castbar.isShown then
|
||||
castbar.isShown = nil
|
||||
castbar.lastEndTime = nil
|
||||
castbar:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
-- Start or stop the plate's castbar from the cast cache and the config.
|
||||
function UpdateCast(plate)
|
||||
local info = castState[plate.guid]
|
||||
if info and cfg.showcastbar and (plate.istarget or not cfg.targetcastbar) then
|
||||
if not activeCasts[plate] then
|
||||
activeCasts[plate] = true
|
||||
plate.casttick = 0
|
||||
driver:Show()
|
||||
end
|
||||
UpdateCastbar(plate, info, GetTime())
|
||||
else
|
||||
HideCast(plate)
|
||||
end
|
||||
end
|
||||
|
||||
driver:SetScript("OnUpdate", function()
|
||||
local now = GetTime()
|
||||
|
||||
-- The target's bar sweeps every frame; the others at the castbar rate.
|
||||
for plate in pairs(activeCasts) do
|
||||
if plate.istarget or plate.casttick + cfg.throttle_castbar <= now then
|
||||
plate.casttick = now
|
||||
local info = castState[plate.guid]
|
||||
if info and info.endTime > now then
|
||||
UpdateCastbar(plate, info, now)
|
||||
else
|
||||
-- ran out without a STOP: treat it as one
|
||||
castState[plate.guid] = nil
|
||||
HideCast(plate)
|
||||
UpdateCombatColor(plate)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for plate in pairs(zooming) do
|
||||
local f = (now - plate.zoomStart) / ZOOM_TIME
|
||||
if f >= 1 then
|
||||
@@ -929,10 +854,57 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
end
|
||||
SetZoom(plate, plate.zoomIn and f or 1 - f)
|
||||
end
|
||||
|
||||
if not next(activeCasts) and not next(zooming) then this:Hide() end
|
||||
if not next(zooming) then this:Hide() end
|
||||
end)
|
||||
|
||||
-- ============================================================================
|
||||
-- Castbars: the bar's timer and its text binding follow the cast's duration
|
||||
-- object on their own. Lua only starts, restyles and stops them.
|
||||
-- ============================================================================
|
||||
local function ShowCast(plate, info)
|
||||
local castbar = plate.castbar
|
||||
castbar:SetTimerDuration(info.duration, Enum.StatusBarInterpolation.Immediate,
|
||||
info.isChannel and Enum.StatusBarTimerDirection.RemainingTime or Enum.StatusBarTimerDirection.ElapsedTime)
|
||||
castbar.timer:SetDuration(info.duration)
|
||||
castbar.timer:Enable()
|
||||
SetCastbarShield(castbar, castbar.icon, info.noInterrupt, info.isChannel)
|
||||
if info.icon then
|
||||
castbar.icon.tex:SetTexture(info.icon)
|
||||
castbar.icon.tex:SetTexCoord(.1,.9,.1,.9)
|
||||
end
|
||||
castbar.spell:SetText(cfg.spellname and info.spellName or "")
|
||||
-- armed exactly while the bar shows
|
||||
if castbar.expiry then castbar.expiry:Cancel() end
|
||||
castbar.expiry = C_Timer.NewTimer(info.duration:GetRemainingDuration(), castbar.onExpire)
|
||||
castbar:Show()
|
||||
end
|
||||
|
||||
function HideCast(plate)
|
||||
local castbar = plate.castbar
|
||||
if not castbar.expiry then return end
|
||||
castbar.expiry:Cancel()
|
||||
castbar.expiry = nil
|
||||
castbar.timer:Disable()
|
||||
castbar:Hide()
|
||||
end
|
||||
|
||||
-- Start or stop the plate's castbar from the cast cache and the config.
|
||||
function UpdateCast(plate)
|
||||
local info = castState[plate.guid]
|
||||
if info and not info.duration:HasExpired() and cfg.showcastbar and (plate.istarget or not cfg.targetcastbar) then
|
||||
ShowCast(plate, info)
|
||||
else
|
||||
HideCast(plate)
|
||||
end
|
||||
end
|
||||
|
||||
-- The bar's cast ran out without a STOP: treat it as one.
|
||||
local function ExpireCast(plate)
|
||||
castState[plate.guid] = nil
|
||||
HideCast(plate)
|
||||
UpdateCombatColor(plate)
|
||||
end
|
||||
|
||||
-- ============================================================================
|
||||
-- Cast events (per plate)
|
||||
-- ============================================================================
|
||||
@@ -957,7 +929,7 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
-- ============================================================================
|
||||
local function SetTarget(plate, istarget)
|
||||
plate.istarget = istarget
|
||||
UpdateStrata(plate)
|
||||
UpdateStacking(plate)
|
||||
UpdateBorder(plate)
|
||||
UpdateLayout(plate)
|
||||
UpdateCombo(plate)
|
||||
@@ -1028,7 +1000,7 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
UpdateLayout(plate)
|
||||
UpdateDebuffs(plate)
|
||||
UpdateCombo(plate)
|
||||
UpdateStrata(plate)
|
||||
UpdateStacking(plate)
|
||||
UpdateAlpha(plate)
|
||||
UpdateCast(plate)
|
||||
if cfg.targetzoom and plate.istarget then StartZoom(plate, true) end
|
||||
@@ -1160,6 +1132,7 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
nameplate.platename = platename
|
||||
nameplate:EnableMouse(false)
|
||||
nameplate.parent = parent
|
||||
nameplate.baselevel = parent:GetFrameLevel()
|
||||
nameplate.cache = {}
|
||||
|
||||
-- Each plate watches its own unit. With RegisterUnitEvent the token IS the
|
||||
@@ -1263,12 +1236,17 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
end
|
||||
end)
|
||||
|
||||
castbar.text = castbar:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
||||
castbar.text = castbar:CreateFontString("Status", "OVERLAY", "GameFontNormal")
|
||||
castbar.text:SetPoint("RIGHT", castbar, "LEFT", -4, 0)
|
||||
castbar.text:SetNonSpaceWrap(false)
|
||||
castbar.text:SetTextColor(1,1,1,.5)
|
||||
|
||||
castbar.spell = castbar:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
||||
castbar.timer = C_DurationUtil.CreateDurationTextBinding()
|
||||
castbar.timer:SetFontString(castbar.text)
|
||||
castbar.timer:SetFormatter(castFormatter)
|
||||
castbar.onExpire = function() ExpireCast(nameplate) end
|
||||
|
||||
castbar.spell = castbar:CreateFontString("Status", "OVERLAY", "GameFontNormal")
|
||||
castbar.spell:SetPoint("CENTER", castbar, "CENTER")
|
||||
castbar.spell:SetNonSpaceWrap(false)
|
||||
castbar.spell:SetTextColor(1,1,1,1)
|
||||
@@ -1359,8 +1337,6 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
nameplate.castbar:SetStatusBarTexture(cbtexture or hptexture)
|
||||
local cbr, cbg, cbb, cba = GetStringColor(C.appearance.castbar.castbarcolor)
|
||||
nameplate.castbar:SetStatusBarColor(cbr, cbg, cbb, cba)
|
||||
-- reset endTime cache so color/texture refresh takes effect on next cast
|
||||
nameplate.castbar.lastEndTime = nil
|
||||
CreateBackdrop(nameplate.castbar, default_border)
|
||||
|
||||
nameplate.castbar.text:SetFont(font, font_size, "OUTLINE")
|
||||
@@ -1639,8 +1615,6 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
local plate = info and plateByGuid[guid]
|
||||
if not plate then return end
|
||||
info.noInterrupt = event == "UNIT_SPELLCAST_NOT_INTERRUPTIBLE"
|
||||
-- UpdateCastbar only restyles on a new cast; force it
|
||||
plate.castbar.lastEndTime = nil
|
||||
UpdateCast(plate)
|
||||
end
|
||||
events.UNIT_SPELLCAST_NOT_INTERRUPTIBLE = events.UNIT_SPELLCAST_INTERRUPTIBLE
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
pfUI:RegisterModule("pixelperfect", function ()
|
||||
-- pre-calculated min values
|
||||
local statics = {
|
||||
[4] = 1.4222222222222,
|
||||
[5] = 1.1377777777778,
|
||||
[6] = 0.94814814814815,
|
||||
[7] = 0.81269841269841,
|
||||
[8] = 0.71111111111111,
|
||||
}
|
||||
|
||||
-- pixel perfect
|
||||
local function pixelperfect()
|
||||
local conf = tonumber(C.global.pixelperfect)
|
||||
if conf < 4 then
|
||||
-- restore gamesettings
|
||||
local scale = GetCVar("uiScale")
|
||||
local use = GetCVar("useUiScale")
|
||||
|
||||
if use == 1 then
|
||||
UIParent:SetScale(tonumber(use))
|
||||
else
|
||||
UIParent:SetScale(.9)
|
||||
end
|
||||
else
|
||||
local scale = conf and statics[conf] or 1
|
||||
|
||||
SetCVar("uiScale", scale)
|
||||
SetCVar("useUiScale", 1)
|
||||
|
||||
UIParent:SetScale(scale)
|
||||
end
|
||||
end
|
||||
|
||||
-- pixelperfect: native UIScale listener
|
||||
if tonumber(C.global.pixelperfect) > 0 then
|
||||
pfUI.events:RegisterFrameEventAndCallback("PLAYER_ENTERING_WORLD", pixelperfect)
|
||||
pixelperfect()
|
||||
end
|
||||
|
||||
pfUI.pixelperfect = {
|
||||
UpdateConfig = pixelperfect
|
||||
}
|
||||
end)
|
||||
@@ -112,18 +112,6 @@ pfUI:RegisterModule("player", function ()
|
||||
UpdateInfoText()
|
||||
end
|
||||
|
||||
-- Add throttle to player frame OnUpdate
|
||||
-- Throttle the unit frame's existing OnUpdate to ~20 FPS so the per-frame
|
||||
-- work stays cheap.
|
||||
if pfUI.uf.player:GetScript("OnUpdate") then
|
||||
local originalOnUpdate = pfUI.uf.player:GetScript("OnUpdate")
|
||||
pfUI.uf.player:SetScript("OnUpdate", function()
|
||||
if (this.throttleTick or 0) > GetTime() then return end
|
||||
this.throttleTick = GetTime() + 0.05
|
||||
originalOnUpdate()
|
||||
end)
|
||||
end
|
||||
|
||||
-- PLAYER_DAMAGE_DONE_MODS fires on the MOD_DAMAGE_DONE fields that
|
||||
-- GetSpellBonusDamage reads, so gear, buffs and talents all reach it.
|
||||
pfUI.events:RegisterFrameEventAndCallback("PLAYER_ENTERING_WORLD", UpdateInfoText)
|
||||
|
||||
+1
-2
@@ -264,8 +264,7 @@ pfUI:RegisterModule("raid", function ()
|
||||
if newGuid ~= oldGuid then
|
||||
-- GUID changed = different player = need full update
|
||||
tracker.frameToGuid[frame] = newGuid
|
||||
frame.update_full = true
|
||||
frame.update_aura = true -- Force aura refresh!
|
||||
pfUI.uf:QueueUpdate(frame, "full")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
+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)
|
||||
|
||||
@@ -5,7 +5,7 @@ pfUI:RegisterModule("socialmod", function ()
|
||||
pfUI.socialmod:SetScript("OnEvent", function()
|
||||
local name = cmatch(arg1, _G.ERR_FRIEND_ONLINE_SS)
|
||||
name = name or cmatch(arg1, _G.ERR_FRIEND_OFFLINE_S)
|
||||
if name and playerdb[name] and playerdb[name].cname then
|
||||
if name and playerdb[name] then
|
||||
playerdb[name].lastseen = date("%a %d-%b-%Y")
|
||||
end
|
||||
end)
|
||||
@@ -92,7 +92,6 @@ pfUI:RegisterModule("socialmod", function ()
|
||||
local cname = ccolor:WrapTextInColorCode(name)
|
||||
if playerdb[name] then
|
||||
playerdb[name].lastseen = date("%a %d-%b-%Y")
|
||||
playerdb[name].cname = cname
|
||||
end
|
||||
|
||||
if friendName then
|
||||
@@ -106,11 +105,13 @@ pfUI:RegisterModule("socialmod", function ()
|
||||
caption:SetVertexColor(1,1,1,.9)
|
||||
friendInfo:SetVertexColor(1,1,1,.9)
|
||||
else
|
||||
if playerdb[name] and playerdb[name].cname and playerdb[name].level and playerdb[name].lastseen then
|
||||
caption:SetFormattedText(TEXT(FRIENDS_LIST_OFFLINE_TEMPLATE), playerdb[name].cname)
|
||||
friendInfo:SetFormattedText(TEXT(FRIENDS_LEVEL_TEMPLATE), playerdb[name].level, playerdb[name].lastseen)
|
||||
local _, class = C_PlayerCache.GetPlayerInfoByName(name)
|
||||
caption:SetFormattedText(TEXT(FRIENDS_LIST_OFFLINE_TEMPLATE), class and PFUI_CLASS_COLORS[class]:WrapTextInColorCode(name) or name.."|r")
|
||||
|
||||
local entry = playerdb[name]
|
||||
if entry and entry.level and entry.lastseen then
|
||||
friendInfo:SetFormattedText(TEXT(FRIENDS_LEVEL_TEMPLATE), entry.level, entry.lastseen)
|
||||
else
|
||||
caption:SetFormattedText(TEXT(FRIENDS_LIST_OFFLINE_TEMPLATE), name.."|r")
|
||||
friendInfo:SetText(TEXT(UNKNOWN))
|
||||
end
|
||||
|
||||
|
||||
+230
-457
@@ -5,14 +5,16 @@ pfUI:RegisterModule("swingtimer", function ()
|
||||
local ON_SWING_QUEUED = 0
|
||||
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)
|
||||
local S = {
|
||||
mhTimer = 0, mhTimerMax = 1,
|
||||
ohTimer = 0, ohTimerMax = 1,
|
||||
raTimer = 0, raTimerMax = 1,
|
||||
mhSpeed = 0, ohSpeed = 0, raSpeed = 0,
|
||||
mhActive = false, ohActive = false, raActive = false,
|
||||
lastMhMarkerX = -1, lastOhMarkerX = -1, lastRaMarkerX = -1,
|
||||
autoAttackActive = false,
|
||||
inCombat = false,
|
||||
hsQueued = false, cleaveQueued = false, maulQueued = false,
|
||||
@@ -21,7 +23,6 @@ pfUI:RegisterModule("swingtimer", function ()
|
||||
isDruid = false,
|
||||
cachedHSSlots = {}, cachedCleaveSlots = {}, cachedMaulSlots = {},
|
||||
useSpellQueueEvent = false,
|
||||
swingThrottle = 0,
|
||||
onSwingCache = {},
|
||||
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 orR, orG, orB = ParseColor(C.unitframes.swingtimeroutrangecolor, 0.5, 0.5, 0.5, 1)
|
||||
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" })
|
||||
|
||||
|
||||
-- Create container frame
|
||||
-- the container keeps the public API
|
||||
pfUI.swingtimer = CreateFrame("Frame", "pfSwingTimer", UIParent)
|
||||
pfUI.swingtimer:SetFrameStrata("MEDIUM")
|
||||
pfUI.swingtimer:Hide()
|
||||
|
||||
-- Mainhand bar
|
||||
pfUI.swingtimer.mainhand = CreateFrame("StatusBar", "pfSwingTimerMainhand", UIParent)
|
||||
pfUI.swingtimer.mainhand:SetPoint("BOTTOM", UIParent, "CENTER", -189, 103)
|
||||
pfUI.swingtimer.mainhand:SetWidth(sw_width)
|
||||
pfUI.swingtimer.mainhand:SetHeight(sw_height)
|
||||
pfUI.swingtimer.mainhand:SetMinMaxValues(0, 1)
|
||||
pfUI.swingtimer.mainhand:SetValue(0)
|
||||
pfUI.swingtimer.mainhand:SetStatusBarTexture(sw_texture)
|
||||
pfUI.swingtimer.mainhand:SetStatusBarColor(mhR, mhG, mhB, mhA)
|
||||
pfUI.swingtimer.mainhand:Hide()
|
||||
-- A bar fills by itself from `swing`, the time span of the whole swing, and
|
||||
-- its text binding counts it down. The marker and its glows ride the edge
|
||||
-- of the fill. `shown` is whether the config lets the bar show at all.
|
||||
local function CreateSwingBar(name, label, shown)
|
||||
local bar = CreateFrame("StatusBar", name, UIParent)
|
||||
bar:SetWidth(sw_width)
|
||||
bar:SetHeight(sw_height)
|
||||
bar:SetStatusBarTexture(sw_texture)
|
||||
bar:Hide()
|
||||
bar.shown = shown
|
||||
|
||||
pfUI.swingtimer.mainhand.text = pfUI.swingtimer.mainhand:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
||||
pfUI.swingtimer.mainhand.text:SetPoint("CENTER", pfUI.swingtimer.mainhand, "CENTER", 0, 0)
|
||||
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
|
||||
bar.swing = C_DurationUtil.CreateDuration()
|
||||
bar:SetTimerDuration(bar.swing, Enum.StatusBarInterpolation.Immediate, Enum.StatusBarTimerDirection.ElapsedTime)
|
||||
|
||||
pfUI.swingtimer.mainhand.label = pfUI.swingtimer.mainhand:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
||||
pfUI.swingtimer.mainhand.label:SetPoint("RIGHT", pfUI.swingtimer.mainhand, "LEFT", -4, 0)
|
||||
pfUI.swingtimer.mainhand.label:SetFont(pfUI.font_default, sw_fontsize, "OUTLINE")
|
||||
pfUI.swingtimer.mainhand.label:SetTextColor(0.8, 0.8, 0.8, 1)
|
||||
pfUI.swingtimer.mainhand.label:SetText(sw_showlabel and "MH" or "")
|
||||
bar.text = bar:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
||||
bar.text:SetPoint("CENTER", bar, "CENTER", 0, 0)
|
||||
bar.text:SetFont(pfUI.font_default, sw_fontsize, "OUTLINE")
|
||||
bar.text:SetTextColor(1, 1, 1, 1)
|
||||
bar.text:SetShown(sw_showtext)
|
||||
|
||||
pfUI.swingtimer.mainhand.speed = pfUI.swingtimer.mainhand:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
||||
pfUI.swingtimer.mainhand.speed:SetPoint("LEFT", pfUI.swingtimer.mainhand, "RIGHT", 4, 0)
|
||||
pfUI.swingtimer.mainhand.speed:SetFont(pfUI.font_default, sw_fontsize, "OUTLINE")
|
||||
pfUI.swingtimer.mainhand.speed:SetTextColor(0.8, 0.8, 0.8, 1)
|
||||
pfUI.swingtimer.mainhand.speed:SetText("")
|
||||
if not sw_showspeed then pfUI.swingtimer.mainhand.speed:Hide() end
|
||||
bar.timer = C_DurationUtil.CreateDurationTextBinding()
|
||||
bar.timer:SetFontString(bar.text)
|
||||
bar.timer:SetDuration(bar.swing)
|
||||
bar.timer:SetFormatter(countdown)
|
||||
|
||||
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")
|
||||
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()
|
||||
CreateBackdrop(bar)
|
||||
|
||||
-- Left glow: fades from transparent to white (right edge = marker)
|
||||
pfUI.swingtimer.mainhand.markerGlowL = pfUI.swingtimer.mainhand:CreateTexture(nil, "OVERLAY")
|
||||
pfUI.swingtimer.mainhand.markerGlowL:SetColorTexture(1, 1, 1, 1)
|
||||
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()
|
||||
bar.edge = CreateFrame("Frame", nil, bar)
|
||||
bar.edge:SetAllPoints(bar)
|
||||
bar.edge:Hide()
|
||||
|
||||
-- Right glow: fades from white to transparent (left edge = marker)
|
||||
pfUI.swingtimer.mainhand.markerGlowR = pfUI.swingtimer.mainhand:CreateTexture(nil, "OVERLAY")
|
||||
pfUI.swingtimer.mainhand.markerGlowR:SetColorTexture(1, 1, 1, 1)
|
||||
pfUI.swingtimer.mainhand.markerGlowR:SetGradientAlpha("HORIZONTAL", 1, 1, 1, 0.35, 1, 1, 1, 0)
|
||||
pfUI.swingtimer.mainhand.markerGlowR:SetWidth(10)
|
||||
pfUI.swingtimer.mainhand.markerGlowR:SetHeight(sw_height)
|
||||
pfUI.swingtimer.mainhand.markerGlowR:Hide()
|
||||
bar.marker = bar.edge:CreateTexture(nil, "OVERLAY")
|
||||
bar.marker:SetColorTexture(1, 1, 1, 1.0)
|
||||
bar.marker:SetWidth(2)
|
||||
bar.marker:SetHeight(sw_height)
|
||||
bar.marker:SetPoint("CENTER", bar:GetStatusBarTexture(), "RIGHT")
|
||||
|
||||
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
|
||||
pfUI.swingtimer.offhand = CreateFrame("StatusBar", "pfSwingTimerOffhand", UIParent)
|
||||
pfUI.swingtimer.offhand:SetPoint("TOP", pfUI.swingtimer.mainhand, "BOTTOM", 0, -4)
|
||||
pfUI.swingtimer.offhand:SetWidth(sw_width)
|
||||
pfUI.swingtimer.offhand:SetHeight(sw_height)
|
||||
pfUI.swingtimer.offhand:SetMinMaxValues(0, 1)
|
||||
pfUI.swingtimer.offhand:SetValue(0)
|
||||
pfUI.swingtimer.offhand:SetStatusBarTexture(sw_texture)
|
||||
pfUI.swingtimer.offhand:SetStatusBarColor(ohR, ohG, ohB, ohA)
|
||||
pfUI.swingtimer.offhand:Hide()
|
||||
-- Right glow: fades from white to transparent (left edge = marker)
|
||||
bar.markerGlowR = bar.edge:CreateTexture(nil, "OVERLAY")
|
||||
bar.markerGlowR:SetColorTexture(1, 1, 1, 1)
|
||||
bar.markerGlowR:SetGradientAlpha("HORIZONTAL", 1, 1, 1, 0.35, 1, 1, 1, 0)
|
||||
bar.markerGlowR:SetWidth(10)
|
||||
bar.markerGlowR:SetHeight(sw_height)
|
||||
bar.markerGlowR:SetPoint("LEFT", bar.marker, "RIGHT", 0, 0)
|
||||
|
||||
pfUI.swingtimer.offhand.text = pfUI.swingtimer.offhand:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
||||
pfUI.swingtimer.offhand.text:SetPoint("CENTER", pfUI.swingtimer.offhand, "CENTER", 0, 0)
|
||||
pfUI.swingtimer.offhand.text:SetFont(pfUI.font_default, sw_fontsize, "OUTLINE")
|
||||
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
|
||||
CreateBackdropShadow(bar)
|
||||
return bar
|
||||
end
|
||||
|
||||
pfUI.swingtimer.offhand.label = pfUI.swingtimer.offhand:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
||||
pfUI.swingtimer.offhand.label:SetPoint("RIGHT", pfUI.swingtimer.offhand, "LEFT", -4, 0)
|
||||
pfUI.swingtimer.offhand.label:SetFont(pfUI.font_default, sw_fontsize, "OUTLINE")
|
||||
pfUI.swingtimer.offhand.label:SetTextColor(0.8, 0.8, 0.8, 1)
|
||||
pfUI.swingtimer.offhand.label:SetText(sw_showlabel and "OH" or "")
|
||||
local mainhand = CreateSwingBar("pfSwingTimerMainhand", "MH", true)
|
||||
mainhand:SetPoint("BOTTOM", UIParent, "CENTER", -189, 103)
|
||||
mainhand.showmarker = true
|
||||
|
||||
pfUI.swingtimer.offhand.speed = pfUI.swingtimer.offhand:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
||||
pfUI.swingtimer.offhand.speed:SetPoint("LEFT", pfUI.swingtimer.offhand, "RIGHT", 4, 0)
|
||||
pfUI.swingtimer.offhand.speed:SetFont(pfUI.font_default, sw_fontsize, "OUTLINE")
|
||||
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
|
||||
local offhand = CreateSwingBar("pfSwingTimerOffhand", "OH", sw_showoh)
|
||||
offhand:SetPoint("TOP", mainhand, "BOTTOM", 0, -4)
|
||||
offhand.showmarker = true
|
||||
|
||||
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
|
||||
-- the reload, then the auto shot deadzone grows back out in the warn color.
|
||||
pfUI.swingtimer.ranged = CreateFrame("StatusBar", "pfSwingTimerRanged", UIParent)
|
||||
pfUI.swingtimer.ranged:SetPoint("BOTTOM", UIParent, "CENTER", -189, 83)
|
||||
pfUI.swingtimer.ranged:SetWidth(sw_width)
|
||||
pfUI.swingtimer.ranged:SetHeight(sw_height)
|
||||
pfUI.swingtimer.ranged:SetMinMaxValues(0, 1)
|
||||
pfUI.swingtimer.ranged:SetValue(0)
|
||||
pfUI.swingtimer.ranged:SetStatusBarTexture(sw_texture)
|
||||
pfUI.swingtimer.ranged:SetStatusBarColor(raR, raG, raB, raA)
|
||||
pfUI.swingtimer.ranged:SetFillStyle(isHunter and "CENTER" or "STANDARD")
|
||||
pfUI.swingtimer.ranged:Hide()
|
||||
-- Each phase is a time span of its own on `phase`.
|
||||
local ranged = CreateSwingBar("pfSwingTimerRanged", "Ra", sw_showranged)
|
||||
ranged:SetPoint("BOTTOM", UIParent, "CENTER", -189, 83)
|
||||
ranged:SetFillStyle(isHunter and "CENTER" or "STANDARD")
|
||||
ranged.showmarker = not isHunter
|
||||
if isHunter then
|
||||
ranged.phase = C_DurationUtil.CreateDuration()
|
||||
ranged.timer:SetDuration(ranged.phase)
|
||||
end
|
||||
|
||||
pfUI.swingtimer.ranged.text = pfUI.swingtimer.ranged:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
||||
pfUI.swingtimer.ranged.text:SetPoint("CENTER", pfUI.swingtimer.ranged, "CENTER", 0, 0)
|
||||
pfUI.swingtimer.ranged.text:SetFont(pfUI.font_default, sw_fontsize, "OUTLINE")
|
||||
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.mainhand = mainhand
|
||||
pfUI.swingtimer.offhand = offhand
|
||||
pfUI.swingtimer.ranged = ranged
|
||||
|
||||
pfUI.swingtimer.ranged.label = pfUI.swingtimer.ranged:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
||||
pfUI.swingtimer.ranged.label:SetPoint("RIGHT", pfUI.swingtimer.ranged, "LEFT", -4, 0)
|
||||
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 "")
|
||||
UpdateMovable(mainhand)
|
||||
UpdateMovable(ranged)
|
||||
|
||||
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
|
||||
-- weapons (22); main-hand-only (21) can never sit there.
|
||||
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
|
||||
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
|
||||
-- localized spell name once, so per-spell classification is rank- and
|
||||
-- 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)
|
||||
end
|
||||
|
||||
-- OnUpdate: countdown all timers with delta, then render
|
||||
pfUI.swingtimer:SetScript("OnUpdate", function()
|
||||
S.swingThrottle = S.swingThrottle + arg1
|
||||
local swingDelay = pfUI.throttle and pfUI.throttle:Get("swingtimer") or 0.02
|
||||
if S.swingThrottle < swingDelay then return end
|
||||
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
|
||||
-- The bar colors follow the queued on-next-swing ability, the range state
|
||||
-- and the hunter deadzone. Runs on the events that change any of them;
|
||||
-- ACTIONBAR_UPDATE_STATE covers the IsCurrentAction reconcile.
|
||||
local function UpdateColors()
|
||||
local r, g, b = mhR, mhG, mhB
|
||||
if sw_hsqueue then
|
||||
if S.isDruid and S.useSpellQueueEvent then
|
||||
S.maulQueued, S.maulSeenCurrent =
|
||||
ReconcileQueued(S.maulQueued, S.cachedMaulSlots, S.maulSeenCurrent)
|
||||
end
|
||||
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
|
||||
local hs, cl = IsHSOrCleaveQueued()
|
||||
if cl then
|
||||
curR, curG, curB = 0.2, 0.9, 0.2
|
||||
r, g, b = 0.2, 0.9, 0.2
|
||||
elseif hs then
|
||||
curR, curG, curB = 0.9, 0.9, 0.2
|
||||
r, g, b = 0.9, 0.9, 0.2
|
||||
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[MAINHAND] then
|
||||
curR, curG, curB = orR, orG, orB
|
||||
if S.outOfRange[OFFHAND] then
|
||||
offhand:SetStatusBarColor(orR, orG, orB, ohA)
|
||||
else
|
||||
offhand:SetStatusBarColor(ohR, ohG, ohB, ohA)
|
||||
end
|
||||
|
||||
if S.mhActive then
|
||||
local progress = 1 - (S.mhTimer / S.mhTimerMax)
|
||||
pfUI.swingtimer.mainhand:SetValue(progress)
|
||||
if S.mhTimer <= 0 then
|
||||
-- Timer expired: hide marker (no gap at right edge)
|
||||
if S.lastMhMarkerX ~= -1 then
|
||||
S.lastMhMarkerX = -1
|
||||
pfUI.swingtimer.mainhand.marker:Hide()
|
||||
pfUI.swingtimer.mainhand.markerGlowL:Hide()
|
||||
pfUI.swingtimer.mainhand.markerGlowR:Hide()
|
||||
end
|
||||
local a
|
||||
if ranged.warn then
|
||||
r, g, b, a = rwR, rwG, rwB, rwA
|
||||
else
|
||||
r, g, b, a = raR, raG, raB, raA
|
||||
end
|
||||
if S.outOfRange[RANGED] then r, g, b = orR, orG, orB end
|
||||
ranged:SetStatusBarColor(r, g, b, a)
|
||||
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
|
||||
local mhMarkerX = progress * sw_width
|
||||
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
|
||||
HunterDeadzone(bar)
|
||||
end
|
||||
pfUI.swingtimer.mainhand:SetStatusBarColor(curR, curG, curB, mhA)
|
||||
if sw_showtext then
|
||||
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
|
||||
else
|
||||
bar.wake = C_Timer.NewTimer(remaining, function() due(bar) end)
|
||||
end
|
||||
|
||||
-- Render OH
|
||||
if sw_showoh and S.ohActive then
|
||||
local progress = 1 - (S.ohTimer / S.ohTimerMax)
|
||||
pfUI.swingtimer.offhand:SetValue(progress)
|
||||
if S.outOfRange[OFFHAND] then
|
||||
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()
|
||||
UpdateColors()
|
||||
if bar.shown then
|
||||
bar.edge:SetShown(bar.showmarker)
|
||||
if sw_showtext then bar.timer:Enable() end
|
||||
bar:Show()
|
||||
end
|
||||
end
|
||||
|
||||
-- Render Ranged
|
||||
if sw_showranged and S.raActive then
|
||||
local remaining = S.raTimer
|
||||
local r, g, b, a = raR, raG, raB, raA
|
||||
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
|
||||
local function StartMH(remaining)
|
||||
UpdateWeaponSpeeds()
|
||||
StartBar(mainhand, remaining, S.mhSpeed, MeleeDue)
|
||||
end
|
||||
|
||||
if not anyActive then
|
||||
if not pfUI.swingtimer.mainhand:IsShown()
|
||||
and not pfUI.swingtimer.offhand:IsShown()
|
||||
and not pfUI.swingtimer.ranged:IsShown() then
|
||||
this:Hide()
|
||||
end
|
||||
end
|
||||
end)
|
||||
local function StartOH(remaining)
|
||||
UpdateWeaponSpeeds()
|
||||
-- The off-hand attack time stays set with a shield equipped
|
||||
if S.ohSpeed <= 0 then return end
|
||||
StartBar(offhand, remaining, S.ohSpeed, MeleeDue)
|
||||
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")
|
||||
events:RegisterEvent("PLAYER_SWING")
|
||||
@@ -658,6 +423,7 @@ pfUI:RegisterModule("swingtimer", function ()
|
||||
events:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||
events:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||
events:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
|
||||
events:RegisterEvent("ACTIONBAR_UPDATE_STATE")
|
||||
events:RegisterEvent("PLAYER_DEAD")
|
||||
events:RegisterUnitEvent("UNIT_SPELLCAST_SENT", "player")
|
||||
events:RegisterUnitEvent("UNIT_SPELLCAST_SUCCEEDED", "player")
|
||||
@@ -682,6 +448,7 @@ pfUI:RegisterModule("swingtimer", function ()
|
||||
-- arg1 = swingType, arg2 = isInRange, arg3 = checksRange; no check
|
||||
-- (no target, nothing to attack, no weapon) is not out of range
|
||||
S.outOfRange[arg1] = arg3 and not arg2
|
||||
UpdateColors()
|
||||
|
||||
elseif event == "UNIT_SPELLCAST_SENT" then
|
||||
-- arg4 = spellID: an on-next-swing ability (HS / Cleave / Maul) queued
|
||||
@@ -689,6 +456,7 @@ pfUI:RegisterModule("swingtimer", function ()
|
||||
if kind then
|
||||
S.useSpellQueueEvent = true
|
||||
SetQueuedKind(kind)
|
||||
UpdateColors()
|
||||
end
|
||||
|
||||
elseif event == "UNIT_SPELLCAST_SUCCEEDED" then
|
||||
@@ -696,6 +464,7 @@ pfUI:RegisterModule("swingtimer", function ()
|
||||
-- the queue, so drop the queued color
|
||||
if IsOnSwingSpell(arg3) then
|
||||
S.hsQueued = false; S.cleaveQueued = false; S.maulQueued = false
|
||||
UpdateColors()
|
||||
end
|
||||
|
||||
elseif event == "SPELL_QUEUE_EVENT" then
|
||||
@@ -707,12 +476,17 @@ pfUI:RegisterModule("swingtimer", function ()
|
||||
elseif eventCode == ON_SWING_QUEUE_POPPED then
|
||||
S.hsQueued = false; S.cleaveQueued = false; S.maulQueued = false
|
||||
end
|
||||
UpdateColors()
|
||||
|
||||
elseif event == "ACTIONBAR_UPDATE_STATE" then
|
||||
if sw_hsqueue then UpdateColors() end
|
||||
|
||||
elseif event == "START_AUTOATTACK" then
|
||||
S.autoAttackActive = true
|
||||
|
||||
elseif event == "STOP_AUTOATTACK" then
|
||||
S.autoAttackActive = false
|
||||
StopWaitingBars()
|
||||
|
||||
elseif event == "PLAYER_ENTERING_WORLD" then
|
||||
local class = UnitClassBase("player")
|
||||
@@ -725,14 +499,8 @@ pfUI:RegisterModule("swingtimer", function ()
|
||||
-- arg1 = changed slot; only weapon slots (main/off/ranged) affect swing speed
|
||||
if not INVSLOTS_EQUIPABLE_IN_COMBAT[arg1] then return end
|
||||
UpdateWeaponSpeeds()
|
||||
if S.ohSpeed == 0 then
|
||||
S.ohActive = false
|
||||
pfUI.swingtimer.offhand:Hide()
|
||||
end
|
||||
if S.raSpeed == 0 then
|
||||
S.raActive = false
|
||||
pfUI.swingtimer.ranged:Hide()
|
||||
end
|
||||
if S.ohSpeed == 0 then StopBar(offhand) end
|
||||
if S.raSpeed == 0 then StopBar(ranged) end
|
||||
|
||||
elseif event == "ACTIONBAR_SLOT_CHANGED" then
|
||||
RebuildQueueSlotCache()
|
||||
@@ -746,12 +514,22 @@ pfUI:RegisterModule("swingtimer", function ()
|
||||
S.hsQueued = false
|
||||
S.cleaveQueued = false
|
||||
S.maulQueued = false
|
||||
UpdateColors()
|
||||
StopWaitingBars()
|
||||
|
||||
elseif event == "PLAYER_DEAD" then
|
||||
ResetAll()
|
||||
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)
|
||||
-- Only available when the swingtimer module is loaded.
|
||||
@@ -763,9 +541,9 @@ pfUI:RegisterModule("swingtimer", function ()
|
||||
-- -------------------------------------------------------------------------
|
||||
pfUI.swingtimer.api = {
|
||||
-- Remaining time in seconds until next swing
|
||||
GetMHTimer = function() return S.mhTimer end,
|
||||
GetOHTimer = function() return S.ohTimer end,
|
||||
GetRangedTimer = function() return S.raTimer end,
|
||||
GetMHTimer = function() return Remaining(mainhand) end,
|
||||
GetOHTimer = function() return Remaining(offhand) end,
|
||||
GetRangedTimer = function() return Remaining(ranged) end,
|
||||
|
||||
-- Weapon speed (full swing duration in seconds)
|
||||
GetMHSpeed = function() return S.mhSpeed end,
|
||||
@@ -773,20 +551,14 @@ pfUI:RegisterModule("swingtimer", function ()
|
||||
GetRangedSpeed = function() return S.raSpeed end,
|
||||
|
||||
-- Whether each timer is currently running
|
||||
IsMHActive = function() return S.mhActive end,
|
||||
IsOHActive = function() return S.ohActive end,
|
||||
IsRangedActive = function() return S.raActive end,
|
||||
IsMHActive = function() return mainhand.active == true end,
|
||||
IsOHActive = function() return offhand.active == true end,
|
||||
IsRangedActive = function() return ranged.active == true end,
|
||||
|
||||
-- Swing progress 0.0 (just reset) to 1.0 (about to swing)
|
||||
GetMHProgress = function()
|
||||
return S.mhActive and S.mhTimerMax > 0 and (1 - S.mhTimer / S.mhTimerMax) or 0
|
||||
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,
|
||||
GetMHProgress = function() return Progress(mainhand) end,
|
||||
GetOHProgress = function() return Progress(offhand) end,
|
||||
GetRangedProgress = function() return Progress(ranged) end,
|
||||
|
||||
-- Warrior HS/Cleave queue state
|
||||
IsHSQueued = function() return S.hsQueued end,
|
||||
@@ -804,4 +576,5 @@ pfUI:RegisterModule("swingtimer", function ()
|
||||
if sw_showranged then EnableRangeCheck(RANGED) end
|
||||
|
||||
UpdateWeaponSpeeds()
|
||||
end)
|
||||
UpdateColors()
|
||||
end)
|
||||
|
||||
@@ -801,11 +801,7 @@ pfUI:RegisterModule("thirdparty-vanilla", function()
|
||||
HookAddon("SortBags", function()
|
||||
if C.thirdparty.sortbags.enable == "0" then return end
|
||||
|
||||
local sort = CreateFrame("Frame", nil)
|
||||
sort:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
sort:SetScript("OnEvent", function()
|
||||
this:UnregisterAllEvents()
|
||||
|
||||
EventUtil.RegisterOnceFrameEventAndCallback("PLAYER_ENTERING_WORLD", function()
|
||||
pfUI.thirdparty.RegisterBagSort("SortBags",
|
||||
function()
|
||||
SortBags()
|
||||
@@ -899,7 +895,7 @@ pfUI:RegisterModule("thirdparty-vanilla", function()
|
||||
|
||||
-- trigger the event whenever SuperMacro got an update
|
||||
hooksecurefunc("SM_UpdateActionSpell", function()
|
||||
for slot=1,120 do pfUI.bars.update[slot] = true end
|
||||
for slot=1,120 do pfUI.bars.QueueSlot(slot) end
|
||||
end)
|
||||
end)
|
||||
|
||||
|
||||
+45
-32
@@ -142,11 +142,7 @@ pfUI:RegisterModule("thirdparty", function()
|
||||
HookAddon("MrPlow", function()
|
||||
if C.thirdparty.mrplow.enable == "0" then return end
|
||||
|
||||
local sort = CreateFrame("Frame", nil)
|
||||
sort:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
sort:SetScript("OnEvent", function()
|
||||
this:UnregisterAllEvents()
|
||||
|
||||
EventUtil.RegisterOnceFrameEventAndCallback("PLAYER_ENTERING_WORLD", function()
|
||||
local MrPlowL = AceLibrary and AceLibrary("AceLocale-2.2"):new("MrPlow")
|
||||
if not (MrPlowL and MrPlowL["Bank"]) then return end
|
||||
|
||||
@@ -373,46 +369,63 @@ pfUI:RegisterModule("thirdparty", function()
|
||||
-- DPSMate Damage Meter
|
||||
-- Vanilla: https://github.com/Geigerkind/DPSMate
|
||||
-- TBC: https://github.com/Geigerkind/DPSMateTBC
|
||||
HookAddon("DPSMate", function()
|
||||
-- DPSMate builds its windows on VARIABLES_LOADED, each named after its
|
||||
-- settings entry, so DPSMate_DPSMate exists only while the first window
|
||||
-- keeps the default name "DPSMate"
|
||||
if not DPSMate_DPSMate then return end
|
||||
-- Repacks ship DPSMate under other folder names, so this waits on login and
|
||||
-- checks DPSMate's globals instead of HookAddon's folder lookup.
|
||||
EventUtil.ContinueOnPlayerLogin(function()
|
||||
if not DPSMate or not DPSMateSettings then return end
|
||||
|
||||
local docktable = { "dpsmate", "DPSMate", "DPSMate_DPSMate",
|
||||
-- DPSMate names each window "DPSMate_<name>" after its settings entry and
|
||||
-- the user can rename it at any time, so the first window is resolved on
|
||||
-- every call
|
||||
local function window()
|
||||
local first = DPSMateSettings.windows and DPSMateSettings.windows[1]
|
||||
return first and _G["DPSMate_"..first.name]
|
||||
end
|
||||
|
||||
local function place(anchor, width)
|
||||
local frame = window()
|
||||
if not frame then return end
|
||||
local name = frame:GetName()
|
||||
|
||||
frame:ClearAllPoints()
|
||||
frame:SetPoint("TOPLEFT", pfUI.chat.right, anchor, 0, 0)
|
||||
frame:SetPoint("BOTTOMRIGHT", pfUI.chat.right, "BOTTOMRIGHT", 0, 0)
|
||||
frame:SetWidth(width)
|
||||
_G[name.."_ScrollFrame"]:ClearAllPoints()
|
||||
_G[name.."_ScrollFrame"]:SetWidth(width)
|
||||
_G[name.."_ScrollFrame"]:SetPoint("TOPLEFT", _G[name.."_Head"], "BOTTOMLEFT", 0, 0)
|
||||
_G[name.."_ScrollFrame"]:SetPoint("BOTTOMRIGHT", pfUI.chat.right, "BOTTOMRIGHT", 0, pfUI.panel.right:GetHeight())
|
||||
_G[name.."_ScrollFrame_Child"]:SetWidth(width)
|
||||
_G[name.."_Resize"]:Hide()
|
||||
end
|
||||
|
||||
local docktable = { "dpsmate", "DPSMate", "DPSMate",
|
||||
function() -- single
|
||||
DPSMate_DPSMate:ClearAllPoints()
|
||||
DPSMate_DPSMate:SetAllPoints(pfUI.chat.right)
|
||||
DPSMate_DPSMate:SetWidth(pfUI.chat.right:GetWidth())
|
||||
DPSMate_DPSMate_ScrollFrame:ClearAllPoints()
|
||||
DPSMate_DPSMate_ScrollFrame:SetWidth(pfUI.chat.right:GetWidth())
|
||||
DPSMate_DPSMate_ScrollFrame:SetPoint("TOPLEFT", DPSMate_DPSMate_Head, "BOTTOMLEFT", 0, 0)
|
||||
DPSMate_DPSMate_ScrollFrame:SetPoint("BOTTOMRIGHT", pfUI.chat.right, "BOTTOMRIGHT", 0, pfUI.panel.right:GetHeight())
|
||||
DPSMate_DPSMate_ScrollFrame_Child:SetWidth(pfUI.chat.right:GetWidth())
|
||||
DPSMate_DPSMate_Resize:Hide()
|
||||
place("TOPLEFT", pfUI.chat.right:GetWidth())
|
||||
end,
|
||||
function() -- dual
|
||||
DPSMate_DPSMate:ClearAllPoints()
|
||||
DPSMate_DPSMate:SetPoint("TOPLEFT", pfUI.chat.right, "TOP", 0, 0)
|
||||
DPSMate_DPSMate:SetPoint("BOTTOMRIGHT", pfUI.chat.right, "BOTTOMRIGHT", 0, 0)
|
||||
DPSMate_DPSMate:SetWidth(pfUI.chat.right:GetWidth() / 2)
|
||||
DPSMate_DPSMate_ScrollFrame:ClearAllPoints()
|
||||
DPSMate_DPSMate_ScrollFrame:SetWidth(pfUI.chat.right:GetWidth() / 2)
|
||||
DPSMate_DPSMate_ScrollFrame:SetPoint("TOPLEFT", DPSMate_DPSMate_Head, "BOTTOMLEFT", 0, 0)
|
||||
DPSMate_DPSMate_ScrollFrame:SetPoint("BOTTOMRIGHT", pfUI.chat.right, "BOTTOMRIGHT", 0, pfUI.panel.right:GetHeight())
|
||||
DPSMate_DPSMate_ScrollFrame_Child:SetWidth(pfUI.chat.right:GetWidth() / 2)
|
||||
DPSMate_DPSMate_Resize:Hide()
|
||||
place("TOP", pfUI.chat.right:GetWidth() / 2)
|
||||
end,
|
||||
function() -- show
|
||||
DPSMate_DPSMate:Show()
|
||||
local frame = window()
|
||||
if frame then frame:Show() end
|
||||
end,
|
||||
function() -- hide
|
||||
DPSMate_DPSMate:Hide()
|
||||
local frame = window()
|
||||
if frame then frame:Hide() end
|
||||
end
|
||||
}
|
||||
|
||||
pfUI.thirdparty.meters:RegisterMeter("damage", docktable)
|
||||
|
||||
-- DPSMate rebuilds its windows at their saved positions whenever its
|
||||
-- settings change, so put the docked one back afterwards
|
||||
hooksecurefunc(DPSMate, "InitializeFrames", function()
|
||||
if pfUI.thirdparty.meters.damage == docktable then
|
||||
pfUI.thirdparty.meters:Resize()
|
||||
end
|
||||
end)
|
||||
|
||||
if C.thirdparty.dpsmate.skin == "1" then
|
||||
if DPSMateSettings then
|
||||
-- set DPSMate appearance to match pfUI
|
||||
|
||||
+1
-1
@@ -216,7 +216,7 @@ pfUI:RegisterModule("tooltip", function ()
|
||||
icon.stacks:SetFont(C.tooltip.font_tooltip, C.tooltip.font_tooltip_size, "OUTLINE")
|
||||
icon.stacks:SetTextColor(1, 1, 1, 1)
|
||||
|
||||
icon.cd = CreateCooldown(icon, "tooltip")
|
||||
icon.cd = CreateCooldown(icon, "aura", C.tooltip, "aura_timers")
|
||||
return icon
|
||||
end
|
||||
|
||||
|
||||
+1
-1
@@ -113,7 +113,7 @@ pfUI:RegisterModule("totems", function ()
|
||||
self.bar[i].cdbg = self.bar[i].cdbg or CreateFrame("Frame", nil, self.bar[i])
|
||||
self.bar[i].cdbg:SetSize(self.iconsize - 3, self.iconsize - 3)
|
||||
self.bar[i].cdbg:SetPoint("CENTER", self.bar[i], "CENTER", 0, 0)
|
||||
self.bar[i].cd = self.bar[i].cd or CreateCooldown(self.bar[i].cdbg, "totem", "pfTotemsBar"..i.."Cooldown")
|
||||
self.bar[i].cd = self.bar[i].cd or CreateCooldown(self.bar[i].cdbg, "aura", C.totems, "timers", "pfTotemsBar"..i.."Cooldown")
|
||||
|
||||
self.bar[i]:RegisterForClicks("LeftButtonUp", "RightButtonUp")
|
||||
self.bar[i]:SetScript("OnClick", self.OnClick)
|
||||
|
||||
@@ -38,7 +38,8 @@ pfUI:RegisterModule("tracking", function ()
|
||||
pfUI.tracking.pulse = pfUI.tracking.icon:CreateAnimationGroup()
|
||||
pfUI.tracking.pulse:SetLooping("BOUNCE")
|
||||
local fade = pfUI.tracking.pulse:CreateAnimation("Alpha")
|
||||
fade:SetChange(-.5)
|
||||
fade:SetFromAlpha(1)
|
||||
fade:SetToAlpha(.5)
|
||||
fade:SetDuration(.5)
|
||||
fade:SetSmoothing("IN_OUT")
|
||||
|
||||
|
||||
+1
-27
@@ -180,33 +180,7 @@ pfUI:RegisterModule("unitxp", function ()
|
||||
CreateTargetIndicators()
|
||||
|
||||
-- Also try on PLAYER_ENTERING_WORLD in case target frame wasn't ready
|
||||
local initFrame = CreateFrame("Frame")
|
||||
initFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
initFrame:RegisterEvent("PLAYER_LOGOUT")
|
||||
initFrame:SetScript("OnEvent", function()
|
||||
-- Handle shutdown to prevent crash 132
|
||||
if event == "PLAYER_LOGOUT" then
|
||||
this:UnregisterAllEvents()
|
||||
this:SetScript("OnEvent", nil)
|
||||
-- Stop indicator OnUpdate scripts
|
||||
if pfUI.uf and pfUI.uf.target then
|
||||
if pfUI.uf.target.behindIndicator then
|
||||
pfUI.uf.target.behindIndicator:SetScript("OnUpdate", nil)
|
||||
end
|
||||
if pfUI.uf.target.distanceIndicator then
|
||||
pfUI.uf.target.distanceIndicator:SetScript("OnUpdate", nil)
|
||||
end
|
||||
-- free-frame mode polls from its own scanner frame, not the indicator
|
||||
if pfUI.uf.target.distanceScanner then
|
||||
pfUI.uf.target.distanceScanner:SetScript("OnUpdate", nil)
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
CreateTargetIndicators()
|
||||
this:UnregisterAllEvents()
|
||||
end)
|
||||
EventUtil.RegisterOnceFrameEventAndCallback("PLAYER_ENTERING_WORLD", CreateTargetIndicators)
|
||||
|
||||
-- OS Notification Support
|
||||
if C.unitframes.unitxp_notify == "1" then
|
||||
|
||||
@@ -37,15 +37,15 @@ pfUI:RegisterModule("unusable", function ()
|
||||
|
||||
-- requirement changes (level, proficiency/skill, required spell, reputation,
|
||||
-- honor rank) don't touch the bags; queue a full rebag through pfUI.bag's
|
||||
-- coalesced delay, whose UpdateSlot resets the tint before we reapply it
|
||||
-- batched updates, whose UpdateSlot resets the tint before we reapply it
|
||||
local function Refresh()
|
||||
for _, bag in pairs(pfUI.BACKPACK) do
|
||||
pfUI.bag.delay.UpdateBag[bag] = true
|
||||
pfUI.bag:QueueBagUpdate(bag)
|
||||
end
|
||||
-- the bank frame is only created on first bank visit
|
||||
if pfUI.bag.left and pfUI.bag.left:IsShown() then
|
||||
for _, bag in pairs(pfUI.BANK) do
|
||||
pfUI.bag.delay.UpdateBag[bag] = true
|
||||
pfUI.bag:QueueBagUpdate(bag)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
+26
-22
@@ -69,11 +69,25 @@ pfUI:RegisterModule("xpbar", function ()
|
||||
self:SetAlpha(1)
|
||||
end
|
||||
|
||||
-- (Re)arm the auto-hide: fade the bar out after delay seconds unless it is
|
||||
-- always shown or under the cursor
|
||||
local function ScheduleFade(self, delay)
|
||||
if self.fadeTimer then self.fadeTimer:Cancel() end
|
||||
self.fadeTimer = nil
|
||||
if self.always or self.hover then return end
|
||||
self.fadeTimer = C_Timer.NewTimer(delay, function()
|
||||
self.fadeTimer = nil
|
||||
if self.hover or self:GetAlpha() == 0 then return end
|
||||
self.fade:Play()
|
||||
end)
|
||||
end
|
||||
|
||||
local function OnLeave(self)
|
||||
local self = self or this
|
||||
|
||||
self.hover = nil
|
||||
self.tick = GetTime() + 3.00
|
||||
if self.text_mouse == "1" then self.bar.text:Hide() end
|
||||
ScheduleFade(self, 3)
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
|
||||
@@ -90,6 +104,9 @@ local function OnEnter(self)
|
||||
end
|
||||
|
||||
self.hover = true
|
||||
if self.fadeTimer then self.fadeTimer:Cancel() end
|
||||
self.fadeTimer = nil
|
||||
if self.text_mouse == "1" then self.bar.text:Show() end
|
||||
Reveal(self)
|
||||
|
||||
if mode == "XP" then
|
||||
@@ -187,21 +204,6 @@ local function OnEnter(self)
|
||||
GameTooltip:Show()
|
||||
end
|
||||
|
||||
local function OnUpdate(self)
|
||||
local self = self or this
|
||||
|
||||
if self.text_mouse == "1" then
|
||||
self.bar.text:SetShown(self.hover)
|
||||
end
|
||||
|
||||
if self.always then return end
|
||||
-- Hover comes from OnEnter/OnLeave, the same mouse focus that reveals the
|
||||
-- bar, so the fade can't restart under the cursor
|
||||
if self:GetAlpha() == 0 or self.hover or self.fade:IsPlaying() then return end
|
||||
if ( self.tick or 1) > GetTime() then return end
|
||||
self.fade:Play()
|
||||
end
|
||||
|
||||
local function OnEvent(self)
|
||||
local self = self or this
|
||||
|
||||
@@ -248,7 +250,7 @@ end
|
||||
if ex then text = "%s: %s%% (%s%% %s)" end
|
||||
self.bar.text:SetFormattedText(text, T["Experience"], xpperc, experc, T["Rested"])
|
||||
|
||||
self.tick = GetTime() + self.timeout
|
||||
ScheduleFade(self, self.timeout)
|
||||
if event == "UPDATE_EXHAUSTION" and GameTooltip:IsOwned(self) then
|
||||
OnEnter(self)
|
||||
end
|
||||
@@ -266,7 +268,7 @@ end
|
||||
local xpperc = nextXP and nextXP ~= 0 and round(currXP / nextXP * 100) or 0
|
||||
self.bar.text:SetFormattedText(text, T["Pet Experience"], xpperc)
|
||||
|
||||
self.tick = GetTime() + self.timeout
|
||||
ScheduleFade(self, self.timeout)
|
||||
return
|
||||
elseif mode == "REP" then
|
||||
self.restedbar:Hide()
|
||||
@@ -294,7 +296,7 @@ end
|
||||
local standing = GetText("FACTION_STANDING_LABEL"..standingID, gender)
|
||||
self.bar.text:SetFormattedText(text, name, perc, standing)
|
||||
|
||||
self.tick = GetTime() + self.timeout
|
||||
ScheduleFade(self, self.timeout)
|
||||
return
|
||||
end
|
||||
end
|
||||
@@ -302,6 +304,9 @@ end
|
||||
self.bar:SetStatusBarColor(.5,.5,.5,1)
|
||||
self.bar:SetMinMaxValues(0, 1)
|
||||
self.bar:SetValue(0)
|
||||
|
||||
-- nothing to show: hide now unless an earlier update is still on display
|
||||
if not self.fadeTimer then ScheduleFade(self, 0) end
|
||||
end
|
||||
|
||||
local function CreateBar(t)
|
||||
@@ -359,7 +364,7 @@ end
|
||||
b.bar.text:SetJustifyH("CENTER")
|
||||
b.bar.text:SetFont(pfUI.font_default, C.global.font_size, "OUTLINE")
|
||||
|
||||
b.bar.text:SetShown(b.text == "1")
|
||||
b.bar.text:SetShown(b.text == "1" and b.text_mouse ~= "1")
|
||||
|
||||
b.restedbar = b.restedbar or CreateFrame("StatusBar", nil, b)
|
||||
b.restedbar:SetStatusBarTexture(pfUI.media[C.panel.xp.texture])
|
||||
@@ -376,10 +381,10 @@ end
|
||||
|
||||
if not b.fade then
|
||||
b.fade = b:CreateAnimationGroup()
|
||||
b.fade:SetToFinalAlpha(true)
|
||||
local fade = b.fade:CreateAnimation("Alpha")
|
||||
fade:SetChange(-1)
|
||||
fade:SetDuration(.3)
|
||||
b.fade:SetScript("OnFinished", function() b:SetAlpha(0) end)
|
||||
end
|
||||
|
||||
b:RegisterEvent("FACTION_STANDING_CHANGED")
|
||||
@@ -392,7 +397,6 @@ end
|
||||
b:RegisterEvent("PLAYER_LEVEL_UP")
|
||||
b:RegisterEvent("UPDATE_FACTION")
|
||||
|
||||
b:SetScript("OnUpdate", OnUpdate)
|
||||
b:SetScript("OnEvent", OnEvent)
|
||||
b:SetScript("OnEnter", OnEnter)
|
||||
b:SetScript("OnLeave", OnLeave)
|
||||
|
||||
@@ -392,6 +392,10 @@ pfUI:SetScript("OnEvent", function()
|
||||
SetupConfigEnvironment()
|
||||
pfUI:UpdateFonts()
|
||||
|
||||
-- scale UIParent before the modules size their borders from it
|
||||
pfUI.api.UpdateUIScale()
|
||||
pfUI.events:RegisterFrameEventAndCallback("UI_SCALE_CHANGED", pfUI.api.UpdateUIScale)
|
||||
|
||||
-- load modules
|
||||
for _, m in pairs(this.modules) do
|
||||
if not ( pfUI_config["disabled"] and pfUI_config["disabled"][m] == "1" ) then
|
||||
@@ -457,15 +461,20 @@ message = function(msg)
|
||||
end
|
||||
print = print or message
|
||||
|
||||
error = function(msg)
|
||||
if PF_DEBUG_MODE then message(debugstack()) end
|
||||
if string.find(msg, "AddOns\\pfUI") then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffcc3333ERROR: |cffff5555".. (msg or "nil" ))
|
||||
elseif not pfUI_config or (pfUI_config.global and pfUI_config.global.errors == "1") then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffcc3333ERROR: |cffff5555".. (msg or "nil" ))
|
||||
-- Errors print to chat: pfUI's own always, other addons' when the errors
|
||||
-- option is on. In debug mode the stack follows, starting at the code that
|
||||
-- raised the error rather than at this handler.
|
||||
seterrorhandler(function(msg)
|
||||
msg = tostring(msg)
|
||||
if PF_DEBUG_MODE then
|
||||
local height = GetErrorCallstackHeight()
|
||||
message(height and debugstack(GetCallstackHeight() - height + 1) or debugstack(2))
|
||||
end
|
||||
end
|
||||
seterrorhandler(error)
|
||||
if string.find(msg, "AddOns\\pfUI") or not pfUI_config
|
||||
or (pfUI_config.global and pfUI_config.global.errors == "1") then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffcc3333ERROR: |cffff5555" .. msg)
|
||||
end
|
||||
end)
|
||||
|
||||
function pfUI.SetupCVars()
|
||||
ClearTutorials()
|
||||
|
||||
@@ -199,7 +199,7 @@ pfUI:RegisterSkin("Character", function ()
|
||||
-- name only while that global is unset, so the global is rebound by
|
||||
-- hand; the Model starts hidden and nothing reaches it after that
|
||||
local cdname = "Character"..slotName.."Cooldown"
|
||||
_G[cdname] = CreateCooldown(frame, "blizzard", cdname)
|
||||
_G[cdname] = CreateCooldown(frame, "spell", C.cooldown, "blizzard_timers", cdname)
|
||||
|
||||
CreateFontString(frame, "scoreText", "OVERLAY", 12)
|
||||
frame.scoreText:SetPoint("TOPRIGHT", 0, 0)
|
||||
|
||||
@@ -5,10 +5,9 @@ pfUI:RegisterSkin("Mailbox", function ()
|
||||
-- Compatibility
|
||||
local StationeryBackgroundLeft, StationeryBackgroundRight
|
||||
do -- SendMailFrame
|
||||
local skin = CreateFrame("Frame")
|
||||
skin:SetScript("OnEvent", function()
|
||||
this:UnregisterEvent("MAIL_SHOW")
|
||||
if not this._Mail then
|
||||
local mailLoaded
|
||||
EventUtil.RegisterOnceFrameEventAndCallback("MAIL_SHOW", function()
|
||||
if not mailLoaded then
|
||||
StripTextures(SendMailPackageButton)
|
||||
SkinButton(SendMailPackageButton, nil, nil, nil, nil, true)
|
||||
|
||||
@@ -26,10 +25,9 @@ pfUI:RegisterSkin("Mailbox", function ()
|
||||
end)
|
||||
end
|
||||
end)
|
||||
skin:RegisterEvent("MAIL_SHOW")
|
||||
|
||||
HookAddon("Mail", function()
|
||||
skin._Mail = true
|
||||
mailLoaded = true
|
||||
for i = 1, 21 do
|
||||
local button = _G["MailAttachment"..i]
|
||||
StripTextures(button)
|
||||
|
||||
@@ -38,9 +38,51 @@ pfUI:RegisterSkin("Options - Interface", function ()
|
||||
elseif ctype == "EditBox" then
|
||||
StripTextures(control, nil, "BACKGROUND")
|
||||
CreateBackdrop(control, nil, true)
|
||||
else
|
||||
elseif ctype == "Button" then
|
||||
-- key binding buttons: UIPanelButtonTemplate2's slices are BACKGROUND
|
||||
StripTextures(control, nil, "BACKGROUND")
|
||||
SkinButton(control)
|
||||
elseif _G[control:GetName() .. "Button"] then
|
||||
SkinDropDown(control, nil, nil, nil, true)
|
||||
end
|
||||
-- a control type without a branch stays unskinned; erroring here would
|
||||
-- stop the loop and leave every later control unskinned too
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
-- the pages scroll with retail's MinimalScrollBar, not the old named
|
||||
-- UIPanelScrollBar, so SkinScrollbar does not fit. Its steppers and thumb set
|
||||
-- their atlas again on every state change, so their art is hidden, not cleared
|
||||
i = 1
|
||||
while _G["ClassicAPIOptionsScrollBar" .. i] do
|
||||
local bar = _G["ClassicAPIOptionsScrollBar" .. i]
|
||||
local thumb = bar.Track.Thumb
|
||||
|
||||
StripTextures(bar)
|
||||
bar.Background:Hide()
|
||||
for _, stepper in ipairs({ bar.Back, bar.Forward }) do
|
||||
stepper.Texture:Hide()
|
||||
stepper.Overlay:SetAlpha(0)
|
||||
end
|
||||
SkinArrowButton(bar.Back, "up")
|
||||
SkinArrowButton(bar.Forward, "down")
|
||||
|
||||
thumb.Begin:Hide()
|
||||
thumb.Middle:Hide()
|
||||
thumb.End:Hide()
|
||||
thumb.thumbTexture:Hide()
|
||||
|
||||
bar.bg = CreateFrame("Frame", nil, bar)
|
||||
bar.bg:SetPoint("TOPLEFT", bar.Back, "BOTTOMLEFT", 0, -3)
|
||||
bar.bg:SetPoint("BOTTOMRIGHT", bar.Forward, "TOPRIGHT", 0, 3)
|
||||
CreateBackdrop(bar.bg, nil, true)
|
||||
|
||||
bar.thumb = bar.bg:CreateTexture(nil, "ARTWORK")
|
||||
bar.thumb:SetColorTexture(.8, .8, .8, .8)
|
||||
bar.thumb:SetPoint("TOP", thumb, "TOP", 0, -4)
|
||||
bar.thumb:SetPoint("BOTTOM", thumb, "BOTTOM", 0, 4)
|
||||
bar.thumb:SetPoint("LEFT", bar.bg, "LEFT", 1, 0)
|
||||
bar.thumb:SetPoint("RIGHT", bar.bg, "RIGHT", -1, 0)
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ pfUI:RegisterSkin("Spellbook", function ()
|
||||
-- the global is rebound by hand; the Model starts hidden and nothing
|
||||
-- reaches it after that
|
||||
local cdname = "SpellButton"..i.."Cooldown"
|
||||
_G[cdname] = CreateCooldown(button, "blizzard", cdname)
|
||||
_G[cdname] = CreateCooldown(button, "spell", C.cooldown, "blizzard_timers", cdname)
|
||||
|
||||
_G["SpellButton"..i.."SubSpellName"]:SetTextColor(1, 1, 1)
|
||||
_G["SpellButton"..i.."AutoCastable"]:SetTexture("Interface\\Buttons\\UI-AutoCastableOverlay")
|
||||
|
||||
Reference in New Issue
Block a user