--[[ ########################################################## S V U I By: Munglunch ########################################################## LOCALIZED LUA FUNCTIONS ########################################################## ]]-- --LUA local unpack = unpack; local select = select; local pairs = pairs; local type = type; local rawset = rawset; local rawget = rawget; local tostring = tostring; local error = error; local next = next; local pcall = pcall; local getmetatable = getmetatable; local setmetatable = setmetatable; local assert = assert; --BLIZZARD local _G = _G; local tinsert = _G.tinsert; local tremove = _G.tremove; local twipe = _G.wipe; --STRING local string = string; local upper = string.upper; local format = string.format; local find = string.find; local match = string.match; local gsub = string.gsub; --MATH local math = math; local floor = math.floor local ceil = math.ceil --TABLE local table = table; local tsort = table.sort; local tremove = table.remove; local CreateFrame = _G.CreateFrame; local InCombatLockdown = _G.InCombatLockdown; local GameTooltip = _G.GameTooltip; --[[ ########################################################## GET ADDON DATA ########################################################## ]]-- local SV = _G['SVUI'] local L = SV.L; local LSM = _G.LibStub("LibSharedMedia-3.0") local MOD = SV.UnitFrames if(not MOD) then return end local oUF_SVUI = MOD.oUF assert(oUF_SVUI, "SVUI UnitFrames: unable to locate oUF.") local DEFAULT_BUFFS_COLOR = {0.04, 0.52, 0.95}; local BUFFS_COLOR = DEFAULT_BUFFS_COLOR; local DEFAULT_DEBUFFS_COLOR = {.9, 0, 0}; local DEBUFFS_COLOR = DEFAULT_DEBUFFS_COLOR; local AURA_STATUSBAR = SV.media.statusbar.default; local BASIC_TEXTURE = SV.media.statusbar.default; local CanSteal = (SV.class == "MAGE"); local CreateFrame = _G.CreateFrame; local UnitIsEnemy = _G.UnitIsEnemy; local IsShiftKeyDown = _G.IsShiftKeyDown; local DebuffTypeColor = _G.DebuffTypeColor; local SVUI_Font_UnitAura = _G.SVUI_Font_UnitAura; local SVUI_Font_UnitAura_Bar = _G.SVUI_Font_UnitAura_Bar; --[[ ########################################################## LOCAL FUNCTIONS ########################################################## ]]-- local FilterAura_OnClick = function(self) if not IsShiftKeyDown() then return end local name = self.name; local spellID = self.spellID; local filterKey = tostring(spellID) if name and filterKey then SV:AddonMessage((L["The spell '%s' has been added to the BlackList unitframe aura filter."]):format(name)) SV.db.Filters["BlackList"][filterKey] = {['enable'] = true, ['id'] = spellID} MOD:RefreshUnitFrames() end end local Aura_OnEnter = function(self) if(not self:IsVisible()) then return end GameTooltip:SetOwner(self, "ANCHOR_BOTTOMRIGHT") GameTooltip:SetUnitAura(self.unit, self.index, self.filter) end local Aura_OnLeave = function() GameTooltip:Hide() end local _hook_AuraBGBorderColor = function(self, ...) self.bg:SetBackdropBorderColor(...) end local CreateAuraIcon = function(icons, index) local baseSize = icons.auraSize or 16 local aura = CreateFrame("Button", nil, icons) aura:RemoveTextures() aura:EnableMouse(true) aura:RegisterForClicks('RightButtonUp') aura:SetWidth(baseSize) aura:SetHeight(baseSize) aura:SetBackdrop({ bgFile = [[Interface\BUTTONS\WHITE8X8]], tile = false, tileSize = 0, edgeFile = [[Interface\BUTTONS\WHITE8X8]], edgeSize = 1, insets = { left = 0, right = 0, top = 0, bottom = 0 } }); aura:SetBackdropColor(0, 0, 0, 0) aura:SetBackdropBorderColor(0, 0, 0) local bg = CreateFrame("Frame", nil, aura) bg:SetFrameStrata("BACKGROUND") bg:SetFrameLevel(0) bg:WrapPoints(aura, 2, 2) bg:SetBackdrop(SV.media.backdrop.aura) bg:SetBackdropColor(0, 0, 0, 0) bg:SetBackdropBorderColor(0, 0, 0, 0) aura.bg = bg; --hooksecurefunc(aura, "SetBackdropBorderColor", _hook_AuraBGBorderColor) local fontgroup = "SVUI_Font_UnitAura"; if(baseSize < 18) then fontgroup = "SVUI_Font_UnitAura_Small"; end --print(baseSize) --print(fontgroup) local cd = CreateFrame("Cooldown", nil, aura, "CooldownFrameTemplate"); cd:InsetPoints(aura, 1, 1); cd.noOCC = true; cd.noCooldownCount = true; cd:SetReverse(true); cd:SetHideCountdownNumbers(true); local fg = CreateFrame("Frame", nil, aura) fg:WrapPoints(aura, 2, 2) local text = fg:CreateFontString(nil, 'OVERLAY'); text:SetFontObject(_G[fontgroup]); text:SetPoint('CENTER', aura, 'CENTER', 1, 1); text:SetJustifyH('CENTER'); local count = fg:CreateFontString(nil, "OVERLAY"); count:SetFontObject(_G[fontgroup]); count:SetPoint("CENTER", aura, "BOTTOMRIGHT", -3, 3); local icon = aura:CreateTexture(nil, "BACKGROUND"); icon:SetAllPoints(aura); icon:InsetPoints(aura, 1, 1); icon:SetTexCoord(unpack(_G.SVUI_ICON_COORDS)); local overlay = aura:CreateTexture(nil, "OVERLAY"); overlay:InsetPoints(aura, 1, 1); overlay:SetTexture(BASIC_TEXTURE); overlay:SetVertexColor(0, 0, 0); overlay:Hide(); -- local stealable = aura:CreateTexture(nil, 'OVERLAY') -- stealable:SetTexture("") -- stealable:SetPoint('TOPLEFT', -3, 3) -- stealable:SetPoint('BOTTOMRIGHT', 3, -3) -- aura.stealable = stealable aura:SetScript("OnClick", FilterAura_OnClick); aura:SetScript("OnEnter", Aura_OnEnter); aura:SetScript("OnLeave", Aura_OnLeave); aura.parent = icons; aura.cooldown = cd; aura.text = text; aura.icon = icon; aura.count = count; aura.overlay = overlay; return aura end local PostCreateAuraBars = function(self) local bar = self.statusBar local barTexture = LSM:Fetch("statusbar", SV.db.UnitFrames.auraBarStatusbar) bar:SetStatusBarTexture(barTexture) bar.spelltime:SetFontObject(SVUI_Font_UnitAura_Bar); bar.spelltime:SetTextColor(1 ,1, 1) bar.spelltime:SetShadowOffset(1, -1) bar.spelltime:SetShadowColor(0, 0, 0) bar.spelltime:SetJustifyH'RIGHT' bar.spelltime:SetJustifyV'CENTER' bar.spelltime:SetPoint'RIGHT' bar.spellname:SetFontObject(SVUI_Font_UnitAura_Bar); bar.spellname:SetTextColor(1, 1, 1) bar.spellname:SetShadowOffset(1, -1) bar.spellname:SetShadowColor(0, 0, 0) bar.spellname:SetJustifyH'LEFT' bar.spellname:SetJustifyV'CENTER' bar.spellname:SetPoint'LEFT' bar.spellname:SetPoint('RIGHT', bar.spelltime, 'LEFT') self:RegisterForClicks("RightButtonUp") self:SetScript("OnClick", FilterAura_OnClick) end local PostBarUpdate = function(self, bar, spellID, isDebuff, debuffType) if((not bar) or (not bar:IsVisible())) then return end local color; if(SV.db.UnitFrames.auraBarByType) then local filterKey = tostring(spellID) if(SV.db.Filters.AuraBars[filterKey]) then color = SV.db.Filters.AuraBars[filterKey] elseif isDebuff then if(debuffType and DebuffTypeColor[debuffType]) then color = {DebuffTypeColor[debuffType].r, DebuffTypeColor[debuffType].g, DebuffTypeColor[debuffType].b} else color = DEBUFFS_COLOR; end else color = BUFFS_COLOR; end else color = BUFFS_COLOR; end bar:SetStatusBarTexture(AURA_STATUSBAR) bar:SetStatusBarColor(unpack(color)) end --[[ AURA FILTERING ]]-- local CommonAuraFilter = function(self, isEnemy, isPlayer, auraName, spellID, debuffType, duration, shouldConsolidate) local db = SV.db.UnitFrames[self.___unitkey] if((not db) or (db and not db[self.___aurakey])) then return false; end local auraDB = db[self.___aurakey]; local filterKey = tostring(spellID) if(auraDB.filterWhiteList and (not SV.db.Filters.WhiteList[filterKey])) then return false; elseif(SV.db.Filters.BlackList[filterKey] and SV.db.Filters.BlackList[filterKey].enable) then return false; else if(auraDB.filterPlayer and (not isPlayer)) then return false end if(auraDB.filterDispellable and (debuffType and not MOD.Dispellable[debuffType])) then return false end if(auraDB.filterRaid and shouldConsolidate) then return false end if(auraDB.filterInfinite and ((not duration) or (duration and duration == 0))) then return false end local active = auraDB.useFilter if(active and SV.db.Filters[active]) then local spellDB = SV.db.Filters[active]; if(spellDB[filterKey] and spellDB[filterKey].enable) then return false end end end return true end --[[ DETAILED AURA FILTERING ]]-- local function filter_test(setting, isEnemy) if((not setting) or (setting and type(setting) ~= "table")) then return false; end if((setting.enemy and isEnemy) or (setting.friendly and (not isEnemy))) then return true; end return false end local DetailedAuraFilter = function(self, isEnemy, isPlayer, auraName, spellID, debuffType, duration, shouldConsolidate) local db = SV.db.UnitFrames[self.___unitkey] local auraType = self.___aurakey if((not db) or (not auraType) or (db and (not db[auraType]))) then return false; end local auraDB = db[self.___aurakey]; local filterKey = tostring(spellID) if(filter_test(auraDB.filterAll, isEnemy)) then return false elseif(filter_test(auraDB.filterWhiteList, isEnemy) and (not SV.db.Filters.WhiteList[filterKey])) then return false; elseif(SV.db.Filters.BlackList[filterKey] and SV.db.Filters.BlackList[filterKey].enable) then return false else if(filter_test(auraDB.filterPlayer, isEnemy) and (not isPlayer)) then return false end if(filter_test(auraDB.filterDispellable, isEnemy)) then if((CanSteal and (auraType == 'buffs' and isStealable)) or (debuffType and (not MOD.Dispellable[debuffType])) or (not debuffType)) then return false end end if(filter_test(auraDB.filterRaid, isEnemy) and shouldConsolidate) then return false end if(filter_test(auraDB.filterInfinite, isEnemy) and ((not duration) or (duration and duration == 0))) then return false end local active = auraDB.useFilter if(active and SV.db.Filters[active]) then local spellDB = SV.db.Filters[active]; if(spellDB[filterKey] and spellDB[filterKey].enable) then return false end end end return true end --[[ ########################################################## BUILD FUNCTION ########################################################## ]]-- local BoolFilters = { ['player'] = true, ['pet'] = true, ['boss'] = true, ['arena'] = true, ['party'] = true, ['raid'] = true, ['raidpet'] = true, }; function MOD:CreateAuraFrames(frame, unit, barsAvailable) local buffs = CreateFrame("Frame", frame:GetName().."Buffs", frame) buffs.___unitkey = unit; buffs.___aurakey = "buffs"; buffs.CreateAuraIcon = CreateAuraIcon; if(BoolFilters[unit]) then buffs.CustomFilter = CommonAuraFilter; else buffs.CustomFilter = DetailedAuraFilter; end buffs:SetFrameLevel(10) frame.Buffs = buffs local debuffs = CreateFrame("Frame", frame:GetName().."Debuffs", frame) debuffs.___unitkey = unit; debuffs.___aurakey = "debuffs"; debuffs.CreateAuraIcon = CreateAuraIcon; if(BoolFilters[unit]) then debuffs.CustomFilter = CommonAuraFilter; else debuffs.CustomFilter = DetailedAuraFilter; end debuffs:SetFrameLevel(10) frame.Debuffs = debuffs if(barsAvailable) then frame.AuraBarsAvailable = true; buffs.PostCreateBar = PostCreateAuraBars; buffs.PostBarUpdate = PostBarUpdate; debuffs.PostCreateBar = PostCreateAuraBars; debuffs.PostBarUpdate = PostBarUpdate; end end --[[ ########################################################## AURA WATCH ########################################################## ]]-- local PreForcedUpdate = function(self) local unit = self.___key; if not SV.db.UnitFrames[unit] then return end local db = SV.db.UnitFrames[unit].auraWatch; if not db then return end; if(unit == "pet" or unit == "raidpet") then self.watchFilter = SV.db.Filters.PetBuffWatch else self.watchFilter = SV.db.Filters.BuffWatch end self.watchEnabled = db.enable; self.watchSize = db.size; end function MOD:CreateAuraWatch(frame, unit) local watch = CreateFrame("Frame", nil, frame) watch:SetFrameLevel(frame:GetFrameLevel() + 25) watch:SetAllPoints(frame); watch.___key = unit; watch.watchEnabled = true; watch.presentAlpha = 1; watch.missingAlpha = 0; if(unit == "pet" or unit == "raidpet") then watch.watchFilter = SV.db.Filters.PetBuffWatch else watch.watchFilter = SV.db.Filters.BuffWatch end watch.PreForcedUpdate = PreForcedUpdate return watch end --[[ ########################################################## CUSTOM EVENT UPDATES ########################################################## ]]-- local function UpdateAuraMediaLocals() BUFFS_COLOR = oUF_SVUI.colors.buff_bars or DEFAULT_BUFFS_COLOR; DEBUFFS_COLOR = oUF_SVUI.colors.debuff_bars or DEFAULT_DEBUFFS_COLOR; AURA_STATUSBAR = LSM:Fetch("statusbar", SV.db.UnitFrames.auraBarStatusbar); end SV.Events:On("UNITFRAME_COLORS_UPDATED", UpdateAuraMediaLocals, true);