--[[ Version 1.4.1.1 Author : Adoriele of US Dragonblight - with permission from Levva of EU Khadgar Repurposed version of ShockAndAwe, an Enhancement Shaman addon, for Balance Druids. Provides Debuff timers, as well as proc and cooldown bars for Eclipse and Omen of Clarity. Changelog: v1.4.1.1 - Added support for T102P v1.4.1 - Eclipse cooldown no longer constantly refreshes to 30s, added eclipse type to Eclipse cooldown bars, changed functionality of Eclipse buff bar to go grey if the buff disappears early v1.4.0 - 3.3 patch workaround for lack of Eclipse in Combat Log v1.3.3 - Fixed bug causing debuffs not to spawn when switching targets. Fixed bug involving disabling a bar that's currently active. v1.3.2 - Oops: Applied Debuff/CC change to Abilities as well, and to be safe did similar things to Procs and Trinkets as a double-check. Also fixed a bug that would not let you turn off the Eclipse bar. v1.3.1 - Fixed "Debuff/CC, a nil value" bug v1.3 - Serious revamp of underlying mechanics. Added trinket bars, cc bars, multiple proc bars. Added ability to merge bars of the same type (except procs). Adding custom bars should now be much easier, relatively. v1.2.1 - Fixed bug with Eclipse and Moonfire bars overlapping, changed FF bar to accept any FF. v1.2 - 3.1 Compatability v1.1.1 - Fixed GCD bar to be localization independent, added SF Combo points, structural changes v1.1 - Finally fixed OoC issue, removed dependency on localization for functionality v1.0.5 - Fixed encoding issue with Russian locale, added German locale v1.0.4 - Fixed a bug with the French localization, added Russian and Taiwan V1.0.3 - Fixed a bug with the OoC bar V1.0.2 - Added French localization, fixed test bar bug V1.0.1 - Added text and icon options --]] -- Don't load if it's not a Druid if select(2, UnitClass('player')) ~= "DRUID" then DisableAddOn("SquawkAndAwe") return end -- Basic Ace3 stuff local L = LibStub("AceLocale-3.0"):GetLocale("SquawkAndAwe") local AceAddon = LibStub("AceAddon-3.0") local media = LibStub:GetLibrary("LibSharedMedia-3.0"); SquawkAndAwe = AceAddon:NewAddon("SquawkAndAwe", "AceConsole-3.0", "AceEvent-3.0", "AceTimer-3.0") local REVISION = tonumber(("$Revision: 1.4.1.1 $"):match("%d+")) -- Frame creation SquawkAndAwe.frames = {} SquawkAndAwe.BaseFrame = CreateFrame("Frame","SquawkAndAweBase",UIParent) -- Other initializations SquawkAndAwe.textures = {} SquawkAndAwe.borders = {} SquawkAndAwe.fonts = {} SquawkAndAwe.sounds = {} SquawkAndAwe.barBackdrop = { bgFile = "Interface/Tooltips/UI-Tooltip-Background", edgeFile = "Interface/Tooltips/UI-Tooltip-Border", tile = false, tileSize = 0, edgeSize = 12, insets = { left = 2, right = 2, top = 2, bottom = 2 } } SquawkAndAwe.frameBackdrop ={ bgFile = "Interface/Tooltips/UI-Tooltip-Background", --edgeFile = "Interface/Tooltips/UI-Tooltip-Border", tile = false, tileSize = 0, edgeSize = 12, insets = { left = 0, right = 0, top = 0, bottom = 0 } } SquawkAndAwe.combat = {} SquawkAndAwe.combat.procs = {} SquawkAndAwe.combat.procs.Eclipse = {id = 48518, name = GetSpellInfo(48518), cd = 30} SquawkAndAwe.combat.procs.Eclipsew = {id = 48517, name = GetSpellInfo(48517), cd = 30} SquawkAndAwe.combat.procs.Omen = {id = 16870, name = GetSpellInfo(16870)} SquawkAndAwe.combat.procs.T102P = {id = 70721, name = GetSpellInfo(70721)} SquawkAndAwe.combat.procs.T84P = {id = 64823, name = GetSpellInfo(64823)} SquawkAndAwe.combat.procs.PVP = {id = 46833, name = GetSpellInfo(46833)} SquawkAndAwe.combat.debuffs = {} SquawkAndAwe.combat.debuffs.Moonfire = {id = 48463, name = GetSpellInfo(48463), tick = 3} SquawkAndAwe.combat.debuffs.Insect = {id = 48468, name = GetSpellInfo(48468), tick = 2} SquawkAndAwe.combat.debuffs.Faerie = {id = 770, name = GetSpellInfo(770)} SquawkAndAwe.combat.cc = {} SquawkAndAwe.combat.cc.Roots = {id = 339, name = GetSpellInfo(339)} SquawkAndAwe.combat.cc.Hibernate = {id = 2637, name = GetSpellInfo(2637)} SquawkAndAwe.combat.cc.Cyclone = {id = 33786, name = GetSpellInfo(33786)} SquawkAndAwe.combat.abilities = {} SquawkAndAwe.combat.abilities.Innervate = {id = 29166, name = GetSpellInfo(29166)} SquawkAndAwe.combat.abilities.Force = {id = 33831, name = GetSpellInfo(33831), dur = 30} SquawkAndAwe.combat.abilities.Starfall = {id = 48505, name = GetSpellInfo(48505)} SquawkAndAwe.combat.abilities.Typhoon = {id = 50516, name = GetSpellInfo(50516)} SquawkAndAwe.combat.abilities.Barkskin = {id = 22812, name = GetSpellInfo(22812)} SquawkAndAwe.combat.trinkets = {} SquawkAndAwe.combat.trinkets.flare = {id = 64713, itemid = 45518, name = GetSpellInfo(64713), itemname = GetItemInfo(45518), color = {r=1, g=0.8, b=0.32, a=0.9}, cd = 45} SquawkAndAwe.combat.trinkets.flame = {id = 64712, itemid = 45148, name = GetSpellInfo(64712), itemname = GetItemInfo(45148), color = {r=1, g=0.42, b=0, a=0.9}} SquawkAndAwe.combat.trinkets.pandora = {id = 64741, itemid = 45490, name = GetSpellInfo(64741), itemname = GetItemInfo(45490), color = {r=0.13, g=1, b=0.35, a=0.9}, cd = 45} SquawkAndAwe.combat.trinkets.fates = {id = 64707, itemid = 45466, name = GetSpellInfo(64707), itemname = GetItemInfo(45466), color = {r=0.16, g=1, b=0.69, a=0.9}} SquawkAndAwe.combat.trinkets.focus = {id = 65004, itemid = 45866, name = GetSpellInfo(65004), itemname = GetItemInfo(45866), color = {r=0.46, g=0.38, b=1, a=0.9}, cd = 45} SquawkAndAwe.combat.trinkets.siphon = {id = 65008, itemid = 45292, name = GetSpellInfo(65008), itemname = GetItemInfo(45292), color = {r=0.5, g=0, b=1, a=0.9}} SquawkAndAwe.combat.trinkets.broodmother = {id = 65006, itemid = 45308, name = GetSpellInfo(65006), itemname = GetItemInfo(45308), color = {r=0, g=1, b=0.3, a=0.9}, cd = 0} SquawkAndAwe.combat.trinkets.dying = {id = 60494, itemid = 40255, name = GetSpellInfo(60494), itemname = GetItemInfo(40255), color = {r=0, g=0.37, b=0.12, a=0.9}, cd = 45} SquawkAndAwe.combat.trinkets.illustration = {id = 60486, itemid = 40432, name = GetSpellInfo(60486), itemname = GetItemInfo(40432), color = {r=0.75, g=0.30, b=0.65, a=0.9}, cd = 0} SquawkAndAwe.combat.trinkets.spider = {id = 60492, itemid = 39229, name = GetSpellInfo(60492), itemname = GetItemInfo(39229), color = {r=0.62, g=0.27, b=0.18, a=0.9}, cd = 45} SquawkAndAwe.combat.trinkets.sundial = {id = 60064, itemid = 40682, name = GetSpellInfo(60064), itemname = GetItemInfo(40682), color = {r=0.16, g=0.93, b=0.91, a=0.9}, cd = 45} SquawkAndAwe.combat.trinkets.serpent = {id = 56184, itemid = 42395, name = GetSpellInfo(56184), itemname = GetItemInfo(42395), color = {r=0.2, g=0.02, b=0.48, a=0.9}} SquawkAndAwe.combat.trinkets.ember = {id = 60479, itemid = 37660, name = GetSpellInfo(60479), itemname = GetItemInfo(37660), color = {r=1, g=0.04, b=0.09, a=0.9}, cd = 45} SquawkAndAwe.combat.trinkets.prisoner = {id = 60480, itemid = 37873, name = GetSpellInfo(60480), itemname = GetItemInfo(37873), color = {r=0.51, g=0.47, b=0.50, a=0.9}} SquawkAndAwe.combat.trinkets.winged = {id = 60521, itemid = 37844, name = GetSpellInfo(60521), itemname = GetItemInfo(37844), color = {r=1, g=0.35, b=0.73, a=0.9}} SquawkAndAwe.combat.trinkets.tome = {id = 60471, itemid = 36972, name = GetSpellInfo(60471), itemname = GetItemInfo(36972), color = {r=0.84, g=0.6, b=0.15, a=0.9}} SquawkAndAwe.combat.Moonglade = {id = 18960, name = GetSpellInfo(18960)} SquawkAndAwe.combat.Starfire = {id = 2912, name = GetSpellInfo(2912)} SquawkAndAwe.combat.Wrath = {id = 5176, name = GetSpellInfo(5176)} SquawkAndAwe.combat.FeralFF = {id = 16857, name = GetSpellInfo(16857)} SquawkAndAwe.actives = {} SquawkAndAwe.actives.trinkets = {} SquawkAndAwe.actives.procs = {} SquawkAndAwe.actives.cc = {} SquawkAndAwe.actives.debuffs = {} SquawkAndAwe.actives.abilities = {} SquawkAndAwe.ActiveEclipseBuff = false SquawkAndAwe.activeTrinketNames = {} SquawkAndAwe.activeTrinketNames.Trinket1 = "flare" SquawkAndAwe.activeTrinketNames.Trinket2 = "flame" SquawkAndAwe.times = {} SquawkAndAwe.barFrames = {} local barFrameIndex = 0 SquawkAndAwe.statusBars = {} local statusbarIndex = 0 local playerName = UnitName("player"); local LastMF = 0 local SFCombos = 0 local EclipseType = "" ------------------- -- Config details ------------------- local defaults = { char = { -- Settings -- Frame fWidth = 300, barHeight = 25, scale = 1, -- Bars bars = { -- Maximum bar length in time MaxLen = 30, -- Trinkets trinketshow = false, mergetrinkets = true, trinketcd = false, -- Procs procs = { Eclipse = { show = true, color = {r=1, g=1, b=1, a=0.9}, wcolor = {r=0, g=1, b=0, a=0.9}, cd = true, flash = true, }, Omen = { show = true, color = {r=0.6, g=0.6, b=1, a=0.9}, flash = false, }, T102P = { show = true, color = {r=0.6, g=0.6, b=1, a=0.9}, flash = false, }, T84P = { show = true, color = {r=0.43, g=0.61, b=1, a=0.9}, flash = true, }, PVP = { show = false, color = {r=0.54, g=0.32, b=1, a=0.9}, flash = true, }, }, cdcolor = {r=0.6, g=0.6, b=0.6, a=0.9}, -- Debuffs debuffs = { Moonfire = { show = true, color = {r=0.5, g=0, b=1, a=0.9}, tick = true, }, Insect = { show = true, color = {r=0, g=1, b=0.3, a=0.9}, tick = true, }, Faerie = { show = true, color = {r=1, g=0.5, b=1, a=0.9}, }, } , mergedebuffs = false, tickcolor = {r=0.6, g=0.6, b=0.6, a=0.9}, -- CC cc = { Roots = { show = true, color = {r=0.38, g=0.2, b=0.08, a=0.9}, }, Hibernate = { show = true, color = {r=1, g=0.55, b=0.54, a=0.9}, }, Cyclone = { show = true, color = {r=0.25, g=0.25, b=0.25, a=0.9}, }, }, mergecc = true, -- Abilities abilities = { Starfall = { show = true, color = {r=1, g=1, b=1, a=0.9}, dur = true, }, Typhoon = { show = true, color = {r=0.5, g=0, b=1, a=0.9}, }, Force = { show = true, color = {r=0, g=1, b=0, a=0.9}, dur = true, }, Innervate = { show = true, color = {r=0, g=0, b=1, a=0.9}, dur = true, }, Barkskin = { show = true, color = {r=1, g=1, b=0, a=0.9}, dur = true, }, }, mergeabilities = true, GCD = { show = true, color = {r=0.6, g=0.6, b=0.6, a=0.6}, }, }, -- Media texture = "BantoBar", border = "None", barborder = "None", icons = true, -- Text barstext = true, barfont = "Friz Quadrata TT", barfontsize = 12, spellnames = true, durations = true, eclipsetype = true, sfcomboshow = true, -- Main debug = false, barshow = true, -- Incidentals relativeTo = "UIParent", relativePoint = "CENTER", point = "CENTER", xOffset = 0, yOffset = 0, --fHeight = 175, -- unused so far message = "Welcome Home!", resetOn = true, } } ----------------------------------------- -- Initialisation & Startup Routines ----------------------------------------- -- Changed to hide uptime, stats, priority frames, kill options for now function SquawkAndAwe:OnInitialize() local AceConfigReg = LibStub("AceConfigRegistry-3.0") local AceConfigDialog = LibStub("AceConfigDialog-3.0") self.db = LibStub("AceDB-3.0"):New("SquawkAndAweDBPC", SquawkAndAwe.defaults, "char") LibStub("AceConfig-3.0"):RegisterOptionsTable("SquawkAndAwe", self:GetOptions(), {"SquawkAndAwe", "saa"} ) media.RegisterCallback(self, "LibSharedMedia_Registered") -- Add the options to blizzard frame (add them backwards so they show up in the proper order self.optionsFrame = AceConfigDialog:AddToBlizOptions("SquawkAndAwe","SquawkAndAwe") self.optionsFrame[L["About"]] = LibStub("LibAboutPanel").new("SquawkAndAwe", "SquawkAndAwe") self.db:RegisterDefaults(defaults) local version = GetAddOnMetadata("SquawkAndAwe","Version") self.version = ("SquawkAndAwe v%s (r%s)"):format(version, REVISION) self:Print(self.version.." Loaded.") end function SquawkAndAwe:OnDisable() -- Called when the addon is disabled end -- Unregistered a couple events, should work function SquawkAndAwe:OnEnable() self:LibSharedMedia_Registered() self:RegisterEvent("PLAYER_ENTERING_WORLD") self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") self:RegisterEvent("PLAYER_TARGET_CHANGED") self:RegisterEvent("SPELL_UPDATE_COOLDOWN") self:RegisterEvent("UNIT_AURA") end -- Should work without changes function SquawkAndAwe:LibSharedMedia_Registered() for k, v in pairs(media:List("statusbar")) do self.textures[v] = v end for k, v in pairs(media:List("border")) do self.borders[v] = v end for k, v in pairs(media:List("font")) do self.fonts[v] = v end for k, v in pairs(media:List("sound")) do self.sounds[v] = v end end ---------------------- -- Event Routines ---------------------- function SquawkAndAwe:PLAYER_ENTERING_WORLD() self:SetBorderTexture(nil, self.db.char.border) self:SetBarBorderTexture(nil, self.db.char.barborder) self:RedrawFrames() end function SquawkAndAwe:UNIT_AURA(event,id) if id == "player" and not SquawkAndAwe.ActiveEclipseBuff then -- local _,_,_,_,_,_,_,_,_,_,spellID = UnitBuff("player",SquawkAndAwe.combat.procs.Eclipse.name); -- if spellID == SquawkAndAwe.combat.procs.Eclipse.id then if UnitBuff("player",SquawkAndAwe.combat.procs.Eclipse.name) then SquawkAndAwe.ActiveEclipseBuff = true SquawkAndAwe:ProcBars("Eclipse", SquawkAndAwe.combat.procs.Eclipse) -- elseif spellID == SquawkAndAwe.combat.procs.Eclipsew.id then elseif UnitBuff("player",SquawkAndAwe.combat.procs.Eclipsew.name) then SquawkAndAwe.ActiveEclipseBuff = true SquawkAndAwe:ProcBars("Eclipsew", SquawkAndAwe.combat.procs.Eclipsew) end end -- if id == "player" end -- function SAA:UNIT_AURA() function SquawkAndAwe:COMBAT_LOG_EVENT_UNFILTERED(_, timestamp, event, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, ...) local k,v,_,icon,color local spellID = select(1, ...) local spellName = select(2,...) if sourceGUID == UnitGUID("player") then if event == "SPELL_AURA_APPLIED" then -- Trinket handler for k,v in pairs (SquawkAndAwe.combat.trinkets) do if spellID == v.id then if self.db.char.bars.trinketshow then SquawkAndAwe:TrinketBars(k,v) end -- if trinketshow return end -- if spellID == v.id end -- for k,v in pairs(trinkets) -- Proc handler for k,v in pairs(SquawkAndAwe.combat.procs) do if spellID == v.id then SquawkAndAwe:ProcBars(k,v) return end -- if spellID == v.id end -- for k,v in pairs(procs) -- Debuff Handler for k,v in pairs(SquawkAndAwe.combat.debuffs) do if spellName == v.name then if spellName == SquawkAndAwe.combat.debuffs.Moonfire.name then SFCombos = 0 LastMF = 0 end SquawkAndAwe:DebuffBars(k,v) return end -- if spellID == v.id end -- for k,v in pairs(debuffs) -- CC Handler for k,v in pairs(SquawkAndAwe.combat.cc) do if spellName == v.name then SquawkAndAwe:CCBars(k) return end end -- Check for IS, MF ticks, reset bars elseif event == "SPELL_PERIODIC_DAMAGE" and destName == UnitName("target")then if spellID == SquawkAndAwe.combat.debuffs.Moonfire.id then if self.db.char.bars.debuffs.Moonfire.tick then SquawkAndAwe.times.MoonfireTick = GetTime() + SquawkAndAwe.combat.debuffs.Moonfire.tick end elseif spellID == SquawkAndAwe.combat.debuffs.Insect.id then if self.db.char.bars.debuffs.Insect.tick then SquawkAndAwe.times.InsectTick = GetTime() + SquawkAndAwe.combat.debuffs.Insect.tick end end -- Check for spell casts for spells that generate them elseif event == "SPELL_CAST_SUCCESS" then -- Ability handler for k,v in pairs(SquawkAndAwe.combat.abilities) do if spellName == v.name then SquawkAndAwe:AbilityBars(k,v) return end end -- Debuff Handler for k,v in pairs(SquawkAndAwe.combat.debuffs) do if spellName == v.name then if spellName == SquawkAndAwe.combat.debuffs.Moonfire.name then SFCombos = 0 LastMF = 0 end SquawkAndAwe:DebuffBars(k,v) return end -- if spellID == v.id end -- for k,v in pairs(debuffs) end -- event == EVENT -- Add handling for FF from any source elseif (spellID == SquawkAndAwe.combat.debuffs.Faerie.id or spellID == SquawkAndAwe.combat.FeralFF.id) and destName == UnitName("target") and (event == "SPELL_CAST_SUCCESS" or event == "SPELL_AURA_APPLIED") then --[[if self.db.char.bars.debuffs.Faerie.show then SquawkAndAwe.actives.debuffs.Faerie = true if self.db.char.bars.mergedebuffs then self.frames["Debuffs"]:Show() else self.frames["Faerie"]:Show() end end--]] SquawkAndAwe:DebuffBars("Faerie", SquawkAndAwe.combat.debuffs.Faerie) end -- if sourceGUID == player end -- Triggers GCD bar function SquawkAndAwe:SPELL_UPDATE_COOLDOWN() if self.db.char.bars.GCD.show then self:GCDBar() end end -- Changing targets should refresh CC and Debuff bars function SquawkAndAwe:PLAYER_TARGET_CHANGED() SquawkAndAwe:TriggerDebuffs() SquawkAndAwe:TriggerCC() end --------------------------- -- Buff Info functions --------------------------- -- Generic spell getter function SquawkAndAwe:GetSpellInfo(spellName, spelltype) local index = 1 if spelltype == "buff" then while UnitBuff("player", index) do local name, _, _, _, _, _, expires = UnitBuff("player", index) -- if name == spellName then if name == spellName or (spellName == "Eclipse (Lunar)" and EclipseType == "Wrath" and name == "Eclipse (Solar)") then return expires end index = index + 1 end return 0 elseif spelltype == "debuff" or spelltype == "cc" then while UnitDebuff("target", index) do local name, _, _, _, _, _, expires, source = UnitDebuff("target", index) if name == spellName and (source == "player" or spellName == self.combat.debuffs.Faerie.name or spellName == self.combat.FeralFF.name) then return expires end index = index + 1 end if spelltype == "cc" then index = 1 while UnitDebuff("focus", index) do local name, _, _, _, _, _, expires, source = UnitDebuff("focus", index) if name == spellName and source == "player" then return expires end index = index + 1 end end return 0 elseif spelltype == "cd" then local start, duration, enable = GetSpellCooldown(spellName) return start + duration elseif spelltype == "item" then local start, duration, enable = GetItemCooldown(spellName) return start + duration end end --------------------------- -- functions --------------------------- -- Alias for CreateBaseFrame() function SquawkAndAwe:RedrawFrames() self:ClearActives() self:HideAllBars() self:SetBaseFrame() end -- Finds the number of bars which have been activated. Merged categories count -- as one bar, no matter how many bars are active function SquawkAndAwe:FindNumBars() local num = 0 local add local k,v -- Add trinket bars if self.db.char.bars.trinketshow and self.db.char.bars.mergetrinkets then num = num + 1 elseif self.db.char.trinketshow then num = num + 2 end -- Add proc bars (checking for Eclipse CD bar, even if buff bar is disabled) for k,v in pairs(self.db.char.bars.procs) do if self.db.char.bars.procs[k].show or self.db.char.bars.procs[k].cd then num = num + 1 end end -- Check for any debuff bars add = 0 for k,v in pairs(self.db.char.bars.debuffs) do if self.db.char.bars.debuffs[k].show then add = add + 1 end end if self.db.char.bars.mergedebuffs and not add == 0 then num = num + 1 -- If merged, only add one bar, and only of any are enabled else num = num + add -- If not, add as many as are enabled end -- Check for cc bars add = 0 for k,v in pairs(self.db.char.bars.cc) do if self.db.char.bars.cc[k].show then add = add + 1 end end if self.db.char.bars.mergecc and not add == 0 then num = num + 1 else num = num + add end -- Check for ability bars add = 0 for k,v in pairs(self.db.char.bars.abilities) do if self.db.char.bars.abilities[k].show then add = add + 1 end end if self.db.char.bars.mergeabilities and not add == 0 then num = num + 1 else num = num + add end -- Check for GCD bar if self.db.char.bars.GCD.show then num = num + 1 end return num end -- Prints version number function SquawkAndAwe:DisplayVersion() self:Print(self.version) end -- Clear the actives listings function SquawkAndAwe:ClearActives() SquawkAndAwe.actives = {} SquawkAndAwe.actives.trinkets = {} SquawkAndAwe.actives.procs = {} SquawkAndAwe.actives.cc = {} SquawkAndAwe.actives.debuffs = {} SquawkAndAwe.actives.abilities = {} end function SquawkAndAwe:HideAllBars() for i,v in ipairs(SquawkAndAwe.barFrames) do v:Hide() end end -- Creates base frame, calls CreateBarFrames() function SquawkAndAwe:SetBaseFrame() -- Basic config self.BaseFrame:SetScale(self.db.char.scale) self.BaseFrame:SetFrameStrata("BACKGROUND") local width self.BaseFrame:SetWidth(self.db.char.fWidth + (self.db.char.icons and self.db.char.barHeight + 9 or 0)) self.BaseFrame:SetHeight((self.db.char.barHeight + 3) * self:FindNumBars() + 3) self.BaseFrame:SetBackdrop(self.frameBackdrop) self.BaseFrame:SetBackdropColor(1, 1, 1, 0) self.BaseFrame:SetMovable(true) self.BaseFrame:RegisterForDrag("LeftButton") self.BaseFrame:SetPoint(self.db.char.point, self.db.char.relativeTo, self.db.char.relativePoint, self.db.char.xOffset, self.db.char.yOffset) -- Set the start-drag script self.BaseFrame:SetScript("OnDragStart", function() self.BaseFrame:StartMoving(); end ); -- Set the stop-drag script self.BaseFrame:SetScript("OnDragStop", function() self.BaseFrame:StopMovingOrSizing(); self.BaseFrame:SetScript("OnUpdate", nil); self:FinishedMoving(self.db.char, self.BaseFrame); end ); -- Show the frame, reset the toggle self.BaseFrame:Show() self.db.char.barshow = false -- Create the bar frames self:CreateBarFrames() end -- Creates bar frames by iterating through categories and setting up each, -- either merged or not function SquawkAndAwe:CreateBarFrames() -- Bar creation local barCount = 0 local k,v local layer local add -- Reset frames container self.frames = {} barFrameIndex = 0 statusbarIndex = 0 -- Trinket Bars if self.db.char.bars.trinketshow then if self.db.char.bars.mergetrinkets then SquawkAndAwe:SetBarFrame("Trinkets", barCount) SquawkAndAwe:AddStatusBar(self.frames["Trinkets"], "Trinket1", SquawkAndAwe.combat.trinkets.flare.color, 2) SquawkAndAwe:AddStatusBar(self.frames["Trinkets"], "Trinket2", SquawkAndAwe.combat.trinkets.flame.color, 1) barCount = barCount + 1 else -- First trinket bar SquawkAndAwe:SetBarFrame("Trinket1", barCount) SquawkAndAwe:SetBarFrame("Trinket2", barCount + 1) barCount = barCount + 2 if self.db.char.bars.trinketcd then SquawkAndAwe:AddStatusBar(self.frames["Trinket1"], "Trinket1CD", self.db.char.bars.cdcolor, 1) SquawkAndAwe:AddStatusBar(self.frames["Trinket1"], "Trinket1", SquawkAndAwe.combat.trinkets.flare.color, 2) SquawkAndAwe:AddStatusBar(self.frames["Trinket2"], "Trinket2CD", self.db.char.bars.cdcolor, 1) SquawkAndAwe:AddStatusBar(self.frames["Trinket2"], "Trinket2", SquawkAndAwe.combat.trinkets.flame.color, 2) else SquawkAndAwe:AddStatusBar(self.frames["Trinket1"], "Trinket1", SquawkAndAwe.combat.trinkets.flare.color, 1) SquawkAndAwe:AddStatusBar(self.frames["Trinket2"], "Trinket2", SquawkAndAwe.combat.trinkets.flame.color, 1) end end end -- Proc bars for k,v in pairs(self.db.char.bars.procs) do if v.show or v.cd then SquawkAndAwe:SetBarFrame(k, barCount, SquawkAndAwe.combat.procs[k].id) if v.cd then SquawkAndAwe:AddStatusBar(self.frames[k], k.."CD", self.db.char.bars.cdcolor, 1) if v.show then SquawkAndAwe:AddStatusBar(self.frames[k], k, v.color, 2) end else SquawkAndAwe:AddStatusBar(self.frames[k], k, v.color, 1) end barCount = barCount + 1 end end -- Debuff bars layer = 1 add = 0 if self.db.char.bars.mergedebuffs then -- Make sure at least one is enabled for k,v in pairs(self.db.char.bars.debuffs)do if v.show then add = add + 1 end end if add > 0 then SquawkAndAwe:SetBarFrame("Debuffs", barCount) for k,v in pairs(self.db.char.bars.debuffs) do if v.show then SquawkAndAwe:AddStatusBar(self.frames["Debuffs"], k, v.color, layer) layer = layer + 1 end end barCount = barCount + 1 end else for k,v in pairs(self.db.char.bars.debuffs) do if v.show then SquawkAndAwe:SetBarFrame(k, barCount, SquawkAndAwe.combat.debuffs[k].id) SquawkAndAwe:AddStatusBar(self.frames[k], k, v.color, 1) if v.tick then SquawkAndAwe:AddStatusBar(self.frames[k], k.."Tick", self.db.char.bars.tickcolor, 2, true, SquawkAndAwe.combat.debuffs[k].tick) end barCount = barCount + 1 end end end -- CC bars layer = 1 add = 0 if self.db.char.bars.mergecc then -- Make sure at least one is enabled for k,v in pairs(self.db.char.bars.cc)do if v.show then add = add + 1 end end if add > 0 then SquawkAndAwe:SetBarFrame("CC", barCount) for k,v in pairs(self.db.char.bars.cc) do if v.show then SquawkAndAwe:AddStatusBar(self.frames["CC"], k, v.color, layer) layer = layer + 1 end end barCount = barCount + 1 end else for k,v in pairs(self.db.char.bars.cc) do if v.show then SquawkAndAwe:SetBarFrame(k, barCount, SquawkAndAwe.combat.cc[k].id) SquawkAndAwe:AddStatusBar(self.frames[k], k, v.color, 1) barCount = barCount + 1 end end end -- Ability bars layer = 1 add = 0 if self.db.char.bars.mergeabilities then -- Make sure at least one is enabled for k,v in pairs(self.db.char.bars.abilities)do if v.show then add = add + 1 end end if add > 0 then SquawkAndAwe:SetBarFrame("Abilities", barCount) for k,v in pairs(self.db.char.bars.abilities) do if v.show then SquawkAndAwe:AddStatusBar(self.frames.Abilities, k, v.color, layer) layer = layer + 1 end end barCount = barCount + 1 end else for k,v in pairs(self.db.char.bars.abilities) do if v.show then SquawkAndAwe:SetBarFrame(k, barCount, SquawkAndAwe.combat.abilities[k].id) if v.dur then SquawkAndAwe:AddStatusBar(self.frames[k], k.."Dur", v.color, 2) SquawkAndAwe:AddStatusBar(self.frames[k], k, self.db.char.bars.cdcolor, 1) else SquawkAndAwe:AddStatusBar(self.frames[k], k, v.color, 1) end barCount = barCount + 1 end end end -- GCD Bar if self.db.char.bars.GCD.show then SquawkAndAwe:SetBarFrame("GCD", barCount) SquawkAndAwe:AddStatusBar(self.frames["GCD"], "GCD", self.db.char.bars.GCD.color, 1) end end -- Can't destroy frames, so we have to reuse them function SquawkAndAwe:GetNextBarFrame() barFrameIndex = barFrameIndex + 1 -- Grab a frame from storage newFrame = SquawkAndAwe.barFrames[barFrameIndex] if newFrame then return newFrame end -- If it wasn't there, create a new one and put it in storage newFrame = CreateFrame("Frame", "SAABarFrame"..barFrameIndex, SquawkAndAwe.BaseFrame) SquawkAndAwe.barFrames[barFrameIndex] = newFrame return newFrame end -- Sets up the bar frame, given its offset in number of bars from the top function SquawkAndAwe:SetBarFrame(frameName, frameOffset, spellID) local newFrame = SquawkAndAwe:GetNextBarFrame() -- Set up the frame newFrame:SetFrameStrata("LOW") newFrame:SetWidth(self.db.char.fWidth) newFrame:SetHeight(self.db.char.barHeight) newFrame:ClearAllPoints() newFrame:SetPoint("TOPRIGHT", self.BaseFrame, "TOPRIGHT", 0, frameOffset * self.db.char.barHeight * -1 - 3) newFrame:SetBackdrop(self.barBackdrop); newFrame:SetBackdropColor(0, 0, 0, 0.2); newFrame:SetBackdropBorderColor( 1, 1, 1, 1); newFrame:EnableMouse(false) -- Set up the icon local _, icon -- Create frame if not newFrame.icon then newFrame.icon = CreateFrame("Frame", "SAA_"..frameName.."Icon", newFrame) end -- Sizing and placement newFrame.icon:SetWidth(self.db.char.barHeight) newFrame.icon:SetHeight(self.db.char.barHeight) newFrame.icon:SetPoint("RIGHT", newFrame, "LEFT", -3, 0) -- If we were given a spell, apply the icon if spellID then _, _, icon = GetSpellInfo(spellID) newFrame.icon:SetBackdrop({bgFile = icon}) end if self.db.char.icons then newFrame.icon:Show() else newFrame.icon:Hide() end -- Set up the text -- Create the text overlay if not newFrame.text then newFrame.text = newFrame:CreateFontString(nil,"OVERLAY") end -- Apply font local barfont = media:Fetch("font", self.db.char.barfont) newFrame.text:SetFont(barfont, self.db.char.barfontsize) newFrame.text:SetTextColor(1, 1, 1, 1) -- Place text overlay newFrame.text:ClearAllPoints() if self.db.char.icons then newFrame.text:SetPoint("LEFT", newFrame.icon, "RIGHT", 9, 0) else newFrame.text:SetPoint("LEFT", newFrame, "LEFT", 6, 0) end -- Clear text newFrame.text:SetText("") -- Set update script newFrame:SetScript("OnUpdate", function() OnUpdate(); end ); -- Hide the frame newFrame:Hide() -- Add it to frame array self.frames[frameName] = newFrame end -- Can't destroy frames, so we have to reuse them function SquawkAndAwe:GetNextStatusBar() statusbarIndex = statusbarIndex + 1 -- Grab a frame from storage newFrame = SquawkAndAwe.statusBars[statusbarIndex] if newFrame then return newFrame end -- If it wasn't there, create a new one and put it in storage newFrame = CreateFrame("StatusBar", "SAA_Statusbar"..statusbarIndex, SquawkAndAwe.BaseFrame) SquawkAndAwe.statusBars[statusbarIndex] = newFrame return newFrame end -- Adds a status bar to a bar frame. If isTick is set, the bar is 1/3 height, -- and max/min values are changed function SquawkAndAwe:AddStatusBar(addToFrame, newFrameName, colors, frameLevel, isTick, tickDur) statusbar = SquawkAndAwe:GetNextStatusBar() statusbar:SetParent(addToFrame) statusbar:SetFrameLevel(frameLevel) statusbar:ClearAllPoints() statusbar:SetHeight((self.db.char.barHeight - 6) / (isTick and 3 or 1)) statusbar:SetWidth(self.db.char.fWidth - 6) statusbar:SetPoint("BOTTOMRIGHT", addToFrame, "BOTTOMRIGHT", -3, 3) statusbar:SetStatusBarTexture(media:Fetch("statusbar", self.db.char.texture)) statusbar:SetStatusBarColor(colors.r, colors.g, colors.b, colors.a) if isTick then statusbar:SetMinMaxValues(0,tickDur) statusbar:SetValue(tickDur / 2) -- Special case for GCD bar elseif newFrameName == "GCD" then statusbar:SetMinMaxValues(0,1.5) statusbar:SetValue(.75) else statusbar:SetMinMaxValues(0, self.db.char.bars.MaxLen) statusbar:SetValue(15) end -- Add the spark if not statusbar.spark then statusbar.spark = statusbar:CreateTexture(nil, "OVERLAY") end statusbar.spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark") statusbar.spark:SetWidth(16) statusbar.spark:SetHeight(self.db.char.barHeight + 10) statusbar.spark:SetBlendMode("ADD") statusbar.spark:SetPoint("CENTER", statusbar, "LEFT",(self.db.char.fWidth - 6)* 15/self.db.char.bars.MaxLen, -1) -- Hide it for ticks if istick then statusbar.spark:Show() else statusbar.spark:Hide() end addToFrame[newFrameName] = statusbar end -- Resets bars to center of screen function SquawkAndAwe:ResetBars() self.BaseFrame:ClearAllPoints() self.db.char.point = defaults.char.point self.db.char.relativeTo = defaults.char.relativeTo self.db.char.relativePoint = defaults.char.relativePoint self.db.char.xOffset = defaults.char.xOffset self.db.char.yOffset = defaults.char.yOffset self.db.char.fWidth = defaults.char.fWidth self.db.char.barHeight = defaults.char.barHeight self.db.char.scale = defaults.char.scale self.db.char.barfont = defaults.char.barfont self.db.char.barfontsize = defaults.char.barfontsize self.db.char.bartexture = defaults.char.bartexture self.db.char.texture = defaults.char.texture barshow = true self.BaseFrame:SetPoint(self.db.char.point, self.db.char.relativeTo, self.db.char.relativePoint, self.db.char.xOffset, self.db.char.yOffset) self:RedrawFrames() self.db.char.barshow = true -- so that call to ShowHideBars resets to false self:ShowHideBars() end -- Handles activating Trinket bars function SquawkAndAwe:TrinketBars(k, v) -- Trinket 1 already active, move to 2 if SquawkAndAwe.actives.trinkets.Trinket1 then SquawkAndAwe.actives.trinkets.Trinket2 = true SquawkAndAwe.activeTrinketNames.Trinket2 = k if v.cd and self.db.char.bars.trinketcd then SquawkAndAwe.times.Trinket2CD = GetTime() + v.cd end if self.db.char.bars.mergetrinkets then self.frames.Trinkets.Trinket2:SetStatusBarColor(v.color.r, v.color.g, v.color.b, v.color.a) self.frames.Trinkets.Trinket2:Show() -- Must set icon in OnUpdate(). Lowest duration trinket effect is not immutable else self.frames.Trinket2.Trinket2:SetStatusBarColor(v.color.r, v.color.g, v.color.b, v.color.a) if self.db.char.icons then _,_,icon = GetSpellInfo(v.id) self.frames.Trinket2.icon:SetBackdrop({bgFile = icon}) end self.frames.Trinket2:Show() end else SquawkAndAwe.actives.trinkets.Trinket1 = true SquawkAndAwe.activeTrinketNames.Trinket1 = k if v.cd and self.db.char.bars.trinketcd then SquawkAndAwe.times.Trinket1CD = GetTime() + v.cd end if self.db.char.bars.mergetrinkets then self.frames.Trinkets.Trinket1:SetStatusBarColor(v.color.r, v.color.g, v.color.b, v.color.a) self.frames.Trinkets:Show() self.frames.Trinkets.Trinket2:Hide() else if self.db.char.bars.trinketcd then SquawkAndAwe.actives.Trinket1CD = true end self.frames.Trinket1.Trinket1:SetStatusBarColor(v.color.r, v.color.g, v.color.b, v.color.a) if self.db.char.icons then _,_,icon = GetSpellInfo(v.id) self.frames.Trinket1.icon:SetBackdrop({bgFile = icon}) end self.frames.Trinket1:Show() end -- if mergetrinkets end -- if actives.Trinket1 end -- Handles activating Proc bars function SquawkAndAwe:ProcBars(k, v) local color -- Special handling for Wrath Eclipse if k == "Eclipsew" then if self.db.char.bars.procs.Eclipse.show or self.db.char.bars.procs.Eclipse.cd then if self.db.char.bars.procs.Eclipse.show then color = self.db.char.bars.procs.Eclipse.wcolor self.frames.Eclipse.Eclipse:SetStatusBarColor(color.r, color.g, color.b, color.a) SquawkAndAwe.actives.procs.Eclipse = true end SquawkAndAwe.times.EclipseCD = GetTime() + v.cd if self.db.char.icons then _,_,icon = GetSpellInfo(v.id) self.frames.Eclipse.icon:SetBackdrop({bgFile = icon}) end EclipseType = SquawkAndAwe.combat.Wrath.name self.frames.Eclipse:Show() end elseif self.db.char.bars.procs[k].show or self.db.char.bars.procs[k].cd then if v.id == SquawkAndAwe.combat.procs.Eclipse.id then EclipseType = SquawkAndAwe.combat.Starfire.name end if self.db.char.bars.procs[k].show then color = self.db.char.bars.procs[k].color self.frames[k][k]:SetStatusBarColor(color.r, color.g, color.b, color.a) SquawkAndAwe.actives.procs[k] = true end if v.cd then SquawkAndAwe.times[k.."CD"] = GetTime() + v.cd end if self.db.char.bars.procs[k].cd then SquawkAndAwe.actives[k.."CD"] = true end if self.db.char.icons then _,_,icon = GetSpellInfo(v.id) self.frames[k].icon:SetBackdrop({bgFile = icon}) end self.frames[k]:Show() end -- if spellID == Wrath else if show end -- Handles activating Debuff bars function SquawkAndAwe:DebuffBars(k, v, notick) if self.db.char.bars.debuffs[k].show then SquawkAndAwe.actives.debuffs[k] = true if self.db.char.bars.mergedebuffs then self.frames.Debuffs:Show() else if self.db.char.bars.debuffs[k].tick and not notick then SquawkAndAwe.times[k.."Tick"] = GetTime() + v.tick SquawkAndAwe.actives[k.."Tick"] = true end self.frames[k]:Show() end end -- if v.show end function SquawkAndAwe:TriggerDebuffs() for k,v in pairs(SquawkAndAwe.combat.debuffs) do if SquawkAndAwe.db.char.bars.debuffs[k].show then SquawkAndAwe:DebuffBars(k, v, true) end end end -- Handles activting CC bars function SquawkAndAwe:CCBars(k) if self.db.char.bars.cc[k].show then SquawkAndAwe.actives.cc[k] = true if self.db.char.bars.mergecc then self.frames.CC:Show() else self.frames[k]:Show() end end end function SquawkAndAwe:TriggerCC() for k,v in pairs(SquawkAndAwe.combat.cc) do if SquawkAndAwe.db.char.bars.cc[k].show then SquawkAndAwe:CCBars(k) end end end -- Handles activating Ability bars function SquawkAndAwe:AbilityBars(k, v) if self.db.char.bars.abilities[k].show then SquawkAndAwe.actives.abilities[k] = true if self.db.char.bars.mergeabilities then self.frames.Abilities:Show() else if self.db.char.bars.abilities[k].dur then if v.dur then SquawkAndAwe.times[k.."Dur"] = GetTime() + v.dur end end self.frames[k]:Show() end end end -- Handles activating the GCD bar function SquawkAndAwe:GCDBar() local startTime, duration, enabled = GetSpellCooldown(SquawkAndAwe.combat.Moonglade.name) -- TM chosen because it has no other cooldown and all druids will have it if duration > 0 then self.frames["GCD"]:Show() SquawkAndAwe.actives.GCD = true end end function SquawkAndAwe:DurationString(duration) local string = (("%1.1f"):format(duration % 60)) .. "s"; if (duration >= 60) then duration = floor(duration - (duration % 60)) / 60; -- minutes string = (duration % 60) .."m " .. string; if (duration >= 60) then duration = (duration - (duration % 60)) / 60; -- hours string = duration .. "h " .. string; end end return string end -- Sorts two arrays by the values in one array. Nominally, sorts keys by -- duration, descending. i.e. after sort, keys[0] will be the last to drop function SquawkAndAwe:SortByDuration(keys, durs) local i,v local swap = true while swap do swap = false for i,v in ipairs(durs) do if durs[i + 1] and v < durs[i + 1] then durs[i + 1], durs[i] = durs[i], durs[i + 1] keys[i + 1], keys[i] = keys[i], keys[i + 1] swap = true end end end return keys, durs end function OnUpdate() local width = SquawkAndAwe.db.char.fWidth - 6 local sparkscale = width / SquawkAndAwe.db.char.bars.MaxLen local timeLeft = 0 local namestring = "" local durstring = "" local k,v,i,_,icon local sort = {} local durs = {} -- Handle Trinket updates if SquawkAndAwe.db.char.bars.trinketshow then if SquawkAndAwe.db.char.bars.mergetrinkets then namestring = "" durstring = "" i = 1 if SquawkAndAwe.actives.trinkets.Trinket1 then sort[i] = "Trinket1" if SquawkAndAwe.db.char.bars.trinketcd then if SquawkAndAwe.combat.trinkets[SquawkAndAwe.activeTrinketNames.Trinket1].cd then durs[i] = SquawkAndAwe.times.Trinket1CD - GetTime() else durs[i] = SquawkAndAwe:GetSpellInfo(SquawkAndAwe.combat.trinkets[SquawkAndAwe.activeTrinketNames.Trinket1].itemname, "item") - GetTime() end else durs[i] = SquawkAndAwe:GetSpellInfo(SquawkAndAwe.combat.trinkets[SquawkAndAwe.activeTrinketNames.Trinket1].name, "buff") - GetTime() end if durs[i] < 0 then SquawkAndAwe.actives.trinkets.Trinket1 = false SquawkAndAwe.frames.Trinkets.Trinket1:Hide() SquawkAndAwe.frames.Trinkets.Trinket1.spark:Hide() else i = i + 1 SquawkAndAwe.frames.Trinkets.Trinket1:Show() SquawkAndAwe.frames.Trinkets.Trinket1.spark:Show() end end if SquawkAndAwe.actives.trinkets.Trinket2 then sort[i] = "Trinket2" if SquawkAndAwe.db.char.bars.trinketcd then if SquawkAndAwe.combat.trinkets[SquawkAndAwe.activeTrinketNames.Trinket2].cd then durs[i] = SquawkAndAwe.times.Trinket2CD - GetTime() else durs[i] = SquawkAndAwe:GetSpellInfo(SquawkAndAwe.combat.trinkets[SquawkAndAwe.activeTrinketNames.Trinket2].itemname, "item") - GetTime() end else durs[i] = SquawkAndAwe:GetSpellInfo(SquawkAndAwe.combat.trinkets[SquawkAndAwe.activeTrinketNames.Trinket2].name, "buff") - GetTime() end if durs[i] < 0 then SquawkAndAwe.actives.trinkets.Trinket2 = false SquawkAndAwe.frames.Trinkets.Trinket2:Hide() SquawkAndAwe.frames.Trinkets.Trinket2.spark:Hide() else i = i + 1 SquawkAndAwe.frames.Trinkets.Trinket2:Show() SquawkAndAwe.frames.Trinkets.Trinket2.spark:Show() end end if i > 1 then sort, durs = SquawkAndAwe:SortByDuration(sort, durs) if SquawkAndAwe.db.char.icons then _,_,icon = GetSpellInfo(SquawkAndAwe.combat.trinkets[SquawkAndAwe.activeTrinketNames[sort[i-1]]].id) SquawkAndAwe.frames.Trinkets.icon:SetBackdrop({bgFile = icon}) SquawkAndAwe.frames.Trinkets.icon:Show() end if SquawkAndAwe.db.char.spellnames then namestring = SquawkAndAwe.combat.trinkets[SquawkAndAwe.activeTrinketNames[sort[i-1]]].itemname..(SquawkAndAwe.db.char.bars.trinketcd and " "..L["Cooldown"] or "")..(SquawkAndAwe.db.char.durations and ": " or "") end if SquawkAndAwe.db.char.durations then durstring = SquawkAndAwe:DurationString(durs[i-1]) end if SquawkAndAwe.db.char.barstext then SquawkAndAwe.frames.Trinkets.text:SetText(namestring..durstring) end while i > 1 do i = i - 1 k = sort[i] SquawkAndAwe.frames.Trinkets[k]:SetFrameLevel(i) timeLeft = math.min(durs[i], SquawkAndAwe.db.char.bars.MaxLen) SquawkAndAwe.frames.Trinkets[k]:SetValue(timeLeft) SquawkAndAwe.frames.Trinkets[k].spark:SetPoint("CENTER", SquawkAndAwe.frames.Trinkets[k], "LEFT", timeLeft * sparkscale, 0) SquawkAndAwe.frames.Trinkets[k].spark:Show() end elseif not SquawkAndAwe.db.char.barshow then SquawkAndAwe.frames.Trinkets:Hide() end else for k,v in pairs(SquawkAndAwe.actives.trinkets) do namestring = "" durstring = "" if v then if SquawkAndAwe.db.char.bars.trinketcd then if SquawkAndAwe.combat.trinkets[SquawkAndAwe.activeTrinketNames[k]].cd then timeLeft = SquawkAndAwe.times[k.."CD"] - GetTime() else timeLeft = SquawkAndAwe:GetSpellInfo(SquawkAndAwe.combat.trinkets[SquawkAndAwe.activeTrinketNames[k]].itemname, "item") - GetTime() end if timeLeft < 0 then SquawkAndAwe.actives.trinkets[k] = false SquawkAndAwe.frames[k]:Hide() SquawkAndAwe.frames[k].text:SetText("") else if SquawkAndAwe.db.char.spellnames then namestring = SquawkAndAwe.combat.trinkets[SquawkAndAwe.activeTrinketNames[k]].itemname.." "..L["Cooldown"]..(SquawkAndAwe.db.char.durations and ": " or "") end if SquawkAndAwe.db.char.durations then durstring = SquawkAndAwe:DurationString(timeLeft) end timeLeft = math.min(timeLeft, SquawkAndAwe.db.char.bars.MaxLen) SquawkAndAwe.frames[k][k.."CD"]:SetValue(timeLeft) SquawkAndAwe.frames[k][k.."CD"].spark:SetPoint("CENTER", SquawkAndAwe.frames[k][k.."CD"], "LEFT", timeLeft * sparkscale, 0) SquawkAndAwe.frames[k][k.."CD"].spark:Show() SquawkAndAwe.frames[k].text:SetText(namestring..durstring) end end timeLeft = SquawkAndAwe:GetSpellInfo(SquawkAndAwe.combat.trinkets[SquawkAndAwe.activeTrinketNames[k]].name, "buff") - GetTime() if timeLeft > 0 then if SquawkAndAwe.db.char.spellnames then namestring = SquawkAndAwe.combat.trinkets[SquawkAndAwe.activeTrinketNames[k]].itemname..(SquawkAndAwe.db.char.durations and ": " or "") end if SquawkAndAwe.db.char.durations then durstring = SquawkAndAwe:DurationString(timeLeft) end timeLeft = math.min(timeLeft, SquawkAndAwe.db.char.bars.MaxLen) SquawkAndAwe.frames[k][k]:SetValue(timeLeft) SquawkAndAwe.frames[k][k].spark:SetPoint("CENTER", SquawkAndAwe.frames[k][k], "LEFT", timeLeft * sparkscale, 0) SquawkAndAwe.frames[k][k].spark:Show() SquawkAndAwe.frames[k][k]:Show() SquawkAndAwe.frames[k].text:SetText(namestring..durstring) else SquawkAndAwe.frames[k][k]:Hide() if not SquawkAndAwe.db.char.bars.trinketcd then SquawkAndAwe.actives.trinkets[k] = false SquawkAndAwe.frames[k]:Hide() SquawkAndAwe.frames[k].text:SetText("") end end end end -- for k,v in trinkets end -- if mergetrinkets end -- if trinketshow -- Handle Proc updates for k,v in pairs(SquawkAndAwe.actives.procs) do namestring = "" durstring = "" if v and SquawkAndAwe.db.char.bars.procs[k].show then if SquawkAndAwe.db.char.bars.procs[k].cd then timeLeft = SquawkAndAwe.times[k.."CD"] - GetTime() if timeLeft < 0 then SquawkAndAwe.actives.procs[k] = false SquawkAndAwe.frames[k]:Hide() SquawkAndAwe.frames[k].text:SetText("") else if SquawkAndAwe.db.char.spellnames then -- namestring = SquawkAndAwe.combat.procs[k].name..((SquawkAndAwe.db.char.eclipsetype and k == "Eclipse") and " ("..EclipseType..")" or "").." "..L["Cooldown"]..(SquawkAndAwe.db.char.durations and ": " or "") namestring = ((k=="Eclipse" and "Eclipse") or SquawkAndAwe.combat.procs[k].name)..((SquawkAndAwe.db.char.eclipsetype and k == "Eclipse") and " ("..EclipseType..")" or "").." "..L["Cooldown"]..(SquawkAndAwe.db.char.durations and ": " or "") end if SquawkAndAwe.db.char.durations then durstring = SquawkAndAwe:DurationString(timeLeft) end timeLeft = math.min(timeLeft, SquawkAndAwe.db.char.bars.MaxLen) SquawkAndAwe.frames[k][k.."CD"]:SetValue(timeLeft) SquawkAndAwe.frames[k][k.."CD"].spark:SetPoint("CENTER", SquawkAndAwe.frames[k][k.."CD"], "LEFT", timeLeft * sparkscale, 0) SquawkAndAwe.frames[k][k.."CD"].spark:Show() SquawkAndAwe.frames[k].text:SetText(namestring..durstring) end end if SquawkAndAwe.db.char.bars.procs[k].show then timeLeft = SquawkAndAwe:GetSpellInfo(SquawkAndAwe.combat.procs[k].name, "buff") - GetTime() if timeLeft > 0 then if SquawkAndAwe.db.char.spellnames then -- namestring = SquawkAndAwe.combat.procs[k].name..((SquawkAndAwe.db.char.eclipsetype and k == "Eclipse") and " ("..EclipseType..")" or "")..(SquawkAndAwe.db.char.durations and ": " or "") namestring = ((k=="Eclipse" and "Eclipse") or SquawkAndAwe.combat.procs[k].name)..((SquawkAndAwe.db.char.eclipsetype and k == "Eclipse") and " ("..EclipseType..")" or "")..(SquawkAndAwe.db.char.durations and ": " or "") end if SquawkAndAwe.db.char.durations then durstring = SquawkAndAwe:DurationString(timeLeft) end timeLeft = math.min(timeLeft, SquawkAndAwe.db.char.bars.MaxLen) SquawkAndAwe.frames[k][k]:SetValue(timeLeft) SquawkAndAwe.frames[k][k].spark:SetPoint("CENTER", SquawkAndAwe.frames[k][k], "LEFT", timeLeft * sparkscale, 0) SquawkAndAwe.frames[k][k].spark:Show() SquawkAndAwe.frames[k][k]:Show() if SquawkAndAwe.db.char.bars.procs[k].flash then UIFrameFlash(SquawkAndAwe.frames[k][k], 0.25, 0.25, 30, true, 0.25, 0.25) end SquawkAndAwe.frames[k].text:SetText(namestring..durstring) else if k == "Eclipse" then if SquawkAndAwe.ActiveEclipseBuff then SquawkAndAwe.ActiveEclipseBuff = false UIFrameFlashRemoveFrame(SquawkAndAwe.frames.Eclipse.Eclipse) SquawkAndAwe.frames.Eclipse.Eclipse:SetStatusBarColor(0.3, 0.3, 0.3, 0.9) end timeLeft = SquawkAndAwe.times.EclipseCD - GetTime() - 15 if timeLeft < 0 then SquawkAndAwe.frames.Eclipse.Eclipse:Hide() else if SquawkAndAwe.db.char.spellnames then -- local typestring = SquawkAndAwe.db.char.eclipsetype and " ("..(EclipseType == SquawkAndAwe.combat.Wrath.name and SquawkAndAwe.combat.Starfire.name or SquawkAndAwe.combat.Wrath.name)..")" -- namestring = SquawkAndAwe.combat.procs.Eclipse.name..(SquawkAndAwe.db.char.eclipsetype and typestring or "").." "..L["Cooldown"]..(SquawkAndAwe.db.char.durations and ": " or "") namestring = "Eclipse ("..EclipseType..")"..(SquawkAndAwe.db.char.durations and ": " or "") end if SquawkAndAwe.db.char.durations then durstring = SquawkAndAwe:DurationString(timeLeft) end timeLeft = math.min(timeLeft, SquawkAndAwe.db.char.bars.MaxLen) SquawkAndAwe.frames.Eclipse.Eclipse:SetValue(timeLeft) SquawkAndAwe.frames.Eclipse.Eclipse.spark:SetPoint("CENTER", SquawkAndAwe.frames[k][k.."CD"], "LEFT", timeLeft * sparkscale, 0) SquawkAndAwe.frames.Eclipse.Eclipse.spark:Show() SquawkAndAwe.frames.Eclipse.text:SetText(namestring..durstring) end else SquawkAndAwe.frames[k][k]:Hide() UIFrameFlashRemoveFrame(SquawkAndAwe.frames[k][k]) if not SquawkAndAwe.db.char.bars.procs[k].cd then SquawkAndAwe.actives.procs[k] = false SquawkAndAwe.frames[k]:Hide() SquawkAndAwe.frames[k].text:SetText("") end end end end end end -- Handle Debuff updates if SquawkAndAwe.db.char.bars.mergedebuffs then namestring = "" durstring = "" i = 1 -- Find out how many are active for k,v in pairs(SquawkAndAwe.db.char.bars.debuffs) do if v.show and SquawkAndAwe.actives.debuffs[k] then sort[i] = k durs[i] = SquawkAndAwe:GetSpellInfo(SquawkAndAwe.combat.debuffs[k].name, "debuff") - GetTime() if durs[i] < 0 then SquawkAndAwe.actives.debuffs[k] = false SquawkAndAwe.frames.Debuffs[k]:Hide() SquawkAndAwe.frames.Debuffs[k].spark:Hide() else i = i + 1 SquawkAndAwe.frames.Debuffs[k]:Show() SquawkAndAwe.frames.Debuffs[k].spark:Show() end elseif v.show and not SquawkAndAwe.db.char.barshow then SquawkAndAwe.frames.Debuffs[k]:Hide() SquawkAndAwe.frames.Debuffs[k].spark:Hide() end end if i > 1 then sort, durs = SquawkAndAwe:SortByDuration(sort, durs) if SquawkAndAwe.db.char.icons then _,_,icon = GetSpellInfo(SquawkAndAwe.combat.debuffs[sort[i-1]].id) SquawkAndAwe.frames.Debuffs.icon:SetBackdrop({bgFile = icon}) SquawkAndAwe.frames.Debuffs.icon:Show() end if SquawkAndAwe.db.char.spellnames then namestring = SquawkAndAwe.combat.debuffs[sort[i-1]].name..(SquawkAndAwe.db.char.durations and ": " or "") end if SquawkAndAwe.db.char.durations then durstring = SquawkAndAwe:DurationString(durs[i-1]) end if SquawkAndAwe.db.char.barstext then SquawkAndAwe.frames.Debuffs.text:SetText(namestring..durstring) end while i > 1 do i = i - 1 k = sort[i] SquawkAndAwe.frames.Debuffs[k]:SetFrameLevel(i) timeLeft = math.min(durs[i], SquawkAndAwe.db.char.bars.MaxLen) SquawkAndAwe.frames.Debuffs[k]:SetValue(timeLeft) SquawkAndAwe.frames.Debuffs[k].spark:SetPoint("CENTER", SquawkAndAwe.frames.Debuffs[k], "LEFT", timeLeft * sparkscale, 0) SquawkAndAwe.frames.Debuffs[k].spark:Show() end elseif ((not SquawkAndAwe.db.char.barshow) and SquawkAndAwe.frames.Debuffs) then SquawkAndAwe.frames.Debuffs:Hide() end else for k,v in pairs(SquawkAndAwe.actives.debuffs) do namestring = "" durstring = "" if v then timeLeft = SquawkAndAwe:GetSpellInfo(SquawkAndAwe.combat.debuffs[k].name, "debuff") - GetTime() if (timeLeft < 0) then SquawkAndAwe.actives.debuffs[k] = false SquawkAndAwe.frames[k]:Hide() SquawkAndAwe.frames[k].text:SetText("") else if SquawkAndAwe.db.char.spellnames then namestring = SquawkAndAwe.combat.debuffs[k].name if k == "Moonfire" and SquawkAndAwe.db.char.sfcomboshow then -- We set LastMF to 0 when we activate the bar. if ((not (LastMF == 0)) and timeLeft > LastMF) then SFCombos = SFCombos + 1 end LastMF = timeLeft namestring = namestring.." ("..SFCombos..")" end if SquawkAndAwe.db.char.durations then namestring = namestring..": " end end if SquawkAndAwe.db.char.durations then durstring = SquawkAndAwe:DurationString(timeLeft) end if SquawkAndAwe.db.char.barstext then SquawkAndAwe.frames[k].text:SetText(namestring..durstring)end timeLeft = math.min(timeLeft, SquawkAndAwe.db.char.bars.MaxLen) SquawkAndAwe.frames[k][k]:SetValue(timeLeft) SquawkAndAwe.frames[k][k].spark:SetPoint("CENTER", SquawkAndAwe.frames[k][k], "LEFT", timeLeft * sparkscale, 0) SquawkAndAwe.frames[k][k].spark:Show() if SquawkAndAwe.db.char.bars.debuffs[k].tick then timeLeft = SquawkAndAwe.times[k.."Tick"] - GetTime() if timeLeft < 0 then SquawkAndAwe.frames[k][k.."Tick"]:Hide() else timeLeft = math.min(timeLeft, SquawkAndAwe.db.char.bars.MaxLen) SquawkAndAwe.frames[k][k.."Tick"]:Show() SquawkAndAwe.frames[k][k.."Tick"]:SetValue(timeLeft) SquawkAndAwe.frames[k][k.."Tick"].spark:SetPoint("CENTER", SquawkAndAwe.frames[k][k.."Tick"], "LEFT", timeLeft * SquawkAndAwe.db.char.fWidth / 1.5 + 1, -1) end end end end end end -- Handle CC updates if SquawkAndAwe.db.char.bars.mergecc then namestring = "" durstring = "" i = 1 -- Find out how many are active for k,v in pairs(SquawkAndAwe.db.char.bars.cc) do if v.show and SquawkAndAwe.actives.cc[k] then sort[i] = k durs[i] = SquawkAndAwe:GetSpellInfo(SquawkAndAwe.combat.cc[k].name, "cc") - GetTime() if durs[i] < 0 then SquawkAndAwe.actives.cc[k] = false SquawkAndAwe.frames.CC[k]:Hide() SquawkAndAwe.frames.CC[k].spark:Hide() else i = i + 1 SquawkAndAwe.frames.CC[k]:Show() SquawkAndAwe.frames.CC[k].spark:Show() end elseif v.show and not SquawkAndAwe.db.char.barshow then SquawkAndAwe.frames.CC[k]:Hide() SquawkAndAwe.frames.CC[k].spark:Hide() end end if i > 1 then sort, durs = SquawkAndAwe:SortByDuration(sort, durs) if SquawkAndAwe.db.char.icons then _,_,icon = GetSpellInfo(SquawkAndAwe.combat.cc[sort[i-1] ].id) SquawkAndAwe.frames.CC.icon:SetBackdrop({bgFile = icon}) SquawkAndAwe.frames.CC.icon:Show() end if SquawkAndAwe.db.char.spellnames then namestring = SquawkAndAwe.combat.cc[sort[i-1] ].name..(SquawkAndAwe.db.char.durations and ": " or "") end if SquawkAndAwe.db.char.durations then durstring = SquawkAndAwe:DurationString(durs[i-1]) end if SquawkAndAwe.db.char.barstext then SquawkAndAwe.frames.CC.text:SetText(namestring..durstring) end while i > 1 do i = i - 1 k = sort[i] SquawkAndAwe.frames.CC[k]:SetFrameLevel(i) timeLeft = math.min(durs[i], SquawkAndAwe.db.char.bars.MaxLen) SquawkAndAwe.frames.CC[k]:SetValue(timeLeft) SquawkAndAwe.frames.CC[k].spark:SetPoint("CENTER", SquawkAndAwe.frames.CC[k], "LEFT", timeLeft * sparkscale, 0) SquawkAndAwe.frames.CC[k].spark:Show() end elseif ((not SquawkAndAwe.db.char.barshow) and SquawkAndAwe.frames.CC) then SquawkAndAwe.frames.CC:Hide() end else for k,v in pairs(SquawkAndAwe.actives.cc) do namestring = "" durstring = "" if v then timeLeft = SquawkAndAwe:GetSpellInfo(SquawkAndAwe.combat.cc[k].name, "cc") - GetTime() if (timeLeft < 0) then SquawkAndAwe.actives.cc[k] = false SquawkAndAwe.frames[k]:Hide() SquawkAndAwe.frames[k].text:SetText("") else if SquawkAndAwe.db.char.spellnames then namestring = SquawkAndAwe.combat.cc[k].name if SquawkAndAwe.db.char.durations then namestring = namestring..": " end end if SquawkAndAwe.db.char.durations then durstring = SquawkAndAwe:DurationString(timeLeft) end if SquawkAndAwe.db.char.barstext then SquawkAndAwe.frames[k].text:SetText(namestring..durstring)end timeLeft = math.min(timeLeft, SquawkAndAwe.db.char.bars.MaxLen) SquawkAndAwe.frames[k][k]:SetValue(timeLeft) SquawkAndAwe.frames[k][k].spark:SetPoint("CENTER", SquawkAndAwe.frames[k][k], "LEFT", timeLeft * sparkscale, 0) SquawkAndAwe.frames[k][k].spark:Show() end end end end -- Handle Ability updates if SquawkAndAwe.db.char.bars.mergeabilities then namestring = "" durstring = "" i = 1 -- Find out how many are active for k,v in pairs(SquawkAndAwe.db.char.bars.abilities) do if v.show and SquawkAndAwe.actives.abilities[k] then sort[i] = k durs[i] = SquawkAndAwe:GetSpellInfo(SquawkAndAwe.combat.abilities[k].name, "cd") - GetTime() if durs[i] < 0 then SquawkAndAwe.actives.abilities[k] = false SquawkAndAwe.frames.Abilities[k]:Hide() SquawkAndAwe.frames.Abilities[k].spark:Hide() else i = i + 1 SquawkAndAwe.frames.Abilities[k]:Show() SquawkAndAwe.frames.Abilities[k].spark:Show() end elseif v.show and not SquawkAndAwe.db.char.barshow then SquawkAndAwe.frames.Abilities[k]:Hide() SquawkAndAwe.frames.Abilities[k].spark:Hide() end end if i > 1 then sort, durs = SquawkAndAwe:SortByDuration(sort, durs) if SquawkAndAwe.db.char.icons then _,_,icon = GetSpellInfo(SquawkAndAwe.combat.abilities[sort[i-1]].id) SquawkAndAwe.frames.Abilities.icon:SetBackdrop({bgFile = icon}) SquawkAndAwe.frames.Abilities.icon:Show() end if SquawkAndAwe.db.char.spellnames then namestring = SquawkAndAwe.combat.abilities[sort[i-1]].name..(SquawkAndAwe.db.char.durations and ": " or "") end if SquawkAndAwe.db.char.durations then durstring = SquawkAndAwe:DurationString(durs[i-1]) end if SquawkAndAwe.db.char.barstext then SquawkAndAwe.frames.Abilities.text:SetText(namestring..durstring) end while i > 1 do i = i - 1 k = sort[i] SquawkAndAwe.frames.Abilities[k]:SetFrameLevel(i) timeLeft = math.min(durs[i], SquawkAndAwe.db.char.bars.MaxLen) SquawkAndAwe.frames.Abilities[k]:SetValue(timeLeft) SquawkAndAwe.frames.Abilities[k].spark:SetPoint("CENTER", SquawkAndAwe.frames.Abilities[k], "LEFT", timeLeft * sparkscale, 0) SquawkAndAwe.frames.Abilities[k].spark:Show() end elseif ((not SquawkAndAwe.db.char.barshow) and SquawkAndAwe.frames.Abilities) then SquawkAndAwe.frames.Abilities:Hide() end else for k,v in pairs(SquawkAndAwe.actives.abilities) do namestring = "" durstring = "" if v then timeLeft = SquawkAndAwe:GetSpellInfo(SquawkAndAwe.combat.abilities[k].name, "cd") - GetTime() if (timeLeft < 0) then SquawkAndAwe.actives.abilities[k] = false SquawkAndAwe.frames[k]:Hide() SquawkAndAwe.frames[k].text:SetText("") else if SquawkAndAwe.db.char.spellnames then namestring = SquawkAndAwe.combat.abilities[k].name.." "..L["Cooldown"] if SquawkAndAwe.db.char.durations then namestring = namestring..": " end end if SquawkAndAwe.db.char.durations then durstring = SquawkAndAwe:DurationString(timeLeft) end timeLeft = math.min(timeLeft, SquawkAndAwe.db.char.bars.MaxLen) SquawkAndAwe.frames[k][k]:SetValue(timeLeft) SquawkAndAwe.frames[k][k].spark:SetPoint("CENTER", SquawkAndAwe.frames[k][k], "LEFT", timeLeft * sparkscale, 0) SquawkAndAwe.frames[k][k].spark:Show() if SquawkAndAwe.db.char.bars.abilities[k].dur then if SquawkAndAwe.combat.abilities[k].dur then timeLeft = SquawkAndAwe.times[k.."Dur"] - GetTime() else timeLeft = SquawkAndAwe:GetSpellInfo(SquawkAndAwe.combat.abilities[k].name, "buff") - GetTime() end if SquawkAndAwe.db.char.spellnames and timeLeft > 0 then namestring = SquawkAndAwe.combat.abilities[k].name if SquawkAndAwe.db.char.durations then namestring = namestring..": " end end if timeLeft < 0 then SquawkAndAwe.frames[k][k.."Dur"]:Hide() else if SquawkAndAwe.db.char.durations then durstring = SquawkAndAwe:DurationString(timeLeft) end timeLeft = math.min(timeLeft, SquawkAndAwe.db.char.bars.MaxLen) SquawkAndAwe.frames[k][k.."Dur"]:Show() SquawkAndAwe.frames[k][k.."Dur"]:SetValue(timeLeft) SquawkAndAwe.frames[k][k.."Dur"].spark:SetPoint("CENTER", SquawkAndAwe.frames[k][k.."Dur"], "LEFT", timeLeft * sparkscale, 0) SquawkAndAwe.frames[k][k.."Dur"].spark:Show() end end if SquawkAndAwe.db.char.barstext then SquawkAndAwe.frames[k].text:SetText(namestring..durstring)end end end end end -- Handle GCD updates if SquawkAndAwe.actives.GCD then timeLeft = SquawkAndAwe:GetSpellInfo(SquawkAndAwe.combat.Moonglade.name, "cd") - GetTime() if timeLeft < 0 then SquawkAndAwe.actives.GCD = false SquawkAndAwe.frames.GCD:Hide() else SquawkAndAwe.frames.GCD.GCD:SetValue(timeLeft) SquawkAndAwe.frames.GCD.GCD.spark:SetPoint("CENTER",SquawkAndAwe.frames.GCD.GCD,"LEFT", timeLeft * width / 1.5, 0) SquawkAndAwe.frames.GCD.GCD.spark:Show() end end end