diff --git a/ElvUI/Core/install.lua b/ElvUI/Core/install.lua
index 9b36938..93cf099 100644
--- a/ElvUI/Core/install.lua
+++ b/ElvUI/Core/install.lua
@@ -558,7 +558,7 @@ function E:SetupLayout(layout, noDataReset)
E.db.unitframe.units.arena.castbar.width = 200
end
- if(layout == "dpsCaster" or layout == "healer" or (layout == "dpsMelee" and E.myclass == "HUNTER")) then
+ if layout == "dpsCaster" or layout == "healer" or (layout == "dpsMelee" and E.myclass == "HUNTER") then
if not E.db.movers then E.db.movers = {} end
E.db.unitframe.units.player.castbar.width = E.PixelMode and 406 or 436
E.db.unitframe.units.player.castbar.height = 28
@@ -664,18 +664,6 @@ local function SetupAuras(style)
UF:Configure_AuraBars(frame)
end
- frame = UF["focus"]
- E:CopyTable(E.db.unitframe.units.focus.buffs, P.unitframe.units.focus.buffs)
- E:CopyTable(E.db.unitframe.units.focus.debuffs, P.unitframe.units.focus.debuffs)
- E:CopyTable(E.db.unitframe.units.focus.aurabar, P.unitframe.units.focus.aurabar)
- E.db.unitframe.units.focus.smartAuraDisplay = P.unitframe.units.focus.smartAuraDisplay
-
- if frame then
- UF:Configure_Auras(frame, "Buffs")
- UF:Configure_Auras(frame, "Debuffs")
- UF:Configure_AuraBars(frame)
- end
-
if not style then
E.db.unitframe.units.player.buffs.enable = true
E.db.unitframe.units.player.buffs.attachTo = "FRAME"
@@ -690,7 +678,7 @@ local function SetupAuras(style)
E:GetModule("UnitFrames"):CreateAndUpdateUF("target")
end
- if(InstallStepComplete) then
+ if InstallStepComplete then
InstallStepComplete.message = L["Auras Set"]
InstallStepComplete:Show()
end
diff --git a/ElvUI/Libraries/Load_Libraries.xml b/ElvUI/Libraries/Load_Libraries.xml
index 4b9c2ae..ea430d1 100644
--- a/ElvUI/Libraries/Load_Libraries.xml
+++ b/ElvUI/Libraries/Load_Libraries.xml
@@ -17,6 +17,7 @@
+
diff --git a/ElvUI/Libraries/oUF/elements/auras.lua b/ElvUI/Libraries/oUF/elements/auras.lua
index e8f834b..9a2db4e 100644
--- a/ElvUI/Libraries/oUF/elements/auras.lua
+++ b/ElvUI/Libraries/oUF/elements/auras.lua
@@ -64,18 +64,25 @@ button.isDebuff - indicates if the button holds a debuff (boolean)
local ns = oUF
local oUF = ns.oUF
-local tinsert = table.insert
-local floor = math.floor
+local tinsert, getn = table.insert, table.getn
+local floor, min, mod = math.floor, math.min, math.mod
local CreateFrame = CreateFrame
local GetTime = GetTime
local UnitAura = UnitAura
+local GetPlayerBuff = GetPlayerBuff
+local GetPlayerBuffTexture = GetPlayerBuffTexture
+local GetPlayerBuffApplications = GetPlayerBuffApplications
+local GetPlayerBuffDispelType = GetPlayerBuffDispelType
+local GetPlayerBuffTimeLeft = GetPlayerBuffTimeLeft
local VISIBLE = 1
local HIDDEN = 0
local function UpdateTooltip(self)
- if self.filter == 'HELPFUL' then
+ if self:GetParent().__owner.unit == "player" then
+ GameTooltip:SetPlayerBuff(self:GetID())
+ elseif self.filter == 'HELPFUL' then
GameTooltip:SetUnitBuff(self:GetParent().__owner.unit, self:GetID(), self.filter)
else
GameTooltip:SetUnitDebuff(self:GetParent().__owner.unit, self:GetID(), self.filter)
@@ -83,7 +90,7 @@ local function UpdateTooltip(self)
end
local function onEnter(self)
- if(not self:IsVisible()) then return end
+ if not self:IsVisible() then return end
GameTooltip:SetOwner(self, 'ANCHOR_BOTTOMRIGHT')
self:UpdateTooltip()
@@ -97,7 +104,7 @@ local function createAuraIcon(element, index)
local button = CreateFrame('Button', '$parentButton' .. index, element)
button:RegisterForClicks('RightButtonUp')
- local cd = CreateFrame('Cooldown', '$parentCooldown', button, 'oUF_CooldownFrameTemplate')
+ local cd = CreateFrame('Frame', '$parentCooldown', button, 'oUF_CooldownFrameTemplate')
cd:SetAllPoints()
local icon = button:CreateTexture(nil, 'BORDER')
@@ -126,117 +133,124 @@ local function createAuraIcon(element, index)
* self - the widget holding the aura buttons
* button - the newly created aura button (Button)
--]]
- if(element.PostCreateIcon) then element:PostCreateIcon(button) end
+ if element.PostCreateIcon then element:PostCreateIcon(button) end
return button
end
local function customFilter(element, unit, button, name)
- if(name) then
- return true
- end
+ if name then return true end
end
local function updateIcon(element, unit, index, offset, filter, isDebuff, visible)
local name, rank, texture, count, dispelType, duration, expiration = UnitAura(unit, index, filter)
+ if unit == "player" then
+ local idx = GetPlayerBuff(index - 1, filter)
+ if idx < 0 then return end
+ index = idx
+ texture = GetPlayerBuffTexture(idx)
+ count = GetPlayerBuffApplications(idx)
+ dispelType = GetPlayerBuffDispelType(idx)
+ duration = GetPlayerBuffTimeLeft(idx)
+ end
+
if element.forceShow then
name, rank, texture = GetSpellInfo(26993)
count, dispelType, duration, expiration = 5, 'Magic', 0, 60
end
- if(name) then
- local position = visible + offset + 1
- local button = element[position]
- if(not button) then
- --[[ Override: Auras:CreateIcon(position)
- Used to create the aura button at a given position.
+ if not name then return end
- * self - the widget holding the aura buttons
- * position - the position at which the aura button is to be created (number)
+ local position = visible + offset + 1
+ local button = element[position]
+ if not button then
+ --[[ Override: Auras:CreateIcon(position)
+ Used to create the aura button at a given position.
- ## Returns
-
- * button - the button used to represent the aura (Button)
- --]]
- button = (element.CreateIcon or createAuraIcon) (element, position)
-
- tinsert(element, button)
- element.createdIcons = element.createdIcons + 1
- end
-
- button.filter = filter
- button.isDebuff = isDebuff
-
- --[[ Override: Auras:CustomFilter(unit, button, ...)
- Defines a custom filter that controls if the aura button should be shown.
-
- * self - the widget holding the aura buttons
- * unit - the unit on which the aura is cast (string)
- * button - the button displaying the aura (Button)
- * ... - the return values from [UnitAura](http://wowprogramming.com/docs/api/UnitAura)
+ * self - the widget holding the aura buttons
+ * position - the position at which the aura button is to be created (number)
## Returns
- * show - indicates whether the aura button should be shown (boolean)
+ * button - the button used to represent the aura (Button)
--]]
- local show = true
- if not element.forceShow then
- show = (element.CustomFilter or customFilter) (element, unit, button, name, rank, texture, count, dispelType, duration, expiration)
- end
+ button = (element.CreateIcon or createAuraIcon) (element, position)
- if(show) then
- -- We might want to consider delaying the creation of an actual cooldown
- -- object to this point, but I think that will just make things needlessly
- -- complicated.
- if(button.cd and not element.disableCooldown) then
- if(duration and duration > 0) then
- button.cd:SetCooldown(GetTime() - (duration - expiration), duration)
- button.cd:Show()
- else
- button.cd:Hide()
- end
- end
+ tinsert(element, button)
+ element.createdIcons = element.createdIcons + 1
+ end
- if(button.overlay) then
- if((isDebuff and element.showDebuffType) or (not isDebuff and element.showBuffType) or element.showType) then
- local color = DebuffTypeColor[dispelType] or DebuffTypeColor.none
+ button.filter = filter
+ button.isDebuff = isDebuff
- button.overlay:SetVertexColor(color.r, color.g, color.b)
- button.overlay:Show()
- else
- button.overlay:Hide()
- end
- end
+ --[[ Override: Auras:CustomFilter(unit, button, ...)
+ Defines a custom filter that controls if the aura button should be shown.
- if(button.icon) then button.icon:SetTexture(texture) end
- if(button.count) then button.count:SetText(count > 1 and count) end
+ * self - the widget holding the aura buttons
+ * unit - the unit on which the aura is cast (string)
+ * button - the button displaying the aura (Button)
+ * ... - the return values from [UnitAura](http://wowprogramming.com/docs/api/UnitAura)
- local size = element.size or 16
- button:SetSize(size, size)
+ ## Returns
- button:EnableMouse(not element.disableMouse)
- button:SetID(index)
- button:Show()
+ * show - indicates whether the aura button should be shown (boolean)
+ --]]
+ local show = true
+ if not element.forceShow then
+ show = (element.CustomFilter or customFilter) (element, unit, button, name, rank, texture, count, dispelType, duration, expiration)
+ end
- --[[ Callback: Auras:PostUpdateIcon(unit, button, index, position)
- Called after the aura button has been updated.
+ if not show then return HIDDEN end
- * self - the widget holding the aura buttons
- * unit - the unit on which the aura is cast (string)
- * button - the updated aura button (Button)
- * index - the index of the aura (number)
- * position - the actual position of the aura button (number)
- --]]
- if(element.PostUpdateIcon) then
- element:PostUpdateIcon(unit, button, index, position)
- end
-
- return VISIBLE
+ -- We might want to consider delaying the creation of an actual cooldown
+ -- object to this point, but I think that will just make things needlessly
+ -- complicated.
+ if button.cd and not element.disableCooldown then
+ if duration and duration > 0 then
+ -- button.cd:SetCooldown(GetTime() - (duration - expiration), duration)
+ button.cd:Show()
else
- return HIDDEN
+ button.cd:Hide()
end
end
+
+ if button.overlay then
+ if (isDebuff and element.showDebuffType) or (not isDebuff and element.showBuffType) or element.showType then
+ local color = DebuffTypeColor[dispelType] or DebuffTypeColor.none
+
+ button.overlay:SetVertexColor(color.r, color.g, color.b)
+ button.overlay:Show()
+ else
+ button.overlay:Hide()
+ end
+ end
+
+ if button.icon then button.icon:SetTexture(texture) end
+ if button.count then button.count:SetText(count > 1 and count) end
+
+ local size = element.size or 16
+ button:SetWidth(size)
+ button:SetHeight(size)
+
+ button:EnableMouse(not element.disableMouse)
+ button:SetID(index)
+ button:Show()
+
+ --[[ Callback: Auras:PostUpdateIcon(unit, button, index, position)
+ Called after the aura button has been updated.
+
+ * self - the widget holding the aura buttons
+ * unit - the unit on which the aura is cast (string)
+ * button - the updated aura button (Button)
+ * index - the index of the aura (number)
+ * position - the actual position of the aura button (number)
+ --]]
+ if element.PostUpdateIcon then
+ element:PostUpdateIcon(unit, button, index, position)
+ end
+
+ return VISIBLE
end
local function SetPosition(element, from, to)
@@ -252,7 +266,7 @@ local function SetPosition(element, from, to)
-- Bail out if the to range is out of scope.
if(not button) then break end
- local col = (i - 1) % cols
+ local col = mod((i - 1), cols)
local row = floor((i - 1) / cols)
button:ClearAllPoints()
@@ -261,25 +275,25 @@ local function SetPosition(element, from, to)
end
local function filterIcons(element, unit, filter, limit, isDebuff, offset, dontHide)
- if(not offset) then offset = 0 end
+ if not offset then offset = 0 end
local index = 1
local visible = 0
local hidden = 0
- while(visible < limit) do
+ while visible < limit do
local result = updateIcon(element, unit, index, offset, filter, isDebuff, visible)
- if(not result) then
+ if not result then
break
- elseif(result == VISIBLE) then
+ elseif result == VISIBLE then
visible = visible + 1
- elseif(result == HIDDEN) then
+ elseif result == HIDDEN then
hidden = hidden + 1
end
index = index + 1
end
- if(not dontHide) then
- for i = visible + offset + 1, #element do
+ if not dontHide then
+ for i = visible + offset + 1, getn(element) do
element[i]:Hide()
end
end
@@ -288,42 +302,42 @@ local function filterIcons(element, unit, filter, limit, isDebuff, offset, dontH
end
local function UpdateAuras(self, event, unit)
- if(self.unit ~= unit) then return end
+ if self.unit ~= unit then return end
local auras = self.Auras
- if(auras) then
+ if auras then
--[[ Callback: Auras:PreUpdate(unit)
Called before the element has been updated.
* self - the widget holding the aura buttons
* unit - the unit for which the update has been triggered (string)
--]]
- if(auras.PreUpdate) then auras:PreUpdate(unit) end
+ if auras.PreUpdate then auras:PreUpdate(unit) end
local numBuffs = auras.numBuffs or 32
local numDebuffs = auras.numDebuffs or 40
local max = auras.numTotal or numBuffs + numDebuffs
- local visibleBuffs, hiddenBuffs = filterIcons(auras, unit, auras.buffFilter or auras.filter or 'HELPFUL', math.min(numBuffs, max), nil, 0, true)
+ local visibleBuffs, hiddenBuffs = filterIcons(auras, unit, auras.buffFilter or auras.filter or 'HELPFUL', min(numBuffs, max), nil, 0, true)
local hasGap
- if(visibleBuffs ~= 0 and auras.gap) then
+ if visibleBuffs ~= 0 and auras.gap then
hasGap = true
visibleBuffs = visibleBuffs + 1
local button = auras[visibleBuffs]
- if(not button) then
+ if not button then
button = (auras.CreateIcon or createAuraIcon) (auras, visibleBuffs)
tinsert(auras, button)
auras.createdIcons = auras.createdIcons + 1
end
-- Prevent the button from displaying anything.
- if(button.cd) then button.cd:Hide() end
- if(button.icon) then button.icon:SetTexture() end
- if(button.overlay) then button.overlay:Hide() end
- if(button.stealable) then button.stealable:Hide() end
- if(button.count) then button.count:SetText() end
+ if button.cd then button.cd:Hide() end
+ if button.icon then button.icon:SetTexture() end
+ if button.overlay then button.overlay:Hide() end
+ if button.stealable then button.stealable:Hide() end
+ if button.count then button.count:SetText() end
button:EnableMouse(false)
button:Show()
@@ -341,10 +355,10 @@ local function UpdateAuras(self, event, unit)
end
end
- local visibleDebuffs, hiddenDebuffs = filterIcons(auras, unit, auras.debuffFilter or auras.filter or 'HARMFUL', math.min(numDebuffs, max - visibleBuffs), true, visibleBuffs)
+ local visibleDebuffs, hiddenDebuffs = filterIcons(auras, unit, auras.debuffFilter or auras.filter or 'HARMFUL', min(numDebuffs, max - visibleBuffs), true, visibleBuffs)
auras.visibleDebuffs = visibleDebuffs
- if(hasGap and visibleDebuffs == 0) then
+ if hasGap and visibleDebuffs == 0 then
auras[visibleBuffs]:Hide()
visibleBuffs = visibleBuffs - 1
end
@@ -364,11 +378,11 @@ local function UpdateAuras(self, event, unit)
* from - the offset of the first aura button to be (re-)anchored (number)
* to - the offset of the last aura button to be (re-)anchored (number)
--]]
- if(auras.PreSetPosition) then
+ if auras.PreSetPosition then
fromRange, toRange = auras:PreSetPosition(max)
end
- if(fromRange or auras.createdIcons > auras.anchoredIcons) then
+ if fromRange or auras.createdIcons > auras.anchoredIcons then
--[[ Override: Auras:SetPosition(from, to)
Used to (re-)anchor the aura buttons.
Called when new aura buttons have been created or if :PreSetPosition is defined.
@@ -387,72 +401,72 @@ local function UpdateAuras(self, event, unit)
* self - the widget holding the aura buttons
* unit - the unit for which the update has been triggered (string)
--]]
- if(auras.PostUpdate) then auras:PostUpdate(unit) end
+ if auras.PostUpdate then auras:PostUpdate(unit) end
end
local buffs = self.Buffs
- if(buffs) then
- if(buffs.PreUpdate) then buffs:PreUpdate(unit) end
+ if buffs then
+ if buffs.PreUpdate then buffs:PreUpdate(unit) end
local numBuffs = buffs.num or 32
local visibleBuffs, hiddenBuffs = filterIcons(buffs, unit, buffs.filter or 'HELPFUL', numBuffs)
buffs.visibleBuffs = visibleBuffs
local fromRange, toRange
- if(buffs.PreSetPosition) then
+ if buffs.PreSetPosition then
fromRange, toRange = buffs:PreSetPosition(numBuffs)
end
- if(fromRange or buffs.createdIcons > buffs.anchoredIcons) then
+ if fromRange or buffs.createdIcons > buffs.anchoredIcons then
(buffs.SetPosition or SetPosition) (buffs, fromRange or buffs.anchoredIcons + 1, toRange or buffs.createdIcons)
buffs.anchoredIcons = buffs.createdIcons
end
- if(buffs.PostUpdate) then buffs:PostUpdate(unit) end
+ if buffs.PostUpdate then buffs:PostUpdate(unit) end
end
local debuffs = self.Debuffs
- if(debuffs) then
- if(debuffs.PreUpdate) then debuffs:PreUpdate(unit) end
+ if debuffs then
+ if debuffs.PreUpdate then debuffs:PreUpdate(unit) end
local numDebuffs = debuffs.num or 40
local visibleDebuffs, hiddenDebuffs = filterIcons(debuffs, unit, debuffs.filter or 'HARMFUL', numDebuffs, true)
debuffs.visibleDebuffs = visibleDebuffs
local fromRange, toRange
- if(debuffs.PreSetPosition) then
+ if debuffs.PreSetPosition then
fromRange, toRange = debuffs:PreSetPosition(numDebuffs)
end
- if(fromRange or debuffs.createdIcons > debuffs.anchoredIcons) then
+ if fromRange or debuffs.createdIcons > debuffs.anchoredIcons then
(debuffs.SetPosition or SetPosition) (debuffs, fromRange or debuffs.anchoredIcons + 1, toRange or debuffs.createdIcons)
debuffs.anchoredIcons = debuffs.createdIcons
end
- if(debuffs.PostUpdate) then debuffs:PostUpdate(unit) end
+ if debuffs.PostUpdate then debuffs:PostUpdate(unit) end
end
end
local function Update(self, event, unit)
- if(self.unit ~= unit) then return end
+ if self.unit ~= unit then return end
UpdateAuras(self, event, unit)
-- Assume no event means someone wants to re-anchor things. This is usually
-- done by UpdateAllElements and :ForceUpdate.
- if(event == 'ForceUpdate' or not event) then
+ if event == 'ForceUpdate' or not event then
local buffs = self.Buffs
- if(buffs) then
+ if buffs then
(buffs.SetPosition or SetPosition) (buffs, 1, buffs.createdIcons)
end
local debuffs = self.Debuffs
- if(debuffs) then
+ if debuffs then
(debuffs.SetPosition or SetPosition) (debuffs, 1, debuffs.createdIcons)
end
local auras = self.Auras
- if(auras) then
+ if auras then
(auras.SetPosition or SetPosition) (auras, 1, auras.createdIcons)
end
end
@@ -463,11 +477,11 @@ local function ForceUpdate(element)
end
local function Enable(self)
- if(self.Buffs or self.Debuffs or self.Auras) then
- self:RegisterEvent('UNIT_AURA', UpdateAuras)
+ if self.Buffs or self.Debuffs or self.Auras then
+ self:RegisterEvent('PLAYER_AURAS_CHANGED', UpdateAuras)
local buffs = self.Buffs
- if(buffs) then
+ if buffs then
buffs.__owner = self
buffs.ForceUpdate = ForceUpdate
@@ -478,7 +492,7 @@ local function Enable(self)
end
local debuffs = self.Debuffs
- if(debuffs) then
+ if debuffs then
debuffs.__owner = self
debuffs.ForceUpdate = ForceUpdate
@@ -489,7 +503,7 @@ local function Enable(self)
end
local auras = self.Auras
- if(auras) then
+ if auras then
auras.__owner = self
auras.ForceUpdate = ForceUpdate
@@ -504,13 +518,13 @@ local function Enable(self)
end
local function Disable(self)
- if(self.Buffs or self.Debuffs or self.Auras) then
- self:UnregisterEvent('UNIT_AURA', UpdateAuras)
+ if self.Buffs or self.Debuffs or self.Auras then
+ self:UnregisterEvent('PLAYER_AURAS_CHANGED', UpdateAuras)
- if(self.Buffs) then self.Buffs:Hide() end
- if(self.Debuffs) then self.Debuffs:Hide() end
- if(self.Auras) then self.Auras:Hide() end
+ if self.Buffs then self.Buffs:Hide() end
+ if self.Debuffs then self.Debuffs:Hide() end
+ if self.Auras then self.Auras:Hide() end
end
end
-oUF:AddElement('Auras', Update, Enable, Disable)
\ No newline at end of file
+oUF:AddElement('Auras', Update, Enable, Disable)
diff --git a/ElvUI/Libraries/oUF/elements/elements.xml b/ElvUI/Libraries/oUF/elements/elements.xml
index 91f969b..d3455b9 100644
--- a/ElvUI/Libraries/oUF/elements/elements.xml
+++ b/ElvUI/Libraries/oUF/elements/elements.xml
@@ -1,6 +1,6 @@
-
+
diff --git a/ElvUI/Libraries/oUF_Plugins/oUF_AuraBars.lua b/ElvUI/Libraries/oUF_Plugins/oUF_AuraBars.lua
new file mode 100644
index 0000000..7dec83e
--- /dev/null
+++ b/ElvUI/Libraries/oUF_Plugins/oUF_AuraBars.lua
@@ -0,0 +1,392 @@
+local ns = oUF
+local oUF = ns.oUF
+assert(oUF, "oUF_AuraBars was unable to locate oUF install.")
+
+local format = string.format
+local floor, huge, min, mod = math.floor, math.huge, math.min, math.mod
+local tsort, getn = table.sort, table.getn
+local tremove = table.remove
+local random = math.random
+
+local CreateFrame = CreateFrame
+local UnitAura = UnitAura
+local UnitIsFriend = UnitIsFriend
+
+local DAY, HOUR, MINUTE = 86400, 3600, 60
+local function FormatTime(s)
+ if s < MINUTE then
+ return format("%.1fs", s)
+ elseif s < HOUR then
+ return format("%dm %ds", mod(s/60,60), mod(s,60))
+ elseif s < DAY then
+ return format("%dh %dm", s/(60*60), mod(s/60,60))
+ else
+ return format("%dd %dh", s/DAY, (s / HOUR) - (floor(s/DAY) * 24))
+ end
+end
+
+local function UpdateTooltip(self)
+ GameTooltip:SetUnitAura(self.__unit, self:GetParent().aura.name, self:GetParent().aura.rank, self:GetParent().aura.filter)
+end
+
+local function OnEnter(self)
+ if(not self:IsVisible()) then return end
+ GameTooltip:SetOwner(self, "ANCHOR_BOTTOMRIGHT")
+ self:UpdateTooltip()
+end
+
+local function OnLeave(self)
+ GameTooltip:Hide()
+end
+
+local function SetAnchors(self)
+ local bars = self.bars
+
+ for index = 1, getn(bars) do
+ local frame = bars[index]
+ local anchor = frame.anchor
+ frame:Height(self.auraBarHeight or 20)
+ frame.statusBar.iconHolder:Size(frame:GetHeight())
+ frame:Width((self.auraBarWidth or self:GetWidth()) - (frame:GetHeight() + (self.gap or 0)))
+ frame:ClearAllPoints()
+ if self.down == true then
+ if self == anchor then -- Root frame so indent for icon
+ frame:SetPoint("TOPLEFT", anchor, "TOPLEFT", (frame:GetHeight() + (self.gap or 0) ), -1)
+ else
+ frame:SetPoint("TOPLEFT", anchor, "BOTTOMLEFT", 0, (-self.spacing or 0))
+ end
+ else
+ if self == anchor then -- Root frame so indent for icon
+ frame:SetPoint("BOTTOMLEFT", anchor, "BOTTOMLEFT", (frame:GetHeight() + (self.gap or 0)), 1)
+ else
+ frame:SetPoint("BOTTOMLEFT", anchor, "TOPLEFT", 0, (self.spacing or 0))
+ end
+ end
+ end
+end
+
+local function CreateAuraBar(oUF, anchor)
+ local auraBarParent = oUF.AuraBars
+
+ local frame = CreateFrame("Frame", nil, auraBarParent)
+ frame:SetHeight(auraBarParent.auraBarHeight or 20)
+ frame:SetWidth((auraBarParent.auraBarWidth or auraBarParent:GetWidth()) - (frame:GetHeight() + (auraBarParent.gap or 0)))
+ frame.anchor = anchor
+
+ -- the main bar
+ local statusBar = CreateFrame("StatusBar", nil, frame)
+ statusBar:SetStatusBarTexture(auraBarParent.auraBarTexture or [[Interface\TargetingFrame\UI-StatusBar]])
+ statusBar:SetAlpha(auraBarParent.fgalpha or 1)
+ statusBar:SetAllPoints(frame)
+
+ frame.statusBar = statusBar
+
+ if auraBarParent.down == true then
+ if auraBarParent == anchor then -- Root frame so indent for icon
+ frame:SetPoint("TOPLEFT", anchor, "TOPLEFT", (frame:GetHeight() + (auraBarParent.gap or 0) ), -1)
+ else
+ frame:SetPoint("TOPLEFT", anchor, "BOTTOMLEFT", 0, (-auraBarParent.spacing or 0))
+ end
+ else
+ if auraBarParent == anchor then -- Root frame so indent for icon
+ frame:SetPoint("BOTTOMLEFT", anchor, "BOTTOMLEFT", (frame:GetHeight() + (auraBarParent.gap or 0)), 1)
+ else
+ frame:SetPoint("BOTTOMLEFT", anchor, "TOPLEFT", 0, (auraBarParent.spacing or 0))
+ end
+ end
+
+ local spark = statusBar:CreateTexture(nil, "OVERLAY", nil)
+ spark:SetTexture([[Interface\CastingBar\UI-CastingBar-Spark]])
+ spark:SetWidth(12)
+ spark:SetBlendMode("ADD")
+ spark:SetPoint("CENTER", statusBar:GetStatusBarTexture(), "RIGHT")
+ statusBar.spark = spark
+
+ statusBar.iconHolder = CreateFrame("Button", nil, statusBar)
+ statusBar.iconHolder:SetHeight(frame:GetHeight())
+ statusBar.iconHolder:SetWidth(frame:GetHeight())
+ statusBar.iconHolder:SetPoint("BOTTOMRIGHT", frame, "BOTTOMLEFT", -auraBarParent.gap, 0)
+ statusBar.iconHolder.__unit = oUF.unit
+ statusBar.iconHolder:SetScript("OnEnter", OnEnter)
+ statusBar.iconHolder:SetScript("OnLeave", OnLeave)
+ statusBar.iconHolder.UpdateTooltip = UpdateTooltip
+
+ statusBar.icon = statusBar.iconHolder:CreateTexture(nil, "BACKGROUND")
+ statusBar.icon:SetTexCoord(.07, .93, .07, .93)
+ statusBar.icon:SetAllPoints()
+
+ statusBar.spelltime = statusBar:CreateFontString(nil, "ARTWORK")
+ if auraBarParent.spellTimeObject then
+ statusBar.spelltime:SetFontObject(auraBarParent.spellTimeObject)
+ else
+ statusBar.spelltime:SetFont(auraBarParent.spellTimeFont or [[Fonts\FRIZQT__.TTF]], auraBarParent.spellTimeSize or 10)
+ end
+ statusBar.spelltime:SetTextColor(1, 1, 1)
+ statusBar.spelltime:SetJustifyH("RIGHT")
+ statusBar.spelltime:SetJustifyV("CENTER")
+ statusBar.spelltime:SetPoint("RIGHT", 0, 0)
+
+ statusBar.spellname = statusBar:CreateFontString(nil, "ARTWORK")
+ if auraBarParent.spellNameObject then
+ statusBar.spellname:SetFontObject(auraBarParent.spellNameObject)
+ else
+ statusBar.spellname:SetFont(auraBarParent.spellNameFont or [[Fonts\FRIZQT__.TTF]], auraBarParent.spellNameSize or 10)
+ end
+ statusBar.spellname:SetTextColor(1, 1, 1)
+ statusBar.spellname:SetJustifyH("LEFT")
+ statusBar.spellname:SetJustifyV("CENTER")
+ statusBar.spellname:SetPoint("LEFT", 0, 0)
+ statusBar.spellname:SetPoint("RIGHT", statusBar.spelltime, "LEFT")
+
+ if auraBarParent.PostCreateBar then
+ auraBarParent.PostCreateBar(frame)
+ end
+
+ return frame
+end
+
+local function UpdateBars(auraBars)
+ local bars = auraBars.bars
+ local timenow = GetTime()
+
+ for index = 1, getn(bars) do
+ local frame = bars[index]
+ local bar = frame.statusBar
+ if not frame:IsVisible() then
+ break
+ end
+ if bar.aura.noTime then
+ bar.spelltime:SetText()
+ bar.spark:Hide()
+ else
+ local timeleft = bar.aura.expirationTime - timenow
+ bar:SetValue(timeleft)
+ bar.spelltime:SetText(FormatTime(timeleft))
+ if auraBars.spark == true then
+ if (auraBars.scaleTime and ((auraBars.scaleTime <= 0) or (auraBars.scaleTime > 0 and timeleft < auraBars.scaleTime))) then
+ bar.spark:Show()
+ else
+ bar.spark:Hide()
+ end
+ end
+ end
+ end
+end
+
+local function DefaultFilter(self, unit, name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable, shouldConsolidate)
+ if unitCaster == "player" and not shouldConsolidate then
+ return true
+ end
+end
+
+local sort = function(a, b)
+ local compa, compb = a.noTime and huge or a.expirationTime, b.noTime and huge or b.expirationTime
+ return compa > compb
+end
+
+local function Update(self, event, unit)
+ if self.unit ~= unit then return end
+ local auraBars = self.AuraBars
+ local helpOrHarm
+ local isFriend = UnitIsFriend("player", unit) == 1 and true or false
+ local both = false
+
+ if auraBars.friendlyAuraType and auraBars.enemyAuraType then
+ if isFriend then
+ helpOrHarm = auraBars.friendlyAuraType
+ else
+ helpOrHarm = auraBars.enemyAuraType
+ end
+ else
+ helpOrHarm = isFriend and "HELPFUL" or "HARMFUL"
+ end
+
+ if helpOrHarm == "BOTH" then
+ both = true
+ helpOrHarm = "HELPFUL"
+ end
+
+ -- Create a table of auras to display
+ local auras = {}
+ local lastAuraIndex = 0
+ local counter = 0
+ if auraBars.forceShow then
+ for index = 1, auraBars.maxBars do
+ local spellID = 47540
+ local name, rank, icon = GetSpellInfo(spellID)
+ local count, debuffType, duration, expirationTime, unitCaster, isStealable, shouldConsolidate = 5, "Magic", 0, 0, "player", nil, nil
+ lastAuraIndex = lastAuraIndex + 1
+ auras[lastAuraIndex] = {}
+ auras[lastAuraIndex].spellID = spellID
+ auras[lastAuraIndex].name = name
+ auras[lastAuraIndex].rank = rank
+ auras[lastAuraIndex].icon = icon
+ auras[lastAuraIndex].count = count
+ auras[lastAuraIndex].debuffType = debuffType
+ auras[lastAuraIndex].duration = duration
+ auras[lastAuraIndex].expirationTime = expirationTime
+ auras[lastAuraIndex].unitCaster = unitCaster
+ auras[lastAuraIndex].isStealable = isStealable
+ auras[lastAuraIndex].noTime = (duration == 0 and expirationTime == 0)
+ auras[lastAuraIndex].filter = helpOrHarm
+ auras[lastAuraIndex].shouldConsolidate = shouldConsolidate
+ end
+ else
+ for index = 1, 40 do
+ local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable, shouldConsolidate, spellID
+
+ if not both then
+ name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable, shouldConsolidate, spellID = UnitAura(unit, index, helpOrHarm)
+
+ if not name then break end
+ else
+ name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable, shouldConsolidate, spellID = UnitAura(unit, index, "HELPFUL")
+
+ if not name then
+ name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable, shouldConsolidate, spellID = UnitAura(unit, index, "HARMFUL")
+
+ if not name then break end
+ end
+ end
+
+ if (auraBars.filter or DefaultFilter)(self, unit, name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable, shouldConsolidate, spellID) then
+ lastAuraIndex = lastAuraIndex + 1
+ auras[lastAuraIndex] = {}
+ auras[lastAuraIndex].spellID = spellID
+ auras[lastAuraIndex].name = name
+ auras[lastAuraIndex].rank = rank
+ auras[lastAuraIndex].icon = icon
+ auras[lastAuraIndex].count = count
+ auras[lastAuraIndex].debuffType = debuffType
+ auras[lastAuraIndex].duration = duration
+ auras[lastAuraIndex].expirationTime = expirationTime
+ auras[lastAuraIndex].unitCaster = unitCaster
+ auras[lastAuraIndex].isStealable = isStealable
+ auras[lastAuraIndex].noTime = (duration == 0 and expirationTime == 0)
+ auras[lastAuraIndex].filter = helpOrHarm
+ auras[lastAuraIndex].shouldConsolidate = shouldConsolidate
+ end
+ end
+ end
+
+ if auraBars.sort and not auraBars.forceShow then
+ tsort(auras, type(auraBars.sort) == "function" and auraBars.sort or sort)
+ end
+
+ for i=1, getn(auras) do
+ if i > auraBars.maxBars then
+ tremove(auras, i)
+ else
+ lastAuraIndex = i
+ end
+ end
+
+ -- Show and configure bars for buffs/debuffs.
+ local bars = auraBars.bars
+ if lastAuraIndex == 0 then
+ self.AuraBars:SetHeight(1)
+ end
+
+ for index = 1 , lastAuraIndex do
+ -- if auraBars:GetWidth() == 0 then break end
+ local aura = auras[index]
+ local frame = bars[index]
+
+ if not frame then
+ frame = CreateAuraBar(self, index == 1 and auraBars or bars[index - 1])
+ bars[index] = frame
+ end
+
+ if index == lastAuraIndex then
+ if self.AuraBars.down then
+ self.AuraBars:SetHeight(self.AuraBars:GetTop() - frame:GetBottom())
+ elseif frame:GetTop() and self.AuraBars:GetBottom() then
+ self.AuraBars:SetHeight(frame:GetTop() - self.AuraBars:GetBottom())
+ else
+ self.AuraBars:SetHeight(20)
+ end
+ end
+
+ local bar = frame.statusBar
+ frame.index = index
+
+ -- Backup the details of the aura onto the bar, so the OnUpdate function can use it
+ bar.aura = aura
+
+ -- Configure
+ if bar.aura.noTime then
+ bar:SetMinMaxValues(0, 1)
+ bar:SetValue(1)
+ else
+ if auraBars.scaleTime and auraBars.scaleTime > 0 then
+ local maxvalue = min(auraBars.scaleTime, bar.aura.duration)
+ bar:SetMinMaxValues(0, auraBars.scaleTime)
+ bar:SetWidth(
+ ( maxvalue / auraBars.scaleTime ) *
+ ( ( auraBars.auraBarWidth or auraBars:GetWidth() ) -
+ ( bar:GetHeight() + (auraBars.gap or 0) ) ) ) -- icon size + gap
+ else
+ bar:SetMinMaxValues(0, bar.aura.duration)
+ end
+ bar:SetValue(bar.aura.expirationTime - GetTime())
+ end
+
+ bar.icon:SetTexture(bar.aura.icon)
+
+ -- bar.spellname:SetText(bar.aura.count > 1 and format("%s [%d]", bar.aura.name, bar.aura.count) or bar.aura.name)
+ bar.spelltime:SetText(not bar.noTime and FormatTime(bar.aura.expirationTime-GetTime()))
+
+ -- Colour bars
+ local r, g, b = .2, .6, 1 -- Colour for buffs
+ if auraBars.buffColor then
+ r, g, b = unpack(auraBars.buffColor)
+ end
+
+ if helpOrHarm == "HARMFUL" then
+ local debuffType = bar.aura.debuffType and bar.aura.debuffType or "none"
+
+ r, g, b = DebuffTypeColor[debuffType].r, DebuffTypeColor[debuffType].g, DebuffTypeColor[debuffType].b
+ if auraBars.debuffColor then
+ r, g, b = unpack(auraBars.debuffColor)
+ else
+ if debuffType == "none" and auraBars.defaultDebuffColor then
+ r, g, b = unpack(auraBars.defaultDebuffColor)
+ end
+ end
+ end
+ bar:SetStatusBarColor(r, g, b)
+ frame:Show()
+ end
+
+ -- Hide unused bars.
+ for index = lastAuraIndex + 1, getn(bars) do
+ bars[index]:Hide()
+ end
+
+ if auraBars.PostUpdate then
+ auraBars:PostUpdate(event, unit)
+ end
+end
+
+local function Enable(self)
+ if self.AuraBars then
+ self:RegisterEvent("PLAYER_AURAS_CHANGED")
+ self:SetScript("OnEvent", function() Update(self, event, "player") end)
+ self.AuraBars:SetHeight(1)
+ self.AuraBars.bars = self.AuraBars.bars or {}
+ self.AuraBars.SetAnchors = SetAnchors
+ self.AuraBars:SetScript("OnUpdate", function() UpdateBars(self.AuraBars) end)
+ self.AuraBars.maxBars = self.AuraBars.maxBars or 40
+ return true
+ end
+end
+
+local function Disable(self)
+ local auraFrame = self.AuraBars
+ if auraFrame then
+ self:UnregisterEvent("PLAYER_AURAS_CHANGED", Update)
+ auraFrame:SetScript("OnUpdate", nil)
+ end
+end
+
+oUF:AddElement("AuraBars", Update, Enable, Disable)
diff --git a/ElvUI/Libraries/oUF_Plugins/oUF_Plugins.xml b/ElvUI/Libraries/oUF_Plugins/oUF_Plugins.xml
new file mode 100644
index 0000000..5793f57
--- /dev/null
+++ b/ElvUI/Libraries/oUF_Plugins/oUF_Plugins.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/ElvUI/Modules/Auras/Auras.lua b/ElvUI/Modules/Auras/Auras.lua
index 6857122..43bf969 100644
--- a/ElvUI/Modules/Auras/Auras.lua
+++ b/ElvUI/Modules/Auras/Auras.lua
@@ -12,13 +12,15 @@ local format = string.format
local wipe, tinsert, tsort, tremove = table.wipe, table.insert, table.sort, table.remove
--WoW API / Variables
local CreateFrame = CreateFrame
-local UnitAura = UnitAura
-local CancelItemTempEnchantment = CancelItemTempEnchantment
-local CancelUnitBuff = CancelUnitBuff
local GetInventoryItemQuality = GetInventoryItemQuality
local GetItemQualityColor = GetItemQualityColor
local GetWeaponEnchantInfo = GetWeaponEnchantInfo
local GetInventoryItemTexture = GetInventoryItemTexture
+local GetPlayerBuff = GetPlayerBuff
+local GetPlayerBuffTexture = GetPlayerBuffTexture
+local GetPlayerBuffApplications = GetPlayerBuffApplications
+local GetPlayerBuffDispelType = GetPlayerBuffDispelType
+local GetPlayerBuffTimeLeft = GetPlayerBuffTimeLeft
local DIRECTION_TO_POINT = {
DOWN_RIGHT = "TOPLEFT",
diff --git a/ElvUI/Modules/UnitFrames/Elements/AuraBars.lua b/ElvUI/Modules/UnitFrames/Elements/AuraBars.lua
new file mode 100644
index 0000000..06c1756
--- /dev/null
+++ b/ElvUI/Modules/UnitFrames/Elements/AuraBars.lua
@@ -0,0 +1,288 @@
+local E, L, V, P, G = unpack(ElvUI) --Inport: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
+local UF = E:GetModule("UnitFrames")
+
+--Cache global variables
+--Lua functions
+local match = string.match
+local strsplit = strsplit
+local tostring = tostring
+local format = format
+local select = select
+local getn = table.getn
+--WoW API / Variables
+local CreateFrame = CreateFrame
+local IsShiftKeyDown = IsShiftKeyDown
+local IsAltKeyDown = IsAltKeyDown
+local IsControlKeyDown = IsControlKeyDown
+local UnitIsFriend = UnitIsFriend
+local UnitIsUnit = UnitIsUnit
+local UnitCanAttack = UnitCanAttack
+local RAID_CLASS_COLORS = RAID_CLASS_COLORS
+
+function UF:Construct_AuraBars()
+ local bar = self.statusBar
+
+ E:SetTemplate(self, "Default", nil, nil, UF.thinBorders, true)
+ local inset = UF.thinBorders and E.mult or nil
+ E:SetInside(bar, self, inset, inset)
+ UF["statusbars"][bar] = true
+ UF:Update_StatusBar(bar)
+
+ UF:Configure_FontString(bar.spelltime)
+ UF:Configure_FontString(bar.spellname)
+ UF:Update_FontString(bar.spelltime)
+ UF:Update_FontString(bar.spellname)
+
+ bar.spellname:ClearAllPoints()
+ E:Point(bar.spellname, "LEFT", bar, "LEFT", 2, 0)
+ E:Point(bar.spellname, "RIGHT", bar.spelltime, "LEFT", -4, 0)
+ -- bar.spellname:SetWordWrap(false)
+
+ E:SetTemplate(bar.iconHolder, "Default", nil, nil, UF.thinBorders, true)
+ E:SetInside(bar.icon, bar.iconHolder, inset, inset)
+ bar.icon:SetDrawLayer("OVERLAY")
+
+ bar.bg = bar:CreateTexture(nil, "BORDER")
+ bar.bg:Hide()
+
+ bar.iconHolder:RegisterForClicks("RightButtonUp")
+ bar.iconHolder:SetScript("OnClick", function(self)
+ if E.db.unitframe.auraBlacklistModifier == "NONE" or not ((E.db.unitframe.auraBlacklistModifier == "SHIFT" and IsShiftKeyDown()) or (E.db.unitframe.auraBlacklistModifier == "ALT" and IsAltKeyDown()) or (E.db.unitframe.auraBlacklistModifier == "CTRL" and IsControlKeyDown())) then return; end
+ local auraName = self:GetParent().aura.name
+
+ if auraName then
+ E:Print(format(L["The spell '%s' has been added to the Blacklist unitframe aura filter."], auraName))
+ E.global["unitframe"]["aurafilters"]["Blacklist"]["spells"][auraName] = {
+ ["enable"] = true,
+ ["priority"] = 0,
+ }
+ UF:Update_AllFrames()
+ end
+ end)
+end
+
+function UF:Construct_AuraBarHeader(frame)
+ local auraBar = CreateFrame("Frame", nil, frame)
+ auraBar:SetFrameLevel(frame.RaisedElementParent:GetFrameLevel() + 10) --Make them appear above any text element
+ auraBar.PostCreateBar = UF.Construct_AuraBars
+ auraBar.gap = (-frame.BORDER + frame.SPACING*3)
+ auraBar.spacing = (-frame.BORDER + frame.SPACING*3)
+ auraBar.spark = true
+ auraBar.filter = UF.AuraBarFilter
+ auraBar.PostUpdate = UF.ColorizeAuraBars
+
+ return auraBar
+end
+
+function UF:Configure_AuraBars(frame)
+ if not frame.VARIABLES_SET then return end
+ local auraBars = frame.AuraBars
+ local db = frame.db
+ if db.aurabar.enable then
+ if not frame:IsElementEnabled("AuraBars") then
+ frame:EnableElement("AuraBars")
+ end
+ auraBars:Show()
+ auraBars.friendlyAuraType = db.aurabar.friendlyAuraType
+ auraBars.enemyAuraType = db.aurabar.enemyAuraType
+ auraBars.scaleTime = db.aurabar.uniformThreshold
+
+ local buffColor = self.db.colors.auraBarBuff
+ local debuffColor = self.db.colors.auraBarDebuff
+ local attachTo = frame
+
+ if E:CheckClassColor(buffColor.r, buffColor.g, buffColor.b) then
+ buffColor = E.myclass == "PRIEST" and E.PriestColors or (CUSTOM_CLASS_COLORS and CUSTOM_CLASS_COLORS[E.myclass] or RAID_CLASS_COLORS[E.myclass])
+ end
+
+ if E:CheckClassColor(debuffColor.r, debuffColor.g, debuffColor.b) then
+ debuffColor = E.myclass == "PRIEST" and E.PriestColors or (CUSTOM_CLASS_COLORS and CUSTOM_CLASS_COLORS[E.myclass] or RAID_CLASS_COLORS[E.myclass])
+ end
+
+ if db.aurabar.attachTo == "BUFFS" then
+ attachTo = frame.Buffs
+ elseif db.aurabar.attachTo == "DEBUFFS" then
+ attachTo = frame.Debuffs
+ elseif db.aurabar.attachTo == "PLAYER_AURABARS" and ElvUF_Player then
+ attachTo = ElvUF_Player.AuraBars
+ end
+
+ local anchorPoint, anchorTo = "BOTTOM", "TOP"
+ if db.aurabar.anchorPoint == "BELOW" then
+ anchorPoint, anchorTo = "TOP", "BOTTOM"
+ end
+
+ local yOffset
+ local spacing = (((db.aurabar.attachTo == "FRAME" and 3) or (db.aurabar.attachTo == "PLAYER_AURABARS" and 4) or 2) * frame.SPACING)
+ local border = (((db.aurabar.attachTo == "FRAME" or db.aurabar.attachTo == "PLAYER_AURABARS") and 2 or 1) * frame.BORDER)
+
+ if db.aurabar.anchorPoint == "BELOW" then
+ yOffset = -spacing + border - (not db.aurabar.yOffset and 0 or db.aurabar.yOffset)
+ else
+ yOffset = spacing - border + (not db.aurabar.yOffset and 0 or db.aurabar.yOffset)
+ end
+
+ local xOffset = (db.aurabar.attachTo == "FRAME" and frame.SPACING or 0)
+ local offsetLeft = xOffset + ((db.aurabar.attachTo == "FRAME" and ((anchorTo == "TOP" and frame.ORIENTATION ~= "LEFT") or (anchorTo == "BOTTOM" and frame.ORIENTATION == "LEFT"))) and frame.POWERBAR_OFFSET or 0)
+ local offsetRight = -xOffset - ((db.aurabar.attachTo == "FRAME" and ((anchorTo == "TOP" and frame.ORIENTATION ~= "RIGHT") or (anchorTo == "BOTTOM" and frame.ORIENTATION == "RIGHT"))) and frame.POWERBAR_OFFSET or 0)
+
+ auraBars.auraBarHeight = db.aurabar.height
+ auraBars:ClearAllPoints()
+ E:Point(auraBars, anchorPoint.."LEFT", attachTo, anchorTo.."LEFT", offsetLeft, yOffset)
+ E:Point(auraBars, anchorPoint.."RIGHT", attachTo, anchorTo.."RIGHT", offsetRight, yOffset)
+ auraBars.buffColor = {buffColor.r, buffColor.g, buffColor.b}
+ if UF.db.colors.auraBarByType then
+ auraBars.debuffColor = nil;
+ auraBars.defaultDebuffColor = {debuffColor.r, debuffColor.g, debuffColor.b}
+ else
+ auraBars.debuffColor = {debuffColor.r, debuffColor.g, debuffColor.b}
+ auraBars.defaultDebuffColor = nil;
+ end
+ auraBars.down = db.aurabar.anchorPoint == "BELOW"
+
+ if db.aurabar.sort == "TIME_REMAINING" then
+ auraBars.sort = true --default function
+ elseif db.aurabar.sort == "TIME_REMAINING_REVERSE" then
+ auraBars.sort = self.SortAuraBarReverse
+ elseif db.aurabar.sort == "TIME_DURATION" then
+ auraBars.sort = self.SortAuraBarDuration
+ elseif db.aurabar.sort == "TIME_DURATION_REVERSE" then
+ auraBars.sort = self.SortAuraBarDurationReverse
+ elseif db.aurabar.sort == "NAME" then
+ auraBars.sort = self.SortAuraBarName
+ else
+ auraBars.sort = nil
+ end
+
+ auraBars.maxBars = db.aurabar.maxBars
+ auraBars.forceShow = frame.forceShowAuras
+ -- auraBars:SetAnchors()
+ else
+ if frame:IsElementEnabled("AuraBars") then
+ frame:DisableElement("AuraBars")
+ auraBars:Hide()
+ end
+ end
+end
+
+local huge = math.huge
+function UF.SortAuraBarReverse(a, b)
+ local compa, compb = a.noTime and huge or a.expirationTime, b.noTime and huge or b.expirationTime
+ return compa < compb
+end
+
+function UF.SortAuraBarDuration(a, b)
+ local compa, compb = a.noTime and huge or a.duration, b.noTime and huge or b.duration
+ return compa > compb
+end
+
+function UF.SortAuraBarDurationReverse(a, b)
+ local compa, compb = a.noTime and huge or a.duration, b.noTime and huge or b.duration
+ return compa < compb
+end
+
+function UF.SortAuraBarName(a, b)
+ return a.name > b.name
+end
+
+function UF:CheckFilter(name, caster, spellID, isFriend, isPlayer, isUnit, allowDuration, noDuration, canDispell, ...)
+ -- local friendCheck, filterName, filter, filterType, spellList, spell
+ -- for i=1, select("#", ...) do
+ -- filterName = select(i, ...)
+ -- friendCheck = (isFriend and match(filterName, "^Friendly:([^,]*)")) or (not isFriend and match(filterName, "^Enemy:([^,]*)")) or nil
+ -- if friendCheck ~= false then
+ -- if friendCheck ~= nil and (G.unitframe.specialFilters[friendCheck] or E.global.unitframe.aurafilters[friendCheck]) then
+ -- filterName = friendCheck -- this is for our filters to handle Friendly and Enemy
+ -- end
+ -- filter = E.global.unitframe.aurafilters[filterName]
+ -- if filter then
+ -- filterType = filter.type
+ -- spellList = filter.spells
+ -- spell = spellList and (spellList[spellID] or spellList[name])
+
+ -- if filterType and (filterType == "Whitelist") and (spell and spell.enable) and allowDuration then
+ -- return true, spell.priority -- this is the only difference from auarbars code
+ -- elseif filterType and (filterType == "Blacklist") and (spell and spell.enable) then
+ -- return false
+ -- end
+ -- elseif filterName == "Personal" and isPlayer and allowDuration then
+ -- return true
+ -- elseif filterName == "nonPersonal" and (not isPlayer) and allowDuration then
+ -- return true
+ -- elseif filterName == "CastByUnit" and (caster and isUnit) and allowDuration then
+ -- return true
+ -- elseif filterName == "notCastByUnit" and (caster and not isUnit) and allowDuration then
+ -- return true
+ -- elseif filterName == "Dispellable" and canDispell and allowDuration then
+ -- return true
+ -- elseif filterName == "blockNoDuration" and noDuration then
+ -- return false
+ -- elseif filterName == "blockNonPersonal" and (not isPlayer) then
+ -- return false
+ -- end
+ -- end
+ -- end
+
+ return true
+end
+
+function UF:AuraBarFilter(unit, name, _, _, _, debuffType, duration, _, unitCaster, isStealable, _, spellID)
+ if not self.db then return; end
+ local db = self.db.aurabar
+
+ if not name then return nil end
+ local filterCheck, isUnit, isFriend, isPlayer, canDispell, allowDuration, noDuration
+
+ if db.priority ~= "" then
+ noDuration = (not duration or duration == 0)
+ isFriend = unit and UnitIsFriend("player", unit) and not UnitCanAttack("player", unit)
+ isPlayer = (unitCaster == "player" or unitCaster == "vehicle")
+ isUnit = unit and unitCaster and UnitIsUnit(unit, unitCaster)
+ canDispell = (self.type == "Buffs" and isStealable) or (self.type == "Debuffs" and debuffType and E:IsDispellableByMe(debuffType))
+ allowDuration = noDuration or (duration and (duration > 0) and (db.maxDuration == 0 or duration <= db.maxDuration) and (db.minDuration == 0 or duration >= db.minDuration))
+ filterCheck = UF:CheckFilter(name, unitCaster, spellID, isFriend, isPlayer, isUnit, allowDuration, noDuration, canDispell, strsplit(",", db.priority))
+ else
+ filterCheck = true -- Allow all auras to be shown when the filter list is empty
+ end
+
+ return filterCheck
+end
+
+function UF:ColorizeAuraBars()
+ local bars = self.bars
+ for index = 1, getn(bars) do
+ local frame = bars[index]
+ if not frame:IsVisible() then break end
+ local spellName = frame.statusBar.aura.name
+ local spellID = frame.statusBar.aura.spellID
+ -- local colors = E.global.unitframe.AuraBarColors[spellID] or E.global.unitframe.AuraBarColors[tostring(spellID)] or E.global.unitframe.AuraBarColors[spellName]
+
+ -- if E.db.unitframe.colors.auraBarTurtle and (E.global.unitframe.aurafilters.TurtleBuffs.spells[spellID] or E.global.unitframe.aurafilters.TurtleBuffs.spells[spellName]) and not colors then
+ -- colors = E.db.unitframe.colors.auraBarTurtleColor
+ -- end
+
+ if colors then
+ frame.statusBar:SetStatusBarColor(colors.r, colors.g, colors.b)
+ frame.statusBar.bg:SetTexture(colors.r * 0.25, colors.g * 0.25, colors.b * 0.25)
+ else
+ local r, g, b = frame.statusBar:GetStatusBarColor()
+ frame.statusBar.bg:SetTexture(r * 0.25, g * 0.25, b * 0.25)
+ end
+
+ if UF.db.colors.transparentAurabars and not frame.statusBar.isTransparent then
+ UF:ToggleTransparentStatusBar(true, frame.statusBar, frame.statusBar.bg, nil, true)
+ elseif(frame.statusBar.isTransparent and not UF.db.colors.transparentAurabars) then
+ UF:ToggleTransparentStatusBar(false, frame.statusBar, frame.statusBar.bg, nil, true)
+ end
+
+ if UF.db.colors.transparentAurabars then
+ local _, _, _, alpha = frame:GetBackdropColor()
+ if colors then
+ frame:SetBackdropColor(colors.r * 0.58, colors.g * 0.58, colors.b * 0.58, alpha)
+ else
+ local r, g, b = frame.statusBar:GetStatusBarColor()
+ frame:SetBackdropColor(r * 0.58, g * 0.58, b * 0.58, alpha)
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/ElvUI/Modules/UnitFrames/Elements/Auras.lua b/ElvUI/Modules/UnitFrames/Elements/Auras.lua
new file mode 100644
index 0000000..94bea4c
--- /dev/null
+++ b/ElvUI/Modules/UnitFrames/Elements/Auras.lua
@@ -0,0 +1,592 @@
+local E, L, V, P, G = unpack(ElvUI); --Import: Engine, Locales, PrivateDB, ProfileDB, GlobalDB
+local UF = E:GetModule("UnitFrames");
+local LSM = LibStub("LibSharedMedia-3.0");
+
+--Cache global variables
+--Lua functions
+local unpack = unpack
+local find, format, lower = string.find, string.format, string.lower
+local strsplit = strsplit
+local tsort, getn = table.sort, table.getn
+local ceil = math.ceil
+--WoW API / Variables
+local GetTime = GetTime
+local CreateFrame = CreateFrame
+local IsShiftKeyDown = IsShiftKeyDown
+local IsAltKeyDown = IsAltKeyDown
+local IsControlKeyDown = IsControlKeyDown
+local UnitCanAttack = UnitCanAttack
+local UnitIsFriend = UnitIsFriend
+local UnitIsUnit = UnitIsUnit
+
+function UF:Construct_Buffs(frame)
+ local buffs = CreateFrame("Frame", frame:GetName().."Buffs", frame)
+ buffs.spacing = E.Spacing
+ buffs.PreSetPosition = (not frame:GetScript("OnUpdate")) and self.SortAuras or nil
+ buffs.PostCreateIcon = self.Construct_AuraIcon
+ buffs.PostUpdateIcon = self.PostUpdateAura
+ buffs.CustomFilter = self.AuraFilter
+ buffs:SetFrameLevel(frame.RaisedElementParent:GetFrameLevel() + 10) --Make them appear above any text element
+ buffs.type = "buffs"
+ --Set initial width to prevent division by zero. This value doesn't matter, as it will be updated later
+ E:Width(buffs, 100)
+
+ return buffs
+end
+
+function UF:Construct_Debuffs(frame)
+ local debuffs = CreateFrame("Frame", frame:GetName().."Debuffs", frame)
+ debuffs.spacing = E.Spacing
+ debuffs.PreSetPosition = (not frame:GetScript("OnUpdate")) and self.SortAuras or nil
+ debuffs.PostCreateIcon = self.Construct_AuraIcon
+ debuffs.PostUpdateIcon = self.PostUpdateAura
+ debuffs.CustomFilter = self.AuraFilter
+ debuffs.type = "debuffs"
+ debuffs:SetFrameLevel(frame.RaisedElementParent:GetFrameLevel() + 10) --Make them appear above any text element
+ --Set initial width to prevent division by zero. This value doesn't matter, as it will be updated later
+ E:Width(debuffs, 100)
+
+ return debuffs
+end
+
+function UF:Construct_AuraIcon(button)
+ local offset = UF.thinBorders and E.mult or E.Border
+
+ button.text = button.cd:CreateFontString(nil, "OVERLAY")
+ E:Point(button.text, "CENTER", 1, 1)
+ button.text:SetJustifyH("CENTER")
+
+ E:SetTemplate(button, "Default", nil, nil, UF.thinBorders, true)
+
+ button.cd.noOCC = true
+ button.cd.noCooldownCount = true
+ -- button.cd:SetReverse(true)
+ -- button.cd:SetDrawEdge(true)
+ E:SetInside(button.cd, button, offset, offset)
+
+ E:SetInside(button.icon, button, offset, offset)
+ button.icon:SetTexCoord(unpack(E.TexCoords))
+ button.icon:SetDrawLayer("ARTWORK")
+
+ button.count:ClearAllPoints()
+ E:Point(button.count, "BOTTOMRIGHT", 1, 1)
+ button.count:SetJustifyH("RIGHT")
+
+ button.overlay:SetTexture(nil)
+ -- button.stealable:SetTexture(nil)
+
+ button:RegisterForClicks("RightButtonUp")
+ button:SetScript("OnClick", function(self)
+ if E.db.unitframe.auraBlacklistModifier == "NONE"
+ or not ((E.db.unitframe.auraBlacklistModifier == "SHIFT" and IsShiftKeyDown())
+ or (E.db.unitframe.auraBlacklistModifier == "ALT" and IsAltKeyDown())
+ or (E.db.unitframe.auraBlacklistModifier == "CTRL" and IsControlKeyDown())) then return end
+
+ local auraName = self.name
+
+ if auraName then
+ E:Print(format(L["The spell '%s' has been added to the Blacklist unitframe aura filter."], auraName))
+ E.global["unitframe"]["aurafilters"]["Blacklist"]["spells"][auraName] = {
+ ["enable"] = true,
+ ["priority"] = 0,
+ }
+
+ UF:Update_AllFrames()
+ end
+ end)
+
+ UF:UpdateAuraIconSettings(button, true)
+end
+
+function UF:EnableDisable_Auras(frame)
+ if frame.db.debuffs.enable or frame.db.buffs.enable then
+ if not frame:IsElementEnabled("Aura") then
+ frame:EnableElement("Aura")
+ end
+ else
+ if frame:IsElementEnabled("Aura") then
+ frame:DisableElement("Aura")
+ end
+ end
+end
+
+local function ReverseUpdate(frame)
+ UF:Configure_Auras(frame, "Debuffs")
+ UF:Configure_Auras(frame, "Buffs")
+end
+
+function UF:Configure_Auras(frame, auraType)
+ if not frame.VARIABLES_SET then return end
+ local db = frame.db
+
+ local auras = frame[auraType]
+ auraType = lower(auraType)
+ local rows = db[auraType].numrows
+
+ local totalWidth = frame.UNIT_WIDTH - frame.SPACING*2
+ if frame.USE_POWERBAR_OFFSET then
+ local powerOffset = ((frame.ORIENTATION == "MIDDLE" and 2 or 1) * frame.POWERBAR_OFFSET)
+
+ if not (db[auraType].attachTo == "POWER" and frame.ORIENTATION == "MIDDLE") then
+ totalWidth = totalWidth - powerOffset
+ end
+ end
+ E:Width(auras, totalWidth)
+
+ auras.forceShow = frame.forceShowAuras
+ auras.num = db[auraType].perrow * rows
+ auras.size = db[auraType].sizeOverride ~= 0 and db[auraType].sizeOverride or ((((auras:GetWidth() - (auras.spacing*(auras.num/rows - 1))) / auras.num)) * rows)
+
+ if db[auraType].sizeOverride and db[auraType].sizeOverride > 0 then
+ auras:Width(db[auraType].perrow * db[auraType].sizeOverride)
+ end
+
+ local attachTo = self:GetAuraAnchorFrame(frame, db[auraType].attachTo, db.debuffs.attachTo == "BUFFS" and db.buffs.attachTo == "DEBUFFS")
+ --Use frame.SPACING override since it may be different from E.Spacing due to forced thin borders
+ local x, y = E:GetXYOffset(db[auraType].anchorPoint, frame.SPACING)
+
+ if db[auraType].attachTo == "FRAME" then
+ y = 0
+ elseif db[auraType].attachTo == "HEALTH" or db[auraType].attachTo == "POWER" then
+ local newX = E:GetXYOffset(db[auraType].anchorPoint, -frame.BORDER)
+ local _, newY = E:GetXYOffset(db[auraType].anchorPoint, (frame.BORDER + frame.SPACING))
+ x = newX
+ y = newY
+ else
+ x = 0
+ end
+
+ if auraType == "buffs" and frame.Debuffs.attachTo and frame.Debuffs.attachTo == frame.Buffs and db[auraType].attachTo == "DEBUFFS" then
+ --Update Debuffs first, as we would otherwise get conflicting anchor points
+ --This is usually only an issue on profile change
+ ReverseUpdate(frame)
+ return
+ end
+
+ auras:ClearAllPoints()
+ E:Point(auras, E.InversePoints[db[auraType].anchorPoint], attachTo, db[auraType].anchorPoint, x + db[auraType].xOffset, y + db[auraType].yOffset)
+ E:Height(auras, auras.size * rows)
+ auras["growth-y"] = find(db[auraType].anchorPoint, "TOP") and "UP" or "DOWN"
+ auras["growth-x"] = db[auraType].anchorPoint == "LEFT" and "LEFT" or db[auraType].anchorPoint == "RIGHT" and "RIGHT" or (find(db[auraType].anchorPoint, "LEFT") and "RIGHT" or "LEFT")
+ auras.initialAnchor = E.InversePoints[db[auraType].anchorPoint]
+
+ --These are needed for SmartAuraPosition
+ auras.attachTo = attachTo
+ auras.point = E.InversePoints[db[auraType].anchorPoint]
+ auras.anchorPoint = db[auraType].anchorPoint
+ auras.xOffset = x + db[auraType].xOffset
+ auras.yOffset = y + db[auraType].yOffset
+
+ if db[auraType].enable then
+ auras:Show()
+ UF:UpdateAuraIconSettings(auras)
+ else
+ auras:Hide()
+ end
+
+ local position = db.smartAuraPosition
+ if position == "BUFFS_ON_DEBUFFS" then
+ if db.debuffs.attachTo == "BUFFS" then
+ E:Print(format(L["This setting caused a conflicting anchor point, where '%s' would be attached to itself. Please check your anchor points. Setting '%s' to be attached to '%s'."], L["Buffs"], L["Debuffs"], L["Frame"]))
+ db.debuffs.attachTo = "FRAME"
+ frame.Debuffs.attachTo = frame
+ end
+ frame.Buffs.PostUpdate = nil
+ frame.Debuffs.PostUpdate = UF.UpdateBuffsHeaderPosition
+ elseif position == "DEBUFFS_ON_BUFFS" then
+ if db.buffs.attachTo == "DEBUFFS" then
+ E:Print(format(L["This setting caused a conflicting anchor point, where '%s' would be attached to itself. Please check your anchor points. Setting '%s' to be attached to '%s'."], L["Debuffs"], L["Buffs"], L["Frame"]))
+ db.buffs.attachTo = "FRAME"
+ frame.Buffs.attachTo = frame
+ end
+ frame.Buffs.PostUpdate = UF.UpdateDebuffsHeaderPosition
+ frame.Debuffs.PostUpdate = nil
+ elseif position == "FLUID_BUFFS_ON_DEBUFFS" then
+ if db.debuffs.attachTo == "BUFFS" then
+ E:Print(format(L["This setting caused a conflicting anchor point, where '%s' would be attached to itself. Please check your anchor points. Setting '%s' to be attached to '%s'."], L["Buffs"], L["Debuffs"], L["Frame"]))
+ db.debuffs.attachTo = "FRAME"
+ frame.Debuffs.attachTo = frame
+ end
+ frame.Buffs.PostUpdate = UF.UpdateBuffsHeight
+ frame.Debuffs.PostUpdate = UF.UpdateBuffsPositionAndDebuffHeight
+ elseif position == "FLUID_DEBUFFS_ON_BUFFS" then
+ if db.buffs.attachTo == "DEBUFFS" then
+ E:Print(format(L["This setting caused a conflicting anchor point, where '%s' would be attached to itself. Please check your anchor points. Setting '%s' to be attached to '%s'."], L["Debuffs"], L["Buffs"], L["Frame"]))
+ db.buffs.attachTo = "FRAME"
+ frame.Buffs.attachTo = frame
+ end
+ frame.Buffs.PostUpdate = UF.UpdateDebuffsPositionAndBuffHeight
+ frame.Debuffs.PostUpdate = UF.UpdateDebuffsHeight
+ else
+ frame.Buffs.PostUpdate = nil
+ frame.Debuffs.PostUpdate = nil
+ end
+end
+
+local function SortAurasByTime(a, b)
+ if a and b and a:GetParent().db then
+ if a:IsShown() and b:IsShown() then
+ local sortDirection = a:GetParent().db.sortDirection
+ local aTime = a.expiration or -1
+ local bTime = b.expiration or -1
+ if aTime and bTime then
+ if sortDirection == "DESCENDING" then
+ return aTime < bTime
+ else
+ return aTime > bTime
+ end
+ end
+ elseif a:IsShown() then
+ return true
+ end
+ end
+end
+
+local function SortAurasByName(a, b)
+ if a and b and a:GetParent().db then
+ if a:IsShown() and b:IsShown() then
+ local sortDirection = a:GetParent().db.sortDirection
+ local aName = a.spell or ""
+ local bName = b.spell or ""
+ if aName and bName then
+ if sortDirection == "DESCENDING" then
+ return aName < bName
+ else
+ return aName > bName
+ end
+ end
+ elseif a:IsShown() then
+ return true
+ end
+ end
+end
+
+local function SortAurasByDuration(a, b)
+ if a and b and a:GetParent().db then
+ if a:IsShown() and b:IsShown() then
+ local sortDirection = a:GetParent().db.sortDirection
+ local aTime = a.duration or -1
+ local bTime = b.duration or -1
+ if aTime and bTime then
+ if sortDirection == "DESCENDING" then
+ return aTime < bTime
+ else
+ return aTime > bTime
+ end
+ end
+ elseif a:IsShown() then
+ return true
+ end
+ end
+end
+
+local function SortAurasByCaster(a, b)
+ if a and b and a:GetParent().db then
+ if a:IsShown() and b:IsShown() then
+ local sortDirection = a:GetParent().db.sortDirection
+ local aPlayer = a.isPlayer or false
+ local bPlayer = b.isPlayer or false
+ if sortDirection == "DESCENDING" then
+ return (aPlayer and not bPlayer)
+ else
+ return (not aPlayer and bPlayer)
+ end
+ elseif a:IsShown() then
+ return true
+ end
+ end
+end
+
+function UF:SortAuras()
+ if not self.db then return end
+
+ --Sorting by Index is Default
+ if self.db.sortMethod == "TIME_REMAINING" then
+ tsort(self, SortAurasByTime)
+ elseif self.db.sortMethod == "NAME" then
+ tsort(self, SortAurasByName)
+ elseif self.db.sortMethod == "DURATION" then
+ tsort(self, SortAurasByDuration)
+ elseif self.db.sortMethod == "PLAYER" then
+ tsort(self, SortAurasByCaster)
+ end
+
+ --Look into possibly applying filter priorities for auras here.
+
+ return 1, getn(self) --from/to range needed for the :SetPosition call in oUF aura element. Without this aura icon position gets all whacky when not sorted by index
+end
+
+function UF:UpdateAuraIconSettings(auras, noCycle)
+ local frame = auras:GetParent()
+ local type = auras.type
+ if noCycle then
+ frame = auras:GetParent():GetParent()
+ type = auras:GetParent().type
+ end
+ if not frame.db then return end
+
+ local db = frame.db[type]
+ local unitframeFont = LSM:Fetch("font", E.db["unitframe"].font)
+ local unitframeFontOutline = E.db["unitframe"].fontOutline
+ local index = 1
+ auras.db = db
+ if db then
+ if not noCycle then
+ while auras[index] do
+ local button = auras[index]
+ E:FontTemplate(button.text, unitframeFont, db.fontSize, unitframeFontOutline)
+ E:FontTemplate(button.count, unitframeFont, db.countFontSize or db.fontSize, unitframeFontOutline)
+
+ if db.clickThrough and button:IsMouseEnabled() then
+ button:EnableMouse(false)
+ elseif not db.clickThrough and not button:IsMouseEnabled() then
+ button:EnableMouse(true)
+ end
+ index = index + 1
+ end
+ else
+ E:FontTemplate(auras.text, unitframeFont, db.fontSize, unitframeFontOutline)
+ E:FontTemplate(auras.count, unitframeFont, db.countFontSize or db.fontSize, unitframeFontOutline)
+
+ if db.clickThrough and auras:IsMouseEnabled() then
+ auras:EnableMouse(false)
+ elseif not db.clickThrough and not auras:IsMouseEnabled() then
+ auras:EnableMouse(true)
+ end
+ end
+ end
+end
+
+function UF:PostUpdateAura(unit, button)
+ local auras = button:GetParent()
+ local frame = auras:GetParent()
+ local type = auras.type
+ local db = frame.db and frame.db[type]
+
+ if db then
+ if db.clickThrough and button:IsMouseEnabled() then
+ button:EnableMouse(false)
+ elseif not db.clickThrough and not button:IsMouseEnabled() then
+ button:EnableMouse(true)
+ end
+ end
+
+ if button.isDebuff then
+ if not button.isFriend and not button.isPlayer then --[[and (not E.isDebuffWhiteList[name])]]
+ button:SetBackdropBorderColor(0.9, 0.1, 0.1)
+ button.icon:SetDesaturated((unit and not find(unit, "arena%d")) and true or false)
+ else
+ local color = (button.dtype and DebuffTypeColor[button.dtype]) or DebuffTypeColor.none
+ button:SetBackdropBorderColor(color.r * 0.6, color.g * 0.6, color.b * 0.6)
+ button.icon:SetDesaturated(false)
+ end
+ else
+ if button.isStealable and not button.isFriend then
+ button:SetBackdropBorderColor(237/255, 234/255, 142/255)
+ else
+ button:SetBackdropBorderColor(unpack(E["media"].unitframeBorderColor))
+ end
+ end
+
+ local size = button:GetParent().size
+ if size then
+ button:SetSize(size, size)
+ end
+
+ if button.expiration and button.duration and (button.duration ~= 0) then
+ local getTime = GetTime()
+ if not button:GetScript("OnUpdate") then
+ button.expirationTime = button.expiration
+ button.expirationSaved = button.expiration - getTime
+ button.nextupdate = -1
+ button:SetScript("OnUpdate", UF.UpdateAuraTimer)
+ end
+ if (button.expirationTime ~= button.expiration) or (button.expirationSaved ~= (button.expiration - getTime)) then
+ button.expirationTime = button.expiration
+ button.expirationSaved = button.expiration - getTime
+ button.nextupdate = -1
+ end
+ end
+
+ if button.expiration and button.duration and (button.duration == 0 or button.expiration <= 0) then
+ button.expirationTime = nil
+ button.expirationSaved = nil
+ button:SetScript("OnUpdate", nil)
+ if button.text:GetFont() then
+ button.text:SetText("")
+ end
+ end
+end
+
+function UF:UpdateAuraTimer(elapsed)
+ self.expirationSaved = self.expirationSaved - elapsed
+ if self.nextupdate > 0 then
+ self.nextupdate = self.nextupdate - elapsed
+ return
+ end
+
+ if self.expirationSaved <= 0 then
+ self:SetScript("OnUpdate", nil)
+
+ if self.text:GetFont() then
+ self.text:SetText("")
+ end
+
+ return
+ end
+
+ local timervalue, formatid
+ timervalue, formatid, self.nextupdate = E:GetTimeInfo(self.expirationSaved, 4)
+ if self.text:GetFont() then
+ self.text:SetFormattedText(format("%s%s|r", E.TimeColors[formatid], E.TimeFormats[formatid][2]), timervalue)
+ elseif self:GetParent():GetParent().db then
+ self.text:FontTemplate(LSM:Fetch("font", E.db["unitframe"].font), self:GetParent():GetParent().db[self:GetParent().type].fontSize, E.db["unitframe"].fontOutline)
+ self.text:SetFormattedText(format("%s%s|r", E.TimeColors[formatid], E.TimeFormats[formatid][2]), timervalue)
+ end
+end
+
+function UF:AuraFilter(unit, button, name, _, _, _, dispelType, duration, expiration, caster, isStealable, _, spellID)
+ local db = self:GetParent().db
+ if not db or not db[self.type] then return true end
+
+ db = db[self.type]
+
+ if not name then return nil end
+ local filterCheck, isUnit, isFriend, isPlayer, canDispell, allowDuration, noDuration, spellPriority
+
+ isPlayer = (caster == "player" or caster == "vehicle")
+ isFriend = unit and UnitIsFriend("player", unit) and not UnitCanAttack("player", unit)
+
+ button.isPlayer = isPlayer
+ button.isFriend = isFriend
+ button.isStealable = isStealable
+ button.dtype = dispelType
+ button.duration = duration
+ button.expiration = expiration
+ button.name = name
+ button.owner = caster --what uses this?
+ button.spell = name --what uses this? (SortAurasByName?)
+ button.priority = 0
+
+ noDuration = (not duration or duration == 0)
+ allowDuration = noDuration or (duration and (duration > 0) and (db.maxDuration == 0 or duration <= db.maxDuration) and (db.minDuration == 0 or duration >= db.minDuration))
+
+ if db.priority ~= "" then
+ isUnit = unit and caster and UnitIsUnit(unit, caster)
+ canDispell = (self.type == "buffs" and isStealable) or (self.type == "debuffs" and dispelType and E:IsDispellableByMe(dispelType))
+ filterCheck, spellPriority = UF:CheckFilter(name, caster, spellID, isFriend, isPlayer, isUnit, allowDuration, noDuration, canDispell, strsplit(",", db.priority))
+ if spellPriority then button.priority = spellPriority end -- this is the only difference from auarbars code
+ else
+ filterCheck = allowDuration and true -- Allow all auras to be shown when the filter list is empty, while obeying duration sliders
+ end
+
+ return filterCheck
+end
+
+function UF:UpdateBuffsHeaderPosition()
+ local parent = self:GetParent()
+ local buffs = parent.Buffs
+ local debuffs = parent.Debuffs
+ local numDebuffs = self.visibleDebuffs
+
+ if numDebuffs == 0 then
+ buffs:ClearAllPoints()
+ buffs:Point(debuffs.point, debuffs.attachTo, debuffs.anchorPoint, debuffs.xOffset, debuffs.yOffset)
+ else
+ buffs:ClearAllPoints()
+ buffs:Point(buffs.point, buffs.attachTo, buffs.anchorPoint, buffs.xOffset, buffs.yOffset)
+ end
+end
+
+function UF:UpdateDebuffsHeaderPosition()
+ local parent = self:GetParent()
+ local debuffs = parent.Debuffs
+ local buffs = parent.Buffs
+ local numBuffs = self.visibleBuffs
+
+ if numBuffs == 0 then
+ debuffs:ClearAllPoints()
+ debuffs:Point(buffs.point, buffs.attachTo, buffs.anchorPoint, buffs.xOffset, buffs.yOffset)
+ else
+ debuffs:ClearAllPoints()
+ debuffs:Point(debuffs.point, debuffs.attachTo, debuffs.anchorPoint, debuffs.xOffset, debuffs.yOffset)
+ end
+end
+
+function UF:UpdateBuffsPositionAndDebuffHeight()
+ local parent = self:GetParent()
+ local db = parent.db
+ local buffs = parent.Buffs
+ local debuffs = parent.Debuffs
+ local numDebuffs = self.visibleDebuffs
+
+ if numDebuffs == 0 then
+ buffs:ClearAllPoints()
+ buffs:Point(debuffs.point, debuffs.attachTo, debuffs.anchorPoint, debuffs.xOffset, debuffs.yOffset)
+ else
+ buffs:ClearAllPoints()
+ buffs:Point(buffs.point, buffs.attachTo, buffs.anchorPoint, buffs.xOffset, buffs.yOffset)
+ end
+
+ if numDebuffs > 0 then
+ local numRows = ceil(numDebuffs/db.debuffs.perrow)
+ debuffs:Height(debuffs.size * (numRows > db.debuffs.numrows and db.debuffs.numrows or numRows))
+ else
+ debuffs:Height(debuffs.size)
+ end
+end
+
+function UF:UpdateDebuffsPositionAndBuffHeight()
+ local parent = self:GetParent()
+ local db = parent.db
+ local debuffs = parent.Debuffs
+ local buffs = parent.Buffs
+ local numBuffs = self.visibleBuffs
+
+ if numBuffs == 0 then
+ debuffs:ClearAllPoints()
+ debuffs:Point(buffs.point, buffs.attachTo, buffs.anchorPoint, buffs.xOffset, buffs.yOffset)
+ else
+ debuffs:ClearAllPoints()
+ debuffs:Point(debuffs.point, debuffs.attachTo, debuffs.anchorPoint, debuffs.xOffset, debuffs.yOffset)
+ end
+
+ if numBuffs > 0 then
+ local numRows = ceil(numBuffs/db.buffs.perrow)
+ buffs:Height(buffs.size * (numRows > db.buffs.numrows and db.buffs.numrows or numRows))
+ else
+ buffs:Height(buffs.size)
+ end
+end
+
+function UF:UpdateBuffsHeight()
+ local parent = self:GetParent()
+ local db = parent.db
+ local buffs = parent.Buffs
+ local numBuffs = self.visibleBuffs
+
+ if numBuffs > 0 then
+ local numRows = ceil(numBuffs/db.buffs.perrow)
+ buffs:Height(buffs.size * (numRows > db.buffs.numrows and db.buffs.numrows or numRows))
+ else
+ buffs:Height(buffs.size)
+ -- Any way to get rid of the last row as well?
+ -- Using buffs:SetHeight(0) makes frames anchored to this one disappear
+ end
+end
+
+function UF:UpdateDebuffsHeight()
+ local parent = self:GetParent()
+ local db = parent.db
+ local debuffs = parent.Debuffs
+ local numDebuffs = self.visibleDebuffs
+
+ if numDebuffs > 0 then
+ local numRows = ceil(numDebuffs/db.debuffs.perrow)
+ debuffs:Height(debuffs.size * (numRows > db.debuffs.numrows and db.debuffs.numrows or numRows))
+ else
+ debuffs:Height(debuffs.size)
+ -- Any way to get rid of the last row as well?
+ -- Using debuffs:SetHeight(0) makes frames anchored to this one disappear
+ end
+end
\ No newline at end of file
diff --git a/ElvUI/Modules/UnitFrames/Elements/Load_Elements.xml b/ElvUI/Modules/UnitFrames/Elements/Load_Elements.xml
index c380c5b..d67a736 100644
--- a/ElvUI/Modules/UnitFrames/Elements/Load_Elements.xml
+++ b/ElvUI/Modules/UnitFrames/Elements/Load_Elements.xml
@@ -1,4 +1,6 @@
+
+
diff --git a/ElvUI/Modules/UnitFrames/Units/Load_Units.xml b/ElvUI/Modules/UnitFrames/Units/Load_Units.xml
index ba62950..b5abfb3 100644
--- a/ElvUI/Modules/UnitFrames/Units/Load_Units.xml
+++ b/ElvUI/Modules/UnitFrames/Units/Load_Units.xml
@@ -2,9 +2,4 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/ElvUI/Modules/UnitFrames/Units/Player.lua b/ElvUI/Modules/UnitFrames/Units/Player.lua
index 71d058d..8bd9e2f 100644
--- a/ElvUI/Modules/UnitFrames/Units/Player.lua
+++ b/ElvUI/Modules/UnitFrames/Units/Player.lua
@@ -22,9 +22,13 @@ function UF:Construct_PlayerFrame(frame)
frame.Portrait3D = self:Construct_Portrait(frame, "model")
frame.Portrait2D = self:Construct_Portrait(frame, "texture")
+ frame.Buffs = self:Construct_Buffs(frame)
+ frame.Debuffs = self:Construct_Debuffs(frame)
+ -- frame.Castbar = self:Construct_Castbar(frame, L["Player Castbar"])
frame.RaidTargetIndicator = UF:Construct_RaidIcon(frame)
frame.RestingIndicator = self:Construct_RestingIndicator(frame)
frame.CombatIndicator = self:Construct_CombatIndicator(frame)
+ frame.AuraBars = self:Construct_AuraBarHeader(frame)
frame.InfoPanel = self:Construct_InfoPanel(frame)
frame:SetPoint("BOTTOMLEFT", E.UIParent, "BOTTOM", -413, 68)
diff --git a/ElvUI/Modules/UnitFrames/Units/Target.lua b/ElvUI/Modules/UnitFrames/Units/Target.lua
index fce91f6..07a6e61 100644
--- a/ElvUI/Modules/UnitFrames/Units/Target.lua
+++ b/ElvUI/Modules/UnitFrames/Units/Target.lua
@@ -20,8 +20,11 @@ function UF:Construct_TargetFrame(frame)
frame.Portrait3D = self:Construct_Portrait(frame, "model")
frame.Portrait2D = self:Construct_Portrait(frame, "texture")
+ frame.Buffs = self:Construct_Buffs(frame)
+ frame.Debuffs = self:Construct_Debuffs(frame)
frame.RaidTargetIndicator = UF:Construct_RaidIcon(frame)
frame.InfoPanel = self:Construct_InfoPanel(frame)
+ frame.AuraBars = self:Construct_AuraBarHeader(frame)
E:Point(frame, "BOTTOMRIGHT", E.UIParent, "BOTTOM", 413, 68)
E:CreateMover(frame, frame:GetName().."Mover", L["Target Frame"], nil, nil, nil, "ALL,SOLO")