305 lines
8.5 KiB
Lua
305 lines
8.5 KiB
Lua
-- Original work by Astromech
|
|
-- Rewritten based on Auras by Azilroka
|
|
|
|
local _, ns = ...
|
|
local oUF = ns.oUF
|
|
|
|
local VISIBLE = 1
|
|
local HIDDEN = 0
|
|
|
|
local min, wipe, pairs, tinsert = min, wipe, pairs, tinsert
|
|
local CreateFrame = CreateFrame
|
|
local UnitAura = UnitAura
|
|
local UnitIsUnit = UnitIsUnit
|
|
local GetSpellTexture = GetSpellTexture
|
|
|
|
local function createAuraIcon(element, index)
|
|
local button = CreateFrame('Button', element:GetName() .. 'Button' .. index, element)
|
|
button:EnableMouse(false)
|
|
button:Hide()
|
|
|
|
local cd = CreateFrame('Cooldown', '$parentCooldown', button, 'CooldownFrameTemplate')
|
|
cd:SetAllPoints()
|
|
cd:SetReverse(true)
|
|
cd:SetDrawBling(false)
|
|
cd:SetDrawEdge(false)
|
|
|
|
local icon = button:CreateTexture(nil, 'ARTWORK')
|
|
icon:SetAllPoints()
|
|
|
|
local countFrame = CreateFrame('Frame', nil, button)
|
|
countFrame:SetAllPoints(button)
|
|
countFrame:SetFrameLevel(cd:GetFrameLevel() + 1)
|
|
|
|
local count = countFrame:CreateFontString(nil, 'OVERLAY', 'NumberFontNormal')
|
|
count:SetPoint('BOTTOMRIGHT', countFrame, 'BOTTOMRIGHT', -1, 0)
|
|
|
|
local overlay = button:CreateTexture(nil, 'OVERLAY')
|
|
overlay:SetTexture([[Interface\Buttons\UI-Debuff-Overlays]])
|
|
overlay:SetAllPoints()
|
|
overlay:SetTexCoord(.296875, .5703125, 0, .515625)
|
|
|
|
button.overlay = overlay
|
|
button.icon = icon
|
|
button.count = count
|
|
button.cd = cd
|
|
|
|
if(element.PostCreateIcon) then element:PostCreateIcon(button) end
|
|
|
|
return button
|
|
end
|
|
|
|
local function customFilter(element, _, button, name, _, _, debuffType, _, _, caster, isStealable, _, spellID, canApply, isBossDebuff, casterIsPlayer)
|
|
local setting = element.watched[spellID]
|
|
if not setting then return false end
|
|
|
|
button.onlyShowMissing = setting.onlyShowMissing
|
|
button.anyUnit = setting.anyUnit
|
|
|
|
if setting.enabled then
|
|
if setting.onlyShowMissing and not setting.anyUnit and caster == 'player' then
|
|
return false
|
|
elseif setting.onlyShowMissing and setting.anyUnit and casterIsPlayer then
|
|
return true
|
|
elseif not setting.onlyShowMissing and setting.anyUnit and casterIsPlayer then
|
|
return true
|
|
elseif not setting.onlyShowMissing and not setting.anyUnit and caster == 'player' then
|
|
return true
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
local function updateIcon(element, unit, index, offset, filter, isDebuff, visible)
|
|
local name, texture, count, debuffType, duration, expiration, caster, isStealable,
|
|
nameplateShowSelf, spellID, canApply, isBossDebuff, casterIsPlayer, nameplateShowAll,
|
|
timeMod, effect1, effect2, effect3 = UnitAura(unit, index, filter)
|
|
|
|
if(name) then
|
|
local position = visible + offset + 1
|
|
local button = element[position]
|
|
if(not button) then
|
|
button = (element.CreateIcon or createAuraIcon) (element, position)
|
|
|
|
tinsert(element, button)
|
|
element.createdIcons = element.createdIcons + 1
|
|
end
|
|
|
|
button.caster = caster
|
|
button.filter = filter
|
|
button.isDebuff = isDebuff
|
|
button.debuffType = debuffType
|
|
button.spellID = spellID
|
|
button.isPlayer = caster == 'player'
|
|
|
|
local show = (element.CustomFilter or customFilter) (element, unit, button, name, texture,
|
|
count, debuffType, duration, expiration, caster, isStealable, nameplateShowSelf, spellID,
|
|
canApply, isBossDebuff, casterIsPlayer, nameplateShowAll, timeMod, effect1, effect2, effect3)
|
|
|
|
if(show) then
|
|
local setting = element.watched[spellID]
|
|
if(button.cd) then
|
|
if(duration and duration > 0) then
|
|
button.cd:SetCooldown(expiration - duration, duration)
|
|
button.cd:Show()
|
|
else
|
|
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 = element.__owner.colors.debuff[debuffType] or element.__owner.colors.debuff.none
|
|
|
|
button.overlay:SetVertexColor(color[1], color[2], color[3])
|
|
button.overlay:Show()
|
|
else
|
|
button.overlay:Hide()
|
|
end
|
|
end
|
|
|
|
if(button.stealable) then
|
|
if(not isDebuff and isStealable and element.showStealableBuffs and not UnitIsUnit('player', unit)) then
|
|
button.stealable:Show()
|
|
else
|
|
button.stealable:Hide()
|
|
end
|
|
end
|
|
|
|
if(button.icon) then button.icon:SetTexture(texture) end
|
|
if(button.count) then button.count:SetText(count > 1 and count) end
|
|
|
|
if setting.sizeOffset == 0 then
|
|
button:SetSize(element.size, element.size)
|
|
else
|
|
button:SetSize(setting.sizeOffset + element.size, setting.sizeOffset + element.size)
|
|
end
|
|
|
|
button:SetID(index)
|
|
button:Show()
|
|
button:ClearAllPoints()
|
|
button:SetPoint(setting.point, setting.xOffset, setting.yOffset)
|
|
|
|
if(element.PostUpdateIcon) then
|
|
element:PostUpdateIcon(unit, button, index, position, duration, expiration, debuffType, isStealable)
|
|
end
|
|
|
|
return VISIBLE
|
|
else
|
|
button.isFiltered = true
|
|
return HIDDEN
|
|
end
|
|
end
|
|
end
|
|
|
|
local missing = {}
|
|
local function onlyShowMissingIcon(element, unit, offset)
|
|
wipe(missing)
|
|
|
|
for SpellID, setting in pairs(element.watched) do
|
|
if setting.onlyShowMissing then
|
|
missing[SpellID] = setting
|
|
end
|
|
end
|
|
|
|
for i = 1, #element do
|
|
local button = element[i]
|
|
if button.isFiltered and missing[button.spellID] then
|
|
missing[button.spellID] = nil
|
|
end
|
|
end
|
|
|
|
local visible = 0
|
|
for SpellID, setting in pairs(missing) do
|
|
local position = visible + offset + 1
|
|
local button = element[position]
|
|
if(not button) then
|
|
button = (element.CreateIcon or createAuraIcon) (element, position)
|
|
tinsert(element, button)
|
|
element.createdIcons = element.createdIcons + 1
|
|
end
|
|
|
|
if(button.cd) then button.cd:Hide() end
|
|
if(button.icon) then button.icon:SetTexture(GetSpellTexture(SpellID)) end
|
|
if(button.overlay) then button.overlay:Hide() end
|
|
|
|
if setting.sizeOffset == 0 then
|
|
button:SetSize(element.size, element.size)
|
|
else
|
|
button:SetSize(setting.sizeOffset + element.size, setting.sizeOffset + element.size)
|
|
end
|
|
|
|
button:SetID(position)
|
|
button.spellID = SpellID
|
|
|
|
button:Show()
|
|
button:ClearAllPoints()
|
|
button:SetPoint(setting.point, setting.xOffset, setting.yOffset)
|
|
|
|
if(element.PostUpdateIcon) then
|
|
element:PostUpdateIcon(unit, button, nil, position)
|
|
end
|
|
|
|
visible = visible + 1
|
|
end
|
|
|
|
return visible
|
|
end
|
|
|
|
local function filterIcons(element, unit, filter, limit, isDebuff, offset, dontHide)
|
|
if (not offset) then offset = 0 end
|
|
local index, visible, hidden = 1, 0, 0
|
|
while (visible < limit) do
|
|
local result = updateIcon(element, unit, index, offset, filter, isDebuff, visible)
|
|
if (not result) then
|
|
break
|
|
elseif (result == VISIBLE) then
|
|
visible = visible + 1
|
|
elseif (result == HIDDEN) then
|
|
hidden = hidden + 1
|
|
end
|
|
|
|
index = index + 1
|
|
end
|
|
|
|
if (not dontHide) then
|
|
for i = visible + offset + 1, #element do
|
|
element[i]:Hide()
|
|
end
|
|
end
|
|
|
|
return visible, hidden
|
|
end
|
|
|
|
local function UpdateAuras(self, event, unit)
|
|
if(self.unit ~= unit) then return end
|
|
|
|
local element = self.AuraWatch
|
|
if(element) then
|
|
if(element.PreUpdate) then element:PreUpdate(unit) end
|
|
|
|
local numBuffs = element.numBuffs or 32
|
|
local numDebuffs = element.numDebuffs or 16
|
|
local numAuras = element.numTotal or (numBuffs + numDebuffs)
|
|
|
|
for i = 1, #element do element[i].isFiltered = false end
|
|
|
|
local visibleBuffs, hiddenBuffs = filterIcons(element, unit, element.buffFilter or element.filter or 'HELPFUL', min(numBuffs, numAuras), nil, 0, true)
|
|
local visibleDebuffs, hiddenDebuffs = filterIcons(element, unit, element.buffFilter or element.filter or 'HARMFUL', min(numDebuffs, numAuras - visibleBuffs), true, visibleBuffs)
|
|
|
|
element.visibleDebuffs = visibleDebuffs
|
|
element.visibleBuffs = visibleBuffs
|
|
|
|
element.visibleAuras = visibleBuffs + visibleDebuffs
|
|
element.allAuras = visibleBuffs + visibleDebuffs + hiddenBuffs + hiddenDebuffs
|
|
|
|
onlyShowMissingIcon(element, unit, element.visibleAuras)
|
|
|
|
if(element.PostUpdate) then element:PostUpdate(unit) end
|
|
end
|
|
end
|
|
|
|
local function Update(self, event, unit)
|
|
if(self.unit ~= unit) then return end
|
|
|
|
UpdateAuras(self, event, unit)
|
|
end
|
|
|
|
local function ForceUpdate(element)
|
|
return Update(element.__owner, 'ForceUpdate', element.__owner.unit)
|
|
end
|
|
|
|
local function SetNewTable(element, table)
|
|
element.watched = table or {}
|
|
end
|
|
|
|
local function Enable(self)
|
|
local element = self.AuraWatch
|
|
if(element) then
|
|
element.__owner = self
|
|
element.SetNewTable = SetNewTable
|
|
element.ForceUpdate = ForceUpdate
|
|
|
|
element.watched = element.watched or {}
|
|
element.createdIcons = element.createdIcons or 0
|
|
element.anchoredIcons = 0
|
|
element.size = 8
|
|
|
|
self:RegisterEvent('UNIT_AURA', UpdateAuras)
|
|
element:Show()
|
|
|
|
return true
|
|
end
|
|
end
|
|
|
|
local function Disable(self)
|
|
if(self.AuraWatch) then
|
|
self:UnregisterEvent('UNIT_AURA', UpdateAuras)
|
|
|
|
if(self.AuraWatch) then self.AuraWatch:Hide() end
|
|
end
|
|
end
|
|
|
|
oUF:AddElement('AuraWatch', Update, Enable, Disable)
|