mirror of
https://github.com/brues-code/pfUI.git
synced 2026-10-30 07:30:52 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26c55bddb0 | ||
|
|
8c22fdb850 | ||
|
|
2d275c53fa | ||
|
|
ba752056ad | ||
|
|
1ccf87c61a | ||
|
|
dc89f01dda | ||
|
|
a917a70b1c | ||
|
|
03ea3d5aa5 | ||
|
|
2b4d33d46a | ||
|
|
94dcfb3dad | ||
|
|
0890905eb6 | ||
|
|
6c76a88467 | ||
|
|
35c32f365e | ||
|
|
6dcb5162be | ||
|
|
8afafe71cf | ||
|
|
99ed538ee7 | ||
|
|
f382039f21 | ||
|
|
8307dd757e |
+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 = 11703 -- (X*10000 + Y*100 + Z)
|
local PFUI_CLASSIC_API_MIN = 11802 -- (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"
|
||||||
|
|||||||
+22
-62
@@ -722,20 +722,7 @@ end
|
|||||||
function pfUI.api.CreateGoldString(money)
|
function pfUI.api.CreateGoldString(money)
|
||||||
if type(money) ~= "number" then return "-" end
|
if type(money) ~= "number" then return "-" end
|
||||||
|
|
||||||
if _G.GetCoinTextureString then
|
return "|cffffffff" .. _G.GetCoinTextureString(money) .. "|r"
|
||||||
return "|cffffffff" .. _G.GetCoinTextureString(money) .. "|r"
|
|
||||||
end
|
|
||||||
|
|
||||||
local gold = floor(money/ 100 / 100)
|
|
||||||
local silver = floor(mod((money/100),100))
|
|
||||||
local copper = floor(mod(money,100))
|
|
||||||
|
|
||||||
local string = ""
|
|
||||||
if gold > 0 then string = string .. "|cffffffff" .. gold .. "|cffffd700g" end
|
|
||||||
if silver > 0 or gold > 0 then string = string .. "|cffffffff " .. silver .. "|cffc7c7cfs" end
|
|
||||||
string = string .. "|cffffffff " .. copper .. "|cffeda55fc"
|
|
||||||
|
|
||||||
return string
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- [ Enable Movable ]
|
-- [ Enable Movable ]
|
||||||
@@ -1353,15 +1340,18 @@ end
|
|||||||
|
|
||||||
-- [ Bar Layout Options ] --
|
-- [ Bar Layout Options ] --
|
||||||
-- 'barsize' size of bar in number of buttons
|
-- 'barsize' size of bar in number of buttons
|
||||||
-- returns: array of options as strings for pfUI.gui.bar
|
-- returns: array of options as strings for pfUI.gui.bar: every grid
|
||||||
|
-- that fits the bar exactly, plus common uneven ones
|
||||||
function pfUI.api.BarLayoutOptions(barsize)
|
function pfUI.api.BarLayoutOptions(barsize)
|
||||||
assert(barsize > 0 and barsize <= NUM_ACTIONBAR_BUTTONS,"BarLayoutOptions: barsize "..tostring(barsize).." is invalid")
|
assert(barsize > 0 and barsize <= NUM_ACTIONBAR_BUTTONS,"BarLayoutOptions: barsize "..tostring(barsize).." is invalid")
|
||||||
local options, seen = {}, {}
|
local options, seen = {}, {}
|
||||||
local function add(option)
|
local function add(option)
|
||||||
if not seen[option] then table.insert(options, option); seen[option] = true end
|
if not seen[option] then table.insert(options, option); seen[option] = true end
|
||||||
end
|
end
|
||||||
for i,layout in ipairs(pfGridmath[barsize]) do
|
for cols = 1, barsize do
|
||||||
add(string.format("%d x %d",layout[1],layout[2]))
|
if barsize % cols == 0 then
|
||||||
|
add(string.format("%d x %d", cols, barsize / cols))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
for _, option in ipairs({
|
for _, option in ipairs({
|
||||||
"1 x 12", "1 x 10", "2 x 10", "2 x 5", "3 x 10", "3 x 5", "3 x 3",
|
"1 x 12", "1 x 10", "2 x 10", "2 x 5", "3 x 10", "3 x 5", "3 x 3",
|
||||||
@@ -1381,49 +1371,23 @@ function pfUI.api.BarLayoutOptions(barsize)
|
|||||||
return options
|
return options
|
||||||
end
|
end
|
||||||
|
|
||||||
-- [ Bar Layout Formfactor ] --
|
-- 'formfactor' has to be a "cols x rows" string; the actionbar module resets
|
||||||
-- 'option' string option as used in pfUI_config.bars[bar].option
|
-- a stored layout that isn't one before it lays out a bar
|
||||||
-- returns: integer formfactor
|
|
||||||
local formfactors = {}
|
|
||||||
setmetatable(formfactors, {__mode = "v"}) -- weak table so values not referenced are collected on next gc
|
|
||||||
function pfUI.api.BarLayoutFormfactor(option)
|
|
||||||
if formfactors[option] then
|
|
||||||
return formfactors[option]
|
|
||||||
else
|
|
||||||
for barsize,_ in ipairs(pfGridmath) do
|
|
||||||
local options = pfUI.api.BarLayoutOptions(barsize)
|
|
||||||
for i,opt in ipairs(options) do
|
|
||||||
if opt == option then
|
|
||||||
formfactors[option] = i
|
|
||||||
return formfactors[option]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function ResolveBarLayout(barsize, formfactor, uneven)
|
local function ResolveBarLayout(barsize, formfactor, uneven)
|
||||||
local layout = tostring(formfactor or "")
|
local _, _, a, b = string.find(formfactor, "(%d+)%s*x%s*(%d+)")
|
||||||
local _, _, a, b = string.find(layout, "(%d+)%s*x%s*(%d+)")
|
local cols, rows = tonumber(a), tonumber(b)
|
||||||
if a and b then
|
cols = math.min(NUM_ACTIONBAR_BUTTONS, math.max(1, cols))
|
||||||
local cols, rows = tonumber(a), tonumber(b)
|
rows = math.min(NUM_ACTIONBAR_BUTTONS, math.max(1, rows))
|
||||||
cols = math.min(NUM_ACTIONBAR_BUTTONS, math.max(1, cols))
|
local orientation = string.upper(uneven or "DOWN")
|
||||||
rows = math.min(NUM_ACTIONBAR_BUTTONS, math.max(1, rows))
|
local mode = (orientation == "LEFT" or orientation == "RIGHT") and "cols" or "rows"
|
||||||
local orientation = string.upper(uneven or "DOWN")
|
if mode == "rows" then
|
||||||
local mode = (orientation == "LEFT" or orientation == "RIGHT") and "cols" or "rows"
|
cols = math.max(1, math.min(cols, barsize))
|
||||||
if mode == "rows" then
|
rows = math.max(1, math.ceil(barsize / cols))
|
||||||
cols = math.max(1, math.min(cols, barsize))
|
else
|
||||||
rows = math.max(1, math.ceil(barsize / cols))
|
rows = math.max(1, math.min(rows, barsize))
|
||||||
else
|
cols = math.max(1, math.ceil(barsize / rows))
|
||||||
rows = math.max(1, math.min(rows, barsize))
|
|
||||||
cols = math.max(1, math.ceil(barsize / rows))
|
|
||||||
end
|
|
||||||
return cols, rows, mode, orientation
|
|
||||||
end
|
end
|
||||||
local index = pfUI.api.BarLayoutFormfactor(layout)
|
return cols, rows, mode, orientation
|
||||||
if not index then return nil end
|
|
||||||
local cols, rows = unpack(pfGridmath[barsize][index])
|
|
||||||
return cols, rows, "rows", "DOWN"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- [ Bar Layout Size ] --
|
-- [ Bar Layout Size ] --
|
||||||
@@ -1434,7 +1398,6 @@ end
|
|||||||
function pfUI.api.BarLayoutSize(bar,barsize,formfactor,iconsize,bordersize,padding,uneven,fillmode)
|
function pfUI.api.BarLayoutSize(bar,barsize,formfactor,iconsize,bordersize,padding,uneven,fillmode)
|
||||||
assert(barsize > 0 and barsize <= NUM_ACTIONBAR_BUTTONS,"BarLayoutSize: barsize "..tostring(barsize).." is invalid")
|
assert(barsize > 0 and barsize <= NUM_ACTIONBAR_BUTTONS,"BarLayoutSize: barsize "..tostring(barsize).." is invalid")
|
||||||
local cols, rows = ResolveBarLayout(barsize, formfactor, uneven)
|
local cols, rows = ResolveBarLayout(barsize, formfactor, uneven)
|
||||||
if not cols or not rows then cols, rows = unpack(pfGridmath[barsize][1]) end
|
|
||||||
local width = (iconsize + bordersize*2+padding) * cols + padding
|
local width = (iconsize + bordersize*2+padding) * cols + padding
|
||||||
local height = (iconsize + bordersize*2+padding) * rows + padding
|
local height = (iconsize + bordersize*2+padding) * rows + padding
|
||||||
bar._size = {width,height}
|
bar._size = {width,height}
|
||||||
@@ -1452,9 +1415,6 @@ end
|
|||||||
function pfUI.api.BarButtonAnchor(button,basename,buttonindex,barsize,formfactor,iconsize,bordersize,padding,uneven,fillmode)
|
function pfUI.api.BarButtonAnchor(button,basename,buttonindex,barsize,formfactor,iconsize,bordersize,padding,uneven,fillmode)
|
||||||
assert(barsize > 0 and barsize <= NUM_ACTIONBAR_BUTTONS,"BarButtonAnchor: barsize "..tostring(barsize).." is invalid")
|
assert(barsize > 0 and barsize <= NUM_ACTIONBAR_BUTTONS,"BarButtonAnchor: barsize "..tostring(barsize).." is invalid")
|
||||||
local cols, rows, mode, orientation = ResolveBarLayout(barsize, formfactor, uneven)
|
local cols, rows, mode, orientation = ResolveBarLayout(barsize, formfactor, uneven)
|
||||||
if not cols or not rows then
|
|
||||||
cols, rows, mode, orientation = unpack(pfGridmath[barsize][1]), "rows", "DOWN"
|
|
||||||
end
|
|
||||||
|
|
||||||
-- fillmode: remap buttonindex to slotindex (grid position in native fill order)
|
-- fillmode: remap buttonindex to slotindex (grid position in native fill order)
|
||||||
-- only needed when fill direction differs from layout mode
|
-- only needed when fill direction differs from layout mode
|
||||||
|
|||||||
@@ -171,7 +171,6 @@ function pfUI:LoadConfig()
|
|||||||
pfUI:UpdateConfig("appearance", "bags", "newitem_color", "1,1,1,1")
|
pfUI:UpdateConfig("appearance", "bags", "newitem_color", "1,1,1,1")
|
||||||
pfUI:UpdateConfig("appearance", "bags", "borderlimit", "1")
|
pfUI:UpdateConfig("appearance", "bags", "borderlimit", "1")
|
||||||
pfUI:UpdateConfig("appearance", "bags", "borderonlygear", "0")
|
pfUI:UpdateConfig("appearance", "bags", "borderonlygear", "0")
|
||||||
pfUI:UpdateConfig("appearance", "bags", "fulltext", "1")
|
|
||||||
pfUI:UpdateConfig("appearance", "bags", "movable", "0")
|
pfUI:UpdateConfig("appearance", "bags", "movable", "0")
|
||||||
pfUI:UpdateConfig("appearance", "bags", "abovechat", "0")
|
pfUI:UpdateConfig("appearance", "bags", "abovechat", "0")
|
||||||
pfUI:UpdateConfig("appearance", "bags", "hidechat", "0")
|
pfUI:UpdateConfig("appearance", "bags", "hidechat", "0")
|
||||||
|
|||||||
+36
-74
@@ -3,19 +3,19 @@ setfenv(1, pfUI:GetEnvironment())
|
|||||||
|
|
||||||
do -- statusbars
|
do -- statusbars
|
||||||
local animations = {}
|
local animations = {}
|
||||||
local stepsize, val
|
local stepsize
|
||||||
local width, height, point
|
|
||||||
|
|
||||||
-- ClassicAPI before v1.18.0 leaves the UI scale in the size of an anchored
|
-- native StatusBar methods the bar overrides
|
||||||
-- frame, so the bar has to divide it back out
|
local statusbar = CreateFrame("StatusBar")
|
||||||
local scaledsize = CLASSIC_API_VERSION < 11800
|
local SetValue, SetMinMaxValues = statusbar.SetValue, statusbar.SetMinMaxValues
|
||||||
|
local SetOrientation, SetFrameLevel = statusbar.SetOrientation, statusbar.SetFrameLevel
|
||||||
|
|
||||||
local animate = CreateFrame("Frame", "pfStatusBarAnimation", UIParent)
|
local animate = CreateFrame("Frame", "pfStatusBarAnimation", UIParent)
|
||||||
animate:SetScript("OnUpdate", function()
|
animate:SetScript("OnUpdate", function()
|
||||||
stepsize = tonumber(pfUI_config.unitframes.animation_speed)
|
stepsize = tonumber(pfUI_config.unitframes.animation_speed)
|
||||||
|
|
||||||
for bar in pairs(animations) do
|
for bar in pairs(animations) do
|
||||||
if not bar.val_ or abs(bar.val_ - bar.val) < stepsize or bar.instant then
|
if not bar.val_ or abs(bar.val_ - bar.val) < stepsize then
|
||||||
bar:DisplayValue(bar.val)
|
bar:DisplayValue(bar.val)
|
||||||
elseif bar.val ~= bar.val_ then
|
elseif bar.val ~= bar.val_ then
|
||||||
bar:DisplayValue(bar.val_ + min((bar.val-bar.val_) / stepsize, max(bar.val-bar.val_, 30 / GetFramerate())))
|
bar:DisplayValue(bar.val_ + min((bar.val-bar.val_) / stepsize, max(bar.val-bar.val_, 30 / GetFramerate())))
|
||||||
@@ -25,7 +25,8 @@ do -- statusbars
|
|||||||
|
|
||||||
local handlers = {
|
local handlers = {
|
||||||
["DisplayValue"] = function(self, val)
|
["DisplayValue"] = function(self, val)
|
||||||
val = Clamp(val, self.min, self.max)
|
local smin, smax = self:GetMinMaxValues()
|
||||||
|
val = Clamp(val, smin, smax)
|
||||||
|
|
||||||
-- remove animation queue
|
-- remove animation queue
|
||||||
if val == self.val_ then
|
if val == self.val_ then
|
||||||
@@ -34,53 +35,20 @@ do -- statusbars
|
|||||||
|
|
||||||
-- set current visible value
|
-- set current visible value
|
||||||
self.val_ = val
|
self.val_ = val
|
||||||
|
SetValue(self, val)
|
||||||
|
|
||||||
if self.mode == "vertical" then
|
-- the background fills the missing part, all of an empty range
|
||||||
height = self:GetHeight()
|
self.bg:SetValue(smax > smin and (smax - val) / (smax - smin) or 1)
|
||||||
if scaledsize then height = height / self:GetEffectiveScale() end
|
|
||||||
point = height / (self.max - self.min) * (val - self.min)
|
|
||||||
|
|
||||||
-- keep values in limits
|
|
||||||
point = Clamp(point, 0, height)
|
|
||||||
|
|
||||||
-- set point to zero if value and max is zero
|
|
||||||
if val == 0 then point = 0 end
|
|
||||||
|
|
||||||
-- set status bar position/size
|
|
||||||
self.bar:SetPoint("TOPLEFT", self, "TOPLEFT", 0, - height + point)
|
|
||||||
self.bar:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 0, 0)
|
|
||||||
|
|
||||||
-- set background bar position/size
|
|
||||||
self.bg:SetPoint("TOPLEFT", self, "TOPLEFT", 0, 0)
|
|
||||||
self.bg:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 0, point)
|
|
||||||
else
|
|
||||||
width = self:GetWidth()
|
|
||||||
if scaledsize then width = width / self:GetEffectiveScale() end
|
|
||||||
point = width / (self.max - self.min) * (val - self.min)
|
|
||||||
|
|
||||||
-- keep values in limits
|
|
||||||
point = Clamp(point, 0, width)
|
|
||||||
|
|
||||||
-- set point to zero if value and max is zero
|
|
||||||
if val == 0 then point = 0 end
|
|
||||||
|
|
||||||
-- set status bar position/size
|
|
||||||
self.bar:SetPoint("TOPLEFT", self, "TOPLEFT", 0, 0)
|
|
||||||
self.bar:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", - width + point, 0)
|
|
||||||
|
|
||||||
-- set background bar position/size
|
|
||||||
self.bg:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", 0, 0)
|
|
||||||
self.bg:SetPoint("TOPLEFT", self, "TOPLEFT", point, 0)
|
|
||||||
end
|
|
||||||
end,
|
end,
|
||||||
|
|
||||||
["SetMinMaxValues"] = function(self, smin, smax, smooth)
|
["SetMinMaxValues"] = function(self, smin, smax, smooth)
|
||||||
-- smoothen the transition by keeping the value at the same percentage as before
|
-- smoothen the transition by keeping the value at the same percentage as before
|
||||||
if smooth and self.max and self.max > 0 and smax > 0 and self.max ~= smax then
|
local _, oldmax = self:GetMinMaxValues()
|
||||||
self.val_ = (self.val_ or self.val) / self.max * smax
|
if smooth and oldmax > 0 and smax > 0 and oldmax ~= smax then
|
||||||
|
self.val_ = (self.val_ or self.val) / oldmax * smax
|
||||||
end
|
end
|
||||||
|
|
||||||
self.min, self.max = smin, smax
|
SetMinMaxValues(self, smin, smax)
|
||||||
self:DisplayValue(self.val_ or self.val)
|
self:DisplayValue(self.val_ or self.val)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
@@ -93,41 +61,35 @@ do -- statusbars
|
|||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
["SetStatusBarTexture"] = function(self, r, g, b, a)
|
|
||||||
self.bar:SetTexture(r, g, b, a)
|
|
||||||
end,
|
|
||||||
|
|
||||||
["SetStatusBarColor"] = function(self, r, g, b, a)
|
|
||||||
self.bar:SetVertexColor(r, g, b, a)
|
|
||||||
end,
|
|
||||||
|
|
||||||
["SetStatusBarBackgroundTexture"] = function(self, r, g, b, a)
|
|
||||||
self.bg:SetTexture(r, g, b, a)
|
|
||||||
end,
|
|
||||||
|
|
||||||
["SetStatusBarBackgroundColor"] = function(self, r, g, b, a)
|
["SetStatusBarBackgroundColor"] = function(self, r, g, b, a)
|
||||||
self.bg:SetVertexColor(r, g, b, a)
|
self.bg:SetColorFill(r, g, b, a)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
["SetOrientation"] = function(self, mode)
|
["SetOrientation"] = function(self, orientation)
|
||||||
self.mode = strlower(mode)
|
SetOrientation(self, orientation)
|
||||||
|
self.bg:SetOrientation(orientation)
|
||||||
|
end,
|
||||||
|
|
||||||
|
-- the background stays one level below the fill, under anything else
|
||||||
|
-- drawn on the fill's frame
|
||||||
|
["SetFrameLevel"] = function(self, level)
|
||||||
|
SetFrameLevel(self, level)
|
||||||
|
self.bg:SetFrameLevel(level - 1)
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
function pfUI.api.CreateStatusBar(name, parent)
|
function pfUI.api.CreateStatusBar(name, parent)
|
||||||
local f = CreateFrame("Button", name, parent)
|
local f = CreateFrame("StatusBar", name, parent)
|
||||||
f:EnableMouse(false)
|
SetMinMaxValues(f, 0, 100)
|
||||||
|
SetValue(f, 0)
|
||||||
|
f.val = 0
|
||||||
|
|
||||||
f.bar = f:CreateTexture(nil, "NORMAL")
|
f.bg = CreateFrame("StatusBar", nil, f)
|
||||||
f.bar:SetPoint("TOPLEFT", f, "TOPLEFT", 0, 0)
|
f.bg:SetFrameLevel(f:GetFrameLevel() - 1)
|
||||||
f.bar:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 0, 0)
|
f.bg:SetAllPoints(f)
|
||||||
|
f.bg:SetReverseFill(true)
|
||||||
f.bg = f:CreateTexture(nil, "BACKGROUND")
|
f.bg:SetMinMaxValues(0, 1)
|
||||||
f.bg:SetPoint("TOPLEFT", f, "TOPLEFT", 0, 0)
|
f.bg:SetValue(1)
|
||||||
f.bg:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 0, 0)
|
|
||||||
|
|
||||||
-- set some default values
|
|
||||||
f.min, f.max, f.val = 0, 100, 0
|
|
||||||
|
|
||||||
-- add all handler functions to the object
|
-- add all handler functions to the object
|
||||||
for name, func in pairs(handlers) do
|
for name, func in pairs(handlers) do
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||||
|
<!--
|
||||||
|
pfUI's scroll bar for ClassicAPI's ScrollBox: a thin track with a flat
|
||||||
|
thumb. ScrollBarMixin needs Back and Forward steppers, so they exist but
|
||||||
|
stay hidden. Hook it up with ScrollUtil.InitScrollBoxListWithScrollBar.
|
||||||
|
-->
|
||||||
|
<EventFrame name="pfUIScrollBarTemplate" inherits="VerticalScrollBarTemplate" virtual="true">
|
||||||
|
<Size x="7"/>
|
||||||
|
<KeyValues>
|
||||||
|
<KeyValue key="hideIfUnscrollable" value="true" type="boolean"/>
|
||||||
|
</KeyValues>
|
||||||
|
<Frames>
|
||||||
|
<Frame parentKey="Track" setAllPoints="true" enableMouse="true">
|
||||||
|
<Frames>
|
||||||
|
<EventButton parentKey="Thumb">
|
||||||
|
<Size x="7"/>
|
||||||
|
<Layers>
|
||||||
|
<Layer level="ARTWORK">
|
||||||
|
<Texture setAllPoints="true">
|
||||||
|
<Color r=".3" g="1" b=".8" a=".5"/>
|
||||||
|
</Texture>
|
||||||
|
</Layer>
|
||||||
|
</Layers>
|
||||||
|
</EventButton>
|
||||||
|
</Frames>
|
||||||
|
</Frame>
|
||||||
|
<EventButton parentKey="Back" hidden="true"/>
|
||||||
|
<EventButton parentKey="Forward" hidden="true"/>
|
||||||
|
</Frames>
|
||||||
|
</EventFrame>
|
||||||
|
</Ui>
|
||||||
+64
-44
@@ -235,7 +235,50 @@ function pfUI.api.GetUnitStats(unitstr)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local aggrodata = { }
|
local aggrodata = { }
|
||||||
local aggroScan = nil -- static { u, t, tt } triples, built once so the hot scan allocates nothing
|
|
||||||
|
-- every unit whose target or target's target UnitHasAggro checks, as static
|
||||||
|
-- { u, t, tt } triples so the hot scan allocates nothing
|
||||||
|
local aggroScan = { }
|
||||||
|
do
|
||||||
|
local function add(u)
|
||||||
|
local t = u .. "target"
|
||||||
|
table.insert(aggroScan, { u = u, t = t, tt = t .. "target" })
|
||||||
|
end
|
||||||
|
|
||||||
|
add("pet")
|
||||||
|
add("player")
|
||||||
|
add("target")
|
||||||
|
add("mouseover")
|
||||||
|
|
||||||
|
add("focus")
|
||||||
|
add("focustarget")
|
||||||
|
add("focustargettarget")
|
||||||
|
|
||||||
|
add("pettarget")
|
||||||
|
add("playertarget")
|
||||||
|
add("targettarget")
|
||||||
|
add("mouseovertarget")
|
||||||
|
add("targettargettarget")
|
||||||
|
|
||||||
|
for i=1,4 do
|
||||||
|
add("party" .. i)
|
||||||
|
add("party" .. i .. "target")
|
||||||
|
add("partypet" .. i)
|
||||||
|
add("partypet" .. i .. "target")
|
||||||
|
end
|
||||||
|
|
||||||
|
for i=1,40 do
|
||||||
|
add("raid" .. i)
|
||||||
|
add("raid" .. i .. "target")
|
||||||
|
|
||||||
|
add("raidpet" .. i)
|
||||||
|
add("raidpet" .. i .. "target")
|
||||||
|
|
||||||
|
add("nameplate" .. i)
|
||||||
|
add("nameplate" .. i .. "target")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function pfUI.api.UnitHasAggro(unit)
|
function pfUI.api.UnitHasAggro(unit)
|
||||||
local now = GetTime()
|
local now = GetTime()
|
||||||
local data = aggrodata[unit]
|
local data = aggrodata[unit]
|
||||||
@@ -250,16 +293,6 @@ function pfUI.api.UnitHasAggro(unit)
|
|||||||
data.state = 0
|
data.state = 0
|
||||||
|
|
||||||
if UnitExists(unit) and UnitIsFriend(unit, "player") then
|
if UnitExists(unit) and UnitIsFriend(unit, "player") then
|
||||||
-- pfValidUnits never changes after load, so precompute the "<u>target" /
|
|
||||||
-- "<u>targettarget" token strings once instead of concatenating per call.
|
|
||||||
if not aggroScan then
|
|
||||||
aggroScan = {}
|
|
||||||
for u in pairs(pfValidUnits) do
|
|
||||||
local t = u .. "target"
|
|
||||||
table.insert(aggroScan, { u = u, t = t, tt = t .. "target" })
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for i = 1, table.getn(aggroScan) do
|
for i = 1, table.getn(aggroScan) do
|
||||||
local s = aggroScan[i]
|
local s = aggroScan[i]
|
||||||
if UnitExists(s.t) and UnitIsUnit(s.t, unit) and UnitCanAttack(s.u, unit) then
|
if UnitExists(s.t) and UnitIsUnit(s.t, unit) and UnitCanAttack(s.u, unit) then
|
||||||
@@ -349,11 +382,10 @@ function pfUI.uf:UpdateVisibility()
|
|||||||
|
|
||||||
-- this runs for every frame five times a second, so only touch the
|
-- this runs for every frame five times a second, so only touch the
|
||||||
-- attribute when the unit actually changed
|
-- attribute when the unit actually changed
|
||||||
local unitstr = (self.label or "") .. (self.id or "")
|
local unitstr = self.label .. self.id
|
||||||
local unit = unitstr ~= "" and unitstr or nil
|
if unitstr ~= self.unitstr then
|
||||||
if unit ~= self.unitstr then
|
self.unitstr = unitstr
|
||||||
self.unitstr = unit
|
self:SetAttribute("unit", unitstr)
|
||||||
self:SetAttribute("unit", unit)
|
|
||||||
end
|
end
|
||||||
-- anything but "show"/"hide" means "show if the unit exists"
|
-- anything but "show"/"hide" means "show if the unit exists"
|
||||||
local visibility = "exists"
|
local visibility = "exists"
|
||||||
@@ -395,9 +427,7 @@ function pfUI.uf:UpdateVisibility()
|
|||||||
self:RegisterUnitEvents(visibility ~= "hide" and self.unitstr or nil)
|
self:RegisterUnitEvents(visibility ~= "hide" and self.unitstr or nil)
|
||||||
|
|
||||||
-- vanilla visibility
|
-- vanilla visibility
|
||||||
if self.unitname then
|
if visibility == "hide" then
|
||||||
self:Show()
|
|
||||||
elseif visibility == "hide" then
|
|
||||||
self:Hide()
|
self:Hide()
|
||||||
elseif visibility == "show" then
|
elseif visibility == "show" then
|
||||||
self:Show()
|
self:Show()
|
||||||
@@ -508,6 +538,8 @@ function pfUI.uf:UpdateConfig()
|
|||||||
if tonumber(f.config.height) < 0 then f.hp:Hide() end
|
if tonumber(f.config.height) < 0 then f.hp:Hide() end
|
||||||
pfUI.api.CreateBackdrop(f.hp, default_border)
|
pfUI.api.CreateBackdrop(f.hp, default_border)
|
||||||
|
|
||||||
|
-- one level above the backdrop for the bar's background, one more for its fill
|
||||||
|
f.hp.bar:SetFrameLevel(f.hp.backdrop:GetFrameLevel() + 2)
|
||||||
f.hp.bar:SetStatusBarTexture(pfUI.media[f.config.bartexture])
|
f.hp.bar:SetStatusBarTexture(pfUI.media[f.config.bartexture])
|
||||||
f.hp.bar:SetAllPoints(f.hp)
|
f.hp.bar:SetAllPoints(f.hp)
|
||||||
if f.config.verticalbar == "1" then
|
if f.config.verticalbar == "1" then
|
||||||
@@ -522,7 +554,7 @@ function pfUI.uf:UpdateConfig()
|
|||||||
if custombg == "1" then
|
if custombg == "1" then
|
||||||
local cr, cg, cb, ca = GetStringColor(custombgcolor)
|
local cr, cg, cb, ca = GetStringColor(custombgcolor)
|
||||||
cr, cg, cb, ca = tonumber(cr), tonumber(cg), tonumber(cb), tonumber(ca)
|
cr, cg, cb, ca = tonumber(cr), tonumber(cg), tonumber(cb), tonumber(ca)
|
||||||
f.hp.bar:SetStatusBarBackgroundTexture(cr,cg,cb,ca)
|
f.hp.bar:SetStatusBarBackgroundColor(cr,cg,cb,ca)
|
||||||
end
|
end
|
||||||
|
|
||||||
f.power:ClearAllPoints()
|
f.power:ClearAllPoints()
|
||||||
@@ -531,7 +563,7 @@ function pfUI.uf:UpdateConfig()
|
|||||||
if tonumber(f.config.pheight) < 0 then f.power:Hide() end
|
if tonumber(f.config.pheight) < 0 then f.power:Hide() end
|
||||||
|
|
||||||
pfUI.api.CreateBackdrop(f.power, default_border)
|
pfUI.api.CreateBackdrop(f.power, default_border)
|
||||||
f.power.bar:SetFrameLevel(f.power.backdrop:GetFrameLevel() + 1)
|
f.power.bar:SetFrameLevel(f.power.backdrop:GetFrameLevel() + 2)
|
||||||
f.power.bar:SetStatusBarTexture(pfUI.media[f.config.pbartexture])
|
f.power.bar:SetStatusBarTexture(pfUI.media[f.config.pbartexture])
|
||||||
f.power.bar:SetAllPoints(f.power)
|
f.power.bar:SetAllPoints(f.power)
|
||||||
|
|
||||||
@@ -541,7 +573,7 @@ function pfUI.uf:UpdateConfig()
|
|||||||
if custompbg == "1" then
|
if custompbg == "1" then
|
||||||
local cr, cg, cb, ca = GetStringColor(custompbgcolor)
|
local cr, cg, cb, ca = GetStringColor(custompbgcolor)
|
||||||
cr, cg, cb, ca = tonumber(cr), tonumber(cg), tonumber(cb), tonumber(ca)
|
cr, cg, cb, ca = tonumber(cr), tonumber(cg), tonumber(cb), tonumber(ca)
|
||||||
f.power.bar:SetStatusBarBackgroundTexture(cr,cg,cb,ca)
|
f.power.bar:SetStatusBarBackgroundColor(cr,cg,cb,ca)
|
||||||
end
|
end
|
||||||
|
|
||||||
local fontname, fontsize, fontstyle
|
local fontname, fontsize, fontstyle
|
||||||
@@ -1019,6 +1051,8 @@ function pfUI.uf.OnEvent()
|
|||||||
this.update_pvp = true
|
this.update_pvp = true
|
||||||
elseif event == "UNIT_COMBAT" then
|
elseif event == "UNIT_COMBAT" then
|
||||||
CombatFeedback_OnCombatEvent(arg2, arg3, arg4, arg5)
|
CombatFeedback_OnCombatEvent(arg2, arg3, arg4, arg5)
|
||||||
|
elseif event == "INCOMING_RESURRECT_CHANGED" then
|
||||||
|
this.update_indicators = true
|
||||||
else
|
else
|
||||||
this.update_base = true
|
this.update_base = true
|
||||||
end
|
end
|
||||||
@@ -1189,10 +1223,6 @@ function pfUI.uf.OnUpdate()
|
|||||||
this.incHeal:Hide()
|
this.incHeal:Hide()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- update ressurections
|
|
||||||
local ress = libpredict:UnitHasIncomingResurrection(unit)
|
|
||||||
this.ressIcon:SetShown(ress and UnitIsDeadOrGhost(unit))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1244,8 +1274,6 @@ function pfUI.uf.OnUpdate()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if not this.label or this.label == "" then return end
|
|
||||||
|
|
||||||
-- update portrait on first visible frame
|
-- update portrait on first visible frame
|
||||||
if this.portrait and this.portrait.model and this.portrait.model.update then
|
if this.portrait and this.portrait.model and this.portrait.model.update then
|
||||||
this.portrait.model.lastUnit = UnitName(this.portrait.model.update)
|
this.portrait.model.lastUnit = UnitName(this.portrait.model.update)
|
||||||
@@ -1272,6 +1300,7 @@ local UNIT_EVENTS = {
|
|||||||
"UNIT_PORTRAIT_UPDATE", "UNIT_MODEL_CHANGED",
|
"UNIT_PORTRAIT_UPDATE", "UNIT_MODEL_CHANGED",
|
||||||
"UNIT_FACTION",
|
"UNIT_FACTION",
|
||||||
"UNIT_AURA", -- frame=buff, frame=debuff
|
"UNIT_AURA", -- frame=buff, frame=debuff
|
||||||
|
"INCOMING_RESURRECT_CHANGED", -- frame=ressIcon
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Point this frame's unit-event subscriptions at `unitstr`, or drop them when
|
-- Point this frame's unit-event subscriptions at `unitstr`, or drop them when
|
||||||
@@ -1332,11 +1361,7 @@ end
|
|||||||
-- ============================================================
|
-- ============================================================
|
||||||
|
|
||||||
function pfUI.uf.OnClick()
|
function pfUI.uf.OnClick()
|
||||||
if not this.label and this.unitname then
|
pfUI.uf:ClickAction(arg1)
|
||||||
TargetByName(this.unitname, true)
|
|
||||||
else
|
|
||||||
pfUI.uf:ClickAction(arg1)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function pfUI.uf:ClickAction(button)
|
function pfUI.uf:ClickAction(button)
|
||||||
@@ -1433,13 +1458,6 @@ function pfUI.uf:CreateUnitFrame(unit, id, config, tick)
|
|||||||
f.config = config or pfUI_config.unitframes.fallback
|
f.config = config or pfUI_config.unitframes.fallback
|
||||||
f.tick = tick
|
f.tick = tick
|
||||||
|
|
||||||
-- disable events for unknown unitstrings
|
|
||||||
if not pfValidUnits[strlower(unit) .. id] then
|
|
||||||
f.unitname = unit
|
|
||||||
f.label, f.id = "", ""
|
|
||||||
f.RegisterEvent = function() return end
|
|
||||||
end
|
|
||||||
|
|
||||||
CreateBackdropShadow(f)
|
CreateBackdropShadow(f)
|
||||||
|
|
||||||
f.hp = CreateFrame("Frame",nil, f)
|
f.hp = CreateFrame("Frame",nil, f)
|
||||||
@@ -1490,7 +1508,7 @@ function pfUI.uf:CreateUnitFrame(unit, id, config, tick)
|
|||||||
|
|
||||||
f.incHeal = CreateFrame("Frame", nil, f.hp)
|
f.incHeal = CreateFrame("Frame", nil, f.hp)
|
||||||
-- Texture lives on hp.bar for correct draw order:
|
-- Texture lives on hp.bar for correct draw order:
|
||||||
-- hp.bar.bg (BACKGROUND) < incHeal (BORDER) < hp.bar.bar (NORMAL)
|
-- hp.bar.bg (a level below) < incHeal (BORDER) < hp.bar's fill (ARTWORK)
|
||||||
f.incHeal.texture = f.hp.bar:CreateTexture(nil, "BORDER")
|
f.incHeal.texture = f.hp.bar:CreateTexture(nil, "BORDER")
|
||||||
f.incHeal.texture:SetAllPoints(f.incHeal)
|
f.incHeal.texture:SetAllPoints(f.incHeal)
|
||||||
-- Override Show/Hide since texture lives on hp.bar, not incHeal
|
-- Override Show/Hide since texture lives on hp.bar, not incHeal
|
||||||
@@ -1556,9 +1574,7 @@ function pfUI.uf:CreateUnitFrame(unit, id, config, tick)
|
|||||||
f:Hide()
|
f:Hide()
|
||||||
end
|
end
|
||||||
|
|
||||||
if f.label ~= "" then
|
f:SetAttribute("unit", f.label .. f.id)
|
||||||
f:SetAttribute("unit", f.label .. f.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- register frame for clique
|
-- register frame for clique
|
||||||
_G.ClickCastFrames = ClickCastFrames or {}
|
_G.ClickCastFrames = ClickCastFrames or {}
|
||||||
@@ -1632,6 +1648,10 @@ function pfUI.uf:RefreshIndicators(unit)
|
|||||||
unit.pvpIcon:SetShown(unit.config.showPVP == "1" and UnitIsPVP(unitstr))
|
unit.pvpIcon:SetShown(unit.config.showPVP == "1" and UnitIsPVP(unitstr))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if unit.ressIcon then -- Resurrection Icon
|
||||||
|
unit.ressIcon:SetShown(libpredict:UnitHasResurrection(unitstr))
|
||||||
|
end
|
||||||
|
|
||||||
if unit.restIcon and unit:GetName() == "pfPlayer" then -- Rest Icon
|
if unit.restIcon and unit:GetName() == "pfPlayer" then -- Rest Icon
|
||||||
unit.restIcon:SetShown(C.unitframes.player.showRest == "1" and UnitIsUnit(unitstr, "player") and IsResting())
|
unit.restIcon:SetShown(C.unitframes.player.showRest == "1" and UnitIsUnit(unitstr, "player") and IsResting())
|
||||||
end
|
end
|
||||||
|
|||||||
Vendored
-50
@@ -1,50 +0,0 @@
|
|||||||
-- barlength = {[formfactor]={cols, rows}}
|
|
||||||
pfGridmath = {
|
|
||||||
[1] = {{1,1}},
|
|
||||||
[2] = {{2,1},{1,2}},
|
|
||||||
[3] = {{3,1},{1,3}},
|
|
||||||
[4] = {{4,1},{2,2},{1,4}},
|
|
||||||
[5] = {{5,1},{1,5}},
|
|
||||||
[6] = {{6,1},{3,2},{2,3},{1,6}},
|
|
||||||
[7] = {{7,1},{1,7}},
|
|
||||||
[8] = {{8,1},{4,2},{2,4},{1,8}},
|
|
||||||
[9] = {{9,1},{3,3},{1,9}},
|
|
||||||
[10] = {{10,1},{5,2},{2,5},{1,10}},
|
|
||||||
[11] = {{11,1},{1,11}},
|
|
||||||
[12] = {{12,1},{6,2},{4,3},{3,4},{2,6},{1,12}}
|
|
||||||
}
|
|
||||||
|
|
||||||
-- list of valid unitstrings
|
|
||||||
pfValidUnits = {}
|
|
||||||
pfValidUnits["pet"] = true
|
|
||||||
pfValidUnits["player"] = true
|
|
||||||
pfValidUnits["target"] = true
|
|
||||||
pfValidUnits["mouseover"] = true
|
|
||||||
|
|
||||||
pfValidUnits["focus"] = true
|
|
||||||
pfValidUnits["focustarget"] = true
|
|
||||||
pfValidUnits["focustargettarget"] = true
|
|
||||||
|
|
||||||
pfValidUnits["pettarget"] = true
|
|
||||||
pfValidUnits["playertarget"] = true
|
|
||||||
pfValidUnits["targettarget"] = true
|
|
||||||
pfValidUnits["mouseovertarget"] = true
|
|
||||||
pfValidUnits["targettargettarget"] = true
|
|
||||||
|
|
||||||
for i=1,4 do
|
|
||||||
pfValidUnits["party" .. i] = true
|
|
||||||
pfValidUnits["party" .. i .. "target"] = true
|
|
||||||
pfValidUnits["partypet" .. i] = true
|
|
||||||
pfValidUnits["partypet" .. i .. "target"] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
for i=1,40 do
|
|
||||||
pfValidUnits["raid" .. i] = true
|
|
||||||
pfValidUnits["raid" .. i .. "target"] = true
|
|
||||||
|
|
||||||
pfValidUnits["raidpet" .. i] = true
|
|
||||||
pfValidUnits["raidpet" .. i .. "target"] = true
|
|
||||||
|
|
||||||
pfValidUnits["nameplate" .. i] = true
|
|
||||||
pfValidUnits["nameplate" .. i .. "target"] = true
|
|
||||||
end
|
|
||||||
Vendored
-1
@@ -281,7 +281,6 @@ pfUI_translation["deDE"] = {
|
|||||||
["Enable Energy Ticks"] = nil,
|
["Enable Energy Ticks"] = nil,
|
||||||
["Enable Extended Guild Information"] = nil,
|
["Enable Extended Guild Information"] = nil,
|
||||||
["Enable Frame Shadow"] = nil,
|
["Enable Frame Shadow"] = nil,
|
||||||
["Enable Full-Text Search"] = nil,
|
|
||||||
["Enable Indicators"] = nil,
|
["Enable Indicators"] = nil,
|
||||||
["Enable Item Quality Color For Equipment Only"] = nil,
|
["Enable Item Quality Color For Equipment Only"] = nil,
|
||||||
["Enable \"Loot & Spam\" Chat Window"] = nil,
|
["Enable \"Loot & Spam\" Chat Window"] = nil,
|
||||||
|
|||||||
Vendored
-1
@@ -290,7 +290,6 @@ pfUI_translation["enUS"] = {
|
|||||||
["Enable Energy Ticks"] = nil,
|
["Enable Energy Ticks"] = nil,
|
||||||
["Enable Extended Guild Information"] = nil,
|
["Enable Extended Guild Information"] = nil,
|
||||||
["Enable Frame Shadow"] = nil,
|
["Enable Frame Shadow"] = nil,
|
||||||
["Enable Full-Text Search"] = nil,
|
|
||||||
["Enable Indicators"] = nil,
|
["Enable Indicators"] = nil,
|
||||||
["Enable Item Quality Color For Equipment Only"] = nil,
|
["Enable Item Quality Color For Equipment Only"] = nil,
|
||||||
["Enable \"Loot & Spam\" Chat Window"] = nil,
|
["Enable \"Loot & Spam\" Chat Window"] = nil,
|
||||||
|
|||||||
Vendored
-1
@@ -281,7 +281,6 @@ pfUI_translation["esES"] = {
|
|||||||
["Enable Energy Ticks"] = "Activar tics de energía",
|
["Enable Energy Ticks"] = "Activar tics de energía",
|
||||||
["Enable Extended Guild Information"] = "Activar información de hermandad extendida",
|
["Enable Extended Guild Information"] = "Activar información de hermandad extendida",
|
||||||
["Enable Frame Shadow"] = "Activar sombra del marco",
|
["Enable Frame Shadow"] = "Activar sombra del marco",
|
||||||
["Enable Full-Text Search"] = nil,
|
|
||||||
["Enable Indicators"] = "Activar indicadores",
|
["Enable Indicators"] = "Activar indicadores",
|
||||||
["Enable Item Quality Color For Equipment Only"] = "Mostrar el color de calidad de objetos solo para equipo",
|
["Enable Item Quality Color For Equipment Only"] = "Mostrar el color de calidad de objetos solo para equipo",
|
||||||
["Enable \"Loot & Spam\" Chat Window"] = "Activar ventana de chat \"Botín y spam\"",
|
["Enable \"Loot & Spam\" Chat Window"] = "Activar ventana de chat \"Botín y spam\"",
|
||||||
|
|||||||
Vendored
-1
@@ -281,7 +281,6 @@ pfUI_translation["frFR"] = {
|
|||||||
["Enable Energy Ticks"] = "Activer la barre de rechargement d'énergie",
|
["Enable Energy Ticks"] = "Activer la barre de rechargement d'énergie",
|
||||||
["Enable Extended Guild Information"] = "Activer les informations de guilde étendues",
|
["Enable Extended Guild Information"] = "Activer les informations de guilde étendues",
|
||||||
["Enable Frame Shadow"] = "Activer l'ombre des cadres",
|
["Enable Frame Shadow"] = "Activer l'ombre des cadres",
|
||||||
["Enable Full-Text Search"] = nil,
|
|
||||||
["Enable Indicators"] = "Activer les indicateurs",
|
["Enable Indicators"] = "Activer les indicateurs",
|
||||||
["Enable Item Quality Color For Equipment Only"] = "Activer la couleur de la qualité des objets seulement sur les pièces d'équipement",
|
["Enable Item Quality Color For Equipment Only"] = "Activer la couleur de la qualité des objets seulement sur les pièces d'équipement",
|
||||||
["Enable \"Loot & Spam\" Chat Window"] = "Activer la fenêtre de chat \"Butins & Spam\"",
|
["Enable \"Loot & Spam\" Chat Window"] = "Activer la fenêtre de chat \"Butins & Spam\"",
|
||||||
|
|||||||
Vendored
-1
@@ -281,7 +281,6 @@ pfUI_translation["koKR"] = {
|
|||||||
["Enable Energy Ticks"] = "Energy Ticks 활성화",
|
["Enable Energy Ticks"] = "Energy Ticks 활성화",
|
||||||
["Enable Extended Guild Information"] = "길드 정보 확장 사용",
|
["Enable Extended Guild Information"] = "길드 정보 확장 사용",
|
||||||
["Enable Frame Shadow"] = nil,
|
["Enable Frame Shadow"] = nil,
|
||||||
["Enable Full-Text Search"] = nil,
|
|
||||||
["Enable Indicators"] = nil,
|
["Enable Indicators"] = nil,
|
||||||
["Enable Item Quality Color For Equipment Only"] = "착용장비 전용 아이템품질 색상 활성화",
|
["Enable Item Quality Color For Equipment Only"] = "착용장비 전용 아이템품질 색상 활성화",
|
||||||
["Enable \"Loot & Spam\" Chat Window"] = "\"루팅 & 스팜\"채팅 창 사용",
|
["Enable \"Loot & Spam\" Chat Window"] = "\"루팅 & 스팜\"채팅 창 사용",
|
||||||
|
|||||||
Vendored
-1
@@ -281,7 +281,6 @@ pfUI_translation["ruRU"] = {
|
|||||||
["Enable Energy Ticks"] = "Включить восполнение энергии",
|
["Enable Energy Ticks"] = "Включить восполнение энергии",
|
||||||
["Enable Extended Guild Information"] = "Включить расширенную информацию о гильдии",
|
["Enable Extended Guild Information"] = "Включить расширенную информацию о гильдии",
|
||||||
["Enable Frame Shadow"] = "Включить тень окон",
|
["Enable Frame Shadow"] = "Включить тень окон",
|
||||||
["Enable Full-Text Search"] = nil,
|
|
||||||
["Enable Indicators"] = "Включить индикаторы",
|
["Enable Indicators"] = "Включить индикаторы",
|
||||||
["Enable Item Quality Color For Equipment Only"] = "Включить цвет качества предметов только для экипировки",
|
["Enable Item Quality Color For Equipment Only"] = "Включить цвет качества предметов только для экипировки",
|
||||||
["Enable \"Loot & Spam\" Chat Window"] = "Включить окно чата \"Добыча & Спам\"",
|
["Enable \"Loot & Spam\" Chat Window"] = "Включить окно чата \"Добыча & Спам\"",
|
||||||
|
|||||||
Vendored
-1
@@ -281,7 +281,6 @@ pfUI_translation["zhCN"] = {
|
|||||||
["Enable Energy Ticks"] = "显示能量刻度",
|
["Enable Energy Ticks"] = "显示能量刻度",
|
||||||
["Enable Extended Guild Information"] = "公会信息扩展显示",
|
["Enable Extended Guild Information"] = "公会信息扩展显示",
|
||||||
["Enable Frame Shadow"] = "启用框架阴影",
|
["Enable Frame Shadow"] = "启用框架阴影",
|
||||||
["Enable Full-Text Search"] = "启用全文搜索",
|
|
||||||
["Enable Indicators"] = "启用指示器",
|
["Enable Indicators"] = "启用指示器",
|
||||||
["Enable Item Quality Color For Equipment Only"] = "仅在装备上显示品质颜色",
|
["Enable Item Quality Color For Equipment Only"] = "仅在装备上显示品质颜色",
|
||||||
["Enable \"Loot & Spam\" Chat Window"] = "启用[拾取、综合]聊天窗口",
|
["Enable \"Loot & Spam\" Chat Window"] = "启用[拾取、综合]聊天窗口",
|
||||||
|
|||||||
Vendored
-1
@@ -281,7 +281,6 @@ pfUI_translation["zhTW"] = {
|
|||||||
["Enable Energy Ticks"] = "顯示能量刻度",
|
["Enable Energy Ticks"] = "顯示能量刻度",
|
||||||
["Enable Extended Guild Information"] = "公會資訊擴展顯示",
|
["Enable Extended Guild Information"] = "公會資訊擴展顯示",
|
||||||
["Enable Frame Shadow"] = "啟用框架陰影",
|
["Enable Frame Shadow"] = "啟用框架陰影",
|
||||||
["Enable Full-Text Search"] = nil,
|
|
||||||
["Enable Indicators"] = nil,
|
["Enable Indicators"] = nil,
|
||||||
["Enable Item Quality Color For Equipment Only"] = "僅在裝備上顯示品質顏色",
|
["Enable Item Quality Color For Equipment Only"] = "僅在裝備上顯示品質顏色",
|
||||||
["Enable \"Loot & Spam\" Chat Window"] = "啟用[拾取、綜合]聊天視窗",
|
["Enable \"Loot & Spam\" Chat Window"] = "啟用[拾取、綜合]聊天視窗",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
<Ui xmlns="http://www.blizzard.com/wow/ui/">
|
||||||
<Include file="..\api\api.lua"/>
|
<Include file="..\api\api.lua"/>
|
||||||
<Include file="..\api\config.lua"/>
|
<Include file="..\api\config.lua"/>
|
||||||
|
<Include file="..\api\ui-widgets.xml"/>
|
||||||
<Include file="..\api\ui-widgets.lua"/>
|
<Include file="..\api\ui-widgets.lua"/>
|
||||||
<Include file="..\api\unitframes.lua"/>
|
<Include file="..\api\unitframes.lua"/>
|
||||||
</Ui>
|
</Ui>
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
<Include file="..\env\locales_esES.lua"/>
|
<Include file="..\env\locales_esES.lua"/>
|
||||||
<Include file="..\env\locales_ruRU.lua"/>
|
<Include file="..\env\locales_ruRU.lua"/>
|
||||||
|
|
||||||
<Include file="..\env\tables.lua"/>
|
|
||||||
<Include file="..\env\profiles.lua"/>
|
<Include file="..\env\profiles.lua"/>
|
||||||
|
|
||||||
<Include file="..\env\translations_enUS.lua"/>
|
<Include file="..\env\translations_enUS.lua"/>
|
||||||
|
|||||||
+58
-167
@@ -2,16 +2,21 @@
|
|||||||
setfenv(1, pfUI:GetEnvironment())
|
setfenv(1, pfUI:GetEnvironment())
|
||||||
|
|
||||||
--[[ libpredict ]]--
|
--[[ libpredict ]]--
|
||||||
-- A pfUI library that detects, receives and sends heal and resurrection predictions.
|
-- A pfUI library that detects, receives and sends heal predictions.
|
||||||
-- Healing predictions are done by caching the last known "normal" heal value of the
|
-- Healing predictions are done by caching the last known "normal" heal value of the
|
||||||
-- spell when last being used. Those chaches are cleared when new talents are detected.
|
-- spell when last being used. Those chaches are cleared when new talents are detected.
|
||||||
-- The API provides function calls similar to later WoW expansions such as:
|
-- The API provides function calls similar to later WoW expansions such as:
|
||||||
-- UnitGetIncomingHeals(unit)
|
-- UnitGetIncomingHeals(unit)
|
||||||
-- UnitHasIncomingResurrection(unit)
|
-- UnitHasResurrection(unit)
|
||||||
--
|
--
|
||||||
-- The library is able to receive and send compatible messages to HealComm
|
-- UnitHasResurrection extends ClassicAPI's UnitHasIncomingResurrection, which
|
||||||
-- including resurrections. It has an option to disable the sending of those
|
-- ends with the cast, to a resurrection that landed and waits for the target
|
||||||
-- messages in case HealComm is already active.
|
-- to accept it.
|
||||||
|
--
|
||||||
|
-- The library is able to receive and send compatible messages to HealComm,
|
||||||
|
-- and announces the player's resurrections to HealComm and CTRA. It has an
|
||||||
|
-- option to disable the sending of those messages in case HealComm is
|
||||||
|
-- already active.
|
||||||
--
|
--
|
||||||
-- Casts are read from ClassicAPI's UNIT_SPELLCAST_* events and heal amounts
|
-- Casts are read from ClassicAPI's UNIT_SPELLCAST_* events and heal amounts
|
||||||
-- from COMBAT_LOG_EVENT_UNFILTERED. GetHotDuration() reads live HoT timers
|
-- from COMBAT_LOG_EVENT_UNFILTERED. GetHotDuration() reads live HoT timers
|
||||||
@@ -20,18 +25,16 @@ setfenv(1, pfUI:GetEnvironment())
|
|||||||
-- return instantly when another libpredict is already active
|
-- return instantly when another libpredict is already active
|
||||||
if pfUI.api.libpredict then return end
|
if pfUI.api.libpredict then return end
|
||||||
|
|
||||||
local heals, ress, events, hots = {}, {}, {}, {}
|
local heals, events, hots = {}, {}, {}
|
||||||
local spell_queue = { "DUMMY", "DUMMYRank 9", "TARGET" }
|
local spell_queue = { "DUMMY", "DUMMYRank 9", "TARGET" }
|
||||||
local player = UnitName("player")
|
local player = UnitName("player")
|
||||||
local cache, gear_string = {}, ""
|
local cache, gear_string = {}, ""
|
||||||
local foreignCache = {} -- [casterName][spellKey] = amount, in-memory cache for other healers
|
local foreignCache = {} -- [casterName][spellKey] = amount, in-memory cache for other healers
|
||||||
local rejuvDuration, renewDuration = 12, 15 --default durations
|
local rejuvDuration, renewDuration = 12, 15 --default durations
|
||||||
local ressGuidToName = {} -- [casterGuid] = casterName, for interrupted-cast cleanup
|
|
||||||
local healGuidToName = {} -- [casterGuid] = casterName, for interrupted-cast cleanup
|
local healGuidToName = {} -- [casterGuid] = casterName, for interrupted-cast cleanup
|
||||||
local sentTargets = {} -- [castGUID] = target name of an own cast, from UNIT_SPELLCAST_SENT
|
local sentTargets = {} -- [castGUID] = target name of an own cast, from UNIT_SPELLCAST_SENT
|
||||||
local castTargets = {} -- [castGUID] = target name of a foreign cast, from UNIT_SPELLCAST_START
|
local resOffers = {} -- [guid] = expiry of a landed resurrection the target has yet to accept
|
||||||
local ress_timers = {} -- [target][sender] = expiry_timestamp (60s rez window)
|
local RES_OFFER_TIMEOUT = 60 -- the target's resurrect popup declines itself after 60s
|
||||||
local RESS_TIMEOUT = 60 -- Vanilla: rez offer expires after 60s
|
|
||||||
|
|
||||||
-- Localized spell names resolved once from canonical rank-1 spellIDs.
|
-- Localized spell names resolved once from canonical rank-1 spellIDs.
|
||||||
-- Every rank shares the same name, so per-rank comparisons elsewhere can
|
-- Every rank shares the same name, so per-rank comparisons elsewhere can
|
||||||
@@ -42,7 +45,6 @@ local RENEW = C_Spell.GetSpellName(139) -- Renew (Rank 1)
|
|||||||
local REGROWTH = C_Spell.GetSpellName(8936) -- Regrowth (Rank 1)
|
local REGROWTH = C_Spell.GetSpellName(8936) -- Regrowth (Rank 1)
|
||||||
|
|
||||||
local libpredict = CreateFrame("Frame")
|
local libpredict = CreateFrame("Frame")
|
||||||
libpredict:RegisterEvent("UNIT_HEALTH")
|
|
||||||
libpredict:RegisterEvent("CHAT_MSG_ADDON")
|
libpredict:RegisterEvent("CHAT_MSG_ADDON")
|
||||||
libpredict:RegisterEvent("PLAYER_TARGET_CHANGED")
|
libpredict:RegisterEvent("PLAYER_TARGET_CHANGED")
|
||||||
libpredict:RegisterEvent("PLAYER_LOGOUT")
|
libpredict:RegisterEvent("PLAYER_LOGOUT")
|
||||||
@@ -55,13 +57,8 @@ libpredict:SetScript("OnEvent", function()
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if event == "CHAT_MSG_ADDON" and (arg1 == "HealComm" or arg1 == "CTRA") then
|
if event == "CHAT_MSG_ADDON" and arg1 == "HealComm" then
|
||||||
this:ParseChatMessage(arg4, arg2, arg1)
|
this:ParseChatMessage(arg4, arg2)
|
||||||
elseif event == "UNIT_HEALTH" then
|
|
||||||
local name = UnitName(arg1)
|
|
||||||
if name and ress[name] and not UnitIsDeadOrGhost(arg1) then
|
|
||||||
ress[name] = nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -95,12 +92,6 @@ local function cacheRaidNames()
|
|||||||
if pguid then guidNameCache[pguid] = UnitName("player") end
|
if pguid then guidNameCache[pguid] = UnitName("player") end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function isRezSpell(spellId)
|
|
||||||
if not L["resurrections"] then return false end
|
|
||||||
local spellName = C_Spell.GetSpellName(spellId)
|
|
||||||
return spellName and L["resurrections"][spellName]
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Build cache on world enter
|
-- Build cache on world enter
|
||||||
libpredict:RegisterEvent("PLAYER_ENTERING_WORLD")
|
libpredict:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||||
libpredict:RegisterEvent("RAID_ROSTER_UPDATE")
|
libpredict:RegisterEvent("RAID_ROSTER_UPDATE")
|
||||||
@@ -131,7 +122,6 @@ local function OnOwnCastStart(spellId, castGUID)
|
|||||||
|
|
||||||
if L["resurrections"][spellName] then
|
if L["resurrections"][spellName] then
|
||||||
if target then
|
if target then
|
||||||
libpredict:Ress(player, target, UnitGUID("player"))
|
|
||||||
libpredict.sender:SendHealCommMsg("Resurrection/" .. target .. "/start/")
|
libpredict.sender:SendHealCommMsg("Resurrection/" .. target .. "/start/")
|
||||||
libpredict.sender:SendResCommMsg("RES " .. target)
|
libpredict.sender:SendResCommMsg("RES " .. target)
|
||||||
libpredict.sender.resurrecting = true
|
libpredict.sender.resurrecting = true
|
||||||
@@ -212,7 +202,7 @@ local function OnOwnCastStart(spellId, castGUID)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Own cast landed: HealStop, Regrowth timer, instant HoTs, own rez timer
|
-- Own cast landed: HealStop, Regrowth timer, instant HoTs
|
||||||
local function OnOwnCastSucceeded(spellId, castGUID)
|
local function OnOwnCastSucceeded(spellId, castGUID)
|
||||||
local target = sentTargets[castGUID] or spell_queue[3]
|
local target = sentTargets[castGUID] or spell_queue[3]
|
||||||
sentTargets[castGUID] = nil
|
sentTargets[castGUID] = nil
|
||||||
@@ -250,14 +240,10 @@ local function OnOwnCastSucceeded(spellId, castGUID)
|
|||||||
libpredict:Hot(player, target, hotType, duration, nil, "UNIT_SPELLCAST_SUCCEEDED", rank)
|
libpredict:Hot(player, target, hotType, duration, nil, "UNIT_SPELLCAST_SUCCEEDED", rank)
|
||||||
libpredict.sender:SendHealCommMsg(hotType .. "/" .. target .. "/" .. duration .. "/" .. rank .. "/")
|
libpredict.sender:SendHealCommMsg(hotType .. "/" .. target .. "/" .. duration .. "/" .. rank .. "/")
|
||||||
end
|
end
|
||||||
|
|
||||||
if isRezSpell(spellId) then
|
|
||||||
libpredict:RessSetTimer(player, target)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Foreign cast-time spell started (heals + rez)
|
-- Foreign cast-time heal started
|
||||||
local function OnOtherCastStart(unit, spellId, castGUID)
|
local function OnOtherCastStart(unit, spellId)
|
||||||
local spellName = C_Spell.GetSpellName(spellId)
|
local spellName = C_Spell.GetSpellName(spellId)
|
||||||
if not spellName then return end
|
if not spellName then return end
|
||||||
|
|
||||||
@@ -267,13 +253,6 @@ local function OnOtherCastStart(unit, spellId, castGUID)
|
|||||||
|
|
||||||
local targetName = UnitSpellTargetName(unit)
|
local targetName = UnitSpellTargetName(unit)
|
||||||
if not targetName then return end
|
if not targetName then return end
|
||||||
castTargets[castGUID] = targetName
|
|
||||||
|
|
||||||
-- Resurrection cast
|
|
||||||
if L["resurrections"][spellName] then
|
|
||||||
libpredict:Ress(casterName, targetName, casterGuid)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Heal cast: look up cached amount from a previous cast by this healer
|
-- Heal cast: look up cached amount from a previous cast by this healer
|
||||||
local _, _, _, startMs, endMs = C_Spell.UnitCastingInfo(unit)
|
local _, _, _, startMs, endMs = C_Spell.UnitCastingInfo(unit)
|
||||||
@@ -324,35 +303,31 @@ local function OnOtherCastStart(unit, spellId, castGUID)
|
|||||||
libpredict:Heal(casterName, targetName, amount, castTime, casterGuid)
|
libpredict:Heal(casterName, targetName, amount, castTime, casterGuid)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Foreign cast landed: rez timer, or the predicted heal is fulfilled
|
-- Foreign cast landed: the predicted heal is fulfilled
|
||||||
local function OnOtherCastSucceeded(unit, spellId, castGUID)
|
local function OnOtherCastSucceeded(unit)
|
||||||
local casterGuid = UnitGUID(unit)
|
local casterName = resolveNameFromGuid(UnitGUID(unit))
|
||||||
local casterName = resolveNameFromGuid(casterGuid)
|
|
||||||
if not casterName then return end
|
if not casterName then return end
|
||||||
|
|
||||||
if isRezSpell(spellId) then
|
|
||||||
local targetName = castTargets[castGUID]
|
|
||||||
if targetName then
|
|
||||||
libpredict:RessSetTimer(casterName, targetName)
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
libpredict:HealStop(casterName)
|
libpredict:HealStop(casterName)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Foreign cast interrupted: remove cancelled resses/heals
|
-- Foreign cast interrupted: remove cancelled heals
|
||||||
local function OnOtherCastInterrupted(unit)
|
local function OnOtherCastInterrupted(unit)
|
||||||
local casterGuid = UnitGUID(unit)
|
local casterGuid = UnitGUID(unit)
|
||||||
if not casterGuid then return end
|
if not casterGuid then return end
|
||||||
local ressName = ressGuidToName[casterGuid]
|
|
||||||
if ressName then
|
|
||||||
libpredict:RessStop(ressName)
|
|
||||||
end
|
|
||||||
local healName = healGuidToName[casterGuid]
|
local healName = healGuidToName[casterGuid]
|
||||||
if healName then libpredict:HealStop(healName) end
|
if healName then libpredict:HealStop(healName) end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Flag the unit frames showing `guid` to redraw their resurrection icon
|
||||||
|
local function RefreshResFrames(guid)
|
||||||
|
for _, frame in pairs(pfUI.uf.frames) do
|
||||||
|
if frame.unitstr and UnitGUID(frame.unitstr) == guid then
|
||||||
|
frame.update_indicators = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
libpredict:SetScript("OnUpdate", function()
|
libpredict:SetScript("OnUpdate", function()
|
||||||
-- throttle cleanup - no need to check every frame
|
-- throttle cleanup - no need to check every frame
|
||||||
local now = pfUI.uf.now or GetTime()
|
local now = pfUI.uf.now or GetTime()
|
||||||
@@ -366,13 +341,12 @@ libpredict:SetScript("OnUpdate", function()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Rez timeout: remove offer after 60s if player doesn't accept
|
-- drop resurrection offers the target accepted or let run out
|
||||||
for target, senders in pairs(ress_timers) do
|
for guid, expiry in pairs(resOffers) do
|
||||||
for sender, expiry in pairs(senders) do
|
local unit = UnitTokenFromGUID(guid)
|
||||||
if now >= expiry then
|
if now >= expiry or not (unit and UnitIsDeadOrGhost(unit)) then
|
||||||
senders[sender] = nil
|
resOffers[guid] = nil
|
||||||
if ress[target] then ress[target][sender] = nil end
|
RefreshResFrames(guid)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
@@ -386,8 +360,6 @@ function libpredict:ParseComm(sender, msg)
|
|||||||
if libpredict.debug then
|
if libpredict.debug then
|
||||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ffff[libpredict RX]|r HealStop from " .. tostring(sender))
|
DEFAULT_CHAT_FRAME:AddMessage("|cff00ffff[libpredict RX]|r HealStop from " .. tostring(sender))
|
||||||
end
|
end
|
||||||
elseif msg == "Resurrection/stop/" then
|
|
||||||
msgtype = "RessStop"
|
|
||||||
elseif msg then
|
elseif msg then
|
||||||
local msgobj = {strsplit("/", msg)}
|
local msgobj = {strsplit("/", msg)}
|
||||||
|
|
||||||
@@ -397,10 +369,6 @@ function libpredict:ParseComm(sender, msg)
|
|||||||
msgtype, time = "Delay", msgobj[2]
|
msgtype, time = "Delay", msgobj[2]
|
||||||
end
|
end
|
||||||
|
|
||||||
if msgobj[1] and msgobj[1] == "Resurrection" and msgobj[2] then
|
|
||||||
msgtype, target = "Ress", msgobj[2]
|
|
||||||
end
|
|
||||||
|
|
||||||
if msgobj[1] == "Heal" and msgobj[2] then
|
if msgobj[1] == "Heal" and msgobj[2] then
|
||||||
msgtype, target, heal, time = "Heal", msgobj[2], msgobj[3], msgobj[4]
|
msgtype, target, heal, time = "Heal", msgobj[2], msgobj[3], msgobj[4]
|
||||||
end
|
end
|
||||||
@@ -472,25 +440,12 @@ end
|
|||||||
local recentHots = {}
|
local recentHots = {}
|
||||||
local DUPLICATE_WINDOW = 0.5 -- Ignoriere gleiche Nachricht innerhalb 0.5s
|
local DUPLICATE_WINDOW = 0.5 -- Ignoriere gleiche Nachricht innerhalb 0.5s
|
||||||
|
|
||||||
function libpredict:ParseChatMessage(sender, msg, comm)
|
function libpredict:ParseChatMessage(sender, msg)
|
||||||
local msgtype, target, heal, time, rank
|
local msgtype, target, heal, time, rank = libpredict:ParseComm(sender, msg)
|
||||||
|
|
||||||
if comm == "HealComm" then
|
|
||||||
msgtype, target, heal, time, rank = libpredict:ParseComm(sender, msg)
|
|
||||||
elseif comm == "CTRA" then
|
|
||||||
local _, _, cmd, ctratarget = string.find(msg, "(%a+)%s?([^#]*)")
|
|
||||||
if cmd and ctratarget and cmd == "RES" and ctratarget ~= "" and ctratarget ~= UNKNOWN then
|
|
||||||
msgtype = "Ress"
|
|
||||||
target = ctratarget
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if msgtype == "Stop" and sender then
|
if msgtype == "Stop" and sender then
|
||||||
libpredict:HealStop(sender)
|
libpredict:HealStop(sender)
|
||||||
return
|
return
|
||||||
elseif ( msg == "RessStop" or msg == "RESNO" ) and sender then
|
|
||||||
libpredict:RessStop(sender)
|
|
||||||
return
|
|
||||||
elseif msgtype == "Delay" and time then
|
elseif msgtype == "Delay" and time then
|
||||||
libpredict:HealDelay(sender, time)
|
libpredict:HealDelay(sender, time)
|
||||||
elseif msgtype == "Heal" and target and heal and time then
|
elseif msgtype == "Heal" and target and heal and time then
|
||||||
@@ -501,29 +456,6 @@ function libpredict:ParseChatMessage(sender, msg, comm)
|
|||||||
else
|
else
|
||||||
libpredict:Heal(sender, target, heal, time)
|
libpredict:Heal(sender, target, heal, time)
|
||||||
end
|
end
|
||||||
elseif msgtype == "Ress" then
|
|
||||||
-- HealComm: only for other players (own resses tracked via UNIT_SPELLCAST_START)
|
|
||||||
local playerName = UnitName("player")
|
|
||||||
if sender ~= playerName then
|
|
||||||
local senderGuid
|
|
||||||
for i = 1, GetNumRaidMembers() do
|
|
||||||
local unit = "raid" .. i
|
|
||||||
if UnitName(unit) == sender then
|
|
||||||
senderGuid = UnitGUID(unit)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if not senderGuid then
|
|
||||||
for i = 1, GetNumPartyMembers() do
|
|
||||||
local unit = "party" .. i
|
|
||||||
if UnitName(unit) == sender then
|
|
||||||
senderGuid = UnitGUID(unit)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
libpredict:Ress(sender, target, senderGuid)
|
|
||||||
end
|
|
||||||
elseif msgtype == "Hot" then
|
elseif msgtype == "Hot" then
|
||||||
-- Duplicate check: ignore same sender+target+spell within DUPLICATE_WINDOW
|
-- Duplicate check: ignore same sender+target+spell within DUPLICATE_WINDOW
|
||||||
local now = pfUI.uf.now or GetTime()
|
local now = pfUI.uf.now or GetTime()
|
||||||
@@ -672,41 +604,6 @@ function libpredict:HealDelay(sender, delay)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function libpredict:Ress(sender, target, senderGuid)
|
|
||||||
ress[target] = ress[target] or {}
|
|
||||||
ress[target][sender] = true
|
|
||||||
if senderGuid then ressGuidToName[senderGuid] = sender end
|
|
||||||
-- no timer here - timer is only set once the cast actually completes
|
|
||||||
end
|
|
||||||
|
|
||||||
function libpredict:RessSetTimer(sender, target)
|
|
||||||
ress_timers[target] = ress_timers[target] or {}
|
|
||||||
local existing = ress_timers[target][sender]
|
|
||||||
if not existing or GetTime() >= existing then
|
|
||||||
ress_timers[target][sender] = GetTime() + RESS_TIMEOUT
|
|
||||||
else
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function libpredict:RessStop(sender)
|
|
||||||
local now = GetTime()
|
|
||||||
for ttarget, t in pairs(ress) do
|
|
||||||
for tsender in pairs(ress[ttarget]) do
|
|
||||||
if sender == tsender then
|
|
||||||
local expiry = ress_timers[ttarget] and ress_timers[ttarget][tsender]
|
|
||||||
if not expiry or now >= expiry then
|
|
||||||
ress[ttarget][tsender] = nil
|
|
||||||
if ress_timers[ttarget] then ress_timers[ttarget][tsender] = nil end
|
|
||||||
else
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
for guid, name in pairs(ressGuidToName) do
|
|
||||||
if name == sender then ressGuidToName[guid] = nil end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function libpredict:UnitGetIncomingHeals(unit)
|
function libpredict:UnitGetIncomingHeals(unit)
|
||||||
if not unit then return 0 end
|
if not unit then return 0 end
|
||||||
local name = UnitName(unit)
|
local name = UnitName(unit)
|
||||||
@@ -729,21 +626,10 @@ function libpredict:UnitGetIncomingHeals(unit)
|
|||||||
return sumheal
|
return sumheal
|
||||||
end
|
end
|
||||||
|
|
||||||
function libpredict:UnitHasIncomingResurrection(unit)
|
-- Whether a resurrection is being cast at the unit, or landed and waits for
|
||||||
if not unit then return nil end
|
-- the unit to accept it
|
||||||
local name = UnitName(unit)
|
function libpredict:UnitHasResurrection(unit)
|
||||||
if not name then return nil end
|
return UnitHasIncomingResurrection(unit) or resOffers[UnitGUID(unit)] ~= nil
|
||||||
|
|
||||||
if not ress[name] then
|
|
||||||
return nil
|
|
||||||
else
|
|
||||||
for sender, val in pairs(ress[name]) do
|
|
||||||
if val == true then
|
|
||||||
return val
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local realm = GetRealmName()
|
local realm = GetRealmName()
|
||||||
@@ -834,7 +720,6 @@ local pendingHots = {}
|
|||||||
|
|
||||||
-- Gather Data by User Actions
|
-- Gather Data by User Actions
|
||||||
hooksecurefunc("CastSpell", function(id, bookType)
|
hooksecurefunc("CastSpell", function(id, bookType)
|
||||||
if not libpredict.sender.enabled then return end
|
|
||||||
local effect, rank = libspell.GetSpellInfo(id, bookType)
|
local effect, rank = libspell.GetSpellInfo(id, bookType)
|
||||||
if not effect then return end
|
if not effect then return end
|
||||||
spell_queue[1] = effect
|
spell_queue[1] = effect
|
||||||
@@ -887,7 +772,6 @@ hooksecurefunc("CastSpell", function(id, bookType)
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
hooksecurefunc("CastSpellByName", function(effect, target)
|
hooksecurefunc("CastSpellByName", function(effect, target)
|
||||||
if not libpredict.sender.enabled then return end
|
|
||||||
local effect, rank = libspell.GetSpellInfo(effect)
|
local effect, rank = libspell.GetSpellInfo(effect)
|
||||||
if not effect then return end
|
if not effect then return end
|
||||||
|
|
||||||
@@ -951,7 +835,6 @@ hooksecurefunc("CastSpellByName", function(effect, target)
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
hooksecurefunc("UseAction", function(slot, target, selfcast)
|
hooksecurefunc("UseAction", function(slot, target, selfcast)
|
||||||
if not libpredict.sender.enabled then return end
|
|
||||||
if not IsCurrentAction(slot) then return end
|
if not IsCurrentAction(slot) then return end
|
||||||
local kind, id = GetActionInfo(slot)
|
local kind, id = GetActionInfo(slot)
|
||||||
local effect, rank
|
local effect, rank
|
||||||
@@ -1012,8 +895,10 @@ hooksecurefunc("UseAction", function(slot, target, selfcast)
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
libpredict.sender = CreateFrame("Frame", "pfPredictionSender", UIParent)
|
libpredict.sender = CreateFrame("Frame", "pfPredictionSender", UIParent)
|
||||||
|
-- cleared when a HealComm addon already broadcasts this player's casts
|
||||||
libpredict.sender.enabled = true
|
libpredict.sender.enabled = true
|
||||||
libpredict.sender.SendHealCommMsg = function(self, msg)
|
libpredict.sender.SendHealCommMsg = function(self, msg)
|
||||||
|
if not self.enabled then return end
|
||||||
-- Smart channel selection: Only send to relevant channel to avoid duplicates
|
-- Smart channel selection: Only send to relevant channel to avoid duplicates
|
||||||
if IsInRaid() then
|
if IsInRaid() then
|
||||||
-- In raid: Only send to RAID (includes all raid members)
|
-- In raid: Only send to RAID (includes all raid members)
|
||||||
@@ -1026,6 +911,7 @@ libpredict.sender.SendHealCommMsg = function(self, msg)
|
|||||||
-- BG groups are handled by RAID channel
|
-- BG groups are handled by RAID channel
|
||||||
end
|
end
|
||||||
libpredict.sender.SendResCommMsg = function(self, msg)
|
libpredict.sender.SendResCommMsg = function(self, msg)
|
||||||
|
if not self.enabled then return end
|
||||||
-- Smart channel selection: Only send to relevant channel to avoid duplicates
|
-- Smart channel selection: Only send to relevant channel to avoid duplicates
|
||||||
if IsInRaid() then
|
if IsInRaid() then
|
||||||
-- In raid: Only send to RAID (includes all raid members)
|
-- In raid: Only send to RAID (includes all raid members)
|
||||||
@@ -1071,7 +957,6 @@ libpredict.sender:RegisterEvent("UNIT_SPELLCAST_DELAYED")
|
|||||||
libpredict.sender:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")
|
libpredict.sender:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")
|
||||||
libpredict.sender:RegisterEvent("UNIT_SPELLCAST_FAILED")
|
libpredict.sender:RegisterEvent("UNIT_SPELLCAST_FAILED")
|
||||||
libpredict.sender:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED")
|
libpredict.sender:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED")
|
||||||
libpredict.sender:RegisterEvent("UNIT_SPELLCAST_STOP")
|
|
||||||
libpredict.sender:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
libpredict.sender:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
|
||||||
|
|
||||||
-- Shared cleanup helper for failed/interrupted casts
|
-- Shared cleanup helper for failed/interrupted casts
|
||||||
@@ -1083,7 +968,6 @@ local function onCastFailed()
|
|||||||
s.healing = nil
|
s.healing = nil
|
||||||
elseif s.resurrecting then
|
elseif s.resurrecting then
|
||||||
local target = s.current_cast_target or spell_queue[3]
|
local target = s.current_cast_target or spell_queue[3]
|
||||||
libpredict:RessStop(UnitName("player"))
|
|
||||||
s:SendHealCommMsg("Resurrection/stop/")
|
s:SendHealCommMsg("Resurrection/stop/")
|
||||||
s:SendResCommMsg("RESNO " .. (target or ""))
|
s:SendResCommMsg("RESNO " .. (target or ""))
|
||||||
s.resurrecting = nil
|
s.resurrecting = nil
|
||||||
@@ -1134,11 +1018,20 @@ local function OnHeal()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- A landed resurrection: the target has an offer to accept, which outlasts
|
||||||
|
-- UnitHasIncomingResurrection's end with the cast
|
||||||
|
local function OnResurrect()
|
||||||
|
-- arg8=destGUID
|
||||||
|
resOffers[arg8] = GetTime() + RES_OFFER_TIMEOUT
|
||||||
|
RefreshResFrames(arg8)
|
||||||
|
end
|
||||||
|
|
||||||
local lastOtherCast = {} -- [event] = castGUID of the last other-unit event handled
|
local lastOtherCast = {} -- [event] = castGUID of the last other-unit event handled
|
||||||
|
|
||||||
libpredict.sender:SetScript("OnEvent", function()
|
libpredict.sender:SetScript("OnEvent", function()
|
||||||
if event == "COMBAT_LOG_EVENT_UNFILTERED" then
|
if event == "COMBAT_LOG_EVENT_UNFILTERED" then
|
||||||
if arg2 == "SPELL_HEAL" then OnHeal() end
|
if arg2 == "SPELL_HEAL" then OnHeal()
|
||||||
|
elseif arg2 == "SPELL_RESURRECT" then OnResurrect() end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1174,13 +1067,11 @@ libpredict.sender:SetScript("OnEvent", function()
|
|||||||
lastOtherCast[event] = arg2
|
lastOtherCast[event] = arg2
|
||||||
|
|
||||||
if event == "UNIT_SPELLCAST_START" then
|
if event == "UNIT_SPELLCAST_START" then
|
||||||
OnOtherCastStart(unit, arg3, arg2)
|
OnOtherCastStart(unit, arg3)
|
||||||
elseif event == "UNIT_SPELLCAST_SUCCEEDED" then
|
elseif event == "UNIT_SPELLCAST_SUCCEEDED" then
|
||||||
OnOtherCastSucceeded(unit, arg3, arg2)
|
OnOtherCastSucceeded(unit)
|
||||||
elseif event == "UNIT_SPELLCAST_INTERRUPTED" then
|
elseif event == "UNIT_SPELLCAST_INTERRUPTED" then
|
||||||
OnOtherCastInterrupted(unit)
|
OnOtherCastInterrupted(unit)
|
||||||
elseif event == "UNIT_SPELLCAST_STOP" then
|
|
||||||
castTargets[arg2] = nil
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|||||||
+1
-14
@@ -382,8 +382,6 @@ pfUI:RegisterModule("actionbar", function ()
|
|||||||
end
|
end
|
||||||
elseif self.spellID then
|
elseif self.spellID then
|
||||||
GameTooltip:SetSpellByID(self.spellID)
|
GameTooltip:SetSpellByID(self.spellID)
|
||||||
elseif self.spellslot and self.booktype then
|
|
||||||
GameTooltip:SetSpell(self.spellslot, self.booktype)
|
|
||||||
else
|
else
|
||||||
GameTooltip:SetAction(self.id)
|
GameTooltip:SetAction(self.id)
|
||||||
end
|
end
|
||||||
@@ -456,11 +454,6 @@ pfUI:RegisterModule("actionbar", function ()
|
|||||||
id = self.bar == 1 and self.slot or sid-((self.bar)-1)*12
|
id = self.bar == 1 and self.slot or sid-((self.bar)-1)*12
|
||||||
end
|
end
|
||||||
|
|
||||||
-- overwrite with spell macro texture where possible
|
|
||||||
if self.spellslot and self.booktype then
|
|
||||||
texture = GetSpellTexture(self.spellslot, self.booktype)
|
|
||||||
end
|
|
||||||
|
|
||||||
if not self.showempty and self.backdrop and not texture and grid == 0 then
|
if not self.showempty and self.backdrop and not texture and grid == 0 then
|
||||||
self.backdrop:Hide()
|
self.backdrop:Hide()
|
||||||
self.hide = true
|
self.hide = true
|
||||||
@@ -590,9 +583,6 @@ pfUI:RegisterModule("actionbar", function ()
|
|||||||
start, duration, enable = GetShapeshiftFormCooldown(button.id)
|
start, duration, enable = GetShapeshiftFormCooldown(button.id)
|
||||||
elseif button.bar == 12 then
|
elseif button.bar == 12 then
|
||||||
start, duration, enable = GetPetActionCooldown(button.id)
|
start, duration, enable = GetPetActionCooldown(button.id)
|
||||||
elseif button.spellslot and button.booktype then
|
|
||||||
start, duration = GetSpellCooldown(button.spellslot, button.booktype)
|
|
||||||
enable = 1
|
|
||||||
else
|
else
|
||||||
start, duration, enable = GetActionCooldown(button.id)
|
start, duration, enable = GetActionCooldown(button.id)
|
||||||
end
|
end
|
||||||
@@ -1150,8 +1140,6 @@ pfUI:RegisterModule("actionbar", function ()
|
|||||||
f.count:SetJustifyH("RIGHT")
|
f.count:SetJustifyH("RIGHT")
|
||||||
f.count:SetJustifyV("BOTTOM")
|
f.count:SetJustifyV("BOTTOM")
|
||||||
|
|
||||||
f.scanmacro, f.spellslot, f.booktype = nil, nil, nil
|
|
||||||
|
|
||||||
-- range glow color
|
-- range glow color
|
||||||
f.rangeColor = GetStringColorObject(C.bars.rangecolor)
|
f.rangeColor = GetStringColorObject(C.bars.rangecolor)
|
||||||
|
|
||||||
@@ -1218,8 +1206,7 @@ pfUI:RegisterModule("actionbar", function ()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- the stored layout is invalid, temporary fallback
|
-- the stored layout is invalid, temporary fallback
|
||||||
local _, _, fcols, frows = string.find(tostring(formfactor or ""), "(%d+)%s*x%s*(%d+)")
|
if not fcols2 or not frows2 then
|
||||||
if not ((fcols and frows) or pfGridmath[buttons][BarLayoutFormfactor(formfactor)]) then
|
|
||||||
formfactor = BarLayoutOptions(buttons)[1]
|
formfactor = BarLayoutOptions(buttons)[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
+117
-144
@@ -69,12 +69,42 @@ pfUI:RegisterModule("addons", function ()
|
|||||||
pfUI.addons:Hide()
|
pfUI.addons:Hide()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
-- installed addons, one entry per row of the addon list
|
||||||
|
local addons = {}
|
||||||
|
for i = 1, GetNumAddOns() do
|
||||||
|
local name, title, notes = GetAddOnInfo(i)
|
||||||
|
addons[i] = {
|
||||||
|
index = i,
|
||||||
|
name = name,
|
||||||
|
title = title,
|
||||||
|
notes = notes,
|
||||||
|
author = GetAddOnMetadata(name, "Author"),
|
||||||
|
version = GetAddOnMetadata(name, "Version"),
|
||||||
|
deps = { GetAddOnDependencies(i) }, -- required (.toc Dependencies)
|
||||||
|
optdeps = { C_AddOns.GetAddOnOptionalDependencies(i) }, -- optional (.toc OptionalDeps)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function IsAddonEnabled(index)
|
||||||
|
local _, _, _, enabled = GetAddOnInfo(index)
|
||||||
|
return enabled
|
||||||
|
end
|
||||||
|
|
||||||
|
local function SetAddonEnabled(index, enabled)
|
||||||
|
if enabled then
|
||||||
|
EnableAddOn(index)
|
||||||
|
else
|
||||||
|
DisableAddOn(index)
|
||||||
|
end
|
||||||
|
pfUI.addons.hasChanged = true
|
||||||
|
end
|
||||||
|
|
||||||
-- addons profile
|
-- addons profile
|
||||||
local function GetSelectedAddonsList()
|
local function GetSelectedAddonsList()
|
||||||
local selected_addons = {}
|
local selected_addons = {}
|
||||||
for i, frame in ipairs(pfUI.addons.list) do
|
for i, addon in ipairs(addons) do
|
||||||
if frame.input:GetChecked() then
|
if IsAddonEnabled(i) then
|
||||||
table.insert(selected_addons, frame.aname)
|
table.insert(selected_addons, addon.name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return selected_addons
|
return selected_addons
|
||||||
@@ -90,28 +120,20 @@ pfUI:RegisterModule("addons", function ()
|
|||||||
pfUI.addons.profile.dropdown:SetSelectionByText(profile)
|
pfUI.addons.profile.dropdown:SetSelectionByText(profile)
|
||||||
|
|
||||||
-- load profile
|
-- load profile
|
||||||
local selected_list = pfUI_addon_profiles[profile]
|
local selected = {}
|
||||||
for i=1, GetNumAddOns() do
|
for _, name in ipairs(pfUI_addon_profiles[profile]) do
|
||||||
local active = false
|
selected[name] = true
|
||||||
local f = pfUI.addons.list[i]
|
end
|
||||||
|
|
||||||
for i_i, n in ipairs(selected_list) do
|
for i, addon in ipairs(addons) do
|
||||||
if f.aname == n then
|
if selected[addon.name] and not IsAddonEnabled(i) then
|
||||||
active = true
|
SetAddonEnabled(i, true)
|
||||||
break
|
elseif not selected[addon.name] and IsAddonEnabled(i) then
|
||||||
end
|
SetAddonEnabled(i, false)
|
||||||
end
|
|
||||||
|
|
||||||
if active then
|
|
||||||
if not f.input:GetChecked() then
|
|
||||||
f.input:Click()
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if f.input:GetChecked() then
|
|
||||||
f.input:Click()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
pfUI.addons.scroll:ReinitializeFrames()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- addon profiles
|
-- addon profiles
|
||||||
@@ -193,23 +215,6 @@ pfUI:RegisterModule("addons", function ()
|
|||||||
return menu
|
return menu
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- addon list: scroll frame
|
|
||||||
pfUI.addons.scroll = CreateScrollFrame("pfAddonListScroll", pfUI.addons)
|
|
||||||
pfUI.addons.scroll:SetSize(360, 410)
|
|
||||||
pfUI.addons.scroll:SetPoint("BOTTOM", 0, 10)
|
|
||||||
|
|
||||||
pfUI.addons.scroll.backdrop = CreateFrame("Frame", nil, pfUI.addons.scroll)
|
|
||||||
pfUI.addons.scroll.backdrop:SetFrameLevel(1)
|
|
||||||
pfUI.addons.scroll.backdrop:SetPoint("TOPLEFT", pfUI.addons.scroll, "TOPLEFT", -5, 5)
|
|
||||||
pfUI.addons.scroll.backdrop:SetPoint("BOTTOMRIGHT", pfUI.addons.scroll, "BOTTOMRIGHT", 5, -5)
|
|
||||||
CreateBackdrop(pfUI.addons.scroll.backdrop, nil, true)
|
|
||||||
|
|
||||||
-- addon list: scroll parent
|
|
||||||
pfUI.addons.list = CreateScrollChild("pfAddonList", pfUI.addons.scroll)
|
|
||||||
pfUI.addons.list:RegisterEvent("ADDON_LOADED")
|
|
||||||
pfUI.addons.list:RegisterEvent("PLAYER_ENTERING_WORLD")
|
|
||||||
pfUI.addons.list:SetHeight(GetNumAddOns() * 25 + 26)
|
|
||||||
|
|
||||||
local function AddDependencyLines(header, deps)
|
local function AddDependencyLines(header, deps)
|
||||||
if not deps or table.getn(deps) == 0 then return end
|
if not deps or table.getn(deps) == 0 then return end
|
||||||
GameTooltip:AddLine(" ")
|
GameTooltip:AddLine(" ")
|
||||||
@@ -225,137 +230,105 @@ pfUI:RegisterModule("addons", function ()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function AddonOnEnter()
|
local function RowOnEnter(self)
|
||||||
this:SetBackdropBorderColor(1,1,1,.08)
|
local addon = self.addon
|
||||||
|
self:SetBackdropBorderColor(1,1,1,.08)
|
||||||
|
|
||||||
GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
|
GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
|
||||||
GameTooltip:SetText(this.atitle)
|
GameTooltip:SetText(addon.title)
|
||||||
if this.aversion then
|
if addon.version then
|
||||||
GameTooltip:AddDoubleLine(T["Version"], this.aversion, 1,1,1, .2,1,.8)
|
GameTooltip:AddDoubleLine(T["Version"], addon.version, 1,1,1, .2,1,.8)
|
||||||
end
|
end
|
||||||
|
|
||||||
if this.aauthor then
|
if addon.author then
|
||||||
GameTooltip:AddDoubleLine(T["Author"], this.aauthor, 1,1,1, .2,1,.8)
|
GameTooltip:AddDoubleLine(T["Author"], addon.author, 1,1,1, .2,1,.8)
|
||||||
end
|
end
|
||||||
|
|
||||||
GameTooltip:AddLine(this.anote, .75,.75,.75,1)
|
GameTooltip:AddLine(addon.notes, .75,.75,.75,1)
|
||||||
AddDependencyLines(T["Dependencies"], this.adeps)
|
AddDependencyLines(T["Dependencies"], addon.deps)
|
||||||
AddDependencyLines(T["Optional Dependencies"], this.aoptdeps)
|
AddDependencyLines(T["Optional Dependencies"], addon.optdeps)
|
||||||
GameTooltip:SetWidth(180)
|
GameTooltip:SetWidth(180)
|
||||||
GameTooltip:Show()
|
GameTooltip:Show()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function AddonOnLeave()
|
local function RowOnLeave(self)
|
||||||
this:SetBackdropBorderColor(1,1,1,.04)
|
self:SetBackdropBorderColor(1,1,1,.04)
|
||||||
GameTooltip:Hide()
|
GameTooltip:Hide()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function AddonOnClick()
|
local function RowOnClick(self)
|
||||||
this.input:Click()
|
self.input:Click()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function InputOnClick()
|
local function InputOnClick(self)
|
||||||
if this:GetChecked() then
|
SetAddonEnabled(self:GetParent().addon.index, self:GetChecked())
|
||||||
EnableAddOn(this:GetID())
|
|
||||||
else
|
|
||||||
DisableAddOn(this:GetID())
|
|
||||||
end
|
|
||||||
pfUI.addons.hasChanged = true
|
|
||||||
|
|
||||||
local id, name = pfUI.addons.profile.dropdown:GetSelection()
|
local _, name = pfUI.addons.profile.dropdown:GetSelection()
|
||||||
name = name or T["Current"]
|
name = name or T["Current"]
|
||||||
pfUI_addon_profiles[name] = GetSelectedAddonsList()
|
pfUI_addon_profiles[name] = GetSelectedAddonsList()
|
||||||
end
|
end
|
||||||
|
|
||||||
pfUI.addons.list:SetScript("OnEvent", function()
|
local function InitRow(row, addon)
|
||||||
for i=1, GetNumAddOns() do
|
-- one-time setup of a pooled row
|
||||||
local aname, atitle, anote = GetAddOnInfo(i)
|
if not row.input then
|
||||||
local aauthor = GetAddOnMetadata(aname, "Author")
|
row:SetBackdrop(pfUI.backdrop_hover)
|
||||||
local aversion = GetAddOnMetadata(aname, "Version")
|
row:SetBackdropBorderColor(1,1,1,.04)
|
||||||
|
|
||||||
-- basic frame
|
row:EnableMouse(true)
|
||||||
if not pfUI.addons.list[i] then
|
row:SetScript("OnEnter", RowOnEnter)
|
||||||
pfUI.addons.list[i] = CreateFrame("Button", nil, pfUI.addons.list)
|
row:SetScript("OnLeave", RowOnLeave)
|
||||||
local frame = pfUI.addons.list[i]
|
row:SetScript("OnClick", RowOnClick)
|
||||||
frame.aname = aname
|
|
||||||
frame.atitle = atitle
|
|
||||||
frame.anote = anote
|
|
||||||
frame.aauthor = aauthor
|
|
||||||
frame.aversion = aversion
|
|
||||||
frame.adeps = { GetAddOnDependencies(i) } -- required (.toc Dependencies)
|
|
||||||
frame.aoptdeps = { C_AddOns.GetAddOnOptionalDependencies(i) } -- optional (.toc OptionalDeps)
|
|
||||||
|
|
||||||
frame:SetSize(340, 25)
|
-- caption
|
||||||
frame:SetPoint("TOPLEFT", 5, i * -25 + 20)
|
row.caption = row:CreateFontString(nil, "LOW", "GameFontNormal")
|
||||||
|
row.caption:SetFont(pfUI.font_default, C.global.font_size + 2, "OUTLINE")
|
||||||
|
row.caption:SetPoint("LEFT", row, "LEFT", 2, 0)
|
||||||
|
row.caption:SetFontObject(GameFontWhite)
|
||||||
|
row.caption:SetJustifyH("LEFT")
|
||||||
|
|
||||||
frame:SetBackdrop(pfUI.backdrop_hover)
|
-- input field
|
||||||
frame:SetBackdropBorderColor(1,1,1,.04)
|
row.input = CreateFrame("CheckButton", nil, row, "UICheckButtonTemplate")
|
||||||
|
row.input:SetNormalTexture("")
|
||||||
frame:EnableMouse(1)
|
row.input:SetPushedTexture("")
|
||||||
frame:SetScript("OnEnter", AddonOnEnter)
|
row.input:SetHighlightTexture("")
|
||||||
frame:SetScript("OnLeave", AddonOnLeave)
|
CreateBackdrop(row.input, nil, true)
|
||||||
frame:SetScript("OnClick", AddonOnClick)
|
row.input:SetBackdropBorderColor(.3,.3,.3,1)
|
||||||
|
row.input:SetSize(14, 14)
|
||||||
-- caption
|
row.input:SetPoint("RIGHT" , -5, 1)
|
||||||
frame.caption = frame:CreateFontString("Status", "LOW", "GameFontNormal")
|
row.input:SetScript("OnClick", InputOnClick)
|
||||||
frame.caption:SetFont(pfUI.font_default, C.global.font_size + 2, "OUTLINE")
|
|
||||||
frame.caption:SetPoint("LEFT", frame, "LEFT", 2, 0)
|
|
||||||
frame.caption:SetFontObject(GameFontWhite)
|
|
||||||
frame.caption:SetJustifyH("LEFT")
|
|
||||||
frame.caption:SetText(atitle)
|
|
||||||
|
|
||||||
-- input field
|
|
||||||
frame.input = CreateFrame("CheckButton", nil, frame, "UICheckButtonTemplate")
|
|
||||||
frame.input:SetFrameLevel(3)
|
|
||||||
frame.input:SetNormalTexture("")
|
|
||||||
frame.input:SetPushedTexture("")
|
|
||||||
frame.input:SetHighlightTexture("")
|
|
||||||
CreateBackdrop(frame.input, nil, true)
|
|
||||||
frame.input:SetBackdropBorderColor(.3,.3,.3,1)
|
|
||||||
frame.input:SetWidth(14)
|
|
||||||
frame.input:SetHeight(14)
|
|
||||||
frame.input:SetPoint("RIGHT" , -5, 1)
|
|
||||||
frame.input:SetID(i)
|
|
||||||
frame.input:SetScript("OnClick", InputOnClick)
|
|
||||||
end
|
|
||||||
|
|
||||||
if IsAddOnLoaded(i) then
|
|
||||||
pfUI.addons.list[i].input:SetChecked()
|
|
||||||
pfUI.addons.list[i].caption:SetAlpha(1)
|
|
||||||
else
|
|
||||||
pfUI.addons.list[i].caption:SetAlpha(.5)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end)
|
|
||||||
|
|
||||||
-- show only frames in visible range
|
row.addon = addon
|
||||||
function pfUI.addons.scroll:ShowVisibleRange()
|
row.caption:SetText(addon.title)
|
||||||
local top_index, bottom_index, range
|
row.caption:SetAlpha(IsAddOnLoaded(addon.index) and 1 or .5)
|
||||||
range = floor(pfUI.addons.scroll:GetHeight() / 25) + 1
|
row.input:SetChecked(IsAddonEnabled(addon.index))
|
||||||
top_index = floor(pfUI.addons.scroll:GetVerticalScroll() / 25) > 0 and floor(pfUI.addons.scroll:GetVerticalScroll() / 25) or 1
|
|
||||||
bottom_index = top_index + range
|
|
||||||
for i=1, GetNumAddOns() do
|
|
||||||
if i >= top_index and i <= bottom_index then
|
|
||||||
pfUI.addons.list[i]:Show()
|
|
||||||
else
|
|
||||||
pfUI.addons.list[i]:Hide()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
pfUI.addons.scroll.slider:SetScript("OnValueChanged", function()
|
-- addon list: a ScrollBox keeps rows only for the addons in view
|
||||||
this:GetParent():SetVerticalScroll(this:GetValue())
|
pfUI.addons.scroll = CreateFrame("Frame", "pfAddonListScroll", pfUI.addons, "WowScrollBoxList")
|
||||||
end)
|
pfUI.addons.scroll:SetSize(360, 410)
|
||||||
pfUI.addons.scroll:SetScript("OnScrollRangeChanged", function()
|
pfUI.addons.scroll:SetPoint("BOTTOM", 0, 10)
|
||||||
this.slider:SetMinMaxValues(1, floor(this:GetVerticalScrollRange() + 25))
|
|
||||||
end)
|
-- the ScrollBox clips its children, so the backdrop is a sibling
|
||||||
pfUI.addons.scroll:SetScript("OnShow", function()
|
pfUI.addons.scroll.backdrop = CreateFrame("Frame", nil, pfUI.addons)
|
||||||
this.slider:SetValue(floor(this:GetVerticalScroll()))
|
pfUI.addons.scroll.backdrop:SetPoint("TOPLEFT", pfUI.addons.scroll, "TOPLEFT", -5, 5)
|
||||||
pfUI.addons.scroll:ShowVisibleRange()
|
pfUI.addons.scroll.backdrop:SetPoint("BOTTOMRIGHT", pfUI.addons.scroll, "BOTTOMRIGHT", 5, -5)
|
||||||
end)
|
CreateBackdrop(pfUI.addons.scroll.backdrop, nil, true)
|
||||||
pfUI.addons.scroll:SetScript("OnVerticalScroll", function()
|
|
||||||
pfUI.addons.scroll:ShowVisibleRange()
|
local scrollbar = CreateFrame("EventFrame", nil, pfUI.addons, "pfUIScrollBarTemplate")
|
||||||
this.slider:SetValue(floor(this:GetVerticalScroll()))
|
scrollbar:SetPoint("TOPRIGHT", pfUI.addons.scroll, "TOPRIGHT")
|
||||||
|
scrollbar:SetPoint("BOTTOMRIGHT", pfUI.addons.scroll, "BOTTOMRIGHT")
|
||||||
|
|
||||||
|
local view = CreateScrollBoxListLinearView(5, 5, 5, 15)
|
||||||
|
view:SetElementExtent(25)
|
||||||
|
view:SetElementInitializer("Button", InitRow)
|
||||||
|
ScrollUtil.InitScrollBoxListWithScrollBar(pfUI.addons.scroll, scrollbar, view)
|
||||||
|
pfUI.addons.scroll:SetDataProvider(CreateDataProvider(addons))
|
||||||
|
|
||||||
|
-- a load-on-demand addon that loads brightens its row
|
||||||
|
pfUI.addons.scroll:RegisterEvent("ADDON_LOADED")
|
||||||
|
pfUI.addons.scroll:SetScript("OnEvent", function(self)
|
||||||
|
self:ReinitializeFrames()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
end)
|
end)
|
||||||
|
|||||||
+10
-11
@@ -29,20 +29,20 @@ pfUI:RegisterModule("afkcam", function ()
|
|||||||
overlay:SetFrameStrata("DIALOG")
|
overlay:SetFrameStrata("DIALOG")
|
||||||
overlay:SetAllPoints(WorldFrame)
|
overlay:SetAllPoints(WorldFrame)
|
||||||
|
|
||||||
overlay:SetScript("OnMouseUp",function()
|
-- /afk toggles, so send it only while AFK is still set: once the client
|
||||||
SendChatMessage("","AFK")
|
-- or the server has cleared it, /afk would set it again
|
||||||
this._parent:stop()
|
local function Wake()
|
||||||
end)
|
if IsChatAFK() then SendChatMessage("", "AFK") end
|
||||||
|
afkcam:stop()
|
||||||
|
end
|
||||||
|
overlay:SetScript("OnMouseUp", Wake)
|
||||||
overlay:SetScript("OnShow", function()
|
overlay:SetScript("OnShow", function()
|
||||||
this:EnableKeyboard(true)
|
this:EnableKeyboard(true)
|
||||||
end)
|
end)
|
||||||
overlay:SetScript("OnHide", function()
|
overlay:SetScript("OnHide", function()
|
||||||
this:EnableKeyboard(false)
|
this:EnableKeyboard(false)
|
||||||
end)
|
end)
|
||||||
overlay:SetScript("OnKeyUp",function()
|
overlay:SetScript("OnKeyUp", Wake)
|
||||||
SendChatMessage("","AFK")
|
|
||||||
this._parent:stop()
|
|
||||||
end)
|
|
||||||
overlay:Hide()
|
overlay:Hide()
|
||||||
|
|
||||||
local chat = CreateFrame("ScrollingMessageFrame", "pfAFKCamChat", overlay)
|
local chat = CreateFrame("ScrollingMessageFrame", "pfAFKCamChat", overlay)
|
||||||
@@ -82,7 +82,6 @@ pfUI:RegisterModule("afkcam", function ()
|
|||||||
end)
|
end)
|
||||||
overlay.chat = chat
|
overlay.chat = chat
|
||||||
|
|
||||||
overlay._parent = afkcam
|
|
||||||
afkcam.overlay = overlay
|
afkcam.overlay = overlay
|
||||||
|
|
||||||
local clock = CreateFrame("Frame", "pfAFKClock", overlay)
|
local clock = CreateFrame("Frame", "pfAFKClock", overlay)
|
||||||
@@ -166,9 +165,9 @@ pfUI:RegisterModule("afkcam", function ()
|
|||||||
if event == "PLAYER_FLAGS_CHANGED" then
|
if event == "PLAYER_FLAGS_CHANGED" then
|
||||||
if UnitIsAFK('player') then
|
if UnitIsAFK('player') then
|
||||||
delay:Show()
|
delay:Show()
|
||||||
elseif delay:IsVisible() then
|
else
|
||||||
delay:Hide()
|
delay:Hide()
|
||||||
this:stop()
|
if this._spinning then this:stop() end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if this._spinning then
|
if this._spinning then
|
||||||
|
|||||||
+29
-55
@@ -6,8 +6,6 @@ pfUI:RegisterModule("bags", function ()
|
|||||||
[1804] = {frame="picklock"},
|
[1804] = {frame="picklock"},
|
||||||
}
|
}
|
||||||
|
|
||||||
local scanner = libtipscan:GetScanner("input_search")
|
|
||||||
|
|
||||||
local function BagSortOpts()
|
local function BagSortOpts()
|
||||||
return {
|
return {
|
||||||
reverse = C.appearance.bags.sortreverse == "1",
|
reverse = C.appearance.bags.sortreverse == "1",
|
||||||
@@ -95,6 +93,7 @@ pfUI:RegisterModule("bags", function ()
|
|||||||
pfUI.bag:RegisterEvent("ITEM_LOCK_CHANGED")
|
pfUI.bag:RegisterEvent("ITEM_LOCK_CHANGED")
|
||||||
pfUI.bag:RegisterEvent("SPELLS_CHANGED")
|
pfUI.bag:RegisterEvent("SPELLS_CHANGED")
|
||||||
pfUI.bag:RegisterEvent("MERCHANT_CLOSED")
|
pfUI.bag:RegisterEvent("MERCHANT_CLOSED")
|
||||||
|
pfUI.bag:RegisterEvent("INVENTORY_SEARCH_UPDATE")
|
||||||
|
|
||||||
pfUI.bag.delay = { UpdateBag = {} }
|
pfUI.bag.delay = { UpdateBag = {} }
|
||||||
|
|
||||||
@@ -122,6 +121,11 @@ pfUI:RegisterModule("bags", function ()
|
|||||||
pfUI.bag:UpdateItemLock()
|
pfUI.bag:UpdateItemLock()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if this.delay.UpdateSearch then
|
||||||
|
this.delay.UpdateSearch = nil
|
||||||
|
pfUI.bag:UpdateSearch()
|
||||||
|
end
|
||||||
|
|
||||||
for bag in pairs(this.delay.UpdateBag) do
|
for bag in pairs(this.delay.UpdateBag) do
|
||||||
this.delay.UpdateBag[bag] = nil
|
this.delay.UpdateBag[bag] = nil
|
||||||
pfUI.bag:UpdateBag(bag)
|
pfUI.bag:UpdateBag(bag)
|
||||||
@@ -159,6 +163,10 @@ pfUI:RegisterModule("bags", function ()
|
|||||||
this.delay.UpdateItemLock = true
|
this.delay.UpdateItemLock = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if event == "INVENTORY_SEARCH_UPDATE" then
|
||||||
|
this.delay.UpdateSearch = true
|
||||||
|
end
|
||||||
|
|
||||||
if event == "PLAYERBANKSLOTS_CHANGED" then
|
if event == "PLAYERBANKSLOTS_CHANGED" then
|
||||||
this.delay.UpdateBag[-1] = true
|
this.delay.UpdateBag[-1] = true
|
||||||
end
|
end
|
||||||
@@ -377,6 +385,21 @@ pfUI:RegisterModule("bags", function ()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- dim the slots that the bag search (C_Container.SetItemSearch) filters out
|
||||||
|
local searchInfo = {}
|
||||||
|
function pfUI.bag:UpdateSlotSearch(bag, slot)
|
||||||
|
local info = C_Container.GetContainerItemInfo(bag, slot, searchInfo)
|
||||||
|
pfUI.bags[bag].slots[slot].frame:SetAlpha(info and info.isFiltered and .25 or 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
function pfUI.bag:UpdateSearch()
|
||||||
|
for bag = -2, 11 do
|
||||||
|
for slot in ipairs(pfUI.bags[bag].slots) do
|
||||||
|
pfUI.bag:UpdateSlotSearch(bag, slot)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function pfUI.bag:UpdateSlot(bag, slot)
|
function pfUI.bag:UpdateSlot(bag, slot)
|
||||||
if not pfUI.bags[bag] then return end
|
if not pfUI.bags[bag] then return end
|
||||||
|
|
||||||
@@ -465,6 +488,7 @@ pfUI:RegisterModule("bags", function ()
|
|||||||
SetItemButtonTexture(pfUI.bags[bag].slots[slot].frame, texture)
|
SetItemButtonTexture(pfUI.bags[bag].slots[slot].frame, texture)
|
||||||
SetItemButtonCount(pfUI.bags[bag].slots[slot].frame, count)
|
SetItemButtonCount(pfUI.bags[bag].slots[slot].frame, count)
|
||||||
SetItemButtonDesaturated(pfUI.bags[bag].slots[slot].frame, locked, 0.5, 0.5, 0.5)
|
SetItemButtonDesaturated(pfUI.bags[bag].slots[slot].frame, locked, 0.5, 0.5, 0.5)
|
||||||
|
pfUI.bag:UpdateSlotSearch(bag, slot)
|
||||||
|
|
||||||
local hasItem = texture and 1 or nil
|
local hasItem = texture and 1 or nil
|
||||||
pfUI.bags[bag].slots[slot].frame.hasItem = hasItem
|
pfUI.bags[bag].slots[slot].frame.hasItem = hasItem
|
||||||
@@ -1010,7 +1034,6 @@ pfUI:RegisterModule("bags", function ()
|
|||||||
-- bag search
|
-- bag search
|
||||||
if not frame.search then
|
if not frame.search then
|
||||||
frame.search = CreateFrame("Frame", "pfBagSearch", frame)
|
frame.search = CreateFrame("Frame", "pfBagSearch", frame)
|
||||||
frame.search.db = {}
|
|
||||||
frame.search:SetHeight(12)
|
frame.search:SetHeight(12)
|
||||||
frame.search:SetPoint("TOPLEFT", frame, "TOPLEFT", default_border, -default_border)
|
frame.search:SetPoint("TOPLEFT", frame, "TOPLEFT", default_border, -default_border)
|
||||||
frame.search:SetPoint("TOPRIGHT", frame.sort, "TOPLEFT", -default_border*3, -default_border)
|
frame.search:SetPoint("TOPRIGHT", frame.sort, "TOPLEFT", -default_border*3, -default_border)
|
||||||
@@ -1035,51 +1058,12 @@ pfUI:RegisterModule("bags", function ()
|
|||||||
|
|
||||||
frame.search.edit:SetScript("OnEditFocusLost", function()
|
frame.search.edit:SetScript("OnEditFocusLost", function()
|
||||||
this:SetText(T["Search"])
|
this:SetText(T["Search"])
|
||||||
for bag=-2, 11 do
|
C_Container.SetItemSearch("")
|
||||||
local bagsize = GetContainerNumSlots(bag)
|
|
||||||
if bag == -2 and pfUI.bag.showKeyring == true then bagsize = GetKeyRingSize() end
|
|
||||||
for slot=1, bagsize do
|
|
||||||
pfUI.bags[bag].slots[slot].frame:SetAlpha(1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
frame.search.edit:SetScript("OnTextChanged", function()
|
frame.search.edit:SetScript("OnTextChanged", function()
|
||||||
if this:GetText() == T["Search"] then return end
|
if this:GetText() == T["Search"] then return end
|
||||||
for bag=-2, 11 do
|
C_Container.SetItemSearch(this:GetText())
|
||||||
local bagsize = GetContainerNumSlots(bag)
|
|
||||||
if bag == -2 and pfUI.bag.showKeyring == true then bagsize = GetKeyRingSize() end
|
|
||||||
for slot=1, bagsize do
|
|
||||||
pfUI.bags[bag].slots[slot].frame:SetAlpha(.25)
|
|
||||||
local texture, itemCount, locked, quality, readable = GetContainerItemInfo(bag, slot)
|
|
||||||
if itemCount then
|
|
||||||
local itemLink = GetContainerItemLink(bag, slot)
|
|
||||||
local itemstring = string.sub(itemLink, string.find(itemLink, "%[")+1, string.find(itemLink, "%]")-1)
|
|
||||||
|
|
||||||
if C.appearance.bags.fulltext == "1" then
|
|
||||||
if not frame.search.db[itemLink] then
|
|
||||||
scanner:SetBagItem(bag, slot)
|
|
||||||
local text = scanner:Text()
|
|
||||||
|
|
||||||
local str = ""
|
|
||||||
for k, v in pairs(text) do
|
|
||||||
str = str .. (v[1] or "") .. (v[2] or "")
|
|
||||||
end
|
|
||||||
|
|
||||||
frame.search.db[itemLink] = strlower(str)
|
|
||||||
end
|
|
||||||
|
|
||||||
if strfind(frame.search.db[itemLink], strlower(this:GetText()), 1, true) then
|
|
||||||
pfUI.bags[bag].slots[slot].frame:SetAlpha(1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if strfind(strlower(itemstring), strlower(this:GetText()), 1, true) then
|
|
||||||
pfUI.bags[bag].slots[slot].frame:SetAlpha(1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
frame.search:SetScript("OnLeave", function()
|
frame.search:SetScript("OnLeave", function()
|
||||||
@@ -1094,17 +1078,7 @@ pfUI:RegisterModule("bags", function ()
|
|||||||
|
|
||||||
frame.search:SetScript("OnHide", function()
|
frame.search:SetScript("OnHide", function()
|
||||||
frame.search.edit:SetText(T["Search"])
|
frame.search.edit:SetText(T["Search"])
|
||||||
for bag = -2, 11 do
|
C_Container.SetItemSearch("")
|
||||||
if pfUI.bags[bag] then
|
|
||||||
local bagsize = GetContainerNumSlots(bag)
|
|
||||||
if bag == -2 and pfUI.bag.showKeyring == true then bagsize = GetKeyRingSize() end
|
|
||||||
for slot = 1, bagsize do
|
|
||||||
if pfUI.bags[bag] and pfUI.bags[bag].slots[slot] then
|
|
||||||
pfUI.bags[bag].slots[slot].frame:SetAlpha(1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|||||||
+6
-11
@@ -150,8 +150,8 @@ pfUI:RegisterModule("castbar", function ()
|
|||||||
-- One-shot poll: read C_Spell for the bar's unit, stamp or clear. Called
|
-- One-shot poll: read C_Spell for the bar's unit, stamp or clear. Called
|
||||||
-- from event handlers (cast start, target/focus change), never per-frame.
|
-- from event handlers (cast start, target/focus change), never per-frame.
|
||||||
local function RefreshBar(cb, rank)
|
local function RefreshBar(cb, rank)
|
||||||
local query = cb.unitstr ~= "" and cb.unitstr or cb.unitname
|
local query = cb.unitstr
|
||||||
if not query or (cb.unitstr ~= "" and not UnitExists(cb.unitstr)) then
|
if not UnitExists(query) then
|
||||||
ClearBar(cb)
|
ClearBar(cb)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@@ -178,7 +178,7 @@ pfUI:RegisterModule("castbar", function ()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function CreateCastbar(name, parent, unitstr, unitname)
|
local function CreateCastbar(name, parent, unitstr)
|
||||||
local cb = CreateFrame("Frame", name, parent or UIParent)
|
local cb = CreateFrame("Frame", name, parent or UIParent)
|
||||||
|
|
||||||
cb:SetHeight(C.global.font_size * 1.5)
|
cb:SetHeight(C.global.font_size * 1.5)
|
||||||
@@ -186,7 +186,6 @@ pfUI:RegisterModule("castbar", function ()
|
|||||||
cb:SetFrameLevel(8)
|
cb:SetFrameLevel(8)
|
||||||
|
|
||||||
cb.unitstr = unitstr
|
cb.unitstr = unitstr
|
||||||
cb.unitname = unitname
|
|
||||||
|
|
||||||
-- icon
|
-- icon
|
||||||
cb.icon = CreateFrame("Frame", nil, cb)
|
cb.icon = CreateFrame("Frame", nil, cb)
|
||||||
@@ -277,7 +276,7 @@ pfUI:RegisterModule("castbar", function ()
|
|||||||
|
|
||||||
-- Non-player bars: if the unit disappears (target died / detarget),
|
-- Non-player bars: if the unit disappears (target died / detarget),
|
||||||
-- drop the bar immediately.
|
-- drop the bar immediately.
|
||||||
if this.unitstr ~= "" and this.unitstr ~= "player" and not UnitExists(this.unitstr) then
|
if this.unitstr ~= "player" and not UnitExists(this.unitstr) then
|
||||||
ClearBar(this)
|
ClearBar(this)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@@ -423,13 +422,12 @@ pfUI:RegisterModule("castbar", function ()
|
|||||||
-- endMs. delay is a positive magnitude; OnUpdate signs it "+" for casts
|
-- endMs. delay is a positive magnitude; OnUpdate signs it "+" for casts
|
||||||
-- and "-" for channels. Skipped during a tradeskill merge.
|
-- and "-" for channels. Skipped during a tradeskill merge.
|
||||||
if this.endTime and not this.tradeskillTotal then
|
if this.endTime and not this.tradeskillTotal then
|
||||||
local query = this.unitstr ~= "" and this.unitstr or this.unitname
|
|
||||||
local startMs, endMs
|
local startMs, endMs
|
||||||
if this.isChannel then
|
if this.isChannel then
|
||||||
local _, _, _, s, e = C_Spell.UnitChannelInfo(query)
|
local _, _, _, s, e = C_Spell.UnitChannelInfo(unit)
|
||||||
startMs, endMs = s, e
|
startMs, endMs = s, e
|
||||||
else
|
else
|
||||||
local _, _, _, s, e = C_Spell.UnitCastingInfo(query)
|
local _, _, _, s, e = C_Spell.UnitCastingInfo(unit)
|
||||||
startMs, endMs = s, e
|
startMs, endMs = s, e
|
||||||
end
|
end
|
||||||
if startMs and endMs then
|
if startMs and endMs then
|
||||||
@@ -544,9 +542,6 @@ pfUI:RegisterModule("castbar", function ()
|
|||||||
pfUI.castbar.focus:SetHeight(C.castbar.focus.height)
|
pfUI.castbar.focus:SetHeight(C.castbar.focus.height)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- bind castbar to the "focus" unit token; the GUID resolves at read time
|
|
||||||
pfUI.castbar.focus.unitstr = "focus"
|
|
||||||
|
|
||||||
UpdateMovable(pfUI.castbar.focus)
|
UpdateMovable(pfUI.castbar.focus)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
+5
-28
@@ -29,38 +29,15 @@ pfUI:RegisterModule("focus", function ()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
-- /focus and /clearfocus live in ClassicAPI's SlashCommandsRegistry now.
|
-- /focus and /clearfocus live in ClassicAPI's SlashCommandsRegistry now.
|
||||||
-- /focusname is pfUI-specific because the engine has no name→GUID
|
-- `/focus Name` takes the nearest prefix match; /focusname tries the exact
|
||||||
-- lookup for off-screen units — we resolve via a short target-swap.
|
-- name first, so "Bob" still wins over a nearer "Bobby".
|
||||||
|
|
||||||
pfUI.api.RegisterSlashCommand("PFFOCUSNAME", { '/focusname', '/pffocusname' }, function(msg)
|
pfUI.api.RegisterSlashCommand("PFFOCUSNAME", { '/focusname', '/pffocusname' }, function(msg)
|
||||||
if msg == "" then return end
|
if msg == "" then return end
|
||||||
|
|
||||||
local prevGUID = UnitGUID("target")
|
local unit = UnitTokenFromName(msg, true) or UnitTokenFromName(msg)
|
||||||
local prevPlayer = UnitIsUnit("target", "player")
|
if unit then
|
||||||
|
FocusUnit(unit)
|
||||||
-- Suppress async "Unknown unit" errors fired by TargetByName misses.
|
|
||||||
UIErrorsFrame:UnregisterEvent("UI_ERROR_MESSAGE")
|
|
||||||
|
|
||||||
-- Try exact match first, then prefix match via /target.
|
|
||||||
TargetByName(msg, true)
|
|
||||||
if not UnitExists("target") then
|
|
||||||
SlashCmdList.TARGET(msg)
|
|
||||||
end
|
|
||||||
|
|
||||||
if UnitExists("target") then
|
|
||||||
FocusUnit("target")
|
|
||||||
end
|
|
||||||
|
|
||||||
RunNextFrame(function()
|
|
||||||
UIErrorsFrame:RegisterEvent("UI_ERROR_MESSAGE")
|
|
||||||
end)
|
|
||||||
|
|
||||||
if prevGUID and prevGUID ~= "0x0000000000000000" then
|
|
||||||
TargetUnit(prevGUID)
|
|
||||||
elseif prevPlayer then
|
|
||||||
TargetUnit("player")
|
|
||||||
else
|
|
||||||
ClearTarget()
|
|
||||||
end
|
end
|
||||||
end, true)
|
end, true)
|
||||||
|
|
||||||
|
|||||||
@@ -2459,7 +2459,6 @@ pfUI:RegisterModule("gui", function ()
|
|||||||
CreateConfig(nil, T["Hide Chat When Bags Are Opened"], C.appearance.bags, "hidechat", "checkbox")
|
CreateConfig(nil, T["Hide Chat When Bags Are Opened"], C.appearance.bags, "hidechat", "checkbox")
|
||||||
CreateConfig(nil, T["Bagslots Per Row"], C.appearance.bags, "bagrowlength")
|
CreateConfig(nil, T["Bagslots Per Row"], C.appearance.bags, "bagrowlength")
|
||||||
CreateConfig(nil, T["Bankslots Per Row"], C.appearance.bags, "bankrowlength")
|
CreateConfig(nil, T["Bankslots Per Row"], C.appearance.bags, "bankrowlength")
|
||||||
CreateConfig(nil, T["Enable Full-Text Search"], C.appearance.bags, "fulltext")
|
|
||||||
CreateConfig(nil, T["Item Slot Size"], C.appearance.bags, "icon_size")
|
CreateConfig(nil, T["Item Slot Size"], C.appearance.bags, "icon_size")
|
||||||
CreateConfig(Reload, T["Reverse Cooldown Animation"], C.appearance.bags, "cooldown_reverse", "checkbox")
|
CreateConfig(Reload, T["Reverse Cooldown Animation"], C.appearance.bags, "cooldown_reverse", "checkbox")
|
||||||
CreateConfig(nil, T["Auto Sell Grey Items"], C.global, "autosell", "checkbox")
|
CreateConfig(nil, T["Auto Sell Grey Items"], C.global, "autosell", "checkbox")
|
||||||
|
|||||||
+53
-3
@@ -105,11 +105,12 @@ pfUI:RegisterModule("panel", function()
|
|||||||
|
|
||||||
do -- FPS & Lag
|
do -- FPS & Lag
|
||||||
local widget = CreateFrame("Frame", "pfPanelWidgetLag", UIParent)
|
local widget = CreateFrame("Frame", "pfPanelWidgetLag", UIParent)
|
||||||
local lag, fps, laghex, fpshex, _
|
local lag, fps, laghex, fpshex, owner, _
|
||||||
widget.Tooltip = function()
|
widget.Tooltip = function(self)
|
||||||
|
owner = self
|
||||||
local active = 0
|
local active = 0
|
||||||
GameTooltip:ClearLines()
|
GameTooltip:ClearLines()
|
||||||
GameTooltip_SetDefaultAnchor(GameTooltip, this)
|
GameTooltip_SetDefaultAnchor(GameTooltip, self)
|
||||||
GameTooltip:AddLine("|cff555555" .. T["Systeminfo"])
|
GameTooltip:AddLine("|cff555555" .. T["Systeminfo"])
|
||||||
for i=1, GetNumAddOns() do
|
for i=1, GetNumAddOns() do
|
||||||
if IsAddOnLoaded(i) then
|
if IsAddOnLoaded(i) then
|
||||||
@@ -128,6 +129,51 @@ pfUI:RegisterModule("panel", function()
|
|||||||
GameTooltip:AddLine(" ")
|
GameTooltip:AddLine(" ")
|
||||||
GameTooltip:AddDoubleLine(T["Memory Usage"], "|cffffffff" .. memmb)
|
GameTooltip:AddDoubleLine(T["Memory Usage"], "|cffffffff" .. memmb)
|
||||||
GameTooltip:AddDoubleLine(T["Next Memory Cleanup"], "|cffffffff" .. gcmb)
|
GameTooltip:AddDoubleLine(T["Next Memory Cleanup"], "|cffffffff" .. gcmb)
|
||||||
|
-- AddOn memory usage (see MainMenuBarPerformanceBarFrame_OnEnter in MainMenuBar.lua)
|
||||||
|
|
||||||
|
local ADDON_MEM_KB_ABBR = _G.ADDON_MEM_KB_ABBR or "(%.0f KB) %s";
|
||||||
|
local ADDON_MEM_MB_ABBR = _G.ADDON_MEM_MB_ABBR or "(%.2f MB) %s";
|
||||||
|
local TOTAL_MEM_KB_ABBR = _G.TOTAL_MEM_KB_ABBR or "AddOn Memory: %.0f KB";
|
||||||
|
local TOTAL_MEM_MB_ABBR = _G.TOTAL_MEM_MB_ABBR or "AddOn Memory: %.2f MB";
|
||||||
|
|
||||||
|
|
||||||
|
UpdateAddOnMemoryUsage()
|
||||||
|
local totalMem = 0
|
||||||
|
local topAddOns = {}
|
||||||
|
for i = 1, GetNumAddOns() do
|
||||||
|
local mem = GetAddOnMemoryUsage(i)
|
||||||
|
if mem and mem > 0 then
|
||||||
|
totalMem = totalMem + mem
|
||||||
|
for j = 1, 3 do
|
||||||
|
if not topAddOns[j] or mem > topAddOns[j].value then
|
||||||
|
for k = 3, j + 1, -1 do
|
||||||
|
topAddOns[k] = topAddOns[k - 1]
|
||||||
|
end
|
||||||
|
topAddOns[j] = { value = mem, name = C_AddOns.GetAddOnName(i) }
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if totalMem > 0 then
|
||||||
|
local str
|
||||||
|
if totalMem > 1000 then
|
||||||
|
str = format(TOTAL_MEM_MB_ABBR, totalMem / 1000)
|
||||||
|
else
|
||||||
|
str = format(TOTAL_MEM_KB_ABBR, totalMem)
|
||||||
|
end
|
||||||
|
GameTooltip:AddLine(" ")
|
||||||
|
GameTooltip:AddLine(str, 1, 1, 1)
|
||||||
|
for i = 1, 3 do
|
||||||
|
if not topAddOns[i] then break end
|
||||||
|
if topAddOns[i].value > 1000 then
|
||||||
|
str = format(ADDON_MEM_MB_ABBR, topAddOns[i].value / 1000, topAddOns[i].name)
|
||||||
|
else
|
||||||
|
str = format(ADDON_MEM_KB_ABBR, topAddOns[i].value, topAddOns[i].name)
|
||||||
|
end
|
||||||
|
GameTooltip:AddLine(str, 1, 1, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
GameTooltip:AddLine(" ")
|
GameTooltip:AddLine(" ")
|
||||||
GameTooltip:AddDoubleLine(T["Network Down"], "|cffffffff" .. round(nin,1) .. "KB/s")
|
GameTooltip:AddDoubleLine(T["Network Down"], "|cffffffff" .. round(nin,1) .. "KB/s")
|
||||||
GameTooltip:AddDoubleLine(T["Network Up"], "|cffffffff" .. round(nout,1) .. "KB/s")
|
GameTooltip:AddDoubleLine(T["Network Up"], "|cffffffff" .. round(nout,1) .. "KB/s")
|
||||||
@@ -157,6 +203,10 @@ pfUI:RegisterModule("panel", function()
|
|||||||
end
|
end
|
||||||
|
|
||||||
pfUI.panel:OutputPanel("fps", fps .. " " .. T["fps"] .. " & " .. lag .. " " .. T["ms"], widget.Tooltip, widget.Click)
|
pfUI.panel:OutputPanel("fps", fps .. " " .. T["fps"] .. " & " .. lag .. " " .. T["ms"], widget.Tooltip, widget.Click)
|
||||||
|
|
||||||
|
if owner and GameTooltip:IsOwned(owner) then
|
||||||
|
widget.Tooltip(owner)
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1172,21 +1172,9 @@ pfUI:RegisterModule("thirdparty-vanilla", function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
local EnableHealComm = function()
|
local EnableHealComm = function()
|
||||||
-- hook healcomm's addon message to parse single-player events
|
-- HealComm-1.0 already broadcasts this player's casts: keep libpredict
|
||||||
|
-- tracking them, but stop it sending a second copy
|
||||||
if AceLibrary and AceLibrary:HasInstance("HealComm-1.0") and pfUI.api.libpredict then
|
if AceLibrary and AceLibrary:HasInstance("HealComm-1.0") and pfUI.api.libpredict then
|
||||||
local HealComm = AceLibrary("HealComm-1.0")
|
|
||||||
|
|
||||||
-- use pfUI frames to draw healComm predictions
|
|
||||||
local pfHookHealCommSendAddonMessage = HealComm.SendAddonMessage
|
|
||||||
function HealComm.SendAddonMessage(this, msg)
|
|
||||||
if not IsInGroup() then
|
|
||||||
libpredict:ParseChatMessage(UnitName("player"), msg, "HealComm")
|
|
||||||
end
|
|
||||||
pfHookHealCommSendAddonMessage(this, msg)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- disable pfUI predictions
|
|
||||||
pfUI.api.libpredict.sender:UnregisterAllEvents()
|
|
||||||
pfUI.api.libpredict.sender.enabled = nil
|
pfUI.api.libpredict.sender.enabled = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -497,19 +497,4 @@ function pfUI.SetupCVars()
|
|||||||
UIParentLoadAddOn("Blizzard_CombatText")
|
UIParentLoadAddOn("Blizzard_CombatText")
|
||||||
end
|
end
|
||||||
|
|
||||||
if not RunMacroText then
|
|
||||||
local obj = setmetatable({ ["GetText"] = function(self) return self.text end }, {
|
|
||||||
__index = function(tab,key)
|
|
||||||
local value = function() return end
|
|
||||||
rawset(tab,key,value)
|
|
||||||
return value
|
|
||||||
end
|
|
||||||
})
|
|
||||||
|
|
||||||
function RunMacroText(text)
|
|
||||||
obj.text = text
|
|
||||||
ChatEdit_ParseText(obj, 1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
_G.PLAYER_BUFF_START_ID = -1
|
_G.PLAYER_BUFF_START_ID = -1
|
||||||
|
|||||||
@@ -279,6 +279,36 @@ pfUI:RegisterSkin("Character", function ()
|
|||||||
SkinCheckbox(ReputationDetailInactiveCheckBox)
|
SkinCheckbox(ReputationDetailInactiveCheckBox)
|
||||||
SkinCheckbox(ReputationDetailMainScreenCheckBox)
|
SkinCheckbox(ReputationDetailMainScreenCheckBox)
|
||||||
|
|
||||||
|
-- Expand or collapse every header at once, as the Skills tab's button
|
||||||
|
-- does. It shows "+" while any header is collapsed.
|
||||||
|
local collapseAll = CreateFrame("Button", "pfReputationCollapseAllButton", ReputationFrame, "ReputationHeaderTemplate")
|
||||||
|
collapseAll:SetText(ALL)
|
||||||
|
collapseAll:SetWidth(collapseAll:GetTextWidth() + 20)
|
||||||
|
-- on the "Faction" label's row, in the headers' +/- column
|
||||||
|
collapseAll:SetPoint("LEFT", ReputationFrameFactionLabel, "LEFT", -43, 0)
|
||||||
|
collapseAll:SetScript("OnClick", function()
|
||||||
|
if this.isCollapsed then
|
||||||
|
ExpandAllFactionHeaders()
|
||||||
|
else
|
||||||
|
CollapseAllFactionHeaders()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
SkinCollapseButton(collapseAll, true)
|
||||||
|
|
||||||
|
-- GetFactionInfo, not C_Reputation.GetFactionDataByIndex: the latter
|
||||||
|
-- returns nil for the Other and Inactive headers.
|
||||||
|
hooksecurefunc("ReputationFrame_Update", function()
|
||||||
|
collapseAll.isCollapsed = nil
|
||||||
|
for i = 1, GetNumFactions() do
|
||||||
|
local _, _, _, _, _, _, _, _, isHeader, isCollapsed = GetFactionInfo(i)
|
||||||
|
if isHeader and isCollapsed then
|
||||||
|
collapseAll.isCollapsed = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
collapseAll:SetNormalTexture(collapseAll.isCollapsed and "Interface\\Buttons\\UI-PlusButton-Up" or "Interface\\Buttons\\UI-MinusButton-Up")
|
||||||
|
end)
|
||||||
|
|
||||||
-- Append "(N)" to each standing label where N is rep remaining to the
|
-- Append "(N)" to each standing label where N is rep remaining to the
|
||||||
-- next reaction. Skip exalted (reaction 8) and effectively-capped bars.
|
-- next reaction. Skip exalted (reaction 8) and effectively-capped bars.
|
||||||
-- Each bar's OnLeave handler (Blizzard's ReputationFrame.xml) restores
|
-- Each bar's OnLeave handler (Blizzard's ReputationFrame.xml) restores
|
||||||
|
|||||||
Reference in New Issue
Block a user