mirror of
https://github.com/brues-code/pfUI.git
synced 2026-09-21 23:26:56 +00:00
Filter unit events to their units, rework energytick, drop macrotweak
Eight commits off classicapi_next. ClassicAPI's RegisterUnitEvent registers for an event but only delivers it when arg1 is one of the given units, so a handler for one unit stops waking for every other one in the world. The 26 registrations whose unit set is fixed at registration time now name it. The rule throughout is register the superset and keep the handler's own check -- the filter narrows what arrives, it does not decide what to act on. Guards that look unreachable stay put: the filter applies only when arg1 is a string, so an event that fires with a number or no argument is delivered as if plainly registered. Frames whose unit changes at runtime own their subscriptions instead of sorting events out per event. unitframes points them at the unitstr UpdateVisibility already computes -- replacing a string concat, and on a miss a second concat plus a UnitGUID call, for every frame on every unit event in the world -- and a frame that is not in use drops its unit events entirely. nameplates registers per plate against the plate's own token, which is also the only workable shape: slots have no cap, so any nameplate1..N list would have been a guess that fails in exactly the crowded scenes where plates matter. marktracking names mark1 through mark8. A registration keeps its kind, so none of these can be plain-registered first. Both teardown paths PLAYER_LOGOUT guards -- the crash 132 -- now cover the per-frame subscriptions: plates tear down rather than dispatching through logout, and a unit frame takes itself off the visibility scan so it cannot re-register what it just dropped. marktracking also drops its once-a-second full rebuild, which ran for the whole session whether or not a marker existed anywhere. The ticker is created and cancelled with group membership. It is deliberately not keyed on a mark being visible -- a marker on an out-of-range unit shows no row, and that is the case the poll exists to catch. nameplates gates the per-plate update against the floor across all four throttle categories before classifying it, instead of running a GetAlpha, a castbar IsShown, a cast lookup and up to two libthrottle:Get resolutions on plates throttled to 10fps that were going to return anyway. Nothing that would have updated can be turned away by a floor. The four throttles resolve in CacheConfig, where config changes already land. energytick sweeps the clock the server actually runs. There is one regen timer for every power, re-armed every 2s by Player::RegenerateAll and never touched by casting; the five-second rule changes what a tick pays, not when it lands. The sweep is a free-running phase lock on that clock, so Illumination refunds, potions and a Mana Spring totem on its own phase no longer snap the spark mid-cycle, and an 80ms band keeps a correct tick from hitching it at the wrap. The FSR window shades rather than predicting a share of spirit the client cannot compute -- the Casting Regen item ladder is equip auras absent from the buff list. The energy period is summed from SPELL_AURA_MOD_ENERGY_REGEN_TIME across the spellbook and buffs, so Blade Rush is found without GetTalentInfo(2, 16), an ordinal that does not fail when the tree changes but reads another talent's rank. macrotweak is gone -- ClassicAPI 1.15 covers it -- with its config entry, its GUI block, its translations in all eight locales, and actionbar's ButtonMacroScan, the #showtooltip scanner that fed it.
This commit is contained in:
+1
-1
@@ -13,7 +13,7 @@ do
|
|||||||
-- on. There pfUI does load, and will throw wherever it reaches for something
|
-- 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
|
-- the installed DLL doesn't have yet -- the popup names the cause so those
|
||||||
-- errors aren't a mystery.
|
-- 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_LATEST = PFUI_CLASSIC_API_MIN
|
||||||
local PFUI_CLASSIC_API_WEBSITE = "https://github.com/brues-code/ClassicAPI"
|
local PFUI_CLASSIC_API_WEBSITE = "https://github.com/brues-code/ClassicAPI"
|
||||||
local PFUI_CLASSIC_API_LATEST_URL = PFUI_CLASSIC_API_WEBSITE .. "/releases/latest"
|
local PFUI_CLASSIC_API_LATEST_URL = PFUI_CLASSIC_API_WEBSITE .. "/releases/latest"
|
||||||
|
|||||||
@@ -645,7 +645,6 @@ function pfUI:LoadConfig()
|
|||||||
pfUI:UpdateConfig("bars", nil, "animation", "zoomfade")
|
pfUI:UpdateConfig("bars", nil, "animation", "zoomfade")
|
||||||
pfUI:UpdateConfig("bars", nil, "animmode", "keypress")
|
pfUI:UpdateConfig("bars", nil, "animmode", "keypress")
|
||||||
pfUI:UpdateConfig("bars", nil, "animalways", "0")
|
pfUI:UpdateConfig("bars", nil, "animalways", "0")
|
||||||
pfUI:UpdateConfig("bars", nil, "macroscan", "1")
|
|
||||||
pfUI:UpdateConfig("bars", nil, "reagents", "1")
|
pfUI:UpdateConfig("bars", nil, "reagents", "1")
|
||||||
pfUI:UpdateConfig("bars", nil, "hunterbar", "0")
|
pfUI:UpdateConfig("bars", nil, "hunterbar", "0")
|
||||||
pfUI:UpdateConfig("bars", nil, "pagemasteralt", "0")
|
pfUI:UpdateConfig("bars", nil, "pagemasteralt", "0")
|
||||||
|
|||||||
+78
-19
@@ -314,7 +314,8 @@ function pfUI.uf:UpdateVisibility()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local unitstr = ("%s%s"):format(self.label or "", self.id or "")
|
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)
|
local visibility = ("[target=%s,exists] show; hide"):format(unitstr)
|
||||||
|
|
||||||
-- Group frames are redundant when the group is already shown as a raid grid:
|
-- 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
|
self.visible = nil
|
||||||
end
|
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
|
-- vanilla visibility
|
||||||
if self.unitname then
|
if self.unitname then
|
||||||
self:Show()
|
self:Show()
|
||||||
@@ -624,11 +634,14 @@ function pfUI.uf:UpdateConfig()
|
|||||||
f.feedbackText:ClearAllPoints()
|
f.feedbackText:ClearAllPoints()
|
||||||
f.feedbackText:SetPoint("CENTER", f.portrait, "CENTER")
|
f.feedbackText:SetPoint("CENTER", f.portrait, "CENTER")
|
||||||
end
|
end
|
||||||
f:RegisterEvent("UNIT_COMBAT")
|
f.combatfeedback = true
|
||||||
else
|
else
|
||||||
f.feedbackText:Hide()
|
f.feedbackText:Hide()
|
||||||
f:UnregisterEvent("UNIT_COMBAT")
|
f.combatfeedback = nil
|
||||||
end
|
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:SetFontObject(GameFontWhite)
|
||||||
f.hpLeftText:SetFont(fontname, fontsize, fontstyle)
|
f.hpLeftText:SetFont(fontname, fontsize, fontstyle)
|
||||||
@@ -918,6 +931,9 @@ function pfUI.uf:UpdateConfig()
|
|||||||
f:UpdateFrameSize()
|
f:UpdateFrameSize()
|
||||||
else
|
else
|
||||||
f:UnregisterAllEvents()
|
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()
|
f:Hide()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -959,6 +975,10 @@ function pfUI.uf.OnEvent()
|
|||||||
this:UnregisterAllEvents()
|
this:UnregisterAllEvents()
|
||||||
this:SetScript("OnEvent", nil)
|
this:SetScript("OnEvent", nil)
|
||||||
this:SetScript("OnUpdate", 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
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1025,8 +1045,12 @@ function pfUI.uf.OnEvent()
|
|||||||
this.update_aura = true
|
this.update_aura = true
|
||||||
elseif this.label == "pet" and event == "UNIT_HAPPINESS" then
|
elseif this.label == "pet" and event == "UNIT_HAPPINESS" then
|
||||||
this.update_full = true
|
this.update_full = true
|
||||||
-- UNIT_XXX Events
|
-- UNIT_XXX Events. RegisterUnitEvents means arg1 can only be this frame's own
|
||||||
elseif arg1 and (arg1 == this.label .. this.id or (UnitGUID and arg1 == UnitGUID(this.label .. this.id))) then
|
-- 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
|
if event == "UNIT_PORTRAIT_UPDATE" or event == "UNIT_MODEL_CHANGED" then
|
||||||
this.update_portrait = true
|
this.update_portrait = true
|
||||||
elseif event == "UNIT_AURA" then
|
elseif event == "UNIT_AURA" then
|
||||||
@@ -1251,25 +1275,56 @@ function pfUI.uf.OnUpdate()
|
|||||||
end
|
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).
|
||||||
|
--
|
||||||
|
-- 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()
|
function pfUI.uf:EnableEvents()
|
||||||
local f = self
|
local f = self
|
||||||
|
|
||||||
f:RegisterEvent("PLAYER_ENTERING_WORLD")
|
f:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||||
f:RegisterEvent("PLAYER_LOGOUT")
|
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_AURAS_CHANGED") -- label=player && frame=buff
|
||||||
f:RegisterEvent("PLAYER_EQUIPMENT_CHANGED") -- label=player && frame=buff (ClassicAPI: weapon-enchant buffs)
|
f:RegisterEvent("PLAYER_EQUIPMENT_CHANGED") -- label=player && frame=buff (ClassicAPI: weapon-enchant buffs)
|
||||||
f:RegisterEvent("PARTY_MEMBERS_CHANGED") -- label=party, frame=leaderIcon
|
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.UpdateConfig = pfUI.uf.UpdateConfig
|
||||||
f.EnableScripts = pfUI.uf.EnableScripts
|
f.EnableScripts = pfUI.uf.EnableScripts
|
||||||
f.EnableEvents = pfUI.uf.EnableEvents
|
f.EnableEvents = pfUI.uf.EnableEvents
|
||||||
|
f.RegisterUnitEvents = pfUI.uf.RegisterUnitEvents
|
||||||
f.EnableClickCast = pfUI.uf.EnableClickCast
|
f.EnableClickCast = pfUI.uf.EnableClickCast
|
||||||
f.GetColor = pfUI.uf.GetColor
|
f.GetColor = pfUI.uf.GetColor
|
||||||
|
|
||||||
@@ -1503,6 +1559,9 @@ function pfUI.uf:CreateUnitFrame(unit, id, config, tick)
|
|||||||
f:UpdateFrameSize()
|
f:UpdateFrameSize()
|
||||||
else
|
else
|
||||||
f:UnregisterAllEvents()
|
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()
|
f:Hide()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Vendored
-1
@@ -670,7 +670,6 @@ pfUI_translation["deDE"] = {
|
|||||||
["Scale"] = nil,
|
["Scale"] = nil,
|
||||||
["Scale Border On HiDPI Displays"] = nil,
|
["Scale Border On HiDPI Displays"] = nil,
|
||||||
["Scaling"] = nil,
|
["Scaling"] = nil,
|
||||||
["Scan Macros For Spells"] = nil,
|
|
||||||
["Screen Edge Glow Intensity"] = nil,
|
["Screen Edge Glow Intensity"] = nil,
|
||||||
["Screen Resolution"] = nil,
|
["Screen Resolution"] = nil,
|
||||||
["Screenshot"] = nil,
|
["Screenshot"] = nil,
|
||||||
|
|||||||
Vendored
-1
@@ -683,7 +683,6 @@ pfUI_translation["enUS"] = {
|
|||||||
["Scale"] = nil,
|
["Scale"] = nil,
|
||||||
["Scale Border On HiDPI Displays"] = nil,
|
["Scale Border On HiDPI Displays"] = nil,
|
||||||
["Scaling"] = nil,
|
["Scaling"] = nil,
|
||||||
["Scan Macros For Spells"] = nil,
|
|
||||||
["Screen Edge Glow Intensity"] = nil,
|
["Screen Edge Glow Intensity"] = nil,
|
||||||
["Screen Resolution"] = nil,
|
["Screen Resolution"] = nil,
|
||||||
["Screenshot"] = nil,
|
["Screenshot"] = nil,
|
||||||
|
|||||||
Vendored
-1
@@ -670,7 +670,6 @@ pfUI_translation["esES"] = {
|
|||||||
["Scale"] = "Escala",
|
["Scale"] = "Escala",
|
||||||
["Scale Border On HiDPI Displays"] = "Escalar los bordes en las pantallas con DPI alto",
|
["Scale Border On HiDPI Displays"] = "Escalar los bordes en las pantallas con DPI alto",
|
||||||
["Scaling"] = "Escalada",
|
["Scaling"] = "Escalada",
|
||||||
["Scan Macros For Spells"] = nil,
|
|
||||||
["Screen Edge Glow Intensity"] = "Intensidad de brillo en los bordes de la pantalla",
|
["Screen Edge Glow Intensity"] = "Intensidad de brillo en los bordes de la pantalla",
|
||||||
["Screen Resolution"] = "Resolución de pantalla",
|
["Screen Resolution"] = "Resolución de pantalla",
|
||||||
["Screenshot"] = "Captura de pantalla",
|
["Screenshot"] = "Captura de pantalla",
|
||||||
|
|||||||
Vendored
-1
@@ -670,7 +670,6 @@ pfUI_translation["frFR"] = {
|
|||||||
["Scale"] = "Échelle",
|
["Scale"] = "Échelle",
|
||||||
["Scale Border On HiDPI Displays"] = "Échelle de bordure sur les écrans HiDPI",
|
["Scale Border On HiDPI Displays"] = "Échelle de bordure sur les écrans HiDPI",
|
||||||
["Scaling"] = "Mise à l'échelle",
|
["Scaling"] = "Mise à l'échelle",
|
||||||
["Scan Macros For Spells"] = nil,
|
|
||||||
["Screen Edge Glow Intensity"] = nil,
|
["Screen Edge Glow Intensity"] = nil,
|
||||||
["Screen Resolution"] = "Résolution d'écran",
|
["Screen Resolution"] = "Résolution d'écran",
|
||||||
["Screenshot"] = "Imprime écran",
|
["Screenshot"] = "Imprime écran",
|
||||||
|
|||||||
Vendored
-1
@@ -670,7 +670,6 @@ pfUI_translation["koKR"] = {
|
|||||||
["Scale"] = nil,
|
["Scale"] = nil,
|
||||||
["Scale Border On HiDPI Displays"] = nil,
|
["Scale Border On HiDPI Displays"] = nil,
|
||||||
["Scaling"] = nil,
|
["Scaling"] = nil,
|
||||||
["Scan Macros For Spells"] = nil,
|
|
||||||
["Screen Edge Glow Intensity"] = nil,
|
["Screen Edge Glow Intensity"] = nil,
|
||||||
["Screen Resolution"] = "화면 해상도",
|
["Screen Resolution"] = "화면 해상도",
|
||||||
["Screenshot"] = nil,
|
["Screenshot"] = nil,
|
||||||
|
|||||||
Vendored
-1
@@ -670,7 +670,6 @@ pfUI_translation["ruRU"] = {
|
|||||||
["Scale"] = "Масштаб",
|
["Scale"] = "Масштаб",
|
||||||
["Scale Border On HiDPI Displays"] = "Масштабировать границы на HiDPI мониторах",
|
["Scale Border On HiDPI Displays"] = "Масштабировать границы на HiDPI мониторах",
|
||||||
["Scaling"] = "Масштаб интерфейса",
|
["Scaling"] = "Масштаб интерфейса",
|
||||||
["Scan Macros For Spells"] = nil,
|
|
||||||
["Screen Edge Glow Intensity"] = "Интенсивность свечения на краях экрана",
|
["Screen Edge Glow Intensity"] = "Интенсивность свечения на краях экрана",
|
||||||
["Screen Resolution"] = "Разрешение экрана",
|
["Screen Resolution"] = "Разрешение экрана",
|
||||||
["Screenshot"] = "Снимок экрана",
|
["Screenshot"] = "Снимок экрана",
|
||||||
|
|||||||
Vendored
-1
@@ -670,7 +670,6 @@ pfUI_translation["zhCN"] = {
|
|||||||
["Scale"] = "比例",
|
["Scale"] = "比例",
|
||||||
["Scale Border On HiDPI Displays"] = "缩放高DPI显示器上的边框",
|
["Scale Border On HiDPI Displays"] = "缩放高DPI显示器上的边框",
|
||||||
["Scaling"] = "UI缩放",
|
["Scaling"] = "UI缩放",
|
||||||
["Scan Macros For Spells"] = "扫描宏命令中的法术",
|
|
||||||
["Screen Edge Glow Intensity"] = "屏幕边缘发光强度",
|
["Screen Edge Glow Intensity"] = "屏幕边缘发光强度",
|
||||||
["Screen Resolution"] = "屏幕分辨率",
|
["Screen Resolution"] = "屏幕分辨率",
|
||||||
["Screenshot"] = "屏幕截图",
|
["Screenshot"] = "屏幕截图",
|
||||||
|
|||||||
Vendored
-1
@@ -670,7 +670,6 @@ pfUI_translation["zhTW"] = {
|
|||||||
["Scale"] = "比例",
|
["Scale"] = "比例",
|
||||||
["Scale Border On HiDPI Displays"] = nil,
|
["Scale Border On HiDPI Displays"] = nil,
|
||||||
["Scaling"] = nil,
|
["Scaling"] = nil,
|
||||||
["Scan Macros For Spells"] = nil,
|
|
||||||
["Screen Edge Glow Intensity"] = nil,
|
["Screen Edge Glow Intensity"] = nil,
|
||||||
["Screen Resolution"] = "螢幕解析度",
|
["Screen Resolution"] = "螢幕解析度",
|
||||||
["Screenshot"] = nil,
|
["Screenshot"] = nil,
|
||||||
|
|||||||
@@ -70,7 +70,6 @@
|
|||||||
<Include file="..\modules\addoncompat.lua"/>
|
<Include file="..\modules\addoncompat.lua"/>
|
||||||
<Include file="..\modules\energytick.lua"/>
|
<Include file="..\modules\energytick.lua"/>
|
||||||
<Include file="..\modules\totems.lua"/>
|
<Include file="..\modules\totems.lua"/>
|
||||||
<Include file="..\modules\macrotweak.lua"/>
|
|
||||||
<Include file="..\modules\macroicons.lua"/>
|
<Include file="..\modules\macroicons.lua"/>
|
||||||
<Include file="..\modules\superwow.lua"/>
|
<Include file="..\modules\superwow.lua"/>
|
||||||
<Include file="..\modules\innervatecall.lua"/>
|
<Include file="..\modules\innervatecall.lua"/>
|
||||||
|
|||||||
+2
-2
@@ -10,8 +10,8 @@ local libhealth = CreateFrame("Frame")
|
|||||||
libhealth.enabled = true
|
libhealth.enabled = true
|
||||||
libhealth.reqhit = 4
|
libhealth.reqhit = 4
|
||||||
libhealth.reqdmg = 5
|
libhealth.reqdmg = 5
|
||||||
libhealth:RegisterEvent("UNIT_HEALTH")
|
libhealth:RegisterUnitEvent("UNIT_HEALTH", "target")
|
||||||
libhealth:RegisterEvent("UNIT_COMBAT")
|
libhealth:RegisterUnitEvent("UNIT_COMBAT", "target")
|
||||||
libhealth:RegisterEvent("PLAYER_TARGET_CHANGED")
|
libhealth:RegisterEvent("PLAYER_TARGET_CHANGED")
|
||||||
libhealth:RegisterEvent("PLAYER_ENTERING_WORLD")
|
libhealth:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||||
libhealth:SetScript("OnEvent", function()
|
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
|
libpredict.sender:RegisterEvent("SPELL_HEAL_BY_OTHER") -- populates foreignCache for other healers
|
||||||
|
|
||||||
-- force cache updates
|
-- force cache updates
|
||||||
libpredict.sender:RegisterEvent("UNIT_INVENTORY_CHANGED")
|
libpredict.sender:RegisterUnitEvent("UNIT_INVENTORY_CHANGED", "player")
|
||||||
libpredict.sender:RegisterEvent("SKILL_LINES_CHANGED")
|
libpredict.sender:RegisterEvent("SKILL_LINES_CHANGED")
|
||||||
|
|
||||||
-- Shared cleanup helper for failed/interrupted casts
|
-- Shared cleanup helper for failed/interrupted casts
|
||||||
|
|||||||
+23
-73
@@ -360,68 +360,6 @@ pfUI:RegisterModule("actionbar", function ()
|
|||||||
end
|
end
|
||||||
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)
|
local function ButtonEnter(self)
|
||||||
self = self or this
|
self = self or this
|
||||||
|
|
||||||
@@ -690,7 +628,6 @@ pfUI:RegisterModule("actionbar", function ()
|
|||||||
local function ButtonFullUpdate(button)
|
local function ButtonFullUpdate(button)
|
||||||
if not button then return end
|
if not button then return end
|
||||||
|
|
||||||
ButtonMacroScan(button)
|
|
||||||
ButtonSlotUpdate(button)
|
ButtonSlotUpdate(button)
|
||||||
ButtonRangeUpdate(button)
|
ButtonRangeUpdate(button)
|
||||||
ButtonUsableUpdate(button)
|
ButtonUsableUpdate(button)
|
||||||
@@ -807,10 +744,28 @@ pfUI:RegisterModule("actionbar", function ()
|
|||||||
|
|
||||||
-- create the main event and update handler for pfUI actionbars
|
-- create the main event and update handler for pfUI actionbars
|
||||||
local bars = CreateFrame("Frame", "pfActionBar", UIParent)
|
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
|
-- The only unit events in the tables above; both concern the player alone.
|
||||||
for event in pairs(aura_events) do bars:RegisterEvent(event) end
|
-- A registration keeps its kind, so these have to go in unit-filtered from
|
||||||
for event in pairs(pet_events) do bars:RegisterEvent(event) end
|
-- 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
|
-- refresh actionbar buttons on event
|
||||||
bars:SetScript("OnEvent", BarsEvent)
|
bars:SetScript("OnEvent", BarsEvent)
|
||||||
@@ -1148,12 +1103,7 @@ pfUI:RegisterModule("actionbar", function ()
|
|||||||
f.count:SetJustifyH("RIGHT")
|
f.count:SetJustifyH("RIGHT")
|
||||||
f.count:SetJustifyV("BOTTOM")
|
f.count:SetJustifyV("BOTTOM")
|
||||||
|
|
||||||
-- macro spell scan (disabled when macro addons are loaded)
|
f.scanmacro, f.spellslot, f.booktype = nil, nil, nil
|
||||||
if C.bars.macroscan == "0" or pfUI:MacroAddonsLoaded() then
|
|
||||||
f.scanmacro, f.spellslot, f.booktype = nil, nil, nil
|
|
||||||
else
|
|
||||||
f.scanmacro = true
|
|
||||||
end
|
|
||||||
|
|
||||||
-- range glow color
|
-- range glow color
|
||||||
f.rangeColor = GetStringColorObject(C.bars.rangecolor)
|
f.rangeColor = GetStringColorObject(C.bars.rangecolor)
|
||||||
|
|||||||
+1
-1
@@ -164,7 +164,7 @@ pfUI:RegisterModule("buff", function ()
|
|||||||
pfUI.buff = CreateFrame("Frame", "pfGlobalBuffFrame", UIParent)
|
pfUI.buff = CreateFrame("Frame", "pfGlobalBuffFrame", UIParent)
|
||||||
pfUI.buff:RegisterEvent("PLAYER_AURAS_CHANGED")
|
pfUI.buff:RegisterEvent("PLAYER_AURAS_CHANGED")
|
||||||
pfUI.buff:RegisterEvent("PLAYER_EQUIPMENT_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("BUFF_UPDATE_DURATION_SELF")
|
||||||
pfUI.buff:RegisterEvent("DEBUFF_UPDATE_DURATION_SELF")
|
pfUI.buff:RegisterEvent("DEBUFF_UPDATE_DURATION_SELF")
|
||||||
pfUI.buff:SetScript("OnEvent", function()
|
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
|
-- 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
|
-- player (target=self). PLAYER_TARGET/FOCUS_CHANGED re-polls so a unit
|
||||||
-- already mid-cast when it becomes the target/focus still shows.
|
-- already mid-cast when it becomes the target/focus still shows.
|
||||||
cb:RegisterEvent("UNIT_SPELLCAST_START")
|
-- Filter to this bar's unit, plus "player" for the target/focus bars: the
|
||||||
cb:RegisterEvent("UNIT_SPELLCAST_STOP")
|
-- player's own casts only ever fire arg1=="player", so a self-targeted cast
|
||||||
cb:RegisterEvent("UNIT_SPELLCAST_FAILED")
|
-- has to reach them too (nil for the player bar itself, which the filter
|
||||||
cb:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED")
|
-- skips). This only narrows what arrives -- the arg1/UnitIsUnit test below
|
||||||
cb:RegisterEvent("UNIT_SPELLCAST_DELAYED")
|
-- still decides whether the bar acts on it.
|
||||||
cb:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")
|
local selfunit = unitstr ~= "player" and "player" or nil
|
||||||
cb:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START")
|
cb:RegisterUnitEvent("UNIT_SPELLCAST_START", unitstr, selfunit)
|
||||||
cb:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP")
|
cb:RegisterUnitEvent("UNIT_SPELLCAST_STOP", unitstr, selfunit)
|
||||||
cb:RegisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE")
|
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
|
if unitstr == "target" then
|
||||||
cb:RegisterEvent("PLAYER_TARGET_CHANGED")
|
cb:RegisterEvent("PLAYER_TARGET_CHANGED")
|
||||||
elseif unitstr == "focus" then
|
elseif unitstr == "focus" then
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ pfUI:RegisterModule("combopoints", function ()
|
|||||||
-- combo
|
-- combo
|
||||||
if class == "DRUID" or class == "ROGUE" then
|
if class == "DRUID" or class == "ROGUE" then
|
||||||
local combo = CreateFrame("Frame")
|
local combo = CreateFrame("Frame")
|
||||||
combo:RegisterEvent("UNIT_COMBO_POINTS")
|
combo:RegisterUnitEvent("UNIT_COMBO_POINTS", "player")
|
||||||
combo:RegisterEvent("PLAYER_COMBO_POINTS")
|
combo:RegisterEvent("PLAYER_COMBO_POINTS")
|
||||||
combo:RegisterEvent("PLAYER_TARGET_CHANGED")
|
combo:RegisterEvent("PLAYER_TARGET_CHANGED")
|
||||||
combo:RegisterEvent("PLAYER_ENTERING_WORLD")
|
combo:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||||
|
|||||||
+185
-60
@@ -1,20 +1,82 @@
|
|||||||
local function getAdjustedTickTimer()
|
-- One server clock drives every power: Player::RegenerateAll fires every
|
||||||
local adjustedEnergyTick = 2
|
-- 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)
|
local FIVE_SECOND_RULE = 5
|
||||||
if UnitClassBase("player") == "ROGUE" then
|
|
||||||
local _, _, _, _, currRank = GetTalentInfo(2, 16)
|
|
||||||
local bladeRushRank = currRank or 0
|
|
||||||
|
|
||||||
if bladeRushRank > 0 then
|
-- gains farther than this from the predicted boundary are not the tick
|
||||||
local agility = UnitStat("player", 2) -- 2 is agility stat index
|
local TICK_TOLERANCE = .25
|
||||||
local reductionPerAgi = 0.0006 * bladeRushRank -- 0.0006 for rank 1, 0.0012 for rank 2
|
|
||||||
local totalReduction = agility * reductionPerAgi
|
-- arrival jitter; a tick inside this band confirms the sweep rather than
|
||||||
adjustedEnergyTick = adjustedEnergyTick - totalReduction
|
-- 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
|
||||||
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
|
end
|
||||||
|
|
||||||
pfUI:RegisterModule("energytick", function()
|
pfUI:RegisterModule("energytick", function()
|
||||||
@@ -22,14 +84,53 @@ pfUI:RegisterModule("energytick", function()
|
|||||||
return
|
return
|
||||||
end
|
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)
|
local energytick = CreateFrame("Frame", nil, pfUI.uf.player.power.bar)
|
||||||
energytick:SetAllPoints(pfUI.uf.player.power.bar)
|
energytick:SetAllPoints(pfUI.uf.player.power.bar)
|
||||||
energytick:RegisterEvent("PLAYER_ENTERING_WORLD")
|
energytick:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||||
energytick:RegisterEvent("UNIT_DISPLAYPOWER")
|
energytick:RegisterUnitEvent("UNIT_DISPLAYPOWER", "player")
|
||||||
energytick:RegisterEvent("UNIT_ENERGY")
|
energytick:RegisterUnitEvent("UNIT_ENERGY", "player")
|
||||||
energytick:RegisterEvent("UNIT_MANA")
|
energytick:RegisterUnitEvent("UNIT_MANA", "player")
|
||||||
energytick:RegisterEvent("CHAT_MSG_SPELL_SELF_BUFF")
|
energytick:RegisterUnitEvent("UNIT_SPELLCAST_SUCCEEDED", "player")
|
||||||
energytick:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS")
|
energytick:RegisterUnitEvent("UNIT_SPELLCAST_CHANNEL_STOP", "player")
|
||||||
|
energytick:RegisterEvent("SPELLS_CHANGED")
|
||||||
|
energytick:RegisterEvent("PLAYER_AURAS_CHANGED")
|
||||||
|
|
||||||
energytick:SetScript("OnEvent", function()
|
energytick:SetScript("OnEvent", function()
|
||||||
if UnitPowerType("player") == Enum.PowerType.Mana and C.unitframes.player.manatick == "1" then
|
if UnitPowerType("player") == Enum.PowerType.Mana and C.unitframes.player.manatick == "1" then
|
||||||
@@ -42,44 +143,52 @@ pfUI:RegisterModule("energytick", function()
|
|||||||
this:Hide()
|
this:Hide()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Filter nur eigene Energy-Gewinne von Talents/Buffs
|
if event == "SPELLS_CHANGED" or event == "PLAYER_AURAS_CHANGED" then
|
||||||
if event == "CHAT_MSG_SPELL_SELF_BUFF" or event == "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS" then
|
energyRegenTimeMod = nil
|
||||||
if string.find(arg1, "You gain") and string.find(arg1, "Energy from") then
|
|
||||||
this.ignoreNextGain = true
|
|
||||||
end
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if event == "PLAYER_ENTERING_WORLD" then
|
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
|
end
|
||||||
|
|
||||||
if (event == "UNIT_MANA" or event == "UNIT_ENERGY") and arg1 == "player" then
|
if (event == "UNIT_MANA" or event == "UNIT_ENERGY") and arg1 == "player" then
|
||||||
this.currentMana = UnitPower("player")
|
local power = UnitPower("player")
|
||||||
local diff = 0
|
local diff = this.lastPower and (power - this.lastPower) or 0
|
||||||
if this.lastMana then
|
this.lastPower = power
|
||||||
diff = this.currentMana - this.lastMana
|
|
||||||
|
-- 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
|
end
|
||||||
|
|
||||||
if this.mode == "MANA" and diff < 0 then
|
-- phase is kept while hidden; OnUpdate catches up by whole periods
|
||||||
this.target = 5
|
if this.mode == "MANA" and power >= UnitPowerMax("player") then
|
||||||
elseif this.mode == "MANA" and diff > 0 then
|
this:Hide()
|
||||||
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
|
|
||||||
end
|
end
|
||||||
this.lastMana = this.currentMana
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -90,37 +199,53 @@ pfUI:RegisterModule("energytick", function()
|
|||||||
end
|
end
|
||||||
this.tick = GetTime() + 0.020 -- ~50 FPS
|
this.tick = GetTime() + 0.020 -- ~50 FPS
|
||||||
|
|
||||||
if this.target then
|
-- five-second rule drains to nothing
|
||||||
this.start, this.max = GetTime(), this.target
|
local remaining = this.fsrEnd and (this.fsrEnd - GetTime()) or 0
|
||||||
this.target = nil
|
if this.mode == "MANA" and remaining > 0 then
|
||||||
this.spark:SetAlpha(1)
|
this.fsrbar:SetWidth(getBarWidth() * remaining / FIVE_SECOND_RULE)
|
||||||
this:Show()
|
this.fsrbar:Show()
|
||||||
|
else
|
||||||
|
this.fsrSpell, this.fsrEnd, this.fsrGain = nil, nil, nil
|
||||||
|
this.fsrbar:Hide()
|
||||||
end
|
end
|
||||||
|
|
||||||
if not this.start then
|
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
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
this.current = GetTime() - this.start
|
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
|
if this.current > this.max then
|
||||||
-- Don't restart tick timer if mana is full
|
this.start = this.start + this.max * math.floor(this.current / this.max)
|
||||||
if this.mode == "MANA" and UnitPower("player") >= UnitPowerMax("player") then
|
this.max = getAdjustedTickTimer()
|
||||||
this.start = nil
|
this.current = GetTime() - this.start
|
||||||
this.spark:SetAlpha(0)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
this.start, this.max, this.current = GetTime(), getAdjustedTickTimer(), 0
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local pos = (C.unitframes.player.pwidth ~= "-1" and C.unitframes.player.pwidth or C.unitframes.player.width)
|
-- dim while the rule is up and nothing has ticked inside it yet
|
||||||
* (this.current / this.max)
|
this.spark:SetAlpha((remaining > 0 and not this.fsrGain) and .4 or 1)
|
||||||
|
|
||||||
if not C.unitframes.player.pheight then
|
if not C.unitframes.player.pheight then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local pos = getBarWidth() * (this.current / this.max)
|
||||||
this.spark:SetPoint("LEFT", pos - ((C.unitframes.player.pheight + 5) / 2), 0)
|
this.spark:SetPoint("LEFT", pos - ((C.unitframes.player.pheight + 5) / 2), 0)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
energytick.fsrbar = energytick:CreateTexture(nil, "ARTWORK")
|
||||||
|
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 = energytick:CreateTexture(nil, "OVERLAY")
|
||||||
energytick.spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark")
|
energytick.spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark")
|
||||||
energytick.spark:SetHeight(C.unitframes.player.pheight + 15)
|
energytick.spark:SetHeight(C.unitframes.player.pheight + 15)
|
||||||
@@ -133,4 +258,4 @@ pfUI:RegisterModule("energytick", function()
|
|||||||
energytick.spark:SetWidth(C.unitframes.player.pheight + 5)
|
energytick.spark:SetWidth(C.unitframes.player.pheight + 5)
|
||||||
hookUpdateConfig(pfUI.uf.player)
|
hookUpdateConfig(pfUI.uf.player)
|
||||||
end
|
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"], 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["Button Animation Trigger"], C.bars, "animmode", "dropdown", pfUI.gui.dropdowns.animationmode)
|
||||||
CreateConfig(U["bars"], T["Show Animation On Hidden Bars"], C.bars, "animalways", "checkbox")
|
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["Show Reagent Count"], C.bars, "reagents", "checkbox")
|
||||||
CreateConfig(U["bars"], T["Highlight Equipped Items"], C.bars, "showequipped", "checkbox")
|
CreateConfig(U["bars"], T["Highlight Equipped Items"], C.bars, "showequipped", "checkbox")
|
||||||
CreateConfig(U["bars"], T["Equipped Item Color"], C.bars, "eqcolor", "color")
|
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()
|
CreateGUIEntry(T["Components"], T["Modules"], function()
|
||||||
table.sort(pfUI.modules)
|
table.sort(pfUI.modules)
|
||||||
for i,m in pairs(pfUI.modules) do
|
for i,m in pairs(pfUI.modules) do
|
||||||
-- skip gui and macrotweak when macro addons are loaded
|
if m ~= "gui" then
|
||||||
if m ~= "gui" and not (m == "macrotweak" and pfUI:MacroAddonsLoaded()) then
|
|
||||||
-- create disabled entry if not existing and display
|
-- create disabled entry if not existing and display
|
||||||
pfUI:UpdateConfig("disabled", nil, m, "0")
|
pfUI:UpdateConfig("disabled", nil, m, "0")
|
||||||
CreateConfig(nil, T["Disable Module"] .. " " .. m, C.disabled, m, "checkbox")
|
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 ()
|
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 rawborder, border = GetBorderSize()
|
||||||
|
|
||||||
local markerOrder = { 8, 7, 6, 5, 4, 3, 2, 1 } -- skull, cross, square, moon, triangle, diamond, circle, star
|
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 = {
|
local markerConfigKeys = {
|
||||||
"raidmarkercolor_star",
|
"raidmarkercolor_star",
|
||||||
@@ -22,6 +19,7 @@ pfUI:RegisterModule("marktracking", function ()
|
|||||||
local markerColors = {}
|
local markerColors = {}
|
||||||
for i, markKey in ipairs(markerConfigKeys) do
|
for i, markKey in ipairs(markerConfigKeys) do
|
||||||
markerTokens[i] = "mark" .. i
|
markerTokens[i] = "mark" .. i
|
||||||
|
markerIndex[markerTokens[i]] = i
|
||||||
local r, g, b, a = GetStringColor(C.unitframes[markKey])
|
local r, g, b, a = GetStringColor(C.unitframes[markKey])
|
||||||
markerColors[i] = { tonumber(r), tonumber(g), tonumber(b), tonumber(a) }
|
markerColors[i] = { tonumber(r), tonumber(g), tonumber(b), tonumber(a) }
|
||||||
end
|
end
|
||||||
@@ -73,8 +71,7 @@ pfUI.marktracking = CreateFrame("Frame", "pfMarkTracking", UIParent)
|
|||||||
else
|
else
|
||||||
pfUI.marktracking:SetPoint("TOP", UIParent, "CENTER", 0, 0)
|
pfUI.marktracking:SetPoint("TOP", UIParent, "CENTER", 0, 0)
|
||||||
end
|
end
|
||||||
pfUI.marktracking:SetWidth(TOTAL_ROW_WIDTH)
|
pfUI.marktracking:SetSize(TOTAL_ROW_WIDTH, 8 * (ROW_HEIGHT + 1) + border * 2 - 1)
|
||||||
pfUI.marktracking:SetHeight(8 * (ROW_HEIGHT + 1) + border * 2 - 1)
|
|
||||||
pfUI.marktracking:Hide()
|
pfUI.marktracking:Hide()
|
||||||
|
|
||||||
CreateBackdrop(pfUI.marktracking)
|
CreateBackdrop(pfUI.marktracking)
|
||||||
@@ -284,27 +281,50 @@ pfUI.marktracking = CreateFrame("Frame", "pfMarkTracking", UIParent)
|
|||||||
-- Event-driven scanner frame
|
-- Event-driven scanner frame
|
||||||
local scanner = CreateFrame("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
|
-- RAID_TARGET_UPDATE: a raid marker was set/cleared -> full refresh
|
||||||
-- PLAYER_ENTERING_WORLD: login/reload/zone -> full refresh
|
-- PLAYER_ENTERING_WORLD: login/reload/zone -> full refresh
|
||||||
-- UNIT_HEALTH/UNIT_MAXHEALTH: ClassicAPI fires these per token; with the mark
|
-- PARTY_MEMBERS_CHANGED/RAID_ROSTER_UPDATE: joined or left a group -> the rows
|
||||||
-- tokens observed they arrive as arg1 == "markN", so we refresh just that
|
-- can change, and the fallback poll starts or stops with it
|
||||||
-- one row (UpdateRow) instead of rescanning all eight.
|
-- 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("RAID_TARGET_UPDATE")
|
||||||
scanner:RegisterEvent("PLAYER_ENTERING_WORLD")
|
scanner:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||||
scanner:RegisterEvent("UNIT_HEALTH")
|
scanner:RegisterEvent("PARTY_MEMBERS_CHANGED")
|
||||||
scanner:RegisterEvent("UNIT_MAXHEALTH")
|
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()
|
scanner:SetScript("OnEvent", function()
|
||||||
if event == "UNIT_HEALTH" or event == "UNIT_MAXHEALTH" then
|
if event == "UNIT_HEALTH" or event == "UNIT_MAXHEALTH" then
|
||||||
-- arg1 is the token; "markN" -> N, nil for any non-mark token.
|
-- arg1 is one of the eight tokens we registered for, so this is a lookup
|
||||||
local i = arg1 and tonumber(string.match(arg1, "^mark(%d)"))
|
-- 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
|
if i then UpdateRow(i) end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
if event ~= "RAID_TARGET_UPDATE" then UpdatePoll() end
|
||||||
UpdateDisplay()
|
UpdateDisplay()
|
||||||
end)
|
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)
|
end)
|
||||||
+1
-1
@@ -225,7 +225,7 @@ pfUI:RegisterModule("minimap", function ()
|
|||||||
pfUI.minimap.pvpicon = CreateFrame("Frame", nil, pfUI.minimap)
|
pfUI.minimap.pvpicon = CreateFrame("Frame", nil, pfUI.minimap)
|
||||||
pfUI.minimap.pvpicon:Hide()
|
pfUI.minimap.pvpicon:Hide()
|
||||||
pfUI.minimap.pvpicon:RegisterEvent("UPDATE_FACTION")
|
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:SetFrameStrata("HIGH")
|
||||||
pfUI.minimap.pvpicon:SetSize(16, 16)
|
pfUI.minimap.pvpicon:SetSize(16, 16)
|
||||||
pfUI.minimap.pvpicon:SetAlpha(.5)
|
pfUI.minimap.pvpicon:SetAlpha(.5)
|
||||||
|
|||||||
+100
-74
@@ -5,10 +5,7 @@ pfUI:RegisterModule("nameplates", function ()
|
|||||||
-- Local function references for performance
|
-- Local function references for performance
|
||||||
local GetTime = GetTime
|
local GetTime = GetTime
|
||||||
local UnitName = UnitName
|
local UnitName = UnitName
|
||||||
local UnitClass = UnitClass
|
|
||||||
local UnitLevel = UnitLevel
|
|
||||||
local UnitIsPlayer = UnitIsPlayer
|
local UnitIsPlayer = UnitIsPlayer
|
||||||
local UnitIsDead = UnitIsDead
|
|
||||||
local UnitAffectingCombat = UnitAffectingCombat
|
local UnitAffectingCombat = UnitAffectingCombat
|
||||||
local UnitIsUnit = UnitIsUnit
|
local UnitIsUnit = UnitIsUnit
|
||||||
local UnitCanAssist = UnitCanAssist
|
local UnitCanAssist = UnitCanAssist
|
||||||
@@ -162,6 +159,24 @@ pfUI:RegisterModule("nameplates", function ()
|
|||||||
cfg.debuffanim = tonumber(C.nameplates.debuffanim) or 0
|
cfg.debuffanim = tonumber(C.nameplates.debuffanim) or 0
|
||||||
cfg.debufftext = tonumber(C.nameplates.debufftext) or 1
|
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
|
-- Rebuild offtanks lookup table
|
||||||
offtanks = {}
|
offtanks = {}
|
||||||
for k, v in pairs({strsplit("#", C.nameplates.combatofftanks)}) do
|
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_ENTERING_WORLD")
|
||||||
nameplates:RegisterEvent("PLAYER_TARGET_CHANGED")
|
nameplates:RegisterEvent("PLAYER_TARGET_CHANGED")
|
||||||
nameplates:RegisterEvent("PLAYER_LOGOUT")
|
nameplates:RegisterEvent("PLAYER_LOGOUT")
|
||||||
nameplates:RegisterEvent("UNIT_COMBO_POINTS")
|
nameplates:RegisterUnitEvent("UNIT_COMBO_POINTS", "player")
|
||||||
nameplates:RegisterEvent("PLAYER_COMBO_POINTS")
|
nameplates:RegisterEvent("PLAYER_COMBO_POINTS")
|
||||||
nameplates:RegisterEvent("ZONE_CHANGED_NEW_AREA")
|
nameplates:RegisterEvent("ZONE_CHANGED_NEW_AREA")
|
||||||
nameplates:RegisterEvent("RAID_ROSTER_UPDATE")
|
nameplates:RegisterEvent("RAID_ROSTER_UPDATE")
|
||||||
@@ -498,13 +513,10 @@ nameplates:RegisterEvent("PARTY_MEMBERS_CHANGED")
|
|||||||
nameplates:RegisterEvent("NAME_PLATE_CREATED")
|
nameplates:RegisterEvent("NAME_PLATE_CREATED")
|
||||||
nameplates:RegisterEvent("NAME_PLATE_UNIT_ADDED")
|
nameplates:RegisterEvent("NAME_PLATE_UNIT_ADDED")
|
||||||
nameplates:RegisterEvent("NAME_PLATE_UNIT_REMOVED")
|
nameplates:RegisterEvent("NAME_PLATE_UNIT_REMOVED")
|
||||||
nameplates:RegisterEvent("UNIT_AURA")
|
|
||||||
nameplates:RegisterEvent("UNIT_FLAGS")
|
|
||||||
nameplates:RegisterEvent("UPDATE_MOUSEOVER_UNIT")
|
nameplates:RegisterEvent("UPDATE_MOUSEOVER_UNIT")
|
||||||
nameplates:RegisterEvent("UNIT_SPELLCAST_START")
|
-- UNIT_AURA / UNIT_FLAGS / UNIT_SPELLCAST_* are registered per plate, on the
|
||||||
nameplates:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START")
|
-- plate's own frame, against its own token -- see OnCreate and
|
||||||
nameplates:RegisterEvent("UNIT_SPELLCAST_STOP")
|
-- NAME_PLATE_UNIT_ADDED.
|
||||||
nameplates:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP")
|
|
||||||
nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
||||||
|
|
||||||
nameplates:SetScript("OnEvent", function()
|
nameplates:SetScript("OnEvent", function()
|
||||||
@@ -516,6 +528,15 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
|||||||
if nameplates.mouselook then
|
if nameplates.mouselook then
|
||||||
nameplates.mouselook:SetScript("OnUpdate", nil)
|
nameplates.mouselook:SetScript("OnUpdate", nil)
|
||||||
end
|
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
|
return
|
||||||
|
|
||||||
elseif event == "PLAYER_GUILD_UPDATE" and arg1 == 'player' then
|
elseif event == "PLAYER_GUILD_UPDATE" and arg1 == 'player' then
|
||||||
@@ -591,6 +612,16 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
|||||||
local guid = UnitGUID(arg1)
|
local guid = UnitGUID(arg1)
|
||||||
plate.nameplate.cachedGuid = guid
|
plate.nameplate.cachedGuid = guid
|
||||||
plate.nameplate.unit = arg1
|
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.creatureType = nil -- recompute for the new unit
|
||||||
plate.nameplate.totemIcon = nil
|
plate.nameplate.totemIcon = nil
|
||||||
plate.nameplate.totemSpell = 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
|
if plate and plate.nameplate and plate.nameplate.cachedGuid == guid then
|
||||||
plate.nameplate.cachedGuid = nil
|
plate.nameplate.cachedGuid = nil
|
||||||
plate.nameplate.unit = nil
|
plate.nameplate.unit = nil
|
||||||
end
|
-- Drop the subscriptions with the token: this slot is now free and the
|
||||||
end
|
-- next plate to take it would otherwise feed this frame its events.
|
||||||
|
plate.nameplate:UnregisterAllEvents()
|
||||||
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
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -643,48 +669,6 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
|||||||
if pn then pn.eventcache = true end
|
if pn then pn.eventcache = true end
|
||||||
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
|
elseif event == "PLAYER_TARGET_CHANGED" then
|
||||||
frameState.targetGuid = UnitGUID('target')
|
frameState.targetGuid = UnitGUID('target')
|
||||||
-- Flag the target's plate for update
|
-- Flag the target's plate for update
|
||||||
@@ -766,6 +750,40 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
|||||||
nameplate.cache = {}
|
nameplate.cache = {}
|
||||||
nameplate.original = {}
|
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
|
-- create shortcuts for all known elements and disable them
|
||||||
nameplate.original.healthbar, nameplate.original.castbar = parent:GetChildren()
|
nameplate.original.healthbar, nameplate.original.castbar = parent:GetChildren()
|
||||||
DisableObject(nameplate.original.healthbar)
|
DisableObject(nameplate.original.healthbar)
|
||||||
@@ -1409,6 +1427,16 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
|||||||
|
|
||||||
-- cachedGuid is maintained by NAME_PLATE_UNIT_ADDED / _REMOVED events.
|
-- 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
|
-- PERF: Intelligent throttling based on target/castbar status and plate count
|
||||||
-- Use GUID comparison as primary target detection: instant, immune to alpha transitions,
|
-- 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)
|
-- and immediately correct on de-target (unlike istarget which updates one tick later)
|
||||||
@@ -1435,25 +1463,24 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Resolved in CacheConfig, so these are table reads rather than a walk
|
||||||
|
-- through the saved variables and preset tables.
|
||||||
local throttle
|
local throttle
|
||||||
if target then
|
if target then
|
||||||
throttle = pfUI.throttle:Get("nameplates_target")
|
throttle = cfg.throttle_target
|
||||||
elseif visiblePlateCount > 20 then
|
elseif visiblePlateCount > 20 then
|
||||||
throttle = pfUI.throttle:Get("nameplates_mass")
|
throttle = cfg.throttle_mass
|
||||||
else
|
else
|
||||||
throttle = pfUI.throttle:Get("nameplates")
|
throttle = cfg.throttle_normal
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Non-target plates with active castbar use the castbar throttle
|
-- Non-target plates with active castbar use the castbar throttle
|
||||||
if isCastingNonTarget then
|
if isCastingNonTarget and cfg.throttle_castbar < throttle then
|
||||||
local cbThrottle = pfUI.throttle:Get("nameplates_castbar")
|
throttle = cfg.throttle_castbar
|
||||||
if cbThrottle < throttle then throttle = cbThrottle end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check for pending event updates (these bypass throttle for immediate response)
|
-- The category-specific gate. hasEventUpdate was read above, before the
|
||||||
local hasEventUpdate = nameplate.eventcache or nameplate.auraUpdate or nameplate.castUpdate or nameplate.targetUpdate or nameplate.comboUpdate
|
-- classification, and still bypasses the throttle.
|
||||||
|
|
||||||
-- Event updates bypass throttle
|
|
||||||
if not hasEventUpdate and (nameplate.lasttick or 0) + throttle > now then return end
|
if not hasEventUpdate and (nameplate.lasttick or 0) + throttle > now then return end
|
||||||
nameplate.lasttick = now
|
nameplate.lasttick = now
|
||||||
|
|
||||||
@@ -1655,10 +1682,9 @@ nameplates:RegisterEvent("PLAYER_GUILD_UPDATE")
|
|||||||
-- engine framerate, decoupled from central loop). Only update non-target castbars here.
|
-- 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)
|
local isTargetPlate = target or nameplate.istarget or (nameplate.health and nameplate.health.zoomed)
|
||||||
if cfg.showcastbar and not cfg.targetcastbar and not isTargetPlate then
|
if cfg.showcastbar and not cfg.targetcastbar and not isTargetPlate then
|
||||||
local cbThrottle = pfUI.throttle:Get("nameplates_castbar")
|
local cbThrottle = cfg.throttle_castbar
|
||||||
if visiblePlateCount > 20 then
|
if visiblePlateCount > 20 and cfg.throttle_mass > cbThrottle then
|
||||||
local massThrottle = pfUI.throttle:Get("nameplates_mass")
|
cbThrottle = cfg.throttle_mass
|
||||||
if massThrottle > cbThrottle then cbThrottle = massThrottle end
|
|
||||||
end
|
end
|
||||||
if (nameplate.castbar_tick or 0) + cbThrottle <= now then
|
if (nameplate.castbar_tick or 0) + cbThrottle <= now then
|
||||||
nameplate.castbar_tick = now
|
nameplate.castbar_tick = now
|
||||||
|
|||||||
+1
-1
@@ -486,7 +486,7 @@ pfUI:RegisterModule("panel", function()
|
|||||||
do -- Ammo
|
do -- Ammo
|
||||||
local widget = CreateFrame("Frame", "pfPanelWidgetAmmo", UIParent)
|
local widget = CreateFrame("Frame", "pfPanelWidgetAmmo", UIParent)
|
||||||
widget:RegisterEvent("PLAYER_ENTERING_WORLD")
|
widget:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||||
widget:RegisterEvent("UNIT_INVENTORY_CHANGED")
|
widget:RegisterUnitEvent("UNIT_INVENTORY_CHANGED", "player")
|
||||||
widget:RegisterEvent("BAG_UPDATE_DELAYED")
|
widget:RegisterEvent("BAG_UPDATE_DELAYED")
|
||||||
widget.Tooltip = function()
|
widget.Tooltip = function()
|
||||||
if GetInventoryItemQuality("player", 0) then
|
if GetInventoryItemQuality("player", 0) then
|
||||||
|
|||||||
@@ -816,7 +816,7 @@ pfUI:RegisterModule("swingtimer", function ()
|
|||||||
events:RegisterEvent("PLAYER_REGEN_DISABLED")
|
events:RegisterEvent("PLAYER_REGEN_DISABLED")
|
||||||
events:RegisterEvent("PLAYER_REGEN_ENABLED")
|
events:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||||
events:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
|
events:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
|
||||||
events:RegisterEvent("UNIT_DIED")
|
events:RegisterUnitEvent("UNIT_DIED", UnitGUID("player"))
|
||||||
events:RegisterEvent("SPELL_QUEUE_EVENT")
|
events:RegisterEvent("SPELL_QUEUE_EVENT")
|
||||||
events:RegisterEvent("START_AUTOATTACK")
|
events:RegisterEvent("START_AUTOATTACK")
|
||||||
events:RegisterEvent("STOP_AUTOATTACK")
|
events:RegisterEvent("STOP_AUTOATTACK")
|
||||||
|
|||||||
+3
-3
@@ -363,9 +363,9 @@ end
|
|||||||
b:EnableMouse(true)
|
b:EnableMouse(true)
|
||||||
|
|
||||||
b:RegisterEvent("FACTION_STANDING_CHANGED")
|
b:RegisterEvent("FACTION_STANDING_CHANGED")
|
||||||
b:RegisterEvent("UNIT_PET")
|
b:RegisterUnitEvent("UNIT_PET", "player")
|
||||||
b:RegisterEvent("UNIT_LEVEL")
|
b:RegisterUnitEvent("UNIT_LEVEL", "player")
|
||||||
b:RegisterEvent("UNIT_PET_EXPERIENCE")
|
b:RegisterUnitEvent("UNIT_PET_EXPERIENCE", "player", "pet")
|
||||||
b:RegisterEvent("PLAYER_ENTERING_WORLD")
|
b:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||||
b:RegisterEvent("UPDATE_EXHAUSTION")
|
b:RegisterEvent("UPDATE_EXHAUSTION")
|
||||||
b:RegisterEvent("PLAYER_XP_UPDATE")
|
b:RegisterEvent("PLAYER_XP_UPDATE")
|
||||||
|
|||||||
Reference in New Issue
Block a user