Compare with Previous | Blame | View Log
local SB = CreateFrame("Frame") local numBuffsSkinned = 0 local numDebuffsSkinned = 0 local LSM = LibStub("LibSharedMedia-3.0") local fonts = AceGUIWidgetLSMlists.font local sbars = AceGUIWidgetLSMlists.statusbar local bgs = AceGUIWidgetLSMlists.background local borders = AceGUIWidgetLSMlists.border local fontFlags = {"None", "Outline", "Monochrome Outline", "Monochrome"} local _, class = UnitClass("player") local classColor, SBmover, moverShown, db local BuffFrame = BuffFrame local defaults = { font = "Friz Quadrata TT", fstyle = "Outline", allWhiteText = true, whoCast = true, buffs = { dfsize = 10, cfsize = 14, size = 36, }, debuffs = { dfsize = 12, cfsize = 14, size = 40, }, bg = "Solid", bgColor = {r = .32, g = .32, b = .32}, classbg = false, border = "SB border", borColor = {r = .5, g = .5, b = .5}, classbor = false, debuffTypeBor = false, borderWidth = 16, debuffOverlayAlpha = .4, sbar = "Solid", sbarColor = {r = 0, g = 1, b = 0}, classbar = false, posX = -205, posY = -13, anchor1 = "TOPRIGHT", anchor2 = "TOPRIGHT", bprow = 8, } local function SkinningMachine(svtable, btn, dur, c, icon, bor, firstTime) btn:SetSize(db[svtable].size, db[svtable].size) icon:SetSize(db[svtable].size-8, db[svtable].size-8) if firstTime then btn.bg = CreateFrame("Frame", nil, btn, "BackdropTemplate") btn.bg:SetPoint("TOPLEFT", btn, "TOPLEFT", -2, 2) dur:SetJustifyH("RIGHT") dur:ClearAllPoints() dur:SetPoint("BOTTOMRIGHT", 1, 1) c:SetJustifyH("LEFT") c:ClearAllPoints() c:SetPoint("TOPLEFT", 2, -2) icon:ClearAllPoints() icon:SetPoint("CENTER", btn, "CENTER") icon:SetTexCoord(.07, .93, .07, .93) if bor then bor:SetParent(btn.bg) bor:SetDrawLayer("OVERLAY", 1) end -- btn.bar = CreateFrame("StatusBar", nil, btn.bg) btn.bar:SetPoint("TOPLEFT", icon, "BOTTOMLEFT", 0, -1.5) btn.bar:SetPoint("TOPRIGHT", icon, "BOTTOMRIGHT", 0, -1.5) btn.bar:SetPoint("BOTTOM", btn.bg, "BOTTOM", 0, 5.5) btn.bar:SetMinMaxValues(0, 1) -- 0%-100% --keep these on top >< icon:SetParent(btn.bg) icon:SetDrawLayer("OVERLAY", 0) dur:SetParent(btn.bar) dur:SetDrawLayer("OVERLAY", 3) c:SetParent(btn.bg) c:SetDrawLayer("OVERLAY", 3) end if bor then bor:SetAlpha(db.debuffOverlayAlpha) bor:ClearAllPoints() if db.debuffTypeBor then bor:SetAllPoints(btn.bg) bor:SetTexture("Interface\\Buttons\\UI-Debuff-Overlays") bor:SetTexCoord(0.296875, 0.5703125, 0, 0.515625) bor:SetAlpha(1) else bor:SetAllPoints(icon) bor:SetColorTexture(1,1,1,1) end end dur:SetFont(LSM:Fetch("font", db.font), db[svtable].dfsize, db.fstyle) c:SetFont(LSM:Fetch("font", db.font), db[svtable].cfsize, db.fstyle) btn.bg:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT", 2, -max(db[svtable].size*.2, 5)) btn.bg:SetBackdrop({ bgFile = LSM:Fetch("background", db.bg), edgeFile = LSM:Fetch("border", db.border), edgeSize = db.borderWidth, insets = {left=3,right=3,top=3,bottom=3} }) btn.bar:SetStatusBarTexture(LSM:Fetch("statusbar", db.sbar)) if db.classbg then btn.bg:SetBackdropColor(classColor.r, classColor.g, classColor.b) else btn.bg:SetBackdropColor(db.bgColor.r, db.bgColor.g, db.bgColor.b) end if db.classbor then btn.bg:SetBackdropBorderColor(classColor.r, classColor.g, classColor.b) else btn.bg:SetBackdropBorderColor(db.borColor.r, db.borColor.g, db.borColor.b) end if db.classbar then btn.bar:SetStatusBarColor(classColor.r, classColor.g, classColor.b) else btn.bar:SetStatusBarColor(db.sbarColor.r, db.sbarColor.g, db.sbarColor.b) end end local function SkinBuffs(i, firstTime) local b = _G["BuffButton"..i] local dur = b.duration local c = b.count local icon = _G["BuffButton"..i.."Icon"] SkinningMachine("buffs", b, dur, c, icon, nil, firstTime) --only setscript and increment count if we're skinning for the first time if firstTime then local timer = 0 local dur, exps, _, val b.bar:SetScript("OnUpdate", function(self, elapsed) timer = timer + elapsed if timer >= .1 then _,_,_,_,dur,exps = UnitBuff("player",i) if dur == 0 then self:SetValue(1) else if exps then val = exps-GetTime() self:SetValue(val/dur) end end timer = 0 end end) numBuffsSkinned = i end end local function SkinDebuffs(i, firstTime) local d = _G["DebuffButton"..i] local dur = d.duration local c = d.count local icon = _G["DebuffButton"..i.."Icon"] local bor = _G["DebuffButton"..i.."Border"] SkinningMachine("debuffs", d, dur, c, icon, bor, firstTime) --only setscript and increment count if we're skinning for the first time if firstTime then local timer = 0 local dur, exps, _, val d.bar:SetScript("OnUpdate", function(self, elapsed) timer = timer + elapsed if timer >= .1 then _,_,_,_,dur,exps = UnitDebuff("player",i) if dur == 0 then self:SetValue(1) else if exps then val = exps-GetTime() self:SetValue(val/dur) end end timer = 0 end end) numDebuffsSkinned = i end end local function SkinTench(firstTime) for i = 1, NUM_TEMP_ENCHANT_FRAMES do local t = _G["TempEnchant"..i] local dur = t.duration local c = t.count local icon = _G["TempEnchant"..i.."Icon"] local bor = _G["TempEnchant"..i.."Border"] SkinningMachine("buffs", t, dur, c, icon, bor, firstTime) if firstTime then bor:SetVertexColor(.9, 0, .9) t.bar:SetValue(1) --keep the buffs spaced correctly from Tench local TenchWidth = TemporaryEnchantFrame.SetWidth local tench1, tench2, tench3, num hooksecurefunc(TemporaryEnchantFrame, "SetWidth", function(self,width) tench1,_,_,tench2,_,_,tench3 = GetWeaponEnchantInfo() num = (tench3 and 3) or (tench2 and 2) or 1 TenchWidth(self, (num * db.buffs.size) + ((num-1) * 5)) end) end end end local OLD_SetUnitAura, NEW_SetUnitAura, caster, casterName = GameTooltip.SetUnitAura local function WhoCast() if db.whoCast then if not NEW_SetUnitAura then NEW_SetUnitAura = function(self, unit, id, filter) OLD_SetUnitAura(self, unit, id, filter) if filter == "HELPFUL" then _,_,_,_,_,_,caster = UnitAura("player", id) --7th return casterName = caster==nil and "unknown" or caster=="player" and "you" or caster=="pet" and "your pet" or UnitName(caster) GameTooltip:AddLine("Provided by "..casterName, .5, .9, 1) GameTooltip:Show() end end end GameTooltip.SetUnitAura = NEW_SetUnitAura else GameTooltip.SetUnitAura = OLD_SetUnitAura end end local function Position() BuffFrame:ClearAllPoints() BuffFrame:NewSetPoint(db.anchor1, UIParent, db.anchor2, db.posX, db.posY) end local function ShowMover() if not SBmover then SBmover = CreateFrame("Frame", nil, UIParent, "BackdropTemplate") SBmover:SetBackdrop({bgFile = "Interface\\AddOns\\ShinyBuffs\\media\\mover.blp"}) SBmover:SetBackdropColor(1,1,1,.5) SBmover:SetPoint("TOPRIGHT", BuffFrame, "TOPRIGHT", 5, 5) SBmover:SetSize(200, 150) SBmover:SetFrameStrata("TOOLTIP") SBmover:EnableMouse(true) BuffFrame:SetMovable(true) BuffFrame:SetClampedToScreen(true) SBmover:SetScript("OnMouseDown", function(self) BuffFrame:StartMoving() end) SBmover:SetScript("OnMouseUp", function(self) BuffFrame:StopMovingOrSizing() db.anchor1, _, db.anchor2, db.posX, db.posY = BuffFrame:GetPoint() --Position() if SB.optionsFrame:IsShown() then InterfaceOptionsFrame_OpenToCategory("ShinyBuffs") end end) end SBmover:SetAlpha(moverShown and 1 or 0) SBmover:EnableMouse(moverShown) end local function SkinAuras() if BUFF_ACTUAL_DISPLAY > numBuffsSkinned then for i = numBuffsSkinned+1, BUFF_ACTUAL_DISPLAY do SkinBuffs(i, true) end end if DEBUFF_ACTUAL_DISPLAY > numDebuffsSkinned then for i = numDebuffsSkinned+1, DEBUFF_ACTUAL_DISPLAY do SkinDebuffs(i, true) end end end local options = { name = "ShinyBuffs Options", type = "group", args = { header1 = { name = "Text Options", type = "header", order = 1, }, font = { name = "Font", type = "select", desc = "Select the font used.", dialogControl = "LSM30_Font", values = fonts, get = function() return db.font end, set = function(_,font) db.font = font for i=1,numBuffsSkinned do SkinBuffs(i,false) end for i=1,numDebuffsSkinned do SkinDebuffs(i,false) end SkinTench(false) end, order = 2, }, fontFlag = { name = "Font Flag", desc = "Set how to alter the displayed font.", type = "select", values = fontFlags, get = function() for k, v in pairs(fontFlags) do if db.fstyle == v then return k end end end, set = function(_,key) db.fstyle = fontFlags[key] for i=1,numBuffsSkinned do SkinBuffs(i,false) end for i=1,numDebuffsSkinned do SkinDebuffs(i,false) end SkinTench(false) end, order = 3, }, allwhite = { name = "White Duration Text", desc = "Show durations in white always. (The default UI colors them yellow until they fall below the 30 sec warning threshold. This raises the threshold, so that they are always white.)", type = "toggle", get = function() return db.allWhiteText end, set = function() db.allWhiteText = not db.allWhiteText if db.allWhiteText then BUFF_DURATION_WARNING_TIME = 7200 else BUFF_DURATION_WARNING_TIME = 60 end end, order = 4, }, buffFonts = { name = "Buff Font Sizes", type = "group", inline = true, order = 5, args = { durSize = { name = "Duration", type = "range", min = 6, max = 24, step = 1, get = function() return db.buffs.dfsize end, set = function(_,size) db.buffs.dfsize = size for i=1,numBuffsSkinned do SkinBuffs(i,false) end SkinTench(false) end, order = 1, }, countSize = { name = "Count", type = "range", min = 6, max = 24, step = 1, get = function() return db.buffs.cfsize end, set = function(_,size) db.buffs.cfsize = size for i=1,numBuffsSkinned do SkinBuffs(i,false) end SkinTench(false) end, order = 2, }, whoCast = { name = "Who Cast?", desc = "Shows who your buff is from in its tooltip.", type = "toggle", get = function() return db.whoCast end, set = function() db.whoCast = not db.whoCast WhoCast() end, order = 3, }, }, }, debuffFonts = { name = "Debuff Font Sizes", type = "group", inline = true, order = 6, args = { durSize = { name = "Duration", type = "range", min = 6, max = 24, step = 1, get = function() return db.debuffs.dfsize end, set = function(_,size) db.debuffs.dfsize = size for i=1,numDebuffsSkinned do SkinDebuffs(i,false) end end, order = 1, }, countSize = { name = "Count", type = "range", min = 6, max = 24, step = 1, get = function() return db.debuffs.cfsize end, set = function(_,size) db.debuffs.cfsize = size for i=1,numDebuffsSkinned do SkinDebuffs(i,false) end end, order = 2, }, }, }, spacer1 = { name = " ", type = "description", width = "full", order = 7, }, header2 = { name = "Skin Options", type = "header", order = 8, }, border = { name = "Border", type = "group", inline = true, order = 9, args = { texture = { name = "Texture", type = "select", desc = "Select the texture used for the border.", dialogControl = "LSM30_Border", values = borders, get = function() return db.border end, set = function(_,border) db.border = border for i=1,numBuffsSkinned do SkinBuffs(i,false) end for i=1,numDebuffsSkinned do SkinDebuffs(i,false) end SkinTench(false) end, order = 1, }, borderWidth = { name = "Border Width", desc = "Width of the border.", type = "range", min = 1, max = 24, step = .5, get = function() return db.borderWidth end, set = function(_,size) db.borderWidth = size for i=1,numBuffsSkinned do SkinBuffs(i,false) end for i=1,numDebuffsSkinned do SkinDebuffs(i,false) end SkinTench(false) end, order = 2, }, borColor = { name = "Color", desc = "Select a color for the border texture.", type = "color", width = "half", disabled = function() return db.classbor end, get = function() return db.borColor.r, db.borColor.g, db.borColor.b end, set = function(_,r,g,b) db.borColor.r,db.borColor.g,db.borColor.b = r,g,b for i=1,numBuffsSkinned do SkinBuffs(i,false) end for i=1,numDebuffsSkinned do SkinDebuffs(i,false) end SkinTench(false) end, order = 3, }, classbor = { name = "By Class", type = "toggle", width = "half", get = function() return db.classbor end, set = function() db.classbor = not db.classbor for i=1,numBuffsSkinned do SkinBuffs(i,false) end for i=1,numDebuffsSkinned do SkinDebuffs(i,false) end SkinTench(false) end, order = 4, }, debuffTypeBor = { name = "By Debuff Type", desc = "Display debuff dispel type as border instead of icon overlay.", type = "toggle", get = function() return db.debuffTypeBor end, set = function() db.debuffTypeBor = not db.debuffTypeBor for i=1,numDebuffsSkinned do SkinDebuffs(i,false) end end, order = 5, }, debuffOverlayAlpha = { name = "Debuff Overlay Alpha", desc = "Transparency of the debuffs' dispel type overlay.", type = "range", disabled = function() return db.debuffTypeBor end, min = .25, max = 1, step = .05, get = function() return db.debuffOverlayAlpha end, set = function(_,alpha) db.debuffOverlayAlpha = alpha for i=1,numDebuffsSkinned do SkinDebuffs(i,false) end end, order = 6, }, }, }, sbar = { name = "Statusbar", type = "group", inline = true, order = 10, args = { texture = { name = "Texture", type = "select", desc = "Select the texture used for the timer bars.", dialogControl = "LSM30_Statusbar", values = sbars, get = function() return db.sbar end, set = function(_,sbar) db.sbar = sbar for i=1,numBuffsSkinned do SkinBuffs(i,false) end for i=1,numDebuffsSkinned do SkinDebuffs(i,false) end SkinTench(false) end, order = 1, }, sbarColor = { name = "Color", desc = "Select a color for the timer bar texture.", type = "color", width = "half", disabled = function() return db.classbar end, get = function() return db.sbarColor.r, db.sbarColor.g, db.sbarColor.b end, set = function(_,r,g,b) db.sbarColor.r,db.sbarColor.g,db.sbarColor.b = r,g,b for i=1,numBuffsSkinned do SkinBuffs(i,false) end for i=1,numDebuffsSkinned do SkinDebuffs(i,false) end SkinTench(false) end, order = 2, }, classbar = { name = "By Class", type = "toggle", width = "half", get = function() return db.classbar end, set = function() db.classbar = not db.classbar for i=1,numBuffsSkinned do SkinBuffs(i,false) end for i=1,numDebuffsSkinned do SkinDebuffs(i,false) end SkinTench(false) end, order = 3, }, }, }, bg = { name = "Background", type = "group", inline = true, order = 11, args = { texture = { name = "Texture", type = "select", desc = "Select the texture used for the background.", dialogControl = "LSM30_Background", values = bgs, get = function() return db.bg end, set = function(_,bg) db.bg = bg for i=1,numBuffsSkinned do SkinBuffs(i,false) end for i=1,numDebuffsSkinned do SkinDebuffs(i,false) end SkinTench(false) end, order = 1, }, bgColor = { name = "Color", desc = "Select a color for the background texture.", type = "color", width = "half", disabled = function() return db.classbg end, get = function() return db.bgColor.r, db.bgColor.g, db.bgColor.b end, set = function(_,r,g,b) db.bgColor.r,db.bgColor.g,db.bgColor.b = r,g,b for i=1,numBuffsSkinned do SkinBuffs(i,false) end for i=1,numDebuffsSkinned do SkinDebuffs(i,false) end SkinTench(false) end, order = 2, }, classbg = { name = "By Class", type = "toggle", width = "half", get = function() return db.classbg end, set = function() db.classbg = not db.classbg for i=1,numBuffsSkinned do SkinBuffs(i,false) end for i=1,numDebuffsSkinned do SkinDebuffs(i,false) end SkinTench(false) end, order = 3, }, }, }, spacer2 = { name = " ", type = "description", width = "full", order = 12, }, header3 = { name = "Layout Options", type = "header", order = 13, }, posX = { name = "X-Offset", desc = "The horizontal offset from the top-right corner of your screen. This should be a negative number.", type = "input", width = "half", get = function() return tostring(db.posX) end, set = function(_,x) db.posX = tonumber(x) Position() end, order = 14, }, posY = { name = "Y-Offset", desc = "The vertical offset from the top-right corner of your screen. This should be a negative number.", type = "input", width = "half", get = function() return tostring(db.posY) end, set = function(_,y) db.posY = tonumber(y) Position() end, order = 15, }, mover = { name = "Show Anchor", type = "toggle", get = function() return moverShown end, set = function() moverShown = not moverShown ShowMover() end, order = 16, }, bprow = { name = "Buffs per Row", desc = "Number of buffs/debuffs before starting a new row.", type = "range", min = 2, max = BUFF_MAX_DISPLAY, step = 1, get = function() return db.bprow end, set = function(_,bprow) db.bprow = bprow BUFFS_PER_ROW = bprow end, order = 17, }, sizes = { name = "Frame Sizes", type = "group", inline = true, order = 17.5, args = { buffSize = { name = "Buffs", desc = "The size of the buff frames.", type = "range", min = 20, max = 60, step = 1, get = function() return db.buffs.size end, set = function(_,size) db.buffs.size = size for i=1,numBuffsSkinned do SkinBuffs(i,false) end SkinTench(false) end, order = 1, }, debuffSize = { name = "Debuffs", desc = "The size of the debuff frames.", type = "range", min = 20, max = 60, step = 1, get = function() return db.debuffs.size end, set = function(_,size) db.debuffs.size = size for i=1,numDebuffsSkinned do SkinDebuffs(i,false) end end, order = 2, }, }, }, spacer3 = { name = " ", type = "description", width = "full", order = 18, }, header4 = { name = "Profile", type = "header", order = 19, }, charSpec = { name = "Character specific settings", desc = "Have this character use their own profile. If checked, any changes made will not affect other characters.\n\n|c00E30016WARNING:|r Your UI will be reloaded in the process!", type = "toggle", width = "full", confirm = true, get = function() return ShinyBuffsDB.charSpec end, set = function() ShinyBuffsPCDB.charSpec = not ShinyBuffsPCDB.charSpec ReloadUI() end, order = 20, }, copyProfile = { name = "Copy from Default", desc = "Copy all settings from the default, global profile to this character's profile. This will not effect other characters' specific profiles.\n\n|c00E30016WARNING:|r Your UI will be reloaded in the process!", type = "execute", confirm = true, disabled = function() return not ShinyBuffsPCDB.charSpec end, func = function() ShinyBuffsPCDB = ShinyBuffsDB ShinyBuffsPCDB.charSpec = true ReloadUI() end, order = 21, }, resetProfile = { name = "Profile Reset", desc = "Reset this profile back to the out-of-the-box settings. If you reset the character specific profile, the global profile will be untouched, and vice versa. This will not effect other character specific profiles.\n\n|c00E30016WARNING:|r Your UI will be reloaded in the process!", type = "execute", confirm = true, func = function() if ShinyBuffsPCDB.charSpec then ShinyBuffsPCDB = {charSpec = true} else ShinyBuffsDB = {} end ReloadUI() end, order = 22, }, }, } local function SetUpDB() if ShinyBuffsPCDB.charSpec then --set defaults if new charSpec DB for k,v in pairs(defaults) do if type(ShinyBuffsPCDB[k]) == "nil" then ShinyBuffsPCDB[k] = v end end db = ShinyBuffsPCDB else db = ShinyBuffsDB end end local function PEW() ShinyBuffsDB = ShinyBuffsDB or {} ShinyBuffsPCDB = ShinyBuffsPCDB or {} if ShinyBuffsPCDB.charSpec == nil then ShinyBuffsPCDB.charSpec = false end for k,v in pairs(defaults) do if type(ShinyBuffsDB[k]) == "nil" then ShinyBuffsDB[k] = v end end SetUpDB() classColor = CUSTOM_CLASS_COLORS and CUSTOM_CLASS_COLORS[class] or RAID_CLASS_COLORS[class] if CUSTOM_CLASS_COLORS then CUSTOM_CLASS_COLORS:RegisterCallback(function() if db.classbor or db.classbg or db.classbar then for i=1,numBuffsSkinned do SkinBuffs(i,false) end for i=1,numDebuffsSkinned do SkinDebuffs(i,false) end SkinTench(false) end end) end LibStub("AceConfig-3.0"):RegisterOptionsTable("ShinyBuffs", options) SB.optionsFrame = LibStub("AceConfigDialog-3.0"):AddToBlizOptions("ShinyBuffs", "ShinyBuffs") SlashCmdList["SHINYBUFFS"] = function() InterfaceOptionsFrame_OpenToCategory("ShinyBuffs") InterfaceOptionsFrame_OpenToCategory("ShinyBuffs") end SLASH_SHINYBUFFS1 = "/shinybuffs" SLASH_SHINYBUFFS2 = "/sb" if db.allWhiteText then BUFF_DURATION_WARNING_TIME = 7200 end BUFF_ROW_SPACING = 15 BUFFS_PER_ROW = db.bprow C_Timer.After(.25, SkinAuras) SkinTench(true) --keep other stuff (like ticket frame) from moving buffs BuffFrame.NewSetPoint = BuffFrame.SetPoint BuffFrame.SetPoint = Position Position() WhoCast() SB:UnregisterEvent("PLAYER_ENTERING_WORLD") SB:RegisterUnitEvent("UNIT_AURA", "player") SB:SetScript("OnEvent", function(s,e,unit) SkinAuras() --don't bother checking if they're all skinned if numBuffsSkinned == BUFF_MAX_DISPLAY and numDebuffsSkinned == DEBUFF_MAX_DISPLAY then SB:UnregisterEvent("UNIT_AURA") SB:SetScript("OnEvent", nil) end end) PEW = nil end LSM:Register("border", "SB border", "Interface\\AddOns\\ShinyBuffs\\media\\5.tga") LSM:Register("statusbar", "Solid", "Interface\\AddOns\\ShinyBuffs\\media\\Solid.tga") LSM:Register("background", "Solid", "Interface\\AddOns\\ShinyBuffs\\media\\Solid.tga") SB:SetScript("OnEvent", PEW) SB:RegisterEvent("PLAYER_ENTERING_WORLD")