mirror of
https://github.com/brues-code/pfUI.git
synced 2026-09-22 07:36:56 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 38b4100353 | |||
| f497c71523 |
+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 = 11304 -- (X*10000 + Y*100 + Z)
|
||||
local PFUI_CLASSIC_API_MIN = 11500 -- (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"
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
# pfUI - ClassicAPI Edition
|
||||
|
||||
[](https://octowow.st/)
|
||||
[](https://github.com/brues-code/ClassicAPI)
|
||||
[](https://github.com/brues-code/nampower)
|
||||
[](https://github.com/balakethelock/SuperWoW)
|
||||
[](https://github.com/brues-code/UnitXP_SP3)
|
||||
|
||||
**A pfUI fork specifically optimized for ClassicAPI on [Octo WoW](https://octowow.st/)**
|
||||
|
||||
This version includes significant performance improvements and DLL-enhanced features.
|
||||
|
||||
## Installation
|
||||
@@ -18,7 +15,7 @@ This version includes significant performance improvements and DLL-enhanced feat
|
||||
|
||||
## DLL Enhancements
|
||||
|
||||
Since pfUI 6.0.0 includes integrations with client-side DLLs for enhanced functionality. These DLLs are permitted on Octo WoW:
|
||||
Since pfUI 6.0.0 includes integrations with client-side DLLs for enhanced functionality:
|
||||
|
||||
### [ClassicAPI](https://github.com/brues-code/ClassicAPI)
|
||||
|
||||
|
||||
@@ -645,7 +645,6 @@ function pfUI:LoadConfig()
|
||||
pfUI:UpdateConfig("bars", nil, "animation", "zoomfade")
|
||||
pfUI:UpdateConfig("bars", nil, "animmode", "keypress")
|
||||
pfUI:UpdateConfig("bars", nil, "animalways", "0")
|
||||
pfUI:UpdateConfig("bars", nil, "macroscan", "1")
|
||||
pfUI:UpdateConfig("bars", nil, "reagents", "1")
|
||||
pfUI:UpdateConfig("bars", nil, "hunterbar", "0")
|
||||
pfUI:UpdateConfig("bars", nil, "pagemasteralt", "0")
|
||||
|
||||
+78
-19
@@ -314,7 +314,8 @@ function pfUI.uf:UpdateVisibility()
|
||||
end
|
||||
|
||||
local unitstr = ("%s%s"):format(self.label or "", self.id or "")
|
||||
self:SetAttribute("unit", unitstr ~= "" and unitstr or nil)
|
||||
self.unitstr = unitstr ~= "" and unitstr or nil
|
||||
self:SetAttribute("unit", self.unitstr)
|
||||
local visibility = ("[target=%s,exists] show; hide"):format(unitstr)
|
||||
|
||||
-- Group frames are redundant when the group is already shown as a raid grid:
|
||||
@@ -344,6 +345,15 @@ function pfUI.uf:UpdateVisibility()
|
||||
self.visible = nil
|
||||
end
|
||||
|
||||
-- This is the single place a frame's unit is ever assigned, so it is also the
|
||||
-- place its subscriptions follow it to: the engine then delivers only this
|
||||
-- unit's events, and OnEvent compares against the cached string instead of
|
||||
-- rebuilding label..id -- and calling UnitGUID -- for every unit event fired
|
||||
-- by anything, anywhere. A frame that is not in use drops them entirely; the
|
||||
-- roster events that would bring it back are registered plainly, and
|
||||
-- visibilityscan re-runs this every 0.2s regardless, so it recovers on its own.
|
||||
self:RegisterUnitEvents(visibility ~= "hide" and self.unitstr or nil)
|
||||
|
||||
-- vanilla visibility
|
||||
if self.unitname then
|
||||
self:Show()
|
||||
@@ -624,11 +634,14 @@ function pfUI.uf:UpdateConfig()
|
||||
f.feedbackText:ClearAllPoints()
|
||||
f.feedbackText:SetPoint("CENTER", f.portrait, "CENTER")
|
||||
end
|
||||
f:RegisterEvent("UNIT_COMBAT")
|
||||
f.combatfeedback = true
|
||||
else
|
||||
f.feedbackText:Hide()
|
||||
f:UnregisterEvent("UNIT_COMBAT")
|
||||
f.combatfeedback = nil
|
||||
end
|
||||
-- RegisterUnitEvents owns UNIT_COMBAT; clearing the cached unit makes the
|
||||
-- next UpdateVisibility re-run it against the new combatfeedback state.
|
||||
f.eventunit = nil
|
||||
|
||||
f.hpLeftText:SetFontObject(GameFontWhite)
|
||||
f.hpLeftText:SetFont(fontname, fontsize, fontstyle)
|
||||
@@ -918,6 +931,9 @@ function pfUI.uf:UpdateConfig()
|
||||
f:UpdateFrameSize()
|
||||
else
|
||||
f:UnregisterAllEvents()
|
||||
-- that dropped the unit filters along with the registrations, so the cache
|
||||
-- has to go too or the next UpdateVisibility believes they are still set
|
||||
f.eventunit = nil
|
||||
f:Hide()
|
||||
end
|
||||
end
|
||||
@@ -959,6 +975,10 @@ function pfUI.uf.OnEvent()
|
||||
this:UnregisterAllEvents()
|
||||
this:SetScript("OnEvent", nil)
|
||||
this:SetScript("OnUpdate", nil)
|
||||
-- visibilityscan is a separate frame and keeps ticking, so leaving this one
|
||||
-- on its list would have UpdateVisibility re-register the unit events we
|
||||
-- just dropped -- straight back into the crash 132 this branch prevents
|
||||
visibilityscan.frames[this] = nil
|
||||
return
|
||||
end
|
||||
|
||||
@@ -1025,8 +1045,12 @@ function pfUI.uf.OnEvent()
|
||||
this.update_aura = true
|
||||
elseif this.label == "pet" and event == "UNIT_HAPPINESS" then
|
||||
this.update_full = true
|
||||
-- UNIT_XXX Events
|
||||
elseif arg1 and (arg1 == this.label .. this.id or (UnitGUID and arg1 == UnitGUID(this.label .. this.id))) then
|
||||
-- UNIT_XXX Events. RegisterUnitEvents means arg1 can only be this frame's own
|
||||
-- unit; the compare is kept for the case the filter sits out, which is when
|
||||
-- arg1 is not a string. The old GUID alternative is gone: these events fire
|
||||
-- once per token that resolves to the unit AND once with the raw GUID, so the
|
||||
-- token form always arrives and the GUID form was only ever a duplicate wake.
|
||||
elseif arg1 and arg1 == this.unitstr then
|
||||
if event == "UNIT_PORTRAIT_UPDATE" or event == "UNIT_MODEL_CHANGED" then
|
||||
this.update_portrait = true
|
||||
elseif event == "UNIT_AURA" then
|
||||
@@ -1251,25 +1275,56 @@ function pfUI.uf.OnUpdate()
|
||||
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).
|
||||
--
|
||||
-- UNIT_PET and UNIT_HAPPINESS are deliberately absent. Their branches key on
|
||||
-- the frame's label, and UNIT_PET's arg1 is the pet's OWNER ("player" for a
|
||||
-- "pet" frame), so filtering them by the frame's own unit would drop them.
|
||||
local UNIT_EVENTS = {
|
||||
"UNIT_DISPLAYPOWER",
|
||||
"UNIT_HEALTH", "UNIT_MAXHEALTH",
|
||||
"UNIT_MANA", "UNIT_MAXMANA",
|
||||
"UNIT_RAGE", "UNIT_MAXRAGE",
|
||||
"UNIT_ENERGY", "UNIT_MAXENERGY",
|
||||
"UNIT_FOCUS",
|
||||
"UNIT_PORTRAIT_UPDATE", "UNIT_MODEL_CHANGED",
|
||||
"UNIT_FACTION",
|
||||
"UNIT_AURA", -- frame=buff, frame=debuff
|
||||
}
|
||||
|
||||
-- Point this frame's unit-event subscriptions at `unitstr`, or drop them when
|
||||
-- the frame has no unit. Cheap to call repeatedly: it no-ops unless the unit
|
||||
-- actually changed, which matters because visibilityscan runs UpdateVisibility
|
||||
-- for every frame five times a second.
|
||||
function pfUI.uf:RegisterUnitEvents(unitstr)
|
||||
if self.eventunit == unitstr then return end
|
||||
self.eventunit = unitstr
|
||||
|
||||
for i = 1, table.getn(UNIT_EVENTS) do
|
||||
if unitstr then
|
||||
self:RegisterUnitEvent(UNIT_EVENTS[i], unitstr)
|
||||
else
|
||||
self:UnregisterEvent(UNIT_EVENTS[i])
|
||||
end
|
||||
end
|
||||
|
||||
-- UNIT_COMBAT rides along only while the frame draws combat feedback text.
|
||||
-- UpdateConfig clears eventunit when it toggles that, so the next
|
||||
-- UpdateVisibility re-runs this.
|
||||
if unitstr and self.combatfeedback then
|
||||
self:RegisterUnitEvent("UNIT_COMBAT", unitstr)
|
||||
else
|
||||
self:UnregisterEvent("UNIT_COMBAT")
|
||||
end
|
||||
end
|
||||
|
||||
function pfUI.uf:EnableEvents()
|
||||
local f = self
|
||||
|
||||
f:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
f:RegisterEvent("PLAYER_LOGOUT")
|
||||
f:RegisterEvent("UNIT_DISPLAYPOWER")
|
||||
f:RegisterEvent("UNIT_HEALTH")
|
||||
f:RegisterEvent("UNIT_MAXHEALTH")
|
||||
f:RegisterEvent("UNIT_MANA")
|
||||
f:RegisterEvent("UNIT_MAXMANA")
|
||||
f:RegisterEvent("UNIT_RAGE")
|
||||
f:RegisterEvent("UNIT_MAXRAGE")
|
||||
f:RegisterEvent("UNIT_ENERGY")
|
||||
f:RegisterEvent("UNIT_MAXENERGY")
|
||||
f:RegisterEvent("UNIT_FOCUS")
|
||||
f:RegisterEvent("UNIT_PORTRAIT_UPDATE")
|
||||
f:RegisterEvent("UNIT_MODEL_CHANGED")
|
||||
f:RegisterEvent("UNIT_FACTION")
|
||||
f:RegisterEvent("UNIT_AURA") -- frame=buff, frame=debuff
|
||||
f:RegisterEvent("PLAYER_AURAS_CHANGED") -- label=player && frame=buff
|
||||
f:RegisterEvent("PLAYER_EQUIPMENT_CHANGED") -- label=player && frame=buff (ClassicAPI: weapon-enchant buffs)
|
||||
f:RegisterEvent("PARTY_MEMBERS_CHANGED") -- label=party, frame=leaderIcon
|
||||
@@ -1387,6 +1442,7 @@ function pfUI.uf:CreateUnitFrame(unit, id, config, tick)
|
||||
f.UpdateConfig = pfUI.uf.UpdateConfig
|
||||
f.EnableScripts = pfUI.uf.EnableScripts
|
||||
f.EnableEvents = pfUI.uf.EnableEvents
|
||||
f.RegisterUnitEvents = pfUI.uf.RegisterUnitEvents
|
||||
f.EnableClickCast = pfUI.uf.EnableClickCast
|
||||
f.GetColor = pfUI.uf.GetColor
|
||||
|
||||
@@ -1503,6 +1559,9 @@ function pfUI.uf:CreateUnitFrame(unit, id, config, tick)
|
||||
f:UpdateFrameSize()
|
||||
else
|
||||
f:UnregisterAllEvents()
|
||||
-- that dropped the unit filters along with the registrations, so the cache
|
||||
-- has to go too or the next UpdateVisibility believes they are still set
|
||||
f.eventunit = nil
|
||||
f:Hide()
|
||||
end
|
||||
|
||||
|
||||
Vendored
-1
@@ -670,7 +670,6 @@ pfUI_translation["deDE"] = {
|
||||
["Scale"] = nil,
|
||||
["Scale Border On HiDPI Displays"] = nil,
|
||||
["Scaling"] = nil,
|
||||
["Scan Macros For Spells"] = nil,
|
||||
["Screen Edge Glow Intensity"] = nil,
|
||||
["Screen Resolution"] = nil,
|
||||
["Screenshot"] = nil,
|
||||
|
||||
Vendored
-1
@@ -683,7 +683,6 @@ pfUI_translation["enUS"] = {
|
||||
["Scale"] = nil,
|
||||
["Scale Border On HiDPI Displays"] = nil,
|
||||
["Scaling"] = nil,
|
||||
["Scan Macros For Spells"] = nil,
|
||||
["Screen Edge Glow Intensity"] = nil,
|
||||
["Screen Resolution"] = nil,
|
||||
["Screenshot"] = nil,
|
||||
|
||||
Vendored
-1
@@ -670,7 +670,6 @@ pfUI_translation["esES"] = {
|
||||
["Scale"] = "Escala",
|
||||
["Scale Border On HiDPI Displays"] = "Escalar los bordes en las pantallas con DPI alto",
|
||||
["Scaling"] = "Escalada",
|
||||
["Scan Macros For Spells"] = nil,
|
||||
["Screen Edge Glow Intensity"] = "Intensidad de brillo en los bordes de la pantalla",
|
||||
["Screen Resolution"] = "Resolución de pantalla",
|
||||
["Screenshot"] = "Captura de pantalla",
|
||||
|
||||
Vendored
-1
@@ -670,7 +670,6 @@ pfUI_translation["frFR"] = {
|
||||
["Scale"] = "Échelle",
|
||||
["Scale Border On HiDPI Displays"] = "Échelle de bordure sur les écrans HiDPI",
|
||||
["Scaling"] = "Mise à l'échelle",
|
||||
["Scan Macros For Spells"] = nil,
|
||||
["Screen Edge Glow Intensity"] = nil,
|
||||
["Screen Resolution"] = "Résolution d'écran",
|
||||
["Screenshot"] = "Imprime écran",
|
||||
|
||||
Vendored
-1
@@ -670,7 +670,6 @@ pfUI_translation["koKR"] = {
|
||||
["Scale"] = nil,
|
||||
["Scale Border On HiDPI Displays"] = nil,
|
||||
["Scaling"] = nil,
|
||||
["Scan Macros For Spells"] = nil,
|
||||
["Screen Edge Glow Intensity"] = nil,
|
||||
["Screen Resolution"] = "화면 해상도",
|
||||
["Screenshot"] = nil,
|
||||
|
||||
Vendored
-1
@@ -670,7 +670,6 @@ pfUI_translation["ruRU"] = {
|
||||
["Scale"] = "Масштаб",
|
||||
["Scale Border On HiDPI Displays"] = "Масштабировать границы на HiDPI мониторах",
|
||||
["Scaling"] = "Масштаб интерфейса",
|
||||
["Scan Macros For Spells"] = nil,
|
||||
["Screen Edge Glow Intensity"] = "Интенсивность свечения на краях экрана",
|
||||
["Screen Resolution"] = "Разрешение экрана",
|
||||
["Screenshot"] = "Снимок экрана",
|
||||
|
||||
Vendored
-1
@@ -670,7 +670,6 @@ pfUI_translation["zhCN"] = {
|
||||
["Scale"] = "比例",
|
||||
["Scale Border On HiDPI Displays"] = "缩放高DPI显示器上的边框",
|
||||
["Scaling"] = "UI缩放",
|
||||
["Scan Macros For Spells"] = "扫描宏命令中的法术",
|
||||
["Screen Edge Glow Intensity"] = "屏幕边缘发光强度",
|
||||
["Screen Resolution"] = "屏幕分辨率",
|
||||
["Screenshot"] = "屏幕截图",
|
||||
|
||||
Vendored
-1
@@ -670,7 +670,6 @@ pfUI_translation["zhTW"] = {
|
||||
["Scale"] = "比例",
|
||||
["Scale Border On HiDPI Displays"] = nil,
|
||||
["Scaling"] = nil,
|
||||
["Scan Macros For Spells"] = nil,
|
||||
["Screen Edge Glow Intensity"] = nil,
|
||||
["Screen Resolution"] = "螢幕解析度",
|
||||
["Screenshot"] = nil,
|
||||
|
||||
@@ -70,7 +70,6 @@
|
||||
<Include file="..\modules\addoncompat.lua"/>
|
||||
<Include file="..\modules\energytick.lua"/>
|
||||
<Include file="..\modules\totems.lua"/>
|
||||
<Include file="..\modules\macrotweak.lua"/>
|
||||
<Include file="..\modules\macroicons.lua"/>
|
||||
<Include file="..\modules\superwow.lua"/>
|
||||
<Include file="..\modules\innervatecall.lua"/>
|
||||
|
||||
+2
-2
@@ -10,8 +10,8 @@ local libhealth = CreateFrame("Frame")
|
||||
libhealth.enabled = true
|
||||
libhealth.reqhit = 4
|
||||
libhealth.reqdmg = 5
|
||||
libhealth:RegisterEvent("UNIT_HEALTH")
|
||||
libhealth:RegisterEvent("UNIT_COMBAT")
|
||||
libhealth:RegisterUnitEvent("UNIT_HEALTH", "target")
|
||||
libhealth:RegisterUnitEvent("UNIT_COMBAT", "target")
|
||||
libhealth:RegisterEvent("PLAYER_TARGET_CHANGED")
|
||||
libhealth:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
libhealth:SetScript("OnEvent", function()
|
||||
|
||||
+1
-1
@@ -1134,7 +1134,7 @@ libpredict.sender:RegisterEvent("SPELL_HEAL_BY_SELF")
|
||||
libpredict.sender:RegisterEvent("SPELL_HEAL_BY_OTHER") -- populates foreignCache for other healers
|
||||
|
||||
-- force cache updates
|
||||
libpredict.sender:RegisterEvent("UNIT_INVENTORY_CHANGED")
|
||||
libpredict.sender:RegisterUnitEvent("UNIT_INVENTORY_CHANGED", "player")
|
||||
libpredict.sender:RegisterEvent("SKILL_LINES_CHANGED")
|
||||
|
||||
-- Shared cleanup helper for failed/interrupted casts
|
||||
|
||||
+23
-73
@@ -360,68 +360,6 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
end
|
||||
end
|
||||
|
||||
local function ButtonMacroScan(self)
|
||||
if self.bar > 10 then return end
|
||||
if not self.scanmacro then return end
|
||||
if pfUI.bars.skip_macro then return end
|
||||
|
||||
-- SuperCleveRoidMacros: for macros it manages, leave spellslot/booktype unset
|
||||
-- so the button's icon, cooldown, and tooltip flow through the hooked
|
||||
-- GetActionTexture / GetActionCooldown / GameTooltip:SetAction and follow the
|
||||
-- active conditional dynamically, instead of being frozen to the first
|
||||
-- statically-scanned spell.
|
||||
if CleveRoids and CleveRoids.IsManagedAction and CleveRoids.IsManagedAction(self.id) then
|
||||
self.spellslot, self.booktype, self.spellID = nil, nil, nil
|
||||
return
|
||||
end
|
||||
|
||||
local kind, slot = GetActionInfo(self.id)
|
||||
self.spellslot, self.booktype, self.spellID = nil, nil, nil
|
||||
if kind == 'macro' then
|
||||
local name, _, body = GetMacroInfo(slot)
|
||||
|
||||
if name and body then
|
||||
local match
|
||||
|
||||
for line in gfind(body, "[^%\n]+") do
|
||||
_, _, match = string.find(line, '^#showtooltip (.+)')
|
||||
|
||||
-- allow the user to disable the scan
|
||||
if match and strfind(match, "disable") then
|
||||
return
|
||||
end
|
||||
|
||||
if not match then
|
||||
-- add support to specify custom tooltips via:
|
||||
-- /run --showtooltip SPELLNAME
|
||||
_, _, match = string.find(line, '%-%-showtooltip (.+)')
|
||||
end
|
||||
|
||||
if not match then
|
||||
_, _, match = string.find(line, '^/cast (.+)')
|
||||
end
|
||||
|
||||
if not match then
|
||||
_, _, match = string.find(line, '^/pfcast (.+)')
|
||||
end
|
||||
|
||||
if not match then
|
||||
_, _, match = string.find(line, '^/pfmouse (.+)')
|
||||
end
|
||||
|
||||
if not match then
|
||||
_, _, match = string.find(line, 'CastSpellByName%(%"(.+)%"%)')
|
||||
end
|
||||
|
||||
if match then
|
||||
self.spellslot, self.booktype, self.spellID = select(7, libspell.GetSpellInfo(match))
|
||||
if self.spellslot and self.spellslot > 0 then return end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function ButtonEnter(self)
|
||||
self = self or this
|
||||
|
||||
@@ -690,7 +628,6 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
local function ButtonFullUpdate(button)
|
||||
if not button then return end
|
||||
|
||||
ButtonMacroScan(button)
|
||||
ButtonSlotUpdate(button)
|
||||
ButtonRangeUpdate(button)
|
||||
ButtonUsableUpdate(button)
|
||||
@@ -807,10 +744,28 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
|
||||
-- create the main event and update handler for pfUI actionbars
|
||||
local bars = CreateFrame("Frame", "pfActionBar", UIParent)
|
||||
for event in pairs(special_events) do bars:RegisterEvent(event) end
|
||||
for event in pairs(global_events) do bars:RegisterEvent(event) end
|
||||
for event in pairs(aura_events) do bars:RegisterEvent(event) end
|
||||
for event in pairs(pet_events) do bars:RegisterEvent(event) end
|
||||
|
||||
-- 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.
|
||||
local event_units = {
|
||||
["UNIT_INVENTORY_CHANGED"] = "player",
|
||||
["UNIT_PET"] = "player",
|
||||
}
|
||||
|
||||
local function RegisterBarEvent(event)
|
||||
local unit = event_units[event]
|
||||
if unit then
|
||||
bars:RegisterUnitEvent(event, unit)
|
||||
else
|
||||
bars:RegisterEvent(event)
|
||||
end
|
||||
end
|
||||
|
||||
for event in pairs(special_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
|
||||
|
||||
-- refresh actionbar buttons on event
|
||||
bars:SetScript("OnEvent", BarsEvent)
|
||||
@@ -1148,12 +1103,7 @@ pfUI:RegisterModule("actionbar", function ()
|
||||
f.count:SetJustifyH("RIGHT")
|
||||
f.count:SetJustifyV("BOTTOM")
|
||||
|
||||
-- macro spell scan (disabled when macro addons are loaded)
|
||||
if C.bars.macroscan == "0" or pfUI:MacroAddonsLoaded() then
|
||||
f.scanmacro, f.spellslot, f.booktype = nil, nil, nil
|
||||
else
|
||||
f.scanmacro = true
|
||||
end
|
||||
f.scanmacro, f.spellslot, f.booktype = nil, nil, nil
|
||||
|
||||
-- range glow color
|
||||
f.rangeColor = GetStringColorObject(C.bars.rangecolor)
|
||||
|
||||
+1
-1
@@ -164,7 +164,7 @@ pfUI:RegisterModule("buff", function ()
|
||||
pfUI.buff = CreateFrame("Frame", "pfGlobalBuffFrame", UIParent)
|
||||
pfUI.buff:RegisterEvent("PLAYER_AURAS_CHANGED")
|
||||
pfUI.buff:RegisterEvent("PLAYER_EQUIPMENT_CHANGED")
|
||||
pfUI.buff:RegisterEvent("UNIT_MODEL_CHANGED")
|
||||
pfUI.buff:RegisterUnitEvent("UNIT_MODEL_CHANGED", "player")
|
||||
pfUI.buff:RegisterEvent("BUFF_UPDATE_DURATION_SELF")
|
||||
pfUI.buff:RegisterEvent("DEBUFF_UPDATE_DURATION_SELF")
|
||||
pfUI.buff:SetScript("OnEvent", function()
|
||||
|
||||
+15
-9
@@ -322,15 +322,21 @@ pfUI:RegisterModule("castbar", function ()
|
||||
-- casts only ever fire arg1=="player" -- when the bar's unit resolves to the
|
||||
-- player (target=self). PLAYER_TARGET/FOCUS_CHANGED re-polls so a unit
|
||||
-- already mid-cast when it becomes the target/focus still shows.
|
||||
cb:RegisterEvent("UNIT_SPELLCAST_START")
|
||||
cb:RegisterEvent("UNIT_SPELLCAST_STOP")
|
||||
cb:RegisterEvent("UNIT_SPELLCAST_FAILED")
|
||||
cb:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED")
|
||||
cb:RegisterEvent("UNIT_SPELLCAST_DELAYED")
|
||||
cb:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")
|
||||
cb:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START")
|
||||
cb:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP")
|
||||
cb:RegisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE")
|
||||
-- Filter to this bar's unit, plus "player" for the target/focus bars: the
|
||||
-- player's own casts only ever fire arg1=="player", so a self-targeted cast
|
||||
-- has to reach them too (nil for the player bar itself, which the filter
|
||||
-- skips). This only narrows what arrives -- the arg1/UnitIsUnit test below
|
||||
-- still decides whether the bar acts on it.
|
||||
local selfunit = unitstr ~= "player" and "player" or nil
|
||||
cb:RegisterUnitEvent("UNIT_SPELLCAST_START", unitstr, selfunit)
|
||||
cb:RegisterUnitEvent("UNIT_SPELLCAST_STOP", unitstr, selfunit)
|
||||
cb:RegisterUnitEvent("UNIT_SPELLCAST_FAILED", unitstr, selfunit)
|
||||
cb:RegisterUnitEvent("UNIT_SPELLCAST_INTERRUPTED", unitstr, selfunit)
|
||||
cb:RegisterUnitEvent("UNIT_SPELLCAST_DELAYED", unitstr, selfunit)
|
||||
cb:RegisterUnitEvent("UNIT_SPELLCAST_SUCCEEDED", unitstr, selfunit)
|
||||
cb:RegisterUnitEvent("UNIT_SPELLCAST_CHANNEL_START", unitstr, selfunit)
|
||||
cb:RegisterUnitEvent("UNIT_SPELLCAST_CHANNEL_STOP", unitstr, selfunit)
|
||||
cb:RegisterUnitEvent("UNIT_SPELLCAST_CHANNEL_UPDATE", unitstr, selfunit)
|
||||
if unitstr == "target" then
|
||||
cb:RegisterEvent("PLAYER_TARGET_CHANGED")
|
||||
elseif unitstr == "focus" then
|
||||
|
||||
@@ -52,7 +52,7 @@ pfUI:RegisterModule("combopoints", function ()
|
||||
-- combo
|
||||
if class == "DRUID" or class == "ROGUE" then
|
||||
local combo = CreateFrame("Frame")
|
||||
combo:RegisterEvent("UNIT_COMBO_POINTS")
|
||||
combo:RegisterUnitEvent("UNIT_COMBO_POINTS", "player")
|
||||
combo:RegisterEvent("PLAYER_COMBO_POINTS")
|
||||
combo:RegisterEvent("PLAYER_TARGET_CHANGED")
|
||||
combo:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
|
||||
+185
-60
@@ -1,20 +1,82 @@
|
||||
local function getAdjustedTickTimer()
|
||||
local adjustedEnergyTick = 2
|
||||
-- One server clock drives every power: Player::RegenerateAll fires every
|
||||
-- REGEN_TIME_FULL (2s), re-arms with `+=`, and is never reset by casting. The
|
||||
-- five-second rule (SetLastManaUse on any mana-costing cast) changes what a tick
|
||||
-- pays, never when it lands; mp5 and the player's MOD_MANA_REGEN_INTERRUPT share
|
||||
-- still come in. That share can't be computed here -- item sources are equip
|
||||
-- auras absent from the buff list and m_modManaRegenInterrupt is never sent --
|
||||
-- so the spark shows it instead: dim through the window until a tick lands.
|
||||
--
|
||||
-- The sweep free-runs on that clock and phase-locks to observed gains. A gain
|
||||
-- mid-sweep (Illumination, Judgement of Wisdom, potions, a Mana Spring totem on
|
||||
-- its own phase) is not the tick and never moves it.
|
||||
|
||||
-- Check rogue talents and compute energy tick timing reduction for Combat spec (1.18.0 Blade Rush Talent)
|
||||
if UnitClassBase("player") == "ROGUE" then
|
||||
local _, _, _, _, currRank = GetTalentInfo(2, 16)
|
||||
local bladeRushRank = currRank or 0
|
||||
local FIVE_SECOND_RULE = 5
|
||||
|
||||
if bladeRushRank > 0 then
|
||||
local agility = UnitStat("player", 2) -- 2 is agility stat index
|
||||
local reductionPerAgi = 0.0006 * bladeRushRank -- 0.0006 for rank 1, 0.0012 for rank 2
|
||||
local totalReduction = agility * reductionPerAgi
|
||||
adjustedEnergyTick = adjustedEnergyTick - totalReduction
|
||||
-- gains farther than this from the predicted boundary are not the tick
|
||||
local TICK_TOLERANCE = .25
|
||||
|
||||
-- arrival jitter; a tick inside this band confirms the sweep rather than
|
||||
-- re-anchoring it, or the spark hitches at every wrap
|
||||
local TICK_JITTER = .08
|
||||
|
||||
-- Player::RegenerateAll:
|
||||
-- mod = GetTotalAuraModifier(SPELL_AURA_MOD_ENERGY_REGEN_TIME)
|
||||
-- if mod > 0 then mod = mod * agility / 10 end
|
||||
-- m_regenTimer += max(1, REGEN_TIME_FULL - mod) -- milliseconds
|
||||
local REGEN_TIME_FULL = 2
|
||||
local ENERGY_REGEN_TIME_AURA = 217 -- SPELL_AURA_MOD_ENERGY_REGEN_TIME
|
||||
|
||||
-- fixed magnitude is basePoints + baseDice (stored 11 -> 12); a die above 1 is
|
||||
-- a roll the client can't know, so it counts as nothing rather than a guess
|
||||
local amountCache = {}
|
||||
local function auraAmount(spellID)
|
||||
local amount = amountCache[spellID]
|
||||
if amount then return amount end
|
||||
amount = 0
|
||||
local effects = C_Spell.GetSpellEffectInfo(spellID) -- nil for an id with no record
|
||||
if effects then
|
||||
for i = 1, 3 do
|
||||
local fx = effects[i]
|
||||
if fx.auraName == ENERGY_REGEN_TIME_AURA and fx.dieSides <= 1 then
|
||||
amount = fx.basePoints + fx.baseDice
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
amountCache[spellID] = amount
|
||||
return amount
|
||||
end
|
||||
|
||||
return adjustedEnergyTick
|
||||
-- A passive is in effect exactly while known (current rank only, never in the
|
||||
-- buff list); anything castable or cast on us counts only while it is up.
|
||||
local function getEnergyRegenTimeMod()
|
||||
local sum = 0
|
||||
for _, spellID in ipairs(C_SpellBook.GetPlayerSpellsByAura(ENERGY_REGEN_TIME_AURA)) do
|
||||
if C_Spell.IsSpellPassive(spellID) then
|
||||
sum = sum + auraAmount(spellID)
|
||||
end
|
||||
end
|
||||
for i = 1, 32 do
|
||||
local spellID = select(10, C_UnitAuras.UnitAura("player", i, "HELPFUL"))
|
||||
if not spellID then break end
|
||||
sum = sum + auraAmount(spellID)
|
||||
end
|
||||
return sum
|
||||
end
|
||||
|
||||
-- cleared on SPELLS_CHANGED (passives) and PLAYER_AURAS_CHANGED (buffs), and
|
||||
-- recomputed by the next tick that asks. Agility stays live: it's one call.
|
||||
local energyRegenTimeMod
|
||||
|
||||
local function getAdjustedTickTimer()
|
||||
if not energyRegenTimeMod then
|
||||
energyRegenTimeMod = getEnergyRegenTimeMod()
|
||||
end
|
||||
if energyRegenTimeMod == 0 then return REGEN_TIME_FULL end
|
||||
|
||||
-- ms on the server, seconds here; the 1ms floor is the server's and this is a divisor
|
||||
local reduction = energyRegenTimeMod * UnitStat("player", 2) / 10000
|
||||
return math.max(0.001, REGEN_TIME_FULL - reduction)
|
||||
end
|
||||
|
||||
pfUI:RegisterModule("energytick", function()
|
||||
@@ -22,14 +84,53 @@ 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
|
||||
|
||||
-- was this gain the regen tick? if so, re-anchor the sweep on it
|
||||
local function lockTick(frame)
|
||||
local now, period = GetTime(), getAdjustedTickTimer()
|
||||
|
||||
if frame.start then
|
||||
-- signed distance to the nearest predicted boundary
|
||||
local err = mod(now - frame.start, period)
|
||||
if err > period / 2 then err = err - period end
|
||||
|
||||
if math.abs(err) <= TICK_TOLERANCE then
|
||||
-- correct only what lies beyond normal jitter
|
||||
if err > TICK_JITTER then
|
||||
frame.start = frame.start + (err - TICK_JITTER)
|
||||
elseif err < -TICK_JITTER then
|
||||
frame.start = frame.start + (err + TICK_JITTER)
|
||||
end
|
||||
frame.max, frame.rejected = period, nil
|
||||
return true
|
||||
end
|
||||
|
||||
-- two rejected gains one period apart are the real clock: relock to it
|
||||
local periodic = frame.rejected and math.abs(now - frame.rejected - period) <= TICK_TOLERANCE
|
||||
if not periodic then
|
||||
frame.rejected = now
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
frame.start, frame.max, frame.rejected = now, period, nil
|
||||
return true
|
||||
end
|
||||
|
||||
local energytick = CreateFrame("Frame", nil, pfUI.uf.player.power.bar)
|
||||
energytick:SetAllPoints(pfUI.uf.player.power.bar)
|
||||
energytick:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
energytick:RegisterEvent("UNIT_DISPLAYPOWER")
|
||||
energytick:RegisterEvent("UNIT_ENERGY")
|
||||
energytick:RegisterEvent("UNIT_MANA")
|
||||
energytick:RegisterEvent("CHAT_MSG_SPELL_SELF_BUFF")
|
||||
energytick:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS")
|
||||
energytick:RegisterUnitEvent("UNIT_DISPLAYPOWER", "player")
|
||||
energytick:RegisterUnitEvent("UNIT_ENERGY", "player")
|
||||
energytick:RegisterUnitEvent("UNIT_MANA", "player")
|
||||
energytick:RegisterUnitEvent("UNIT_SPELLCAST_SUCCEEDED", "player")
|
||||
energytick:RegisterUnitEvent("UNIT_SPELLCAST_CHANNEL_STOP", "player")
|
||||
energytick:RegisterEvent("SPELLS_CHANGED")
|
||||
energytick:RegisterEvent("PLAYER_AURAS_CHANGED")
|
||||
|
||||
energytick:SetScript("OnEvent", function()
|
||||
if UnitPowerType("player") == Enum.PowerType.Mana and C.unitframes.player.manatick == "1" then
|
||||
@@ -42,44 +143,52 @@ pfUI:RegisterModule("energytick", function()
|
||||
this:Hide()
|
||||
end
|
||||
|
||||
-- Filter nur eigene Energy-Gewinne von Talents/Buffs
|
||||
if event == "CHAT_MSG_SPELL_SELF_BUFF" or event == "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS" then
|
||||
if string.find(arg1, "You gain") and string.find(arg1, "Energy from") then
|
||||
this.ignoreNextGain = true
|
||||
end
|
||||
if event == "SPELLS_CHANGED" or event == "PLAYER_AURAS_CHANGED" then
|
||||
energyRegenTimeMod = nil
|
||||
return
|
||||
end
|
||||
|
||||
if event == "PLAYER_ENTERING_WORLD" then
|
||||
this.lastMana = UnitPower("player")
|
||||
this.lastPower = UnitPower("player")
|
||||
end
|
||||
|
||||
-- the rule arms on the cast (Spell::TakePower: mana powerType, cost > 0),
|
||||
-- not on a mana drop -- Mana Burn lowers mana without arming it
|
||||
if event == "UNIT_SPELLCAST_SUCCEEDED" and arg1 == "player" then
|
||||
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
|
||||
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
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if (event == "UNIT_MANA" or event == "UNIT_ENERGY") and arg1 == "player" then
|
||||
this.currentMana = UnitPower("player")
|
||||
local diff = 0
|
||||
if this.lastMana then
|
||||
diff = this.currentMana - this.lastMana
|
||||
local power = UnitPower("player")
|
||||
local diff = this.lastPower and (power - this.lastPower) or 0
|
||||
this.lastPower = power
|
||||
|
||||
-- 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
|
||||
this.fsrGain = true
|
||||
end
|
||||
end
|
||||
|
||||
if this.mode == "MANA" and diff < 0 then
|
||||
this.target = 5
|
||||
elseif this.mode == "MANA" and diff > 0 then
|
||||
if UnitPower("player") >= UnitPowerMax("player") then
|
||||
this.start = nil
|
||||
this.spark:SetAlpha(0)
|
||||
this:Hide()
|
||||
elseif this.max ~= 5 and diff > (this.badtick and this.badtick * 1.2 or 5) then
|
||||
this.target = 2
|
||||
else
|
||||
this.badtick = diff
|
||||
end
|
||||
elseif this.mode == "ENERGY" and diff >= 0 then
|
||||
if not this.ignoreNextGain then
|
||||
this.target = getAdjustedTickTimer()
|
||||
end
|
||||
this.ignoreNextGain = false
|
||||
-- phase is kept while hidden; OnUpdate catches up by whole periods
|
||||
if this.mode == "MANA" and power >= UnitPowerMax("player") then
|
||||
this:Hide()
|
||||
end
|
||||
this.lastMana = this.currentMana
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -90,37 +199,53 @@ pfUI:RegisterModule("energytick", function()
|
||||
end
|
||||
this.tick = GetTime() + 0.020 -- ~50 FPS
|
||||
|
||||
if this.target then
|
||||
this.start, this.max = GetTime(), this.target
|
||||
this.target = nil
|
||||
this.spark:SetAlpha(1)
|
||||
this:Show()
|
||||
-- five-second rule drains to nothing
|
||||
local remaining = this.fsrEnd and (this.fsrEnd - GetTime()) or 0
|
||||
if this.mode == "MANA" and remaining > 0 then
|
||||
this.fsrbar:SetWidth(getBarWidth() * remaining / FIVE_SECOND_RULE)
|
||||
this.fsrbar:Show()
|
||||
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
|
||||
-- Don't restart tick timer if mana is full
|
||||
if this.mode == "MANA" and UnitPower("player") >= UnitPowerMax("player") then
|
||||
this.start = nil
|
||||
this.spark:SetAlpha(0)
|
||||
return
|
||||
end
|
||||
this.start, this.max, this.current = GetTime(), getAdjustedTickTimer(), 0
|
||||
this.start = this.start + this.max * math.floor(this.current / this.max)
|
||||
this.max = getAdjustedTickTimer()
|
||||
this.current = GetTime() - this.start
|
||||
end
|
||||
|
||||
local pos = (C.unitframes.player.pwidth ~= "-1" and C.unitframes.player.pwidth or C.unitframes.player.width)
|
||||
* (this.current / this.max)
|
||||
-- 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.fsrbar = energytick:CreateTexture(nil, "ARTWORK")
|
||||
energytick.fsrbar:SetTexture(1, 1, 1, .15)
|
||||
energytick.fsrbar:SetPoint("TOPLEFT", 0, 0)
|
||||
energytick.fsrbar:SetPoint("BOTTOMLEFT", 0, 0)
|
||||
energytick.fsrbar:Hide()
|
||||
|
||||
energytick.spark = energytick:CreateTexture(nil, "OVERLAY")
|
||||
energytick.spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark")
|
||||
energytick.spark:SetHeight(C.unitframes.player.pheight + 15)
|
||||
@@ -133,4 +258,4 @@ pfUI:RegisterModule("energytick", function()
|
||||
energytick.spark:SetWidth(C.unitframes.player.pheight + 5)
|
||||
hookUpdateConfig(pfUI.uf.player)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
+1
-5
@@ -2556,9 +2556,6 @@ pfUI:RegisterModule("gui", function ()
|
||||
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(U["bars"], T["Show Animation On Hidden Bars"], C.bars, "animalways", "checkbox")
|
||||
if not pfUI:MacroAddonsLoaded() then
|
||||
CreateConfig(U["bars"], T["Scan Macros For Spells"], C.bars, "macroscan", "checkbox", nil, nil, nil, nil)
|
||||
end
|
||||
CreateConfig(U["bars"], T["Show Reagent Count"], C.bars, "reagents", "checkbox")
|
||||
CreateConfig(U["bars"], T["Highlight Equipped Items"], C.bars, "showequipped", "checkbox")
|
||||
CreateConfig(U["bars"], T["Equipped Item Color"], C.bars, "eqcolor", "color")
|
||||
@@ -3029,8 +3026,7 @@ pfUI:RegisterModule("gui", function ()
|
||||
CreateGUIEntry(T["Components"], T["Modules"], function()
|
||||
table.sort(pfUI.modules)
|
||||
for i,m in pairs(pfUI.modules) do
|
||||
-- skip gui and macrotweak when macro addons are loaded
|
||||
if m ~= "gui" and not (m == "macrotweak" and pfUI:MacroAddonsLoaded()) then
|
||||
if m ~= "gui" then
|
||||
-- create disabled entry if not existing and display
|
||||
pfUI:UpdateConfig("disabled", nil, m, "0")
|
||||
CreateConfig(nil, T["Disable Module"] .. " " .. m, C.disabled, m, "checkbox")
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
pfUI:RegisterModule("macrotweak", function ()
|
||||
local conflictAddons = { "Supermacro", "SuperCleveRoidMacros", "UltimaMacros" }
|
||||
local disabled = false
|
||||
|
||||
for _, addon in pairs(conflictAddons) do
|
||||
local name = addon
|
||||
EventUtil.ContinueOnAddOnLoaded(name, function()
|
||||
if not disabled then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff33ffccpfUI|r: " .. name .. " found, macrotweak disabled.")
|
||||
end
|
||||
disabled = true
|
||||
end)
|
||||
end
|
||||
|
||||
-- do not write macro calls into chat input history
|
||||
-- (install once: _AddHistoryLine is our backup slot and is nil until we set it)
|
||||
if not ChatFrameEditBox._AddHistoryLine then
|
||||
local userinput
|
||||
ChatFrameEditBox._AddHistoryLine = ChatFrameEditBox.AddHistoryLine
|
||||
ChatFrameEditBox.AddHistoryLine = function(self, text)
|
||||
if disabled then return ChatFrameEditBox._AddHistoryLine(self, text) end
|
||||
if not userinput and text and string.find(text, "^/run(.+)") then return end
|
||||
if not userinput and string.find(text, "^/script(.+)") then return end
|
||||
if not userinput and string.find(text, "^/cast(.+)") then return end
|
||||
ChatFrameEditBox._AddHistoryLine(self, text)
|
||||
end
|
||||
|
||||
local OnEnter = ChatFrameEditBox:GetScript("OnEnterPressed")
|
||||
ChatFrameEditBox:SetScript("OnEnterPressed", function(a1,a2,a3,a4)
|
||||
userinput = true
|
||||
OnEnter(a1,a2,a3,a4)
|
||||
userinput = nil
|
||||
end)
|
||||
end
|
||||
|
||||
-- make sure #showtooltip inside macros won't be sent
|
||||
local hookSendChatMessage = SendChatMessage
|
||||
function _G.SendChatMessage(msg, ...)
|
||||
if disabled then return hookSendChatMessage(msg, unpack(arg)) end
|
||||
if msg and string.find(msg, "^#showtooltip ") then return end
|
||||
hookSendChatMessage(msg, unpack(arg))
|
||||
end
|
||||
|
||||
-- add /use and /equip to the macro api:
|
||||
-- https://wowwiki.fandom.com/wiki/Making_a_macro
|
||||
-- supported arguments:
|
||||
-- /use <itemname>
|
||||
-- /use <inventory slot>
|
||||
-- /use <bag> <slot>
|
||||
pfUI.api.RegisterSlashCommand("PFUSE", { "/equip" , "/use", "/pfequip", "/pfuse" }, function (msg)
|
||||
if not msg or msg == "" then return end
|
||||
local bag, slot, _
|
||||
if string.find(msg, "%d+%s+%d+") then
|
||||
_, _, bag, slot = string.find(msg, "(%d+)%s+(%d+)")
|
||||
elseif string.find(msg, "%d+") then
|
||||
_, _, slot = string.find(msg, "(%d+)")
|
||||
else
|
||||
bag, slot = FindItem(msg)
|
||||
end
|
||||
|
||||
if bag and slot then
|
||||
UseContainerItem(bag, slot)
|
||||
elseif not bag and slot then
|
||||
UseInventoryItem(slot)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
+38
-18
@@ -1,12 +1,9 @@
|
||||
pfUI:RegisterModule("marktracking", function ()
|
||||
if not UnitExists("mark1") and not UnitExists("mark8") then
|
||||
if not pcall(function() UnitExists("mark1") end) then return end
|
||||
end
|
||||
|
||||
local rawborder, border = GetBorderSize()
|
||||
|
||||
local markerOrder = { 8, 7, 6, 5, 4, 3, 2, 1 } -- skull, cross, square, moon, triangle, diamond, circle, star
|
||||
local markerTokens = {}
|
||||
local markerTokens = {} -- [i] = "markN"
|
||||
local markerIndex = {} -- ["markN"] = i, for the event handler's arg1
|
||||
|
||||
local markerConfigKeys = {
|
||||
"raidmarkercolor_star",
|
||||
@@ -22,6 +19,7 @@ pfUI:RegisterModule("marktracking", function ()
|
||||
local markerColors = {}
|
||||
for i, markKey in ipairs(markerConfigKeys) do
|
||||
markerTokens[i] = "mark" .. i
|
||||
markerIndex[markerTokens[i]] = i
|
||||
local r, g, b, a = GetStringColor(C.unitframes[markKey])
|
||||
markerColors[i] = { tonumber(r), tonumber(g), tonumber(b), tonumber(a) }
|
||||
end
|
||||
@@ -73,8 +71,7 @@ pfUI.marktracking = CreateFrame("Frame", "pfMarkTracking", UIParent)
|
||||
else
|
||||
pfUI.marktracking:SetPoint("TOP", UIParent, "CENTER", 0, 0)
|
||||
end
|
||||
pfUI.marktracking:SetWidth(TOTAL_ROW_WIDTH)
|
||||
pfUI.marktracking:SetHeight(8 * (ROW_HEIGHT + 1) + border * 2 - 1)
|
||||
pfUI.marktracking:SetSize(TOTAL_ROW_WIDTH, 8 * (ROW_HEIGHT + 1) + border * 2 - 1)
|
||||
pfUI.marktracking:Hide()
|
||||
|
||||
CreateBackdrop(pfUI.marktracking)
|
||||
@@ -284,27 +281,50 @@ pfUI.marktracking = CreateFrame("Frame", "pfMarkTracking", UIParent)
|
||||
-- Event-driven scanner frame
|
||||
local scanner = CreateFrame("Frame")
|
||||
|
||||
-- Fallback poll: catches units that come into range AFTER a marker was set
|
||||
-- (no event fires for that case, so we need this safety net). UpdateDisplay
|
||||
-- is a full eight-row rebuild, so it exists only while grouped -- raid markers
|
||||
-- are a group feature and there is nothing to discover alone. The group events
|
||||
-- below start and cancel it, so outside a group there is no timer queued at
|
||||
-- all rather than one waking every second to return early.
|
||||
--
|
||||
-- Deliberately NOT keyed on a mark being visible: a marker set on a unit that
|
||||
-- is out of range shows no row, and that is exactly what this poll catches.
|
||||
local poll
|
||||
local function UpdatePoll()
|
||||
local grouped = IsInGroup()
|
||||
if grouped and not poll then
|
||||
poll = C_Timer.NewTicker(FALLBACK_INTERVAL, UpdateDisplay)
|
||||
elseif not grouped and poll then
|
||||
poll:Cancel()
|
||||
poll = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- RAID_TARGET_UPDATE: a raid marker was set/cleared -> full refresh
|
||||
-- PLAYER_ENTERING_WORLD: login/reload/zone -> full refresh
|
||||
-- UNIT_HEALTH/UNIT_MAXHEALTH: ClassicAPI fires these per token; with the mark
|
||||
-- tokens observed they arrive as arg1 == "markN", so we refresh just that
|
||||
-- one row (UpdateRow) instead of rescanning all eight.
|
||||
-- PARTY_MEMBERS_CHANGED/RAID_ROSTER_UPDATE: joined or left a group -> the rows
|
||||
-- can change, and the fallback poll starts or stops with it
|
||||
-- UNIT_HEALTH/UNIT_MAXHEALTH: filtered to the eight mark tokens, so arg1 is
|
||||
-- always "markN" and we refresh just that row (UpdateRow) instead of
|
||||
-- rescanning all eight.
|
||||
scanner:RegisterEvent("RAID_TARGET_UPDATE")
|
||||
scanner:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
scanner:RegisterEvent("UNIT_HEALTH")
|
||||
scanner:RegisterEvent("UNIT_MAXHEALTH")
|
||||
scanner:RegisterEvent("PARTY_MEMBERS_CHANGED")
|
||||
scanner:RegisterEvent("RAID_ROSTER_UPDATE")
|
||||
scanner:RegisterUnitEvent("UNIT_HEALTH", "mark1", "mark2", "mark3", "mark4", "mark5", "mark6", "mark7", "mark8")
|
||||
scanner:RegisterUnitEvent("UNIT_MAXHEALTH", "mark1", "mark2", "mark3", "mark4", "mark5", "mark6", "mark7", "mark8")
|
||||
|
||||
scanner:SetScript("OnEvent", function()
|
||||
if event == "UNIT_HEALTH" or event == "UNIT_MAXHEALTH" then
|
||||
-- arg1 is the token; "markN" -> N, nil for any non-mark token.
|
||||
local i = arg1 and tonumber(string.match(arg1, "^mark(%d)"))
|
||||
-- arg1 is one of the eight tokens we registered for, so this is a lookup
|
||||
-- rather than a parse -- string.match would allocate a capture and
|
||||
-- tonumber would parse it, on every health tick of every marked unit.
|
||||
local i = arg1 and markerIndex[arg1]
|
||||
if i then UpdateRow(i) end
|
||||
return
|
||||
end
|
||||
if event ~= "RAID_TARGET_UPDATE" then UpdatePoll() end
|
||||
UpdateDisplay()
|
||||
end)
|
||||
|
||||
-- Fallback poll: catches units that come into range AFTER a marker was set
|
||||
-- (no event fires for that case, so we need this safety net)
|
||||
C_Timer.NewTicker(FALLBACK_INTERVAL, UpdateDisplay)
|
||||
end)
|
||||
+1
-1
@@ -225,7 +225,7 @@ pfUI:RegisterModule("minimap", function ()
|
||||
pfUI.minimap.pvpicon = CreateFrame("Frame", nil, pfUI.minimap)
|
||||
pfUI.minimap.pvpicon:Hide()
|
||||
pfUI.minimap.pvpicon:RegisterEvent("UPDATE_FACTION")
|
||||
pfUI.minimap.pvpicon:RegisterEvent("UNIT_FACTION")
|
||||
pfUI.minimap.pvpicon:RegisterUnitEvent("UNIT_FACTION", "player")
|
||||
pfUI.minimap.pvpicon:SetFrameStrata("HIGH")
|
||||
pfUI.minimap.pvpicon:SetSize(16, 16)
|
||||
pfUI.minimap.pvpicon:SetAlpha(.5)
|
||||
|
||||
+100
-74
@@ -5,10 +5,7 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
-- Local function references for performance
|
||||
local GetTime = GetTime
|
||||
local UnitName = UnitName
|
||||
local UnitClass = UnitClass
|
||||
local UnitLevel = UnitLevel
|
||||
local UnitIsPlayer = UnitIsPlayer
|
||||
local UnitIsDead = UnitIsDead
|
||||
local UnitAffectingCombat = UnitAffectingCombat
|
||||
local UnitIsUnit = UnitIsUnit
|
||||
local UnitCanAssist = UnitCanAssist
|
||||
@@ -162,6 +159,24 @@ pfUI:RegisterModule("nameplates", function ()
|
||||
cfg.debuffanim = tonumber(C.nameplates.debuffanim) or 0
|
||||
cfg.debufftext = tonumber(C.nameplates.debufftext) or 1
|
||||
|
||||
-- Throttle delays, resolved once instead of per plate per tick.
|
||||
-- libthrottle:Get walks the saved-variable table, a defaults fallback and a
|
||||
-- preset table, and can build a "<category>_custom" key -- the per-plate
|
||||
-- OnUpdate was calling it one or two times for every visible plate, a
|
||||
-- hundred times a second, just to decide it had nothing to do.
|
||||
--
|
||||
-- cfg.throttle_min is the floor across all four. No plate can ever be due
|
||||
-- sooner than that, so the update can bail on it before working out which
|
||||
-- category it actually belongs to.
|
||||
cfg.throttle_target = pfUI.throttle:Get("nameplates_target")
|
||||
cfg.throttle_mass = pfUI.throttle:Get("nameplates_mass")
|
||||
cfg.throttle_normal = pfUI.throttle:Get("nameplates")
|
||||
cfg.throttle_castbar = pfUI.throttle:Get("nameplates_castbar")
|
||||
cfg.throttle_min = cfg.throttle_target
|
||||
if cfg.throttle_mass < cfg.throttle_min then cfg.throttle_min = cfg.throttle_mass end
|
||||
if cfg.throttle_normal < cfg.throttle_min then cfg.throttle_min = cfg.throttle_normal end
|
||||
if cfg.throttle_castbar < cfg.throttle_min then cfg.throttle_min = cfg.throttle_castbar end
|
||||
|
||||
-- Rebuild offtanks lookup table
|
||||
offtanks = {}
|
||||
for k, v in pairs({strsplit("#", C.nameplates.combatofftanks)}) do
|
||||
@@ -490,7 +505,7 @@ local nameplates = CreateFrame("Frame", "pfNameplates", UIParent)
|
||||
nameplates:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
nameplates:RegisterEvent("PLAYER_TARGET_CHANGED")
|
||||
nameplates:RegisterEvent("PLAYER_LOGOUT")
|
||||
nameplates:RegisterEvent("UNIT_COMBO_POINTS")
|
||||
nameplates:RegisterUnitEvent("UNIT_COMBO_POINTS", "player")
|
||||
nameplates:RegisterEvent("PLAYER_COMBO_POINTS")
|
||||
nameplates:RegisterEvent("ZONE_CHANGED_NEW_AREA")
|
||||
nameplates:RegisterEvent("RAID_ROSTER_UPDATE")
|
||||
@@ -498,13 +513,10 @@ nameplates:RegisterEvent("PARTY_MEMBERS_CHANGED")
|
||||
nameplates:RegisterEvent("NAME_PLATE_CREATED")
|
||||
nameplates:RegisterEvent("NAME_PLATE_UNIT_ADDED")
|
||||
nameplates:RegisterEvent("NAME_PLATE_UNIT_REMOVED")
|
||||
nameplates:RegisterEvent("UNIT_AURA")
|
||||
nameplates:RegisterEvent("UNIT_FLAGS")
|
||||
nameplates:RegisterEvent("UPDATE_MOUSEOVER_UNIT")
|
||||
nameplates:RegisterEvent("UNIT_SPELLCAST_START")
|
||||
nameplates:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START")
|
||||
nameplates:RegisterEvent("UNIT_SPELLCAST_STOP")
|
||||
nameplates:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP")
|
||||
-- UNIT_AURA / UNIT_FLAGS / UNIT_SPELLCAST_* are registered per plate, on the
|
||||
-- plate's own frame, against its own token -- see OnCreate and
|
||||
-- NAME_PLATE_UNIT_ADDED.
|
||||
nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||
|
||||
nameplates:SetScript("OnEvent", function()
|
||||
@@ -516,6 +528,15 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||
if nameplates.mouselook then
|
||||
nameplates.mouselook:SetScript("OnUpdate", nil)
|
||||
end
|
||||
-- The plates hold their own unit subscriptions now, so silencing this
|
||||
-- frame alone would leave them dispatching through logout -- exactly what
|
||||
-- this branch exists to prevent.
|
||||
for plate in pairs(registry) do
|
||||
if plate.nameplate then
|
||||
plate.nameplate:UnregisterAllEvents()
|
||||
plate.nameplate:SetScript("OnEvent", nil)
|
||||
end
|
||||
end
|
||||
return
|
||||
|
||||
elseif event == "PLAYER_GUILD_UPDATE" and arg1 == 'player' then
|
||||
@@ -591,6 +612,16 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||
local guid = UnitGUID(arg1)
|
||||
plate.nameplate.cachedGuid = guid
|
||||
plate.nameplate.unit = arg1
|
||||
|
||||
-- Point this plate's own subscriptions at the token it just took. On a
|
||||
-- recycled frame these replace the previous unit rather than stacking:
|
||||
-- RegisterUnitEvent on an already-filtered registration swaps the units.
|
||||
plate.nameplate:RegisterUnitEvent("UNIT_AURA", arg1)
|
||||
plate.nameplate:RegisterUnitEvent("UNIT_FLAGS", arg1)
|
||||
plate.nameplate:RegisterUnitEvent("UNIT_SPELLCAST_START", arg1)
|
||||
plate.nameplate:RegisterUnitEvent("UNIT_SPELLCAST_CHANNEL_START", arg1)
|
||||
plate.nameplate:RegisterUnitEvent("UNIT_SPELLCAST_STOP", arg1)
|
||||
plate.nameplate:RegisterUnitEvent("UNIT_SPELLCAST_CHANNEL_STOP", arg1)
|
||||
plate.nameplate.creatureType = nil -- recompute for the new unit
|
||||
plate.nameplate.totemIcon = nil
|
||||
plate.nameplate.totemSpell = nil
|
||||
@@ -621,14 +652,9 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||
if plate and plate.nameplate and plate.nameplate.cachedGuid == guid then
|
||||
plate.nameplate.cachedGuid = nil
|
||||
plate.nameplate.unit = nil
|
||||
end
|
||||
end
|
||||
|
||||
elseif event == "UNIT_FLAGS" then
|
||||
if arg1 and strfind(arg1, "^nameplate") then
|
||||
local plate = C_NamePlate.GetNamePlateForUnit(arg1)
|
||||
if plate and plate.nameplate then
|
||||
plate.nameplate.eventcache = true
|
||||
-- Drop the subscriptions with the token: this slot is now free and the
|
||||
-- next plate to take it would otherwise feed this frame its events.
|
||||
plate.nameplate:UnregisterAllEvents()
|
||||
end
|
||||
end
|
||||
|
||||
@@ -643,48 +669,6 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||
if pn then pn.eventcache = true end
|
||||
end
|
||||
|
||||
elseif event == "UNIT_SPELLCAST_START" or event == "UNIT_SPELLCAST_CHANNEL_START" then
|
||||
-- ClassicAPI fires UNIT_SPELLCAST_* per unit token, including the caster's
|
||||
-- "nameplateN". The payload has no timing, so poll it (PollCastInfo picks
|
||||
-- cast vs channel) and cache -- only for a unit we have a plate for, so
|
||||
-- the table stays bounded to on-screen casters.
|
||||
if arg1 and strfind(arg1, "^nameplate") then
|
||||
local guid = UnitGUID(arg1)
|
||||
local plate = guid and plateByGuid[guid]
|
||||
if plate then
|
||||
castState[guid] = PollCastInfo(arg1)
|
||||
if castState[guid] then
|
||||
plate.castUpdate = true -- bypass the throttle so the bar shows now
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
elseif event == "UNIT_SPELLCAST_STOP" or event == "UNIT_SPELLCAST_CHANNEL_STOP" then
|
||||
-- Cast/channel ended (natural, interrupted, or cancelled -- the poll fires
|
||||
-- STOP for all three). Clear the cached cast and refresh its plate.
|
||||
if arg1 and strfind(arg1, "^nameplate") then
|
||||
local guid = UnitGUID(arg1)
|
||||
if guid and castState[guid] then
|
||||
castState[guid] = nil
|
||||
local plate = plateByGuid[guid]
|
||||
if plate then plate.castUpdate = true end
|
||||
end
|
||||
end
|
||||
|
||||
elseif event == "UNIT_AURA" then
|
||||
-- ClassicAPI: fires with arg1 == "nameplateN" when a unit's aura set
|
||||
-- changes (add/remove/modify). Flag the matching plate so OnUpdate does a
|
||||
-- fresh C_UnitAuras read next tick instead of waiting on the 0.5s
|
||||
-- throttle -- covers expirations, dispels, refreshes, and stack changes
|
||||
-- in one event. Guard on the token prefix (UNIT_AURA also fires for
|
||||
-- target/party/raid).
|
||||
if arg1 and strfind(arg1, "^nameplate") then
|
||||
local plate = C_NamePlate.GetNamePlateForUnit(arg1)
|
||||
if plate and plate.nameplate then
|
||||
plate.nameplate.auraUpdate = true
|
||||
end
|
||||
end
|
||||
|
||||
elseif event == "PLAYER_TARGET_CHANGED" then
|
||||
frameState.targetGuid = UnitGUID('target')
|
||||
-- Flag the target's plate for update
|
||||
@@ -766,6 +750,40 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||
nameplate.cache = {}
|
||||
nameplate.original = {}
|
||||
|
||||
-- Each plate watches its own unit. With RegisterUnitEvent the token IS the
|
||||
-- subscription, so there is no central listener sifting every unit event in
|
||||
-- the world for a "^nameplate" prefix and then resolving the plate back out
|
||||
-- of arg1 -- the event arrives only at the plate it concerns, and `this` is
|
||||
-- already that plate. NAME_PLATE_UNIT_ADDED points the registration at the
|
||||
-- new token; _REMOVED drops it, which matters because freed slots are
|
||||
-- reused and a stale token would feed this frame another unit's events.
|
||||
nameplate:SetScript("OnEvent", function()
|
||||
if event == "UNIT_AURA" then
|
||||
-- a fresh C_UnitAuras read next tick rather than waiting out the 0.5s
|
||||
-- throttle -- covers expiry, dispels, refreshes and stack changes
|
||||
this.auraUpdate = true
|
||||
elseif event == "UNIT_FLAGS" then
|
||||
this.eventcache = true
|
||||
elseif event == "UNIT_SPELLCAST_START" or event == "UNIT_SPELLCAST_CHANNEL_START" then
|
||||
-- the payload carries no timing, so poll it (PollCastInfo picks cast
|
||||
-- vs channel)
|
||||
local guid = this.cachedGuid
|
||||
if guid then
|
||||
castState[guid] = PollCastInfo(this.unit)
|
||||
if castState[guid] then
|
||||
this.castUpdate = true -- bypass the throttle so the bar shows now
|
||||
end
|
||||
end
|
||||
elseif event == "UNIT_SPELLCAST_STOP" or event == "UNIT_SPELLCAST_CHANNEL_STOP" then
|
||||
-- ended: natural, interrupted or cancelled -- the poll fires STOP for all
|
||||
local guid = this.cachedGuid
|
||||
if guid and castState[guid] then
|
||||
castState[guid] = nil
|
||||
this.castUpdate = true
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- create shortcuts for all known elements and disable them
|
||||
nameplate.original.healthbar, nameplate.original.castbar = parent:GetChildren()
|
||||
DisableObject(nameplate.original.healthbar)
|
||||
@@ -1409,6 +1427,16 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||
|
||||
-- cachedGuid is maintained by NAME_PLATE_UNIT_ADDED / _REMOVED events.
|
||||
|
||||
-- Cheap gate first. The central loop calls this for every visible plate ~100
|
||||
-- times a second, and classifying the plate below costs two C calls, a cast
|
||||
-- lookup and a throttle resolution -- all of it wasted on a plate that is
|
||||
-- throttled to 10fps. cfg.throttle_min is the floor across every category,
|
||||
-- so nothing that would have updated can be turned away here; the real
|
||||
-- category-specific throttle is still applied after the classification.
|
||||
-- Event flags bypass both gates, as before.
|
||||
local hasEventUpdate = nameplate.eventcache or nameplate.auraUpdate or nameplate.castUpdate or nameplate.targetUpdate or nameplate.comboUpdate
|
||||
if not hasEventUpdate and (nameplate.lasttick or 0) + cfg.throttle_min > now then return end
|
||||
|
||||
-- PERF: Intelligent throttling based on target/castbar status and plate count
|
||||
-- Use GUID comparison as primary target detection: instant, immune to alpha transitions,
|
||||
-- and immediately correct on de-target (unlike istarget which updates one tick later)
|
||||
@@ -1435,25 +1463,24 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||
end
|
||||
end
|
||||
|
||||
-- Resolved in CacheConfig, so these are table reads rather than a walk
|
||||
-- through the saved variables and preset tables.
|
||||
local throttle
|
||||
if target then
|
||||
throttle = pfUI.throttle:Get("nameplates_target")
|
||||
throttle = cfg.throttle_target
|
||||
elseif visiblePlateCount > 20 then
|
||||
throttle = pfUI.throttle:Get("nameplates_mass")
|
||||
throttle = cfg.throttle_mass
|
||||
else
|
||||
throttle = pfUI.throttle:Get("nameplates")
|
||||
throttle = cfg.throttle_normal
|
||||
end
|
||||
|
||||
-- Non-target plates with active castbar use the castbar throttle
|
||||
if isCastingNonTarget then
|
||||
local cbThrottle = pfUI.throttle:Get("nameplates_castbar")
|
||||
if cbThrottle < throttle then throttle = cbThrottle end
|
||||
if isCastingNonTarget and cfg.throttle_castbar < throttle then
|
||||
throttle = cfg.throttle_castbar
|
||||
end
|
||||
|
||||
-- Check for pending event updates (these bypass throttle for immediate response)
|
||||
local hasEventUpdate = nameplate.eventcache or nameplate.auraUpdate or nameplate.castUpdate or nameplate.targetUpdate or nameplate.comboUpdate
|
||||
|
||||
-- Event updates bypass throttle
|
||||
-- The category-specific gate. hasEventUpdate was read above, before the
|
||||
-- classification, and still bypasses the throttle.
|
||||
if not hasEventUpdate and (nameplate.lasttick or 0) + throttle > now then return end
|
||||
nameplate.lasttick = now
|
||||
|
||||
@@ -1655,10 +1682,9 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||
-- engine framerate, decoupled from central loop). Only update non-target castbars here.
|
||||
local isTargetPlate = target or nameplate.istarget or (nameplate.health and nameplate.health.zoomed)
|
||||
if cfg.showcastbar and not cfg.targetcastbar and not isTargetPlate then
|
||||
local cbThrottle = pfUI.throttle:Get("nameplates_castbar")
|
||||
if visiblePlateCount > 20 then
|
||||
local massThrottle = pfUI.throttle:Get("nameplates_mass")
|
||||
if massThrottle > cbThrottle then cbThrottle = massThrottle end
|
||||
local cbThrottle = cfg.throttle_castbar
|
||||
if visiblePlateCount > 20 and cfg.throttle_mass > cbThrottle then
|
||||
cbThrottle = cfg.throttle_mass
|
||||
end
|
||||
if (nameplate.castbar_tick or 0) + cbThrottle <= now then
|
||||
nameplate.castbar_tick = now
|
||||
|
||||
+1
-1
@@ -486,7 +486,7 @@ pfUI:RegisterModule("panel", function()
|
||||
do -- Ammo
|
||||
local widget = CreateFrame("Frame", "pfPanelWidgetAmmo", UIParent)
|
||||
widget:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
widget:RegisterEvent("UNIT_INVENTORY_CHANGED")
|
||||
widget:RegisterUnitEvent("UNIT_INVENTORY_CHANGED", "player")
|
||||
widget:RegisterEvent("BAG_UPDATE_DELAYED")
|
||||
widget.Tooltip = function()
|
||||
if GetInventoryItemQuality("player", 0) then
|
||||
|
||||
@@ -816,7 +816,7 @@ pfUI:RegisterModule("swingtimer", function ()
|
||||
events:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||
events:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||
events:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
|
||||
events:RegisterEvent("UNIT_DIED")
|
||||
events:RegisterUnitEvent("UNIT_DIED", UnitGUID("player"))
|
||||
events:RegisterEvent("SPELL_QUEUE_EVENT")
|
||||
events:RegisterEvent("START_AUTOATTACK")
|
||||
events:RegisterEvent("STOP_AUTOATTACK")
|
||||
|
||||
+3
-3
@@ -363,9 +363,9 @@ end
|
||||
b:EnableMouse(true)
|
||||
|
||||
b:RegisterEvent("FACTION_STANDING_CHANGED")
|
||||
b:RegisterEvent("UNIT_PET")
|
||||
b:RegisterEvent("UNIT_LEVEL")
|
||||
b:RegisterEvent("UNIT_PET_EXPERIENCE")
|
||||
b:RegisterUnitEvent("UNIT_PET", "player")
|
||||
b:RegisterUnitEvent("UNIT_LEVEL", "player")
|
||||
b:RegisterUnitEvent("UNIT_PET_EXPERIENCE", "player", "pet")
|
||||
b:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
b:RegisterEvent("UPDATE_EXHAUSTION")
|
||||
b:RegisterEvent("PLAYER_XP_UPDATE")
|
||||
|
||||
Reference in New Issue
Block a user