1553 lines
48 KiB
Lua
1553 lines
48 KiB
Lua
local E, L, V, P, G = unpack(select(2, ...)); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
|
|
local UF = E:GetModule('UnitFrames')
|
|
local LSM = E.Libs.LSM
|
|
|
|
local ElvUF = E.oUF
|
|
assert(ElvUF, 'ElvUI was unable to locate oUF.')
|
|
|
|
local _G = _G
|
|
local select, type, unpack, assert, tostring = select, type, unpack, assert, tostring
|
|
local min, pairs, ipairs, tinsert, strsub = min, pairs, ipairs, tinsert, strsub
|
|
local strfind, gsub, format = strfind, gsub, format
|
|
|
|
local CompactRaidFrameManager_SetSetting = CompactRaidFrameManager_SetSetting
|
|
local CreateFrame = CreateFrame
|
|
local GetInstanceInfo = GetInstanceInfo
|
|
local hooksecurefunc = hooksecurefunc
|
|
local IsReplacingUnit = IsReplacingUnit
|
|
local IsAddOnLoaded = IsAddOnLoaded
|
|
local RegisterStateDriver = RegisterStateDriver
|
|
local SetCVar = SetCVar
|
|
local UnitExists = UnitExists
|
|
local UnitIsEnemy = UnitIsEnemy
|
|
local UnitIsFriend = UnitIsFriend
|
|
local UnitFrame_OnEnter = UnitFrame_OnEnter
|
|
local UnitFrame_OnLeave = UnitFrame_OnLeave
|
|
local UnregisterStateDriver = UnregisterStateDriver
|
|
local PlaySound = PlaySound
|
|
|
|
local C_NamePlate_GetNamePlateForUnit = C_NamePlate.GetNamePlateForUnit
|
|
local SOUNDKIT_IG_CREATURE_AGGRO_SELECT = SOUNDKIT.IG_CREATURE_AGGRO_SELECT
|
|
local SOUNDKIT_IG_CHARACTER_NPC_SELECT = SOUNDKIT.IG_CHARACTER_NPC_SELECT
|
|
local SOUNDKIT_IG_CREATURE_NEUTRAL_SELECT = SOUNDKIT.IG_CREATURE_NEUTRAL_SELECT
|
|
local SOUNDKIT_INTERFACE_SOUND_LOST_TARGET_UNIT = SOUNDKIT.INTERFACE_SOUND_LOST_TARGET_UNIT
|
|
local ALTERNATE_POWER_INDEX = Enum.PowerType.Alternate or 10
|
|
|
|
-- GLOBALS: ElvUF_Parent, Arena_LoadUI
|
|
local hiddenParent = CreateFrame('Frame', nil, _G.UIParent)
|
|
hiddenParent:SetAllPoints()
|
|
hiddenParent:Hide()
|
|
|
|
UF.headerstoload = {}
|
|
UF.unitgroupstoload = {}
|
|
UF.unitstoload = {}
|
|
|
|
UF.groupPrototype = {}
|
|
UF.headerPrototype = {}
|
|
UF.headers = {}
|
|
UF.groupunits = {}
|
|
UF.units = {}
|
|
|
|
UF.statusbars = {}
|
|
UF.fontstrings = {}
|
|
UF.badHeaderPoints = {
|
|
TOP = 'BOTTOM',
|
|
LEFT = 'RIGHT',
|
|
BOTTOM = 'TOP',
|
|
RIGHT = 'LEFT',
|
|
}
|
|
|
|
UF.headerFunctions = {}
|
|
UF.classMaxResourceBar = {
|
|
DEATHKNIGHT = 6,
|
|
PALADIN = 5,
|
|
WARLOCK = 5,
|
|
MONK = 6,
|
|
MAGE = 4,
|
|
ROGUE = 6,
|
|
DRUID = 5
|
|
}
|
|
|
|
UF.instanceMapIDs = {
|
|
[30] = 40, -- Alterac Valley
|
|
[489] = 10, -- Classic Warsong Gulch
|
|
[529] = 15, -- Classic Arathi Basin
|
|
[566] = 15, -- Eye of the Storm
|
|
[607] = 15, -- Strand of the Ancients
|
|
[628] = 40, -- Isle of Conquest
|
|
[726] = 10, -- Twin Peaks
|
|
[727] = 10, -- Silvershard Mines
|
|
[761] = 10, -- The Battle for Gilneas
|
|
[968] = 10, -- Rated Eye of the Storm
|
|
[998] = 10, -- Temple of Kotmogu
|
|
[1191] = 40, -- Ashran
|
|
[1280] = 40, -- Southshore vs Tarren Mill
|
|
[1681] = 15, -- Arathi Basin Winter
|
|
[1803] = 10, -- Seething Shore
|
|
[2106] = 10, -- Warsong Gulch
|
|
[2107] = 15, -- Arathi Basin
|
|
[2118] = 40, -- Battle for Wintergrasp
|
|
[2245] = 15, -- Deepwind Gorge
|
|
[3358] = 15, -- Arathi Basin (NEW - Only Brawl?)
|
|
}
|
|
|
|
UF.headerGroupBy = {
|
|
CLASS = function(header)
|
|
header:SetAttribute('groupingOrder', 'DEATHKNIGHT,DEMONHUNTER,DRUID,HUNTER,MAGE,PALADIN,PRIEST,ROGUE,SHAMAN,WARLOCK,WARRIOR,MONK')
|
|
header:SetAttribute('sortMethod', 'NAME')
|
|
header:SetAttribute('groupBy', 'CLASS')
|
|
end,
|
|
MTMA = function(header)
|
|
header:SetAttribute('groupingOrder', 'MAINTANK,MAINASSIST,NONE')
|
|
header:SetAttribute('sortMethod', 'NAME')
|
|
header:SetAttribute('groupBy', 'ROLE')
|
|
end,
|
|
ROLE = function(header)
|
|
header:SetAttribute('groupingOrder', 'TANK,HEALER,DAMAGER,NONE')
|
|
header:SetAttribute('sortMethod', 'NAME')
|
|
header:SetAttribute('groupBy', 'ASSIGNEDROLE')
|
|
end,
|
|
ROLE2 = function(header)
|
|
header:SetAttribute('groupingOrder', 'TANK,DAMAGER,HEALER,NONE')
|
|
header:SetAttribute('sortMethod', 'NAME')
|
|
header:SetAttribute('groupBy', 'ASSIGNEDROLE')
|
|
end,
|
|
NAME = function(header)
|
|
header:SetAttribute('groupingOrder', '1,2,3,4,5,6,7,8')
|
|
header:SetAttribute('sortMethod', 'NAME')
|
|
header:SetAttribute('groupBy', nil)
|
|
end,
|
|
GROUP = function(header)
|
|
header:SetAttribute('groupingOrder', '1,2,3,4,5,6,7,8')
|
|
header:SetAttribute('sortMethod', 'INDEX')
|
|
header:SetAttribute('groupBy', 'GROUP')
|
|
end,
|
|
CLASSROLE = function(header)
|
|
header:SetAttribute('groupingOrder', 'DEATHKNIGHT,WARRIOR,DEMONHUNTER,ROGUE,MONK,PALADIN,DRUID,SHAMAN,HUNTER,PRIEST,MAGE,WARLOCK')
|
|
header:SetAttribute('sortMethod', 'NAME')
|
|
header:SetAttribute('groupBy', 'CLASS')
|
|
end,
|
|
PETNAME = function(header)
|
|
header:SetAttribute('groupingOrder', '1,2,3,4,5,6,7,8')
|
|
header:SetAttribute('sortMethod', 'NAME')
|
|
header:SetAttribute('groupBy', nil)
|
|
header:SetAttribute('filterOnPet', true) --This is the line that matters. Without this, it sorts based on the owners name
|
|
end,
|
|
INDEX = function(header)
|
|
header:SetAttribute('groupingOrder', '1,2,3,4,5,6,7,8')
|
|
header:SetAttribute('sortMethod', 'INDEX')
|
|
header:SetAttribute('groupBy', nil)
|
|
end,
|
|
}
|
|
|
|
local POINT_COLUMN_ANCHOR_TO_DIRECTION = {
|
|
TOPTOP = 'UP_RIGHT',
|
|
BOTTOMBOTTOM = 'TOP_RIGHT',
|
|
LEFTLEFT = 'RIGHT_UP',
|
|
RIGHTRIGHT = 'LEFT_UP',
|
|
RIGHTTOP = 'LEFT_DOWN',
|
|
LEFTTOP = 'RIGHT_DOWN',
|
|
LEFTBOTTOM = 'RIGHT_UP',
|
|
RIGHTBOTTOM = 'LEFT_UP',
|
|
BOTTOMRIGHT = 'UP_LEFT',
|
|
BOTTOMLEFT = 'UP_RIGHT',
|
|
TOPRIGHT = 'DOWN_LEFT',
|
|
TOPLEFT = 'DOWN_RIGHT'
|
|
}
|
|
|
|
local DIRECTION_TO_POINT = {
|
|
DOWN_RIGHT = 'TOP',
|
|
DOWN_LEFT = 'TOP',
|
|
UP_RIGHT = 'BOTTOM',
|
|
UP_LEFT = 'BOTTOM',
|
|
RIGHT_DOWN = 'LEFT',
|
|
RIGHT_UP = 'LEFT',
|
|
LEFT_DOWN = 'RIGHT',
|
|
LEFT_UP = 'RIGHT',
|
|
UP = 'BOTTOM',
|
|
DOWN = 'TOP'
|
|
}
|
|
|
|
local DIRECTION_TO_GROUP_ANCHOR_POINT = {
|
|
DOWN_RIGHT = 'TOPLEFT',
|
|
DOWN_LEFT = 'TOPRIGHT',
|
|
UP_RIGHT = 'BOTTOMLEFT',
|
|
UP_LEFT = 'BOTTOMRIGHT',
|
|
RIGHT_DOWN = 'TOPLEFT',
|
|
RIGHT_UP = 'BOTTOMLEFT',
|
|
LEFT_DOWN = 'TOPRIGHT',
|
|
LEFT_UP = 'BOTTOMRIGHT',
|
|
OUT_RIGHT_UP = 'BOTTOM',
|
|
OUT_LEFT_UP = 'BOTTOM',
|
|
OUT_RIGHT_DOWN = 'TOP',
|
|
OUT_LEFT_DOWN = 'TOP',
|
|
OUT_UP_RIGHT = 'LEFT',
|
|
OUT_UP_LEFT = 'RIGHT',
|
|
OUT_DOWN_RIGHT = 'LEFT',
|
|
OUT_DOWN_LEFT = 'RIGHT',
|
|
}
|
|
|
|
local INVERTED_DIRECTION_TO_COLUMN_ANCHOR_POINT = {
|
|
DOWN_RIGHT = 'RIGHT',
|
|
DOWN_LEFT = 'LEFT',
|
|
UP_RIGHT = 'RIGHT',
|
|
UP_LEFT = 'LEFT',
|
|
RIGHT_DOWN = 'BOTTOM',
|
|
RIGHT_UP = 'TOP',
|
|
LEFT_DOWN = 'BOTTOM',
|
|
LEFT_UP = 'TOP',
|
|
UP = 'TOP',
|
|
DOWN = 'BOTTOM'
|
|
}
|
|
|
|
local DIRECTION_TO_COLUMN_ANCHOR_POINT = {
|
|
DOWN_RIGHT = 'LEFT',
|
|
DOWN_LEFT = 'RIGHT',
|
|
UP_RIGHT = 'LEFT',
|
|
UP_LEFT = 'RIGHT',
|
|
RIGHT_DOWN = 'TOP',
|
|
RIGHT_UP = 'BOTTOM',
|
|
LEFT_DOWN = 'TOP',
|
|
LEFT_UP = 'BOTTOM',
|
|
}
|
|
|
|
local DIRECTION_TO_HORIZONTAL_SPACING_MULTIPLIER = {
|
|
DOWN_RIGHT = 1,
|
|
DOWN_LEFT = -1,
|
|
UP_RIGHT = 1,
|
|
UP_LEFT = -1,
|
|
RIGHT_DOWN = 1,
|
|
RIGHT_UP = 1,
|
|
LEFT_DOWN = -1,
|
|
LEFT_UP = -1,
|
|
}
|
|
|
|
local DIRECTION_TO_VERTICAL_SPACING_MULTIPLIER = {
|
|
DOWN_RIGHT = -1,
|
|
DOWN_LEFT = -1,
|
|
UP_RIGHT = 1,
|
|
UP_LEFT = 1,
|
|
RIGHT_DOWN = -1,
|
|
RIGHT_UP = 1,
|
|
LEFT_DOWN = -1,
|
|
LEFT_UP = 1,
|
|
}
|
|
|
|
function UF:ConvertGroupDB(group)
|
|
local db = self.db.units[group.groupName]
|
|
if db.point and db.columnAnchorPoint then
|
|
db.growthDirection = POINT_COLUMN_ANCHOR_TO_DIRECTION[db.point..db.columnAnchorPoint];
|
|
db.point = nil;
|
|
db.columnAnchorPoint = nil;
|
|
end
|
|
|
|
if db.growthDirection == 'UP' then
|
|
db.growthDirection = 'UP_RIGHT'
|
|
end
|
|
|
|
if db.growthDirection == 'DOWN' then
|
|
db.growthDirection = 'DOWN_RIGHT'
|
|
end
|
|
end
|
|
|
|
function UF:Construct_UF(frame, unit)
|
|
frame:SetScript('OnEnter', UnitFrame_OnEnter)
|
|
frame:SetScript('OnLeave', UnitFrame_OnLeave)
|
|
|
|
frame.SHADOW_SPACING = 3
|
|
frame.CLASSBAR_YOFFSET = 0 --placeholder
|
|
frame.BOTTOM_OFFSET = 0 --placeholder
|
|
|
|
frame.RaisedElementParent = CreateFrame('Frame', nil, frame)
|
|
frame.RaisedElementParent.TextureParent = CreateFrame('Frame', nil, frame.RaisedElementParent)
|
|
frame.RaisedElementParent:SetFrameLevel(frame:GetFrameLevel() + 100)
|
|
|
|
if not UF.groupunits[unit] then
|
|
UF['Construct_'..gsub(E:StringTitle(unit), 't(arget)', 'T%1')..'Frame'](UF, frame, unit)
|
|
else
|
|
UF['Construct_'..E:StringTitle(UF.groupunits[unit])..'Frames'](UF, frame, unit)
|
|
end
|
|
|
|
return frame
|
|
end
|
|
|
|
function UF:GetObjectAnchorPoint(frame, point)
|
|
if point == 'Frame' then
|
|
return frame
|
|
end
|
|
|
|
local place = frame[point]
|
|
if place and place:IsShown() then
|
|
return place
|
|
else
|
|
return frame
|
|
end
|
|
end
|
|
|
|
function UF:GetPositionOffset(position, offset)
|
|
if not offset then offset = 2; end
|
|
local x, y = 0, 0
|
|
if strfind(position, 'LEFT') then
|
|
x = offset
|
|
elseif strfind(position, 'RIGHT') then
|
|
x = -offset
|
|
end
|
|
|
|
if strfind(position, 'TOP') then
|
|
y = -offset
|
|
elseif strfind(position, 'BOTTOM') then
|
|
y = offset
|
|
end
|
|
|
|
return x, y
|
|
end
|
|
|
|
function UF:GetAuraOffset(p1, p2)
|
|
local x, y = 0, 0
|
|
if p1 == 'RIGHT' and p2 == 'LEFT' then
|
|
x = -3
|
|
elseif p1 == 'LEFT' and p2 == 'RIGHT' then
|
|
x = 3
|
|
end
|
|
|
|
if strfind(p1, 'TOP') and strfind(p2, 'BOTTOM') then
|
|
y = -1
|
|
elseif strfind(p1, 'BOTTOM') and strfind(p2, 'TOP') then
|
|
y = 1
|
|
end
|
|
|
|
return x, y
|
|
end
|
|
|
|
function UF:GetAuraAnchorFrame(frame, attachTo)
|
|
if attachTo == 'FRAME' then
|
|
return frame
|
|
elseif attachTo == 'BUFFS' and frame.Buffs then
|
|
return frame.Buffs
|
|
elseif attachTo == 'DEBUFFS' and frame.Debuffs then
|
|
return frame.Debuffs
|
|
elseif attachTo == 'HEALTH' and frame.Health then
|
|
return frame.Health
|
|
elseif attachTo == 'POWER' and frame.Power then
|
|
return frame.Power
|
|
elseif attachTo == 'TRINKET' and (frame.Trinket or frame.PVPSpecIcon) then
|
|
local _, instanceType = GetInstanceInfo()
|
|
return (instanceType == 'arena' and frame.Trinket) or frame.PVPSpecIcon
|
|
else
|
|
return frame
|
|
end
|
|
end
|
|
|
|
function UF:ClearChildPoints(...)
|
|
for i=1, select('#', ...) do
|
|
local child = select(i, ...)
|
|
child:ClearAllPoints()
|
|
end
|
|
end
|
|
|
|
function UF:UpdateColors()
|
|
local db = self.db.colors
|
|
|
|
ElvUF.colors.tapped = E:SetColorTable(ElvUF.colors.tapped, db.tapped)
|
|
ElvUF.colors.disconnected = E:SetColorTable(ElvUF.colors.disconnected, db.disconnected)
|
|
ElvUF.colors.health = E:SetColorTable(ElvUF.colors.health, db.health)
|
|
ElvUF.colors.power.MANA = E:SetColorTable(ElvUF.colors.power.MANA, db.power.MANA)
|
|
ElvUF.colors.power.RAGE = E:SetColorTable(ElvUF.colors.power.RAGE, db.power.RAGE)
|
|
ElvUF.colors.power.FOCUS = E:SetColorTable(ElvUF.colors.power.FOCUS, db.power.FOCUS)
|
|
ElvUF.colors.power.ENERGY = E:SetColorTable(ElvUF.colors.power.ENERGY, db.power.ENERGY)
|
|
ElvUF.colors.power.RUNIC_POWER = E:SetColorTable(ElvUF.colors.power.RUNIC_POWER, db.power.RUNIC_POWER)
|
|
ElvUF.colors.power.PAIN = E:SetColorTable(ElvUF.colors.power.PAIN, db.power.PAIN)
|
|
ElvUF.colors.power.FURY = E:SetColorTable(ElvUF.colors.power.FURY, db.power.FURY)
|
|
ElvUF.colors.power.LUNAR_POWER = E:SetColorTable(ElvUF.colors.power.LUNAR_POWER, db.power.LUNAR_POWER)
|
|
ElvUF.colors.power.INSANITY = E:SetColorTable(ElvUF.colors.power.INSANITY, db.power.INSANITY)
|
|
ElvUF.colors.power.MAELSTROM = E:SetColorTable(ElvUF.colors.power.MAELSTROM, db.power.MAELSTROM)
|
|
ElvUF.colors.power[ALTERNATE_POWER_INDEX] = E:SetColorTable(ElvUF.colors.power[ALTERNATE_POWER_INDEX], db.power.ALT_POWER)
|
|
|
|
ElvUF.colors.threat[0] = E:SetColorTable(ElvUF.colors.threat[0], db.threat[0])
|
|
ElvUF.colors.threat[1] = E:SetColorTable(ElvUF.colors.threat[1], db.threat[1])
|
|
ElvUF.colors.threat[2] = E:SetColorTable(ElvUF.colors.threat[2], db.threat[2])
|
|
ElvUF.colors.threat[3] = E:SetColorTable(ElvUF.colors.threat[3], db.threat[3])
|
|
|
|
ElvUF.colors.selection[0] = E:SetColorTable(ElvUF.colors.selection[0], db.selection[0])
|
|
ElvUF.colors.selection[1] = E:SetColorTable(ElvUF.colors.selection[1], db.selection[1])
|
|
ElvUF.colors.selection[2] = E:SetColorTable(ElvUF.colors.selection[2], db.selection[2])
|
|
ElvUF.colors.selection[3] = E:SetColorTable(ElvUF.colors.selection[3], db.selection[3])
|
|
ElvUF.colors.selection[5] = E:SetColorTable(ElvUF.colors.selection[5], db.selection[5])
|
|
ElvUF.colors.selection[6] = E:SetColorTable(ElvUF.colors.selection[6], db.selection[6])
|
|
ElvUF.colors.selection[7] = E:SetColorTable(ElvUF.colors.selection[7], db.selection[7])
|
|
ElvUF.colors.selection[8] = E:SetColorTable(ElvUF.colors.selection[8], db.selection[8])
|
|
ElvUF.colors.selection[9] = E:SetColorTable(ElvUF.colors.selection[9], db.selection[9])
|
|
ElvUF.colors.selection[13] = E:SetColorTable(ElvUF.colors.selection[13], db.selection[13])
|
|
|
|
if not ElvUF.colors.ComboPoints then ElvUF.colors.ComboPoints = {} end
|
|
ElvUF.colors.ComboPoints[1] = E:SetColorTable(ElvUF.colors.ComboPoints[1], db.classResources.comboPoints[1])
|
|
ElvUF.colors.ComboPoints[2] = E:SetColorTable(ElvUF.colors.ComboPoints[2], db.classResources.comboPoints[2])
|
|
ElvUF.colors.ComboPoints[3] = E:SetColorTable(ElvUF.colors.ComboPoints[3], db.classResources.comboPoints[3])
|
|
|
|
--Monk, Mage, Paladin and Warlock, Death Knight
|
|
if not ElvUF.colors.ClassBars then ElvUF.colors.ClassBars = {} end
|
|
if not ElvUF.colors.ClassBars.MONK then ElvUF.colors.ClassBars.MONK = {} end
|
|
ElvUF.colors.ClassBars.PALADIN = E:SetColorTable(ElvUF.colors.ClassBars.PALADIN, db.classResources.PALADIN)
|
|
ElvUF.colors.ClassBars.MAGE = E:SetColorTable(ElvUF.colors.ClassBars.MAGE, db.classResources.MAGE)
|
|
ElvUF.colors.ClassBars.MONK[1] = E:SetColorTable(ElvUF.colors.ClassBars.MONK[1], db.classResources.MONK[1])
|
|
ElvUF.colors.ClassBars.MONK[2] = E:SetColorTable(ElvUF.colors.ClassBars.MONK[2], db.classResources.MONK[2])
|
|
ElvUF.colors.ClassBars.MONK[3] = E:SetColorTable(ElvUF.colors.ClassBars.MONK[3], db.classResources.MONK[3])
|
|
ElvUF.colors.ClassBars.MONK[4] = E:SetColorTable(ElvUF.colors.ClassBars.MONK[4], db.classResources.MONK[4])
|
|
ElvUF.colors.ClassBars.MONK[5] = E:SetColorTable(ElvUF.colors.ClassBars.MONK[5], db.classResources.MONK[5])
|
|
ElvUF.colors.ClassBars.MONK[6] = E:SetColorTable(ElvUF.colors.ClassBars.MONK[6], db.classResources.MONK[6])
|
|
ElvUF.colors.ClassBars.DEATHKNIGHT = E:SetColorTable(ElvUF.colors.ClassBars.DEATHKNIGHT, db.classResources.DEATHKNIGHT)
|
|
ElvUF.colors.ClassBars.WARLOCK = E:SetColorTable(ElvUF.colors.ClassBars.WARLOCK, db.classResources.WARLOCK)
|
|
|
|
-- these are just holders.. to maintain and update tables
|
|
if not ElvUF.colors.reaction.good then ElvUF.colors.reaction.good = {} end
|
|
if not ElvUF.colors.reaction.bad then ElvUF.colors.reaction.bad = {} end
|
|
if not ElvUF.colors.reaction.neutral then ElvUF.colors.reaction.neutral = {} end
|
|
ElvUF.colors.reaction.good = E:SetColorTable(ElvUF.colors.reaction.good, db.reaction.GOOD)
|
|
ElvUF.colors.reaction.bad = E:SetColorTable(ElvUF.colors.reaction.bad, db.reaction.BAD)
|
|
ElvUF.colors.reaction.neutral = E:SetColorTable(ElvUF.colors.reaction.neutral, db.reaction.NEUTRAL)
|
|
|
|
if not ElvUF.colors.smoothHealth then ElvUF.colors.smoothHealth = {} end
|
|
ElvUF.colors.smoothHealth = E:SetColorTable(ElvUF.colors.smoothHealth, db.health)
|
|
|
|
if not ElvUF.colors.smooth then ElvUF.colors.smooth = {1, 0, 0, 1, 1, 0} end
|
|
-- end
|
|
|
|
ElvUF.colors.reaction[1] = ElvUF.colors.reaction.bad
|
|
ElvUF.colors.reaction[2] = ElvUF.colors.reaction.bad
|
|
ElvUF.colors.reaction[3] = ElvUF.colors.reaction.bad
|
|
ElvUF.colors.reaction[4] = ElvUF.colors.reaction.neutral
|
|
ElvUF.colors.reaction[5] = ElvUF.colors.reaction.good
|
|
ElvUF.colors.reaction[6] = ElvUF.colors.reaction.good
|
|
ElvUF.colors.reaction[7] = ElvUF.colors.reaction.good
|
|
ElvUF.colors.reaction[8] = ElvUF.colors.reaction.good
|
|
ElvUF.colors.smooth[7] = ElvUF.colors.smoothHealth[1]
|
|
ElvUF.colors.smooth[8] = ElvUF.colors.smoothHealth[2]
|
|
ElvUF.colors.smooth[9] = ElvUF.colors.smoothHealth[3]
|
|
|
|
ElvUF.colors.castColor = E:SetColorTable(ElvUF.colors.castColor, db.castColor)
|
|
ElvUF.colors.castNoInterrupt = E:SetColorTable(ElvUF.colors.castNoInterrupt, db.castNoInterrupt)
|
|
|
|
if not ElvUF.colors.DebuffHighlight then ElvUF.colors.DebuffHighlight = {} end
|
|
ElvUF.colors.DebuffHighlight.Magic = E:SetColorTable(ElvUF.colors.DebuffHighlight.Magic, db.debuffHighlight.Magic)
|
|
ElvUF.colors.DebuffHighlight.Curse = E:SetColorTable(ElvUF.colors.DebuffHighlight.Curse, db.debuffHighlight.Curse)
|
|
ElvUF.colors.DebuffHighlight.Disease = E:SetColorTable(ElvUF.colors.DebuffHighlight.Disease, db.debuffHighlight.Disease)
|
|
ElvUF.colors.DebuffHighlight.Poison = E:SetColorTable(ElvUF.colors.DebuffHighlight.Poison, db.debuffHighlight.Poison)
|
|
end
|
|
|
|
function UF:Update_StatusBars()
|
|
local statusBarTexture = LSM:Fetch('statusbar', self.db.statusbar)
|
|
for statusbar in pairs(UF.statusbars) do
|
|
if statusbar then
|
|
local useBlank = statusbar.isTransparent
|
|
if statusbar.parent then
|
|
useBlank = statusbar.parent.isTransparent
|
|
end
|
|
if statusbar:IsObjectType('StatusBar') then
|
|
if not useBlank then
|
|
statusbar:SetStatusBarTexture(statusBarTexture)
|
|
end
|
|
elseif statusbar:IsObjectType('Texture') then
|
|
statusbar:SetTexture(statusBarTexture)
|
|
end
|
|
|
|
UF:Update_StatusBar(statusbar.bg or statusbar.BG, (not useBlank and statusBarTexture) or E.media.blankTex)
|
|
end
|
|
end
|
|
end
|
|
|
|
function UF:Update_StatusBar(statusbar, texture)
|
|
if not statusbar then return end
|
|
if not texture then texture = LSM:Fetch('statusbar', self.db.statusbar) end
|
|
|
|
if statusbar:IsObjectType('StatusBar') then
|
|
statusbar:SetStatusBarTexture(texture)
|
|
elseif statusbar:IsObjectType('Texture') then
|
|
statusbar:SetTexture(texture)
|
|
end
|
|
end
|
|
|
|
function UF:Update_FontString(object)
|
|
object:FontTemplate(LSM:Fetch('font', self.db.font), self.db.fontSize, self.db.fontOutline)
|
|
end
|
|
|
|
function UF:Update_FontStrings()
|
|
local font, size, outline = LSM:Fetch('font', self.db.font), self.db.fontSize, self.db.fontOutline
|
|
for obj in pairs(UF.fontstrings) do
|
|
obj:FontTemplate(font, size, outline)
|
|
end
|
|
end
|
|
|
|
function UF:Construct_Fader()
|
|
return { UpdateRange = UF.UpdateRange }
|
|
end
|
|
|
|
function UF:Configure_Fader(frame)
|
|
if frame.db and frame.db.enable and (frame.db.fader and frame.db.fader.enable) then
|
|
if not frame:IsElementEnabled('Fader') then
|
|
frame:EnableElement('Fader')
|
|
end
|
|
|
|
frame.Fader:SetOption('Hover', frame.db.fader.hover)
|
|
frame.Fader:SetOption('Combat', frame.db.fader.combat)
|
|
frame.Fader:SetOption('PlayerTarget', frame.db.fader.playertarget)
|
|
frame.Fader:SetOption('Focus', frame.db.fader.focus)
|
|
frame.Fader:SetOption('Health', frame.db.fader.health)
|
|
frame.Fader:SetOption('Power', frame.db.fader.power)
|
|
frame.Fader:SetOption('Vehicle', frame.db.fader.vehicle)
|
|
frame.Fader:SetOption('Casting', frame.db.fader.casting)
|
|
frame.Fader:SetOption('MinAlpha', frame.db.fader.minAlpha)
|
|
frame.Fader:SetOption('MaxAlpha', frame.db.fader.maxAlpha)
|
|
|
|
if frame ~= _G.ElvUF_Player then
|
|
frame.Fader:SetOption('Range', frame.db.fader.range)
|
|
frame.Fader:SetOption('UnitTarget', frame.db.fader.unittarget)
|
|
end
|
|
|
|
frame.Fader:SetOption('Smooth', (frame.db.fader.smooth > 0 and frame.db.fader.smooth) or nil)
|
|
frame.Fader:SetOption('Delay', (frame.db.fader.delay > 0 and frame.db.fader.delay) or nil)
|
|
|
|
frame.Fader:ClearTimers()
|
|
frame.Fader.configTimer = E:ScheduleTimer(frame.Fader.ForceUpdate, 0.25, frame.Fader, true)
|
|
elseif frame:IsElementEnabled('Fader') then
|
|
frame:DisableElement('Fader')
|
|
E:UIFrameFadeIn(frame, 1, frame:GetAlpha(), 1)
|
|
end
|
|
end
|
|
|
|
function UF:Configure_FontString(obj)
|
|
UF.fontstrings[obj] = true
|
|
obj:FontTemplate() --This is temporary.
|
|
end
|
|
|
|
function UF:Update_AllFrames()
|
|
if not E.private.unitframe.enable then return end
|
|
UF:UpdateColors()
|
|
UF:Update_FontStrings()
|
|
UF:Update_StatusBars()
|
|
|
|
for unit in pairs(UF.units) do
|
|
if UF.db.units[unit].enable then
|
|
UF[unit]:Update()
|
|
UF[unit]:Enable()
|
|
E:EnableMover(UF[unit].mover:GetName())
|
|
else
|
|
UF[unit]:Update()
|
|
UF[unit]:Disable()
|
|
E:DisableMover(UF[unit].mover:GetName())
|
|
end
|
|
end
|
|
|
|
for unit, group in pairs(UF.groupunits) do
|
|
if UF.db.units[group].enable then
|
|
UF[unit]:Enable()
|
|
UF[unit]:Update()
|
|
E:EnableMover(UF[unit].mover:GetName())
|
|
else
|
|
UF[unit]:Disable()
|
|
E:DisableMover(UF[unit].mover:GetName())
|
|
end
|
|
|
|
if UF[unit].isForced then
|
|
UF:ForceShow(UF[unit])
|
|
end
|
|
end
|
|
|
|
if UF.db.smartRaidFilter then
|
|
UF:HandleSmartVisibility()
|
|
else
|
|
UF:UpdateAllHeaders()
|
|
end
|
|
end
|
|
|
|
function UF:CreateAndUpdateUFGroup(group, numGroup)
|
|
for i=1, numGroup do
|
|
local unit = group..i
|
|
local frameName = gsub(E:StringTitle(unit), 't(arget)', 'T%1')
|
|
local frame = self[unit]
|
|
|
|
if not frame then
|
|
self.groupunits[unit] = group;
|
|
frame = ElvUF:Spawn(unit, 'ElvUF_'..frameName)
|
|
frame.index = i
|
|
frame:SetParent(ElvUF_Parent)
|
|
frame:SetID(i)
|
|
self[unit] = frame
|
|
end
|
|
|
|
frameName = gsub(E:StringTitle(group), 't(arget)', 'T%1')
|
|
frame.Update = function()
|
|
UF['Update_'..E:StringTitle(frameName)..'Frames'](self, frame, self.db.units[group])
|
|
end
|
|
|
|
if self.db.units[group].enable then
|
|
frame:Enable()
|
|
|
|
if group == 'arena' then
|
|
frame:SetAttribute('oUF-enableArenaPrep', true)
|
|
end
|
|
|
|
frame.Update()
|
|
|
|
E:EnableMover(frame.mover:GetName())
|
|
else
|
|
frame:Disable()
|
|
|
|
if group == 'arena' then
|
|
frame:SetAttribute('oUF-enableArenaPrep', false)
|
|
end
|
|
|
|
-- for some reason the boss/arena 'uncheck disable' doesnt fire this, we need to so putting it here.
|
|
if group == 'boss' or group == 'arena' then
|
|
UF:Configure_Fader(frame)
|
|
end
|
|
|
|
E:DisableMover(frame.mover:GetName())
|
|
end
|
|
|
|
if frame.isForced then
|
|
self:ForceShow(frame)
|
|
end
|
|
end
|
|
end
|
|
|
|
function UF:HeaderUpdateSpecificElement(group, elementName)
|
|
local Header = self[group]
|
|
assert(Header, 'Invalid group specified.')
|
|
|
|
for i=1, Header:GetNumChildren() do
|
|
local frame = select(i, Header:GetChildren())
|
|
if frame and frame.Health then
|
|
frame:UpdateElement(elementName)
|
|
end
|
|
end
|
|
end
|
|
|
|
--Keep an eye on this one, it may need to be changed too
|
|
--Reference: http://www.tukui.org/forums/topic.php?id=35332
|
|
function UF.groupPrototype:GetAttribute(name)
|
|
return self.groups[1]:GetAttribute(name)
|
|
end
|
|
|
|
function UF.groupPrototype:Configure_Groups(Header)
|
|
local db = UF.db.units[Header.groupName]
|
|
|
|
local width, height, newCols, newRows = 0, 0, 0, 0
|
|
local direction, dbWidth, dbHeight = db.growthDirection, db.width, db.height
|
|
local xMult, yMult = DIRECTION_TO_HORIZONTAL_SPACING_MULTIPLIER[direction], DIRECTION_TO_VERTICAL_SPACING_MULTIPLIER[direction]
|
|
local UNIT_HEIGHT = dbHeight + (db.infoPanel and db.infoPanel.enable and db.infoPanel.height or 0)
|
|
|
|
local groupBy = db.groupBy
|
|
local groupSpacing = db.groupSpacing
|
|
local groupsPerRowCol = db.groupsPerRowCol
|
|
local horizontalSpacing = db.horizontalSpacing
|
|
local invertGroupingOrder = db.invertGroupingOrder
|
|
local raidWideSorting = db.raidWideSorting
|
|
local showPlayer = db.showPlayer
|
|
local sortDir = db.sortDir
|
|
local startFromCenter = db.startFromCenter
|
|
local verticalSpacing = db.verticalSpacing
|
|
|
|
local numGroups = Header.numGroups
|
|
for i = 1, numGroups do
|
|
local group = Header.groups[i]
|
|
|
|
if group then
|
|
UF:ConvertGroupDB(group)
|
|
group:ClearAllPoints()
|
|
group:ClearChildPoints()
|
|
|
|
local point = DIRECTION_TO_POINT[direction]
|
|
group:SetAttribute('point', point)
|
|
|
|
if point == 'LEFT' or point == 'RIGHT' then
|
|
group:SetAttribute('xOffset', horizontalSpacing * DIRECTION_TO_HORIZONTAL_SPACING_MULTIPLIER[direction])
|
|
group:SetAttribute('yOffset', 0)
|
|
group:SetAttribute('columnSpacing', verticalSpacing)
|
|
else
|
|
group:SetAttribute('xOffset', 0)
|
|
group:SetAttribute('yOffset', verticalSpacing * DIRECTION_TO_VERTICAL_SPACING_MULTIPLIER[direction])
|
|
group:SetAttribute('columnSpacing', horizontalSpacing)
|
|
end
|
|
|
|
if not group.isForced then
|
|
if not group.initialized then
|
|
group:SetAttribute('startingIndex', raidWideSorting and (-min(numGroups * (groupsPerRowCol * 5), _G.MAX_RAID_MEMBERS) + 1) or -4)
|
|
group:Show()
|
|
group.initialized = true
|
|
end
|
|
group:SetAttribute('startingIndex', 1)
|
|
end
|
|
|
|
if raidWideSorting and invertGroupingOrder then
|
|
group:SetAttribute('columnAnchorPoint', INVERTED_DIRECTION_TO_COLUMN_ANCHOR_POINT[direction])
|
|
else
|
|
group:SetAttribute('columnAnchorPoint', DIRECTION_TO_COLUMN_ANCHOR_POINT[direction])
|
|
end
|
|
|
|
if not group.isForced then
|
|
group:SetAttribute('maxColumns', raidWideSorting and numGroups or 1)
|
|
group:SetAttribute('unitsPerColumn', raidWideSorting and (groupsPerRowCol * 5) or 5)
|
|
group:SetAttribute('sortDir', sortDir)
|
|
group:SetAttribute('showPlayer', showPlayer)
|
|
UF.headerGroupBy[groupBy](group)
|
|
end
|
|
|
|
local groupWide = i == 1 and raidWideSorting and strsub('1,2,3,4,5,6,7,8', 1, numGroups + numGroups-1)
|
|
group:SetAttribute('groupFilter', groupWide or tostring(i))
|
|
end
|
|
|
|
--MATH!! WOOT
|
|
local point = DIRECTION_TO_GROUP_ANCHOR_POINT[direction]
|
|
if raidWideSorting and startFromCenter then
|
|
point = DIRECTION_TO_GROUP_ANCHOR_POINT['OUT_'..direction]
|
|
end
|
|
|
|
if (i - 1) % groupsPerRowCol == 0 then
|
|
if DIRECTION_TO_POINT[direction] == 'LEFT' or DIRECTION_TO_POINT[direction] == 'RIGHT' then
|
|
if group then group:Point(point, Header, point, 0, height * yMult) end
|
|
height = height + UNIT_HEIGHT + verticalSpacing + groupSpacing
|
|
newRows = newRows + 1
|
|
else
|
|
if group then group:Point(point, Header, point, width * xMult, 0) end
|
|
width = width + dbWidth + horizontalSpacing + groupSpacing
|
|
newCols = newCols + 1
|
|
end
|
|
else
|
|
if DIRECTION_TO_POINT[direction] == 'LEFT' or DIRECTION_TO_POINT[direction] == 'RIGHT' then
|
|
if newRows == 1 then
|
|
if group then group:Point(point, Header, point, width * xMult, 0) end
|
|
width = width + ((dbWidth + horizontalSpacing) * 5) + groupSpacing
|
|
newCols = newCols + 1
|
|
elseif group then
|
|
group:Point(point, Header, point, ((((dbWidth + horizontalSpacing) * 5) * ((i-1) % groupsPerRowCol))+((i-1) % groupsPerRowCol)*groupSpacing) * xMult, (((UNIT_HEIGHT + verticalSpacing+groupSpacing) * (newRows - 1))) * yMult)
|
|
end
|
|
else
|
|
if newCols == 1 then
|
|
if group then group:Point(point, Header, point, 0, height * yMult) end
|
|
height = height + ((UNIT_HEIGHT + verticalSpacing) * 5) + groupSpacing
|
|
newRows = newRows + 1
|
|
elseif group then
|
|
group:Point(point, Header, point, (((dbWidth + horizontalSpacing +groupSpacing) * (newCols - 1))) * xMult, ((((UNIT_HEIGHT + verticalSpacing) * 5) * ((i-1) % groupsPerRowCol))+((i-1) % groupsPerRowCol)*groupSpacing) * yMult)
|
|
end
|
|
end
|
|
end
|
|
|
|
if height == 0 then
|
|
height = height + ((UNIT_HEIGHT + verticalSpacing) * 5) +groupSpacing
|
|
elseif width == 0 then
|
|
width = width + ((dbWidth + horizontalSpacing) * 5) +groupSpacing
|
|
end
|
|
end
|
|
|
|
Header:Size(width - horizontalSpacing - groupSpacing, height - verticalSpacing - groupSpacing)
|
|
end
|
|
|
|
function UF.groupPrototype:Update(Header)
|
|
local group = Header.groupName
|
|
|
|
UF[group].db = UF.db.units[group]
|
|
|
|
for _, Group in ipairs(Header.groups) do
|
|
Group.db = UF.db.units[group]
|
|
Group:Update()
|
|
end
|
|
end
|
|
|
|
function UF.groupPrototype:AdjustVisibility(Header)
|
|
if not Header.isForced then
|
|
local numGroups = Header.numGroups
|
|
for i=1, #Header.groups do
|
|
local group = Header.groups[i]
|
|
if i <= numGroups and ((Header.db.raidWideSorting and i <= 1) or not Header.db.raidWideSorting) then
|
|
group:Show()
|
|
else
|
|
if group.forceShow then
|
|
group:Hide()
|
|
group:SetAttribute('startingIndex', 1)
|
|
UF:UnshowChildUnits(group, group:GetChildren())
|
|
else
|
|
group:Reset()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function UF.headerPrototype:ClearChildPoints()
|
|
for i=1, self:GetNumChildren() do
|
|
select(i, self:GetChildren()):ClearAllPoints()
|
|
end
|
|
end
|
|
|
|
function UF.headerPrototype:UpdateChild(func, child, db)
|
|
func(UF, child, db)
|
|
|
|
local name = child:GetName()
|
|
|
|
local target = name..'Target'
|
|
if _G[target] then func(UF, _G[target], db) end
|
|
|
|
local pet = name..'Pet'
|
|
if _G[pet] then func(UF, _G[pet], db) end
|
|
end
|
|
|
|
function UF.headerPrototype:Update(isForced)
|
|
local group = self.groupName
|
|
local db = UF.db.units[group]
|
|
local groupName = E:StringTitle(group)
|
|
|
|
UF['Update_'..groupName..'Header'](UF, self, db, isForced)
|
|
|
|
local i = 1
|
|
local child = self:GetAttribute('child' .. i)
|
|
local func = UF['Update_'..groupName..'Frames']
|
|
|
|
while child do
|
|
self:UpdateChild(func, child, db)
|
|
|
|
i = i + 1
|
|
child = self:GetAttribute('child' .. i)
|
|
end
|
|
end
|
|
|
|
function UF.headerPrototype:Reset()
|
|
self:SetAttribute('showPlayer', true)
|
|
self:SetAttribute('showSolo', true)
|
|
self:SetAttribute('showParty', true)
|
|
self:SetAttribute('showRaid', true)
|
|
self:SetAttribute('columnSpacing', nil)
|
|
self:SetAttribute('columnAnchorPoint', nil)
|
|
self:SetAttribute('groupBy', nil)
|
|
self:SetAttribute('groupFilter', nil)
|
|
self:SetAttribute('groupingOrder', nil)
|
|
self:SetAttribute('maxColumns', nil)
|
|
self:SetAttribute('nameList', nil)
|
|
self:SetAttribute('point', nil)
|
|
self:SetAttribute('sortDir', nil)
|
|
self:SetAttribute('sortMethod', 'NAME')
|
|
self:SetAttribute('startingIndex', nil)
|
|
self:SetAttribute('strictFiltering', nil)
|
|
self:SetAttribute('unitsPerColumn', nil)
|
|
self:SetAttribute('xOffset', nil)
|
|
self:SetAttribute('yOffset', nil)
|
|
self:Hide()
|
|
end
|
|
|
|
UF.SmartSettings = {
|
|
raid = {},
|
|
raid40 = { numGroups = 8 },
|
|
raidpet = { enable = false }
|
|
}
|
|
|
|
function UF:HandleSmartVisibility(skip)
|
|
local sv = UF.SmartSettings
|
|
sv.raid.numGroups = 6
|
|
|
|
local _, instanceType, _, _, maxPlayers, _, _, instanceID = GetInstanceInfo()
|
|
if instanceType == 'raid' or instanceType == 'pvp' then
|
|
local maxInstancePlayers = UF.instanceMapIDs[instanceID]
|
|
if maxInstancePlayers then
|
|
maxPlayers = maxInstancePlayers
|
|
elseif not maxPlayers or maxPlayers == 0 then
|
|
maxPlayers = 40
|
|
end
|
|
|
|
sv.raid.visibility = '[@raid6,noexists] hide;show'
|
|
sv.raid40.visibility = '[@raid6,noexists] hide;show'
|
|
sv.raid.enable = maxPlayers < 40
|
|
sv.raid40.enable = maxPlayers == 40
|
|
|
|
if sv.raid.enable then
|
|
local maxGroups = E:Round(maxPlayers/5)
|
|
if sv.raid.numGroups ~= maxGroups and maxGroups > 0 then
|
|
sv.raid.numGroups = maxGroups
|
|
end
|
|
end
|
|
else
|
|
sv.raid.visibility = '[@raid6,noexists][@raid31,exists] hide;show'
|
|
sv.raid40.visibility = '[@raid31,noexists] hide;show'
|
|
sv.raid.enable = true
|
|
sv.raid40.enable = true
|
|
end
|
|
|
|
UF:UpdateAllHeaders(true, skip)
|
|
end
|
|
|
|
function UF:ZONE_CHANGED_NEW_AREA()
|
|
if UF.db.smartRaidFilter then
|
|
UF:HandleSmartVisibility(true)
|
|
end
|
|
end
|
|
|
|
function UF:PLAYER_ENTERING_WORLD(_, initLogin, isReload)
|
|
UF:RegisterRaidDebuffIndicator()
|
|
|
|
if initLogin then
|
|
UF:Update_AllFrames()
|
|
elseif isReload then
|
|
UF:Update_AllFrames()
|
|
elseif UF.db.smartRaidFilter then
|
|
UF:HandleSmartVisibility(true)
|
|
end
|
|
end
|
|
|
|
function UF:CreateHeader(parent, groupFilter, overrideName, template, groupName, headerTemplate)
|
|
local group = parent.groupName or groupName
|
|
local db = UF.db.units[group]
|
|
ElvUF:SetActiveStyle('ElvUF_'..E:StringTitle(group))
|
|
|
|
local header = ElvUF:SpawnHeader(overrideName, headerTemplate, nil,
|
|
'oUF-initialConfigFunction', format('self:SetWidth(%d); self:SetHeight(%d);', db.width, db.height),
|
|
'groupFilter', groupFilter, 'showParty', true, 'showRaid', true, 'showSolo', true,
|
|
template and 'template', template
|
|
)
|
|
|
|
header.groupName = group
|
|
header:SetParent(parent)
|
|
header:Show()
|
|
|
|
for k, v in pairs(UF.headerPrototype) do
|
|
header[k] = v
|
|
end
|
|
|
|
return header
|
|
end
|
|
|
|
function UF:GetSmartVisibilitySetting(setting, group, smart, db)
|
|
if smart then
|
|
local options = UF.SmartSettings[group]
|
|
local value = options and options[setting]
|
|
|
|
if value ~= nil then
|
|
return value
|
|
end
|
|
end
|
|
|
|
return db[setting]
|
|
end
|
|
|
|
function UF:CreateAndUpdateHeaderGroup(group, groupFilter, template, headerTemplate, smart, skip)
|
|
local db = UF.db.units[group]
|
|
local Header = UF[group]
|
|
|
|
local numGroups = UF:GetSmartVisibilitySetting('numGroups', group, smart, db)
|
|
local visibility = UF:GetSmartVisibilitySetting('visibility', group, smart, db)
|
|
local enable = UF:GetSmartVisibilitySetting('enable', group, smart, db)
|
|
local name = E:StringTitle(group)
|
|
|
|
if not Header then
|
|
ElvUF:RegisterStyle('ElvUF_'..name, UF['Construct_'..name..'Frames'])
|
|
ElvUF:SetActiveStyle('ElvUF_'..name)
|
|
|
|
if numGroups then
|
|
Header = CreateFrame('Frame', 'ElvUF_'..name, ElvUF_Parent, 'SecureHandlerStateTemplate');
|
|
Header.groups = {}
|
|
Header.groupName = group
|
|
Header.template = Header.template or template
|
|
Header.headerTemplate = Header.headerTemplate or headerTemplate
|
|
if not UF.headerFunctions[group] then UF.headerFunctions[group] = {} end
|
|
for k, v in pairs(self.groupPrototype) do
|
|
UF.headerFunctions[group][k] = v
|
|
end
|
|
else
|
|
Header = self:CreateHeader(ElvUF_Parent, groupFilter, 'ElvUF_'..name, template, group, headerTemplate)
|
|
end
|
|
|
|
Header:Show()
|
|
|
|
self[group] = Header
|
|
self.headers[group] = Header
|
|
end
|
|
|
|
local groupsChanged = (Header.numGroups ~= numGroups)
|
|
local stateChanged = (Header.enableState ~= enable)
|
|
Header.enableState = enable
|
|
Header.numGroups = numGroups
|
|
Header.db = db
|
|
|
|
if numGroups then
|
|
if db.raidWideSorting then
|
|
if not Header.groups[1] then
|
|
Header.groups[1] = self:CreateHeader(Header, nil, 'ElvUF_'..name..'Group1', template or Header.template, nil, headerTemplate or Header.headerTemplate)
|
|
end
|
|
else
|
|
while numGroups > #Header.groups do
|
|
local index = tostring(#Header.groups + 1)
|
|
tinsert(Header.groups, self:CreateHeader(Header, index, 'ElvUF_'..name..'Group'..index, template or Header.template, nil, headerTemplate or Header.headerTemplate))
|
|
end
|
|
end
|
|
|
|
if groupsChanged or not skip then
|
|
UF.headerFunctions[group]:AdjustVisibility(Header)
|
|
UF.headerFunctions[group]:Configure_Groups(Header)
|
|
end
|
|
else
|
|
if not UF.headerFunctions[group] then UF.headerFunctions[group] = {} end
|
|
if not UF.headerFunctions[group].Update then
|
|
UF.headerFunctions[group].Update = function()
|
|
local func = UF['Update_'..name..'Frames']
|
|
UF['Update_'..name..'Header'](UF, Header, Header.db)
|
|
|
|
for i = 1, Header:GetNumChildren() do
|
|
Header:UpdateChild(func, select(i, Header:GetChildren()), Header.db)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if stateChanged or not skip then
|
|
UF.headerFunctions[group]:Update(Header)
|
|
end
|
|
|
|
if enable then
|
|
if not Header.isForced then
|
|
RegisterStateDriver(Header, 'visibility', visibility)
|
|
end
|
|
if Header.mover then
|
|
E:EnableMover(Header.mover:GetName())
|
|
end
|
|
else
|
|
UnregisterStateDriver(Header, 'visibility')
|
|
Header:Hide()
|
|
if Header.mover then
|
|
E:DisableMover(Header.mover:GetName())
|
|
end
|
|
end
|
|
end
|
|
|
|
function UF:CreateAndUpdateUF(unit)
|
|
assert(unit, 'No unit provided to create or update.')
|
|
|
|
local frameName = gsub(E:StringTitle(unit), 't(arget)', 'T%1')
|
|
if not self[unit] then
|
|
self[unit] = ElvUF:Spawn(unit, 'ElvUF_'..frameName)
|
|
self.units[unit] = unit
|
|
end
|
|
|
|
self[unit].Update = function()
|
|
UF['Update_'..frameName..'Frame'](self, self[unit], self.db.units[unit])
|
|
end
|
|
|
|
if self[unit]:GetParent() ~= ElvUF_Parent then
|
|
self[unit]:SetParent(ElvUF_Parent)
|
|
end
|
|
|
|
if self.db.units[unit].enable then
|
|
self[unit]:Enable()
|
|
self[unit].Update()
|
|
E:EnableMover(self[unit].mover:GetName())
|
|
else
|
|
self[unit].Update()
|
|
self[unit]:Disable()
|
|
E:DisableMover(self[unit].mover:GetName())
|
|
end
|
|
end
|
|
|
|
function UF:LoadUnits()
|
|
for _, unit in pairs(UF.unitstoload) do
|
|
UF:CreateAndUpdateUF(unit)
|
|
end
|
|
UF.unitstoload = nil
|
|
|
|
for group, groupOptions in pairs(UF.unitgroupstoload) do
|
|
local numGroup, template = unpack(groupOptions)
|
|
UF:CreateAndUpdateUFGroup(group, numGroup, template)
|
|
end
|
|
UF.unitgroupstoload = nil
|
|
|
|
for group, groupOptions in pairs(UF.headerstoload) do
|
|
local groupFilter, template, headerTemplate
|
|
if type(groupOptions) == 'table' then
|
|
groupFilter, template, headerTemplate = unpack(groupOptions)
|
|
end
|
|
|
|
UF:CreateAndUpdateHeaderGroup(group, groupFilter, template, headerTemplate)
|
|
end
|
|
UF.headerstoload = nil
|
|
end
|
|
|
|
function UF:RegisterRaidDebuffIndicator()
|
|
local ORD = E.oUF_RaidDebuffs or _G.oUF_RaidDebuffs
|
|
if ORD then
|
|
ORD:ResetDebuffData()
|
|
|
|
local _, instanceType = GetInstanceInfo()
|
|
if instanceType == 'party' or instanceType == 'raid' then
|
|
local instance = E.global.unitframe.raidDebuffIndicator.instanceFilter
|
|
local instanceSpells = ((E.global.unitframe.aurafilters[instance] and E.global.unitframe.aurafilters[instance].spells) or E.global.unitframe.aurafilters.RaidDebuffs.spells)
|
|
ORD:RegisterDebuffs(instanceSpells)
|
|
else
|
|
local other = E.global.unitframe.raidDebuffIndicator.otherFilter
|
|
local otherSpells = ((E.global.unitframe.aurafilters[other] and E.global.unitframe.aurafilters[other].spells) or E.global.unitframe.aurafilters.CCDebuffs.spells)
|
|
ORD:RegisterDebuffs(otherSpells)
|
|
end
|
|
end
|
|
end
|
|
|
|
function UF:UpdateAllHeaders(smart, skip)
|
|
if E.private.unitframe.disabledBlizzardFrames.party then
|
|
ElvUF:DisableBlizzard('party')
|
|
end
|
|
|
|
for group in pairs(UF.headers) do
|
|
UF:CreateAndUpdateHeaderGroup(group, nil, nil, nil, smart, skip)
|
|
end
|
|
end
|
|
|
|
function UF:DisableBlizzard()
|
|
if (not E.private.unitframe.disabledBlizzardFrames.raid) and (not E.private.unitframe.disabledBlizzardFrames.party) then return; end
|
|
if not CompactRaidFrameManager_SetSetting then
|
|
E:StaticPopup_Show('WARNING_BLIZZARD_ADDONS')
|
|
else
|
|
CompactRaidFrameManager_SetSetting('IsShown', '0')
|
|
_G.UIParent:UnregisterEvent('GROUP_ROSTER_UPDATE')
|
|
_G.CompactRaidFrameManager:UnregisterAllEvents()
|
|
_G.CompactRaidFrameManager:SetParent(hiddenParent)
|
|
end
|
|
end
|
|
|
|
local function insecureOnShow(self)
|
|
self:Hide()
|
|
end
|
|
|
|
local HandleFrame = function(baseName, doNotReparent)
|
|
local frame
|
|
if type(baseName) == 'string' then
|
|
frame = _G[baseName]
|
|
else
|
|
frame = baseName
|
|
end
|
|
|
|
if frame then
|
|
frame:UnregisterAllEvents()
|
|
frame:Hide()
|
|
|
|
if not doNotReparent then
|
|
frame:SetParent(hiddenParent)
|
|
end
|
|
|
|
local health = frame.healthBar or frame.healthbar
|
|
if health then
|
|
health:UnregisterAllEvents()
|
|
end
|
|
|
|
local power = frame.manabar
|
|
if power then
|
|
power:UnregisterAllEvents()
|
|
end
|
|
|
|
local spell = frame.castBar or frame.spellbar
|
|
if spell then
|
|
spell:UnregisterAllEvents()
|
|
end
|
|
|
|
local altpowerbar = frame.powerBarAlt
|
|
if altpowerbar then
|
|
altpowerbar:UnregisterAllEvents()
|
|
end
|
|
|
|
local buffFrame = frame.BuffFrame
|
|
if buffFrame then
|
|
buffFrame:UnregisterAllEvents()
|
|
end
|
|
end
|
|
end
|
|
|
|
function ElvUF:DisableBlizzard(unit)
|
|
if not unit then return end
|
|
|
|
if (unit == 'player') and E.private.unitframe.disabledBlizzardFrames.player then
|
|
local PlayerFrame = _G.PlayerFrame
|
|
HandleFrame(PlayerFrame)
|
|
|
|
-- For the damn vehicle support:
|
|
PlayerFrame:RegisterEvent('PLAYER_ENTERING_WORLD')
|
|
PlayerFrame:RegisterEvent('UNIT_ENTERING_VEHICLE')
|
|
PlayerFrame:RegisterEvent('UNIT_ENTERED_VEHICLE')
|
|
PlayerFrame:RegisterEvent('UNIT_EXITING_VEHICLE')
|
|
PlayerFrame:RegisterEvent('UNIT_EXITED_VEHICLE')
|
|
|
|
-- User placed frames don't animate
|
|
PlayerFrame:SetMovable(true)
|
|
PlayerFrame:SetUserPlaced(true)
|
|
PlayerFrame:SetDontSavePosition(true)
|
|
elseif (unit == 'pet') and E.private.unitframe.disabledBlizzardFrames.player then
|
|
HandleFrame(_G.PetFrame)
|
|
elseif (unit == 'target') and E.private.unitframe.disabledBlizzardFrames.target then
|
|
HandleFrame(_G.TargetFrame)
|
|
HandleFrame(_G.ComboFrame)
|
|
elseif (unit == 'focus') and E.private.unitframe.disabledBlizzardFrames.focus then
|
|
HandleFrame(_G.FocusFrame)
|
|
HandleFrame(_G.TargetofFocusFrame)
|
|
elseif (unit == 'targettarget') and E.private.unitframe.disabledBlizzardFrames.target then
|
|
HandleFrame(_G.TargetFrameToT)
|
|
elseif (unit:match('boss%d?$')) and E.private.unitframe.disabledBlizzardFrames.boss then
|
|
local id = unit:match('boss(%d)')
|
|
if id then
|
|
HandleFrame('Boss' .. id .. 'TargetFrame')
|
|
else
|
|
for i = 1, _G.MAX_BOSS_FRAMES do
|
|
HandleFrame(('Boss%dTargetFrame'):format(i))
|
|
end
|
|
end
|
|
elseif (unit:match('party%d?$')) and E.private.unitframe.disabledBlizzardFrames.party then
|
|
local id = unit:match('party(%d)')
|
|
if id then
|
|
HandleFrame('PartyMemberFrame' .. id)
|
|
else
|
|
for i=1, 4 do
|
|
HandleFrame(('PartyMemberFrame%d'):format(i))
|
|
end
|
|
end
|
|
HandleFrame(_G.PartyMemberBackground)
|
|
elseif (unit:match('arena%d?$')) and E.private.unitframe.disabledBlizzardFrames.arena then
|
|
local id = unit:match('arena(%d)')
|
|
if id then
|
|
HandleFrame('ArenaEnemyFrame' .. id)
|
|
else
|
|
for i = 1, _G.MAX_ARENA_ENEMIES do
|
|
HandleFrame(format('ArenaEnemyFrame%d', i))
|
|
end
|
|
end
|
|
|
|
-- Blizzard_ArenaUI should not be loaded
|
|
Arena_LoadUI = E.noop
|
|
SetCVar('showArenaEnemyFrames', '0', 'SHOW_ARENA_ENEMY_FRAMES_TEXT')
|
|
elseif unit:match('nameplate%d+$') then
|
|
local frame = C_NamePlate_GetNamePlateForUnit(unit)
|
|
if frame and frame.UnitFrame then
|
|
if not frame.UnitFrame.isHooked then
|
|
frame.UnitFrame:HookScript('OnShow', insecureOnShow)
|
|
frame.UnitFrame.isHooked = true
|
|
end
|
|
|
|
HandleFrame(frame.UnitFrame, true)
|
|
end
|
|
end
|
|
end
|
|
|
|
function UF:ADDON_LOADED(_, addon)
|
|
if addon ~= 'Blizzard_ArenaUI' then return; end
|
|
ElvUF:DisableBlizzard('arena')
|
|
self:UnregisterEvent('ADDON_LOADED');
|
|
end
|
|
|
|
function UF:UnitFrameThreatIndicator_Initialize(_, unitFrame)
|
|
unitFrame:UnregisterAllEvents() --Arena Taint Fix
|
|
end
|
|
|
|
function UF:ResetUnitSettings(unit)
|
|
E:CopyTable(self.db.units[unit], P.unitframe.units[unit]);
|
|
|
|
if self.db.units[unit].buffs and self.db.units[unit].buffs.sizeOverride then
|
|
self.db.units[unit].buffs.sizeOverride = P.unitframe.units[unit].buffs.sizeOverride or 0
|
|
end
|
|
|
|
if self.db.units[unit].debuffs and self.db.units[unit].debuffs.sizeOverride then
|
|
self.db.units[unit].debuffs.sizeOverride = P.unitframe.units[unit].debuffs.sizeOverride or 0
|
|
end
|
|
|
|
self:Update_AllFrames()
|
|
end
|
|
|
|
function UF:ToggleForceShowGroupFrames(unitGroup, numGroup)
|
|
for i=1, numGroup do
|
|
if self[unitGroup..i] and not self[unitGroup..i].isForced then
|
|
UF:ForceShow(self[unitGroup..i])
|
|
elseif self[unitGroup..i] then
|
|
UF:UnforceShow(self[unitGroup..i])
|
|
end
|
|
end
|
|
end
|
|
|
|
local Blacklist = {
|
|
arena = {
|
|
enable = true,
|
|
fader = true,
|
|
},
|
|
assist = {
|
|
enable = true,
|
|
fader = true,
|
|
},
|
|
boss = {
|
|
enable = true,
|
|
fader = true,
|
|
},
|
|
focus = {
|
|
enable = true,
|
|
fader = true,
|
|
},
|
|
focustarget = {
|
|
enable = true,
|
|
fader = true,
|
|
},
|
|
party = {
|
|
enable = true,
|
|
visibility = true,
|
|
fader = true,
|
|
},
|
|
pet = {
|
|
enable = true,
|
|
fader = true,
|
|
},
|
|
pettarget = {
|
|
enable = true,
|
|
fader = true,
|
|
},
|
|
player = {
|
|
enable = true,
|
|
aurabars = true,
|
|
fader = true,
|
|
buffs = {
|
|
priority = true,
|
|
minDuration = true,
|
|
maxDuration = true,
|
|
},
|
|
debuffs = {
|
|
priority = true,
|
|
minDuration = true,
|
|
maxDuration = true,
|
|
},
|
|
},
|
|
raid = {
|
|
enable = true,
|
|
fader = true,
|
|
visibility = true,
|
|
},
|
|
raid40 = {
|
|
enable = true,
|
|
fader = true,
|
|
visibility = true,
|
|
},
|
|
raidpet = {
|
|
enable = true,
|
|
fader = true,
|
|
visibility = true,
|
|
},
|
|
tank = {
|
|
fader = true,
|
|
enable = true,
|
|
},
|
|
target = {
|
|
fader = true,
|
|
enable = true,
|
|
},
|
|
targettarget = {
|
|
fader = true,
|
|
enable = true,
|
|
},
|
|
targettargettarget = {
|
|
fader = true,
|
|
enable = true,
|
|
},
|
|
}
|
|
|
|
function UF:MergeUnitSettings(from, to)
|
|
if from == to then
|
|
E:Print(L["You cannot copy settings from the same unit."])
|
|
return
|
|
end
|
|
|
|
E:CopyTable(UF.db.units[to], E:FilterTableFromBlacklist(UF.db.units[from], Blacklist[to]))
|
|
|
|
UF:Update_AllFrames()
|
|
end
|
|
|
|
function UF:UpdateBackdropTextureColor(r, g, b)
|
|
local m = 0.35
|
|
local n = self.isTransparent and (m * 2) or m
|
|
|
|
if self.invertColors then
|
|
local nn = n;n=m;m=nn
|
|
end
|
|
|
|
if self.isTransparent then
|
|
if self.backdrop then
|
|
local _, _, _, a = self.backdrop:GetBackdropColor()
|
|
self.backdrop:SetBackdropColor(r * n, g * n, b * n, a)
|
|
else
|
|
local parent = self:GetParent()
|
|
if parent and parent.template then
|
|
local _, _, _, a = parent:GetBackdropColor()
|
|
parent:SetBackdropColor(r * n, g * n, b * n, a)
|
|
end
|
|
end
|
|
end
|
|
|
|
local bg = self.bg or self.BG
|
|
if bg and bg:IsObjectType('Texture') and not bg.multiplier then
|
|
if self.custom_backdrop then
|
|
bg:SetVertexColor(self.custom_backdrop.r, self.custom_backdrop.g, self.custom_backdrop.b, self.custom_backdrop.a or 1)
|
|
else
|
|
bg:SetVertexColor(r * m, g * m, b * m, 1)
|
|
end
|
|
end
|
|
end
|
|
|
|
function UF:SetStatusBarBackdropPoints(statusBar, statusBarTex, backdropTex, statusBarOrientation, reverseFill)
|
|
backdropTex:ClearAllPoints()
|
|
if statusBarOrientation == 'VERTICAL' then
|
|
if reverseFill then
|
|
backdropTex:Point('BOTTOMRIGHT', statusBar, 'BOTTOMRIGHT')
|
|
backdropTex:Point('TOPRIGHT', statusBarTex, 'BOTTOMRIGHT')
|
|
backdropTex:Point('TOPLEFT', statusBarTex, 'BOTTOMLEFT')
|
|
else
|
|
backdropTex:Point('TOPLEFT', statusBar, 'TOPLEFT')
|
|
backdropTex:Point('BOTTOMLEFT', statusBarTex, 'TOPLEFT')
|
|
backdropTex:Point('BOTTOMRIGHT', statusBarTex, 'TOPRIGHT')
|
|
end
|
|
else
|
|
if reverseFill then
|
|
backdropTex:Point('TOPRIGHT', statusBarTex, 'TOPLEFT')
|
|
backdropTex:Point('BOTTOMRIGHT', statusBarTex, 'BOTTOMLEFT')
|
|
backdropTex:Point('BOTTOMLEFT', statusBar, 'BOTTOMLEFT')
|
|
else
|
|
backdropTex:Point('TOPLEFT', statusBarTex, 'TOPRIGHT')
|
|
backdropTex:Point('BOTTOMLEFT', statusBarTex, 'BOTTOMRIGHT')
|
|
backdropTex:Point('BOTTOMRIGHT', statusBar, 'BOTTOMRIGHT')
|
|
end
|
|
end
|
|
end
|
|
|
|
function UF:ToggleTransparentStatusBar(isTransparent, statusBar, backdropTex, adjustBackdropPoints, invertColors, reverseFill)
|
|
statusBar.isTransparent = isTransparent
|
|
statusBar.invertColors = invertColors
|
|
statusBar.backdropTex = backdropTex
|
|
|
|
if not statusBar.hookedColor then
|
|
hooksecurefunc(statusBar, 'SetStatusBarColor', UF.UpdateBackdropTextureColor)
|
|
statusBar.hookedColor = true
|
|
end
|
|
|
|
local parent = statusBar:GetParent()
|
|
local orientation = statusBar:GetOrientation()
|
|
if isTransparent then
|
|
if statusBar.backdrop then
|
|
statusBar.backdrop:SetTemplate('Transparent', nil, nil, nil, true)
|
|
elseif parent.template then
|
|
parent:SetTemplate('Transparent', nil, nil, nil, true)
|
|
end
|
|
|
|
statusBar:SetStatusBarTexture(0, 0, 0, 0)
|
|
UF:Update_StatusBar(statusBar.bg or statusBar.BG, E.media.blankTex)
|
|
|
|
local barTexture = statusBar:GetStatusBarTexture()
|
|
barTexture:SetInside(nil, 0, 0) --This fixes Center Pixel offset problem
|
|
|
|
UF:SetStatusBarBackdropPoints(statusBar, barTexture, backdropTex, orientation, reverseFill)
|
|
else
|
|
if statusBar.backdrop then
|
|
statusBar.backdrop:SetTemplate(nil, nil, nil, nil, true)
|
|
elseif parent.template then
|
|
parent:SetTemplate(nil, nil, nil, nil, true)
|
|
end
|
|
|
|
local texture = LSM:Fetch('statusbar', self.db.statusbar)
|
|
statusBar:SetStatusBarTexture(texture)
|
|
UF:Update_StatusBar(statusBar.bg or statusBar.BG, texture)
|
|
|
|
local barTexture = statusBar:GetStatusBarTexture()
|
|
barTexture:SetInside(nil, 0, 0)
|
|
|
|
if adjustBackdropPoints then
|
|
UF:SetStatusBarBackdropPoints(statusBar, barTexture, backdropTex, orientation, reverseFill)
|
|
end
|
|
end
|
|
end
|
|
|
|
function UF:TargetSound(unit)
|
|
if UnitExists(unit) and not IsReplacingUnit() then
|
|
if UnitIsEnemy(unit, 'player') then
|
|
PlaySound(SOUNDKIT_IG_CREATURE_AGGRO_SELECT)
|
|
elseif UnitIsFriend('player', unit) then
|
|
PlaySound(SOUNDKIT_IG_CHARACTER_NPC_SELECT)
|
|
else
|
|
PlaySound(SOUNDKIT_IG_CREATURE_NEUTRAL_SELECT)
|
|
end
|
|
else
|
|
PlaySound(SOUNDKIT_INTERFACE_SOUND_LOST_TARGET_UNIT)
|
|
end
|
|
end
|
|
|
|
function UF:PLAYER_FOCUS_CHANGED()
|
|
if E.db.unitframe.targetSound then
|
|
UF:TargetSound('focus')
|
|
end
|
|
end
|
|
|
|
function UF:PLAYER_TARGET_CHANGED()
|
|
if E.db.unitframe.targetSound then
|
|
UF:TargetSound('target')
|
|
end
|
|
end
|
|
|
|
function UF:AfterStyleCallback()
|
|
-- this will wait until after ouf pushes `EnableElement` onto the newly spawned frames
|
|
-- calling an update onto assist or tank in the styleFunc is before the `EnableElement`
|
|
-- that would cause the auras to be shown when a new frame is spawned (tank2, assist2)
|
|
-- even when they are disabled. this makes sure the update happens after so its proper.
|
|
if self.unitframeType == 'tank' or self.unitframeType == 'tanktarget' then
|
|
UF:Update_TankFrames(self, E.db.unitframe.units.tank)
|
|
UF:Update_FontStrings()
|
|
elseif self.unitframeType == 'assist' or self.unitframeType == 'assisttarget' then
|
|
UF:Update_AssistFrames(self, E.db.unitframe.units.assist)
|
|
UF:Update_FontStrings()
|
|
end
|
|
end
|
|
|
|
function UF:Initialize()
|
|
UF.db = E.db.unitframe
|
|
UF.thinBorders = UF.db.thinBorders
|
|
|
|
UF.SPACING = (UF.thinBorders or E.twoPixelsPlease) and 0 or 1
|
|
UF.BORDER = (UF.thinBorders and not E.twoPixelsPlease) and 1 or 2
|
|
|
|
if E.private.unitframe.enable ~= true then return end
|
|
UF.Initialized = true
|
|
|
|
E.ElvUF_Parent = CreateFrame('Frame', 'ElvUF_Parent', E.UIParent, 'SecureHandlerStateTemplate');
|
|
E.ElvUF_Parent:SetFrameStrata('LOW')
|
|
RegisterStateDriver(E.ElvUF_Parent, 'visibility', '[petbattle] hide; show')
|
|
|
|
UF:UpdateColors()
|
|
ElvUF:RegisterInitCallback(UF.AfterStyleCallback)
|
|
ElvUF:RegisterStyle('ElvUF', function(frame, unit)
|
|
UF:Construct_UF(frame, unit)
|
|
end)
|
|
ElvUF:SetActiveStyle('ElvUF')
|
|
UF:LoadUnits()
|
|
|
|
UF:RegisterEvent('PLAYER_ENTERING_WORLD')
|
|
UF:RegisterEvent('ZONE_CHANGED_NEW_AREA')
|
|
UF:RegisterEvent('PLAYER_TARGET_CHANGED')
|
|
UF:RegisterEvent('PLAYER_FOCUS_CHANGED')
|
|
|
|
if E.private.unitframe.disabledBlizzardFrames.party and E.private.unitframe.disabledBlizzardFrames.raid then
|
|
UF:DisableBlizzard()
|
|
end
|
|
|
|
if (not E.private.unitframe.disabledBlizzardFrames.party) and (not E.private.unitframe.disabledBlizzardFrames.raid) then
|
|
E.RaidUtility.Initialize = E.noop
|
|
end
|
|
|
|
if E.private.unitframe.disabledBlizzardFrames.arena then
|
|
UF:SecureHook('UnitFrameThreatIndicator_Initialize')
|
|
|
|
if not IsAddOnLoaded('Blizzard_ArenaUI') then
|
|
UF:RegisterEvent('ADDON_LOADED')
|
|
else
|
|
ElvUF:DisableBlizzard('arena')
|
|
end
|
|
end
|
|
|
|
UF:UpdateRangeCheckSpells()
|
|
|
|
local ORD = E.oUF_RaidDebuffs or _G.oUF_RaidDebuffs
|
|
if not ORD then return end
|
|
ORD.ShowDispellableDebuff = true
|
|
ORD.FilterDispellableDebuff = true
|
|
ORD.MatchBySpellName = false
|
|
end
|
|
|
|
E:RegisterInitialModule(UF:GetName())
|