mirror of
https://github.com/brues-code/pfUI.git
synced 2026-09-22 15:46:56 +00:00
d6951b386e
ClassicAPI's recent C_UnitAuras additions (sourceUnit / sourceGUID / non-player expirationTime / the PLAYER filter token) finally cover everything libdebuff:UnitDebuff and :UnitOwnDebuff were doing — caster attribution, accurate timing for non-player units, and the own-debuffs filter. Migrating the remaining callers off the libdebuff readers. - api/unitframes.lua: collapses the debuff render path's three-branch if/else into a single C_UnitAuras.GetAuraDataByIndex with a HARMFUL or HARMFUL|PLAYER filter selected by the selfdebuff config; tooltip slot-finders match by sourceGUID instead of libdebuff's caster flag; custom-debuff indicator scan unifies the same way. - modules/buffwatch.lua: GetBuffData drops the libdebuff fallback; tooltip slot-finder mirrors the unitframes pattern. - libs/libpredict.lua: drops the orphaned UnitHasBuff slot-loop (no callers left). - api/api.lua: pfUI.api.UnitHasBuff tightens from a HELPFUL iteration to a single GetAuraDataBySpellName lookup. Each site that builds a cooldown ring from expirationTime carries the talent-extension guard — when expirationTime exceeds the dbc base duration (e.g. Shadow Affinity → SW:P), clamp start to now and use the remaining time as the effective duration so CooldownFrame_SetTimer doesn't get a future start it treats as "not yet begun".
503 lines
18 KiB
Lua
503 lines
18 KiB
Lua
pfUI:RegisterModule("buffwatch", function ()
|
|
local rawborder, border = GetBorderSize("panels")
|
|
|
|
local fcache = {}
|
|
local function BuffIsVisible(config, name)
|
|
-- return if all buffs should be shown
|
|
if config.filter == "none" then return true end
|
|
|
|
local index = tostring(config)
|
|
local mode = config.filter
|
|
|
|
if not fcache[index] then
|
|
fcache[index] = {}
|
|
for _, val in pairs({strsplit("#", config[mode])}) do
|
|
fcache[index][val] = true
|
|
end
|
|
end
|
|
|
|
if mode == "whitelist" then
|
|
return fcache[index][name]
|
|
elseif mode == "blacklist" then
|
|
return not fcache[index][name]
|
|
end
|
|
end
|
|
|
|
local rgbcache = setmetatable({},{__mode="kv"})
|
|
local function str2rgb(text)
|
|
if not text then return 1, 1, 1 end
|
|
if rgbcache[text] then return unpack(rgbcache[text]) end
|
|
local counter = 1
|
|
local l = string.len(text)
|
|
for i = 1, l, 3 do
|
|
counter = mod(counter*8161, 4294967279) + (string.byte(text,i)*16776193) + ((string.byte(text,i+1) or (l-i+256))*8372226) + ((string.byte(text,i+2) or (l-i+256))*3932164)
|
|
end
|
|
counter = mod(8161, 4294967279) + (string.byte(text,l)*16776193) + ((string.byte(text,l+1) or (l-l+256))*8372226) + ((string.byte(text,l+2) or (l+256))*3932164)
|
|
|
|
local hash = mod(mod(counter, 4294967291),16777216)
|
|
local r = (hash - (mod(hash,65536))) / 65536
|
|
local g = ((hash - r*65536) - ( mod((hash - r*65536),256)) ) / 256
|
|
local b = hash - r*65536 - g*256
|
|
rgbcache[text] = { r / 255, g / 255, b / 255 }
|
|
return unpack(rgbcache[text])
|
|
end
|
|
|
|
|
|
local function GetSafeTop(frame)
|
|
if frame and frame.IsShown and frame:IsShown() and frame:IsVisible() then
|
|
return frame:GetTop(), frame
|
|
end
|
|
|
|
return 0
|
|
end
|
|
|
|
-- iterate over given tables and return the first frame that is shown
|
|
local function GetTopAnchor(anchors)
|
|
local top, anchor = 0, anchors[1]
|
|
|
|
for _, tbl in pairs(anchors) do
|
|
|
|
-- in case of multiple anchor elements, iterate over each one
|
|
for i=32, 1, -1 do
|
|
if GetSafeTop(tbl[i]) > top then
|
|
top, anchor = GetSafeTop(tbl[i])
|
|
end
|
|
end
|
|
|
|
-- check top of regular anchor elements
|
|
if GetSafeTop(tbl) > top then
|
|
top, anchor = GetSafeTop(tbl)
|
|
end
|
|
end
|
|
|
|
return anchor
|
|
end
|
|
|
|
local function GetBuffData(unit, id, type, selfdebuff)
|
|
local filter = (selfdebuff and type == "HARMFUL") and "HARMFUL|PLAYER" or type
|
|
local aura = C_UnitAuras.GetAuraDataByIndex(unit, id, filter)
|
|
if not aura then return end
|
|
local remaining = aura.expirationTime > 0 and (aura.expirationTime - GetTime()) or 0
|
|
return remaining, aura.icon, aura.name, aura.applications
|
|
end
|
|
|
|
local function StatusBarOnClick()
|
|
if arg1 == "LeftButton" then
|
|
local config = this.parent.config
|
|
local skill = this.text:GetText()
|
|
if IsControlKeyDown() then
|
|
for _, val in pairs({strsplit("#", config.whitelist)}) do
|
|
if val == skill then return end
|
|
end
|
|
config.whitelist = config.whitelist .. "#" .. skill
|
|
DEFAULT_CHAT_FRAME:AddMessage("|cff33ffcc" .. skill .. "|r" .. T["is now whitelisted."])
|
|
elseif IsShiftKeyDown() then
|
|
for _, val in pairs({strsplit("#", config.blacklist)}) do
|
|
if val == skill then return end
|
|
end
|
|
config.blacklist = config.blacklist .. "#" .. skill
|
|
DEFAULT_CHAT_FRAME:AddMessage("|cff33ffcc" .. skill .. "|r" .. T["is now blacklisted."])
|
|
end
|
|
elseif this.parent.unit == "player" then
|
|
local bid = GetPlayerBuff(PLAYER_BUFF_START_ID + this.id, this.type)
|
|
if bid >= 0 then CancelPlayerBuff(bid) end
|
|
end
|
|
end
|
|
|
|
local function StatusBarOnEnter()
|
|
GameTooltip:SetOwner(this, "NONE")
|
|
|
|
if this.unit == "player" then
|
|
GameTooltip:SetUnitAura("player", this.id, this.type)
|
|
elseif this.type == "HARMFUL" then
|
|
-- selfdebuff filters the displayed list to player-cast harmful auras, but
|
|
-- SetUnitAura's index has to be into the engine's full HARMFUL list. Look
|
|
-- up the displayed aura via the PLAYER filter, then scan engine slots for
|
|
-- one whose name + sourceGUID match.
|
|
local config = this.parent and this.parent.config
|
|
if config and config.selfdebuff == "1" then
|
|
local ownAura = C_UnitAuras.GetAuraDataByIndex(this.unit, this.id, "HARMFUL|PLAYER")
|
|
if ownAura then
|
|
for gameSlot = 1, 16 do
|
|
local check = C_UnitAuras.GetDebuffDataByIndex(this.unit, gameSlot)
|
|
if check and check.name == ownAura.name and check.sourceGUID == ownAura.sourceGUID then
|
|
GameTooltip:SetUnitAura(this.unit, gameSlot, "HARMFUL")
|
|
break
|
|
end
|
|
end
|
|
end
|
|
else
|
|
GameTooltip:SetUnitAura(this.unit, this.id, "HARMFUL")
|
|
end
|
|
elseif this.type == "HELPFUL" then
|
|
GameTooltip:SetUnitAura(this.unit, this.id, "HELPFUL")
|
|
end
|
|
|
|
if IsShiftKeyDown() then
|
|
GameTooltip:AddLine(" ")
|
|
GameTooltip:AddDoubleLine(T["Ctrl-Click"], T["Add to Whitelist"], 1,1,1, .2,1,.8)
|
|
GameTooltip:AddDoubleLine(T["Shift-Click"], T["Add to Blacklist"], 1,1,1, .2,1,.8)
|
|
end
|
|
|
|
GameTooltip:Show()
|
|
end
|
|
|
|
local function StatusBarOnLeave()
|
|
GameTooltip:Hide()
|
|
end
|
|
|
|
local function StatusBarOnUpdate()
|
|
local remaining = this.endtime - GetTime()
|
|
this.bar:SetValue(remaining > 0 and remaining or 0)
|
|
|
|
if ( this.tick or 1) > GetTime() then return else this.tick = GetTime() + .1 end
|
|
this.time:SetText(remaining > 0 and GetColoredTimeString(remaining) or "")
|
|
end
|
|
|
|
local function StatusBarRefreshParent()
|
|
this.parent:RefreshPosition()
|
|
end
|
|
|
|
local function CreateStatusBar(bar, parent)
|
|
local color = parent.color
|
|
local bordercolor = parent.bordercolor
|
|
local textcolor = parent.textcolor
|
|
local width = parent:GetWidth()
|
|
local height = parent:GetHeight()
|
|
local framename = "pf" .. parent.unit .. ( parent.type == "HARMFUL" and "Debuff" or "Buff" ) .. "Bar" .. bar
|
|
|
|
local font = parent.config.use_unitfonts == "1" and pfUI.font_unit or pfUI.font_default
|
|
|
|
local frame = _G[framename] or CreateFrame("Button", framename, parent)
|
|
frame:EnableMouse(1)
|
|
frame:Hide()
|
|
frame:SetPoint("BOTTOM", 0, (bar-1)*(height+2*border+1))
|
|
frame:SetWidth(width)
|
|
frame:SetHeight(height)
|
|
|
|
frame.bar = CreateFrame("StatusBar", "pfBuffBar" .. bar, frame)
|
|
frame.bar:SetPoint("TOPLEFT", frame, "TOPLEFT", height+1, 0)
|
|
frame.bar:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", 0, 0)
|
|
frame.bar:SetStatusBarTexture(pfUI.media["img:bar"])
|
|
frame.bar:SetStatusBarColor(color.r, color.g, color.b, color.a)
|
|
|
|
frame.text = frame.bar:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
|
frame.text:ClearAllPoints()
|
|
frame.text:SetPoint("TOPLEFT", frame.bar, "TOPLEFT", 3, 0)
|
|
frame.text:SetPoint("BOTTOMRIGHT", frame.bar, "BOTTOMRIGHT", -3, 0)
|
|
frame.text:SetNonSpaceWrap(false)
|
|
frame.text:SetFontObject(GameFontWhite)
|
|
frame.text:SetFont(font, C.global.font_size)
|
|
frame.text:SetTextColor(textcolor.r,textcolor.g,textcolor.b,1)
|
|
frame.text:SetJustifyH("LEFT")
|
|
|
|
frame.time = frame.bar:CreateFontString("Status", "DIALOG", "GameFontNormal")
|
|
frame.time:ClearAllPoints()
|
|
frame.time:SetPoint("TOPLEFT", frame.bar, "TOPLEFT", 3, 0)
|
|
frame.time:SetPoint("BOTTOMRIGHT", frame.bar, "BOTTOMRIGHT", -3, 0)
|
|
frame.time:SetNonSpaceWrap(false)
|
|
frame.time:SetFontObject(GameFontWhite)
|
|
frame.time:SetFont(font, C.global.font_size)
|
|
frame.time:SetTextColor(1,1,1,1)
|
|
frame.time:SetJustifyH("RIGHT")
|
|
|
|
frame.icon = frame:CreateTexture(nil, "OVERLAY")
|
|
frame.icon:SetWidth(height)
|
|
frame.icon:SetHeight(height)
|
|
frame.icon:SetPoint("LEFT", frame, "LEFT", 0, 0)
|
|
frame.icon:SetTexCoord(.07,.93,.07,.93)
|
|
|
|
frame.stacks = frame.bar:CreateFontString("Status", "DIALOG", "GameFontWhite")
|
|
frame.stacks:SetFont(font, C.global.font_size, "OUTLINE")
|
|
frame.stacks:SetAllPoints(frame.icon)
|
|
frame.stacks:SetJustifyH("CENTER")
|
|
frame.stacks:SetJustifyV("CENTER")
|
|
|
|
frame.parent = parent
|
|
frame:SetScript("OnUpdate", StatusBarOnUpdate)
|
|
frame:SetScript("OnShow", StatusBarRefreshParent)
|
|
frame:SetScript("OnHide", StatusBarRefreshParent)
|
|
|
|
frame:RegisterForClicks("LeftButtonUp", "RightButtonUp")
|
|
frame:SetScript("OnClick", StatusBarOnClick)
|
|
frame:SetScript("OnEnter", StatusBarOnEnter)
|
|
frame:SetScript("OnLeave", StatusBarOnLeave)
|
|
|
|
CreateBackdrop(frame)
|
|
CreateBackdropShadow(frame)
|
|
if bordercolor.r ~= "0" and bordercolor.g ~= "0" and bordercolor.b ~= "0" and bordercolor.a ~= "0" then
|
|
frame.backdrop:SetBackdropBorderColor(bordercolor.r,bordercolor.g,bordercolor.b,1)
|
|
end
|
|
|
|
return frame
|
|
end
|
|
|
|
local function RefreshBuffBarFrame(frame)
|
|
-- reinitialize all active buffs
|
|
local selfdebuff = frame.config.selfdebuff == "1"
|
|
|
|
for i=1,32 do
|
|
local timeleft, texture, name, stacks = GetBuffData(frame.unit, i, frame.type, selfdebuff)
|
|
timeleft = timeleft or 0
|
|
|
|
if texture and name and name ~= "" and BuffIsVisible(frame.config, name) then
|
|
frame.buffs[i][1] = timeleft
|
|
frame.buffs[i][2] = i
|
|
frame.buffs[i][3] = name
|
|
frame.buffs[i][4] = texture
|
|
frame.buffs[i][5] = stacks
|
|
else
|
|
frame.buffs[i][1] = 0
|
|
frame.buffs[i][2] = nil
|
|
frame.buffs[i][3] = nil
|
|
frame.buffs[i][4] = nil
|
|
frame.buffs[i][5] = 0
|
|
end
|
|
end
|
|
|
|
table.sort(frame.buffs, frame.buffcmp)
|
|
|
|
-- create a buff bar for each below threshold
|
|
local bar = 1
|
|
for id, data in pairs(frame.buffs) do
|
|
if data[1] and ((data[1] ~= 0 and data[1] < frame.threshold) or frame.threshold == -1) -- timeleft checks
|
|
and data[3] and data[3] ~= "" -- buff has a name
|
|
and data[4] and data[4] ~= "" -- buff has a texture
|
|
then
|
|
-- No slot in uuid: slots shift when debuffs expire causing timer resets
|
|
local uuid = data[4] .. data[3] -- texture + name only
|
|
|
|
-- update bar data
|
|
frame.bars[bar] = frame.bars[bar] or CreateStatusBar(bar, frame)
|
|
frame.bars[bar].id = data[2]
|
|
frame.bars[bar].unit = frame.unit
|
|
frame.bars[bar].type = frame.type
|
|
frame.bars[bar].endtime = GetTime() + ( data[1] > 0 and data[1] or -1 )
|
|
|
|
-- update max duration the cached remaining values is less than
|
|
-- the real one, indicates a buff renewal
|
|
frame.durations[uuid] = frame.durations[uuid] or {}
|
|
if not frame.durations[uuid][1] or frame.durations[uuid][1] < data[1] then
|
|
frame.durations[uuid][2] = data[1] -- max
|
|
end
|
|
frame.durations[uuid][1] = data[1] -- current
|
|
|
|
-- cache max stacks for the buff
|
|
if not frame.charges[uuid] or frame.charges[uuid] < data[5] then
|
|
frame.charges[uuid] = data[5]
|
|
end
|
|
|
|
-- set name
|
|
if frame.bars[bar].cacheName ~= data[3] then
|
|
frame.bars[bar].cacheName = data[3]
|
|
frame.bars[bar].text:SetText(data[3])
|
|
|
|
-- calculate dynamic auto color
|
|
local r, g, b
|
|
if frame.type == "HARMFUL" then
|
|
r, g, b = 1, .2, .2
|
|
local a = C_UnitAuras.GetDebuffDataByIndex(frame.unit, data[2])
|
|
local dtype = a and a.dispelName
|
|
if dtype and DebuffTypeColor[dtype] then
|
|
r,g,b = DebuffTypeColor[dtype].r,DebuffTypeColor[dtype].g,DebuffTypeColor[dtype].b
|
|
end
|
|
else
|
|
r,g,b = str2rgb(data[3])
|
|
end
|
|
|
|
-- set auto background color
|
|
if frame.config.dtypebg == "1" then
|
|
frame.bars[bar].bar:SetStatusBarColor(r,g,b,1)
|
|
end
|
|
|
|
-- set auto border color
|
|
if frame.config.dtypeborder == "1" then
|
|
frame.bars[bar].backdrop:SetBackdropBorderColor(r,g,b,1)
|
|
end
|
|
|
|
-- set auto text color
|
|
if frame.config.dtypetext == "1" then
|
|
frame.bars[bar].text:SetTextColor(r,g,b,1)
|
|
end
|
|
end
|
|
|
|
-- set texture
|
|
if frame.bars[bar].cacheTexture ~= data[4] then
|
|
frame.bars[bar].cacheTexture = data[4]
|
|
frame.bars[bar].icon:SetTexture(data[4])
|
|
end
|
|
|
|
-- cache maxduration
|
|
if frame.bars[bar].cacheMaxDuration ~= frame.durations[uuid][2] then
|
|
frame.bars[bar].cacheMaxDuration = frame.durations[uuid][2]
|
|
frame.bars[bar].bar:SetMinMaxValues(0, frame.durations[uuid][2])
|
|
end
|
|
|
|
-- set stacks
|
|
if data[5] > 1 then
|
|
local stacks_percentage = data[5] / (frame.charges[uuid] * .01)
|
|
local sr, sg, sb, sa
|
|
if stacks_percentage >= 90 then
|
|
sr, sg, sb, sa = .3, 1, .3, 1
|
|
elseif stacks_percentage >= 60 then
|
|
sr, sg, sb, sa = 1, 1, .3, 1
|
|
elseif stacks_percentage >= 0 then
|
|
sr, sg, sb, sa = 1, .3, .3, 1
|
|
end
|
|
if frame.config.colorstacks == "1" then
|
|
frame.bars[bar].stacks:SetText(rgbhex(sr,sg,sb) .. data[5])
|
|
else
|
|
frame.bars[bar].stacks:SetText(data[5])
|
|
end
|
|
else
|
|
frame.bars[bar].stacks:SetText("")
|
|
end
|
|
|
|
frame.bars[bar]:Show()
|
|
bar = bar + 1
|
|
end
|
|
end
|
|
|
|
-- hide remaining bars
|
|
for i = bar, table.getn(frame.bars) do
|
|
frame.bars[i]:Hide()
|
|
end
|
|
end
|
|
|
|
-- Create a new Buff Bar
|
|
local function BuffBarFrameOnUpdate()
|
|
if ( this.tick or 1) > GetTime() then return else this.tick = GetTime() + .4 end
|
|
RefreshBuffBarFrame(this)
|
|
this:RefreshPosition()
|
|
end
|
|
|
|
local function RefreshPosition(self)
|
|
-- avoid position changes during unlock
|
|
if pfUI.unlock and pfUI.unlock:IsShown() then return end
|
|
|
|
if not pfUI_config["position"][self:GetName()] then
|
|
local anchor = GetTopAnchor(self.anchors)
|
|
|
|
if not self.lastanchor or self.lastanchor ~= anchor then
|
|
self:ClearAllPoints()
|
|
self:SetPoint("LEFT", self.anchors[1], "LEFT", 0, 0)
|
|
self:SetPoint("BOTTOM", anchor, "TOP", 0, border*2+1)
|
|
UpdateMovable(self, true)
|
|
self.lastanchor = anchor
|
|
end
|
|
end
|
|
end
|
|
|
|
local function CreateBuffBarFrame(unit, type)
|
|
local framename = "pf" .. unit .. ( type == "HARMFUL" and "Debuff" or "Buff" ) .. "Bar"
|
|
local frame = _G[framename] or CreateFrame("Frame", framename, UIParent)
|
|
|
|
frame.unit = strlower(unit)
|
|
frame.type = type
|
|
frame.bars = { }
|
|
frame.durations = { }
|
|
frame.charges = { }
|
|
frame.buffs = { }
|
|
for i=1,32 do
|
|
frame.buffs[i] = { }
|
|
end
|
|
|
|
frame.RefreshPosition = RefreshPosition
|
|
|
|
-- OnEvent (UNIT_AURA) doesn't trigger properly on buff refresh
|
|
frame:SetScript("OnUpdate", BuffBarFrameOnUpdate)
|
|
|
|
return frame
|
|
end
|
|
|
|
local function asc(a,b)
|
|
return a[1] > b[1]
|
|
end
|
|
|
|
local function desc(a,b)
|
|
return a[1] < b[1]
|
|
end
|
|
|
|
-- create player buffbars
|
|
if pfUI.uf.player and C.buffbar.pbuff.enable == "1" then
|
|
pfUI.uf.player.buffbar = CreateBuffBarFrame("Player", "HELPFUL")
|
|
local config = C.buffbar.pbuff
|
|
local r, g, b, a = strsplit(",", config.color)
|
|
local br, bg, bb, ba = strsplit(",", config.bordercolor)
|
|
local tr, tg, tb, ta = strsplit(",", config.textcolor)
|
|
|
|
pfUI.uf.player.buffbar:SetWidth(config.width == "-1" and pfUI.uf.player:GetWidth() or config.width)
|
|
pfUI.uf.player.buffbar:SetHeight(config.height)
|
|
pfUI.uf.player.buffbar.threshold = tonumber(config.threshold)
|
|
pfUI.uf.player.buffbar.config = config
|
|
pfUI.uf.player.buffbar.buffcmp = config.sort == "asc" and asc or desc
|
|
pfUI.uf.player.buffbar.color = { r = r, g = g, b = b, a = a }
|
|
pfUI.uf.player.buffbar.bordercolor = { r = br, g = bg, b = bb, a = ba }
|
|
pfUI.uf.player.buffbar.textcolor = { r = tr, g = tg, b = tb, a = ta }
|
|
pfUI.uf.player.buffbar.anchors = {
|
|
pfUI.uf.player,
|
|
pfUI.uf.player and pfUI.uf.player.debuffs,
|
|
pfUI.uf.player and pfUI.uf.player.buffs
|
|
}
|
|
|
|
pfUI.uf.player.buffbar:SetPoint("LEFT", pfUI.uf.player, "LEFT", 0, 0)
|
|
pfUI.uf.player.buffbar:SetPoint("BOTTOM", pfUI.uf.player, "TOP", 0, border*2+1)
|
|
UpdateMovable(pfUI.uf.player.buffbar)
|
|
end
|
|
|
|
-- create player debuffbars
|
|
if pfUI.uf.player and C.buffbar.pdebuff.enable == "1" then
|
|
local config = C.buffbar.pdebuff
|
|
local r, g, b, a = strsplit(",", config.color)
|
|
local br, bg, bb, ba = strsplit(",", config.bordercolor)
|
|
local tr, tg, tb, ta = strsplit(",", config.textcolor)
|
|
|
|
pfUI.uf.player.debuffbar = CreateBuffBarFrame("Player", "HARMFUL")
|
|
pfUI.uf.player.debuffbar:SetWidth(config.width == "-1" and pfUI.uf.player:GetWidth() or config.width)
|
|
pfUI.uf.player.debuffbar:SetHeight(config.height)
|
|
pfUI.uf.player.debuffbar.threshold = tonumber(config.threshold)
|
|
pfUI.uf.player.debuffbar.config = config
|
|
pfUI.uf.player.debuffbar.buffcmp = config.sort == "asc" and asc or desc
|
|
pfUI.uf.player.debuffbar.color = { r = r, g = g, b = b, a = a }
|
|
pfUI.uf.player.debuffbar.bordercolor = { r = br, g = bg, b = bb, a = ba }
|
|
pfUI.uf.player.debuffbar.textcolor = { r = tr, g = tg, b = tb, a = ta }
|
|
pfUI.uf.player.debuffbar.anchors = {
|
|
pfUI.uf.player,
|
|
pfUI.uf.player and pfUI.uf.player.buffbar and pfUI.uf.player.buffbar.bars,
|
|
pfUI.uf.player and pfUI.uf.player.debuffs,
|
|
pfUI.uf.player and pfUI.uf.player.buffs
|
|
}
|
|
|
|
pfUI.uf.player.debuffbar:SetPoint("LEFT", pfUI.uf.player, "LEFT", 0, 0)
|
|
pfUI.uf.player.debuffbar:SetPoint("BOTTOM", pfUI.uf.player, "TOP", 0, border*2+1)
|
|
UpdateMovable(pfUI.uf.player.debuffbar)
|
|
end
|
|
|
|
-- create target debuffbars
|
|
if pfUI.uf.target and C.buffbar.tdebuff.enable == "1" then
|
|
local config = C.buffbar.tdebuff
|
|
local r, g, b, a = strsplit(",", config.color)
|
|
local br, bg, bb, ba = strsplit(",", config.bordercolor)
|
|
local tr, tg, tb, ta = strsplit(",", config.textcolor)
|
|
|
|
pfUI.uf.target.debuffbar = CreateBuffBarFrame("Target", "HARMFUL")
|
|
pfUI.uf.target.debuffbar:SetWidth(config.width == "-1" and pfUI.uf.target:GetWidth() or config.width)
|
|
pfUI.uf.target.debuffbar:SetHeight(config.height)
|
|
pfUI.uf.target.debuffbar.config = config
|
|
pfUI.uf.target.debuffbar.buffcmp = config.sort == "asc" and asc or desc
|
|
pfUI.uf.target.debuffbar.color = { r = r, g = g, b = b, a = a }
|
|
pfUI.uf.target.debuffbar.bordercolor = { r = br, g = bg, b = bb, a = ba }
|
|
pfUI.uf.target.debuffbar.textcolor = { r = tr, g = tg, b = tb, a = ta }
|
|
pfUI.uf.target.debuffbar.threshold = tonumber(config.threshold)
|
|
pfUI.uf.target.debuffbar.anchors = {
|
|
pfUI.uf.target,
|
|
pfUI.uf.target and pfUI.uf.target.buffbar and pfUI.uf.target.buffbar.bars,
|
|
pfUI.uf.target and pfUI.uf.target.debuffs,
|
|
pfUI.uf.target and pfUI.uf.target.buffs
|
|
}
|
|
|
|
pfUI.uf.target.debuffbar:SetPoint("LEFT", pfUI.uf.target, "LEFT", 0, 0)
|
|
pfUI.uf.target.debuffbar:SetPoint("BOTTOM", pfUI.uf.target, "TOP", 0, border*2+1)
|
|
UpdateMovable(pfUI.uf.target.debuffbar)
|
|
end
|
|
end) |