-------------------------------------------------------------------------------- -- Module Declaration -- local mod, CL = BigWigs:NewBoss("Spellblade Aluriel", 1530, 1751) if not mod then return end mod:RegisterEnableMob(104881) mod.engageId = 1871 mod.respawnTime = 30 -------------------------------------------------------------------------------- -- Locals -- local heroicTimers = { -- Annihilate [212492] = {8, 45, 40, 44, 38, 37, 33, 47, 41, 44, 38, 37}, } local mythicTimers = { -- Annihilate [212492] = {8, 45, 30, 37, 35, 43, 27, 37, 41, 37, 35, 43, 27}, -- Fel Lash [230403] = {5.5, 11, 6, 12, 6}, } local timers = mod:Mythic() and mythicTimers or heroicTimers local phase = 0 -- will immediately get incremented by mod:Stages() local annihilateCount = 1 local felLashCount = 1 local searingBrandTargets = {} local markOfFrostTargets = {} local proxList = {} -- Mark of Frost and Searing Brand local frostbittenStacks = {} local mobCollector = {} local isInfoOpen = false local markOfFrostOnMe = nil local searingBrandOnMe = nil -------------------------------------------------------------------------------- -- Upvalues -- local tDeleteItem, tContains = tDeleteItem, tContains -------------------------------------------------------------------------------- -- Initialization -- local searingBrandMarker = mod:AddMarkerOption(false, "player", 1, 213166, 1, 2, 3, 4, 5, 6) local fieryAddMarker = mod:AddMarkerOption(false, "npc", 1, 213867, 1, 2, 3, 4, 5, 6) function mod:GetOptions() return { --[[ General ]]-- {212492, "TANK_HEALER"}, -- Annihilate "stages", "berserk", --[[ Master of Frost ]]-- {212531, "SAY", "FLASH"}, -- Pre Mark of Frost {212587, "SAY", "FLASH", "PROXIMITY"}, -- Mark of Frost {212647, "INFOBOX"}, -- Frostbitten 212530, -- Replicate: Mark of Frost {212735, "SAY"}, -- Detonate: Mark of Frost 213853, -- Animate: Mark of Frost" 213083, -- Frozen Tempest 212736, -- Pool of Frost --[[ Master of Fire ]]-- {213148, "SAY"}, -- Pre Searing Brand {213166, "PROXIMITY"}, -- Searing Brand searingBrandMarker, {213275, "SAY"}, -- Detonate: Searing Brand 213567, -- Animate: Searing Brand fieryAddMarker, 213278, -- Burning Ground --[[ Master of the Arcane ]]-- 213520, -- Arcane Orb 213852, -- Replicate: Arcane Orb 213390, -- Detonate: Arcane Orb 213564, -- Animate: Arcane Orb 213569, -- Armageddon 213504, -- Arcane Fog --[[ Mythic ]]-- 230901, -- Fel Soul {230504, "TANK"}, -- Decimate 230414, -- Fel Stomp 230403, -- Fel Lash }, { [212492] = "general", [212531] = -13376, -- Master of Frost [213148] = -13379, -- Master of Fire [213520] = -13380, -- Master of the Arcane [230901] = "mythic", } end function mod:OnBossEnable() self:RegisterUnitEvent("UNIT_SPELLCAST_SUCCEEDED", nil, "boss1") --[[ General ]]-- self:Log("SPELL_CAST_START", "AnnihilateCast", 212492) self:Log("SPELL_AURA_APPLIED", "AnnihilateApplied", 215458) self:Log("SPELL_AURA_APPLIED_DOSE", "AnnihilateApplied", 215458) self:Log("SPELL_AURA_APPLIED", "Stages", 216389, 213867, 213869, 213864) -- Icy / Fiery / Magic / Icy² Enchantment --[[ Master of Frost ]]-- self:Log("SPELL_AURA_APPLIED", "PreMarkOfFrostApplied", 212531) self:Log("SPELL_AURA_APPLIED", "MarkOfFrostApplied", 212587) self:Log("SPELL_AURA_REMOVED", "MarkOfFrostRemoved", 212587) self:Log("SPELL_AURA_APPLIED", "Frostbitten", 212647) self:Log("SPELL_AURA_APPLIED_DOSE", "Frostbitten", 212647) self:Log("SPELL_CAST_START", "ReplicateMarkOfFrost", 212530) self:Log("SPELL_CAST_START", "DetonateMarkOfFrost", 212735) -- Detonate: Mark of Frost self:Log("SPELL_CAST_START", "AnimateMarkOfFrost", 213853) self:Log("SPELL_CAST_START", "FrozenTempest", 213083) self:Death("IcyEnchantmentDeath", 107237) --[[ Master of Fire ]]-- self:Log("SPELL_AURA_APPLIED", "PreSearingBrandApplied", 213148) self:Log("SPELL_AURA_APPLIED", "SearingBrandApplied", 213166) self:Log("SPELL_AURA_REMOVED", "SearingBrandRemoved", 213166) self:Log("SPELL_CAST_START", "DetonateSearingBrand", 213275) -- Detonate: Searing Brand self:Log("SPELL_CAST_SUCCESS", "DetonateSearingBrandSuccess", 213275) self:Log("SPELL_CAST_START", "AnimateSearingBrand", 213567) --[[ Master of the Arcane ]]-- self:Log("SPELL_CAST_START", "ReplicateArcaneOrb", 213852) self:Log("SPELL_CAST_START", "AnimateArcaneOrb", 213564) self:Log("SPELL_AURA_APPLIED", "Armageddon", 213569) --[[ Mythic ]]-- self:Log("SPELL_CAST_SUCCESS", "SeveredSoul", 230951) self:Log("SPELL_AURA_REMOVED", "SeveredSoulRemoved", 230951) self:Log("SPELL_CAST_START", "Decimate", 230504) self:Log("SPELL_CAST_SUCCESS", "FelLash", 230403) --[[ Many ground effects, handle it! ]]-- self:Log("SPELL_AURA_APPLIED", "GroundEffectDamage", 212736, 213278, 213504, 230414) -- Pool of Frost / Burning Ground / Arcane Fog / Fel Stomp self:Log("SPELL_PERIODIC_DAMAGE", "GroundEffectDamage", 212736, 213278, 213504, 230414) self:Log("SPELL_PERIODIC_MISSED", "GroundEffectDamage", 212736, 213278, 213504, 230414) self:Log("SPELL_DAMAGE", "GroundEffectDamage", 213520) -- Arcane Orb self:Log("SPELL_MISSED", "GroundEffectDamage", 213520) end function mod:OnEngage() phase = 0 -- will immediately get incremented by mod:Stages() annihilateCount = 1 isInfoOpen = false searingBrandTargets = {} markOfFrostTargets = {} frostbittenStacks = {} mobCollector = {} proxList = {} markOfFrostOnMe = nil searingBrandOnMe = nil timers = self:Mythic() and mythicTimers or heroicTimers self:Bar(212492, timers[212492][annihilateCount]) -- Annihilate -- other bars are in mod:Stages() if self:Normal() then self:Berserk(645) elseif self:Heroic() then self:Berserk(490) elseif self:Mythic() then self:Berserk(450) end end -------------------------------------------------------------------------------- -- Event Handlers -- local function updateProximity(self) local showMark = self:CheckOption(212587, "PROXIMITY") -- Mark of Frost Radius: 8 yards local showBrand = self:CheckOption(213166, "PROXIMITY") -- Searing Brand http://www.wowhead.com/spell=213276 Radius: 10 yards if showMark and markOfFrostOnMe then self:OpenProximity(212587, 8) elseif showBrand and searingBrandOnMe then self:OpenProximity(213166, 10) elseif showMark and showBrand and #markOfFrostTargets > 0 and #searingBrandTargets > 0 then self:OpenProximity(213166, 10, proxList) elseif showMark and #markOfFrostTargets > 0 then self:OpenProximity(212587, 8, markOfFrostTargets) elseif showBrand and #searingBrandTargets > 0 then self:OpenProximity(213166, 10, searingBrandTargets) end end function mod:UNIT_SPELLCAST_SUCCEEDED(_, _, _, spellId) if spellId == 215455 then -- Arcane Orb self:MessageOld(213520, "red") elseif spellId == 213390 then -- Detonate: Arcane Orb self:MessageOld(spellId, "red", "alarm") end end --[[ General ]]-- function mod:AnnihilateCast(args) self:MessageOld(args.spellId, "red", self:Tank() and "alarm", CL.casting:format(CL.count:format(args.spellName, annihilateCount))) self:StopBar(CL.count:format(args.spellName, annihilateCount)) self:CastBar(args.spellId, 7, CL.count:format(args.spellName, annihilateCount)) annihilateCount = annihilateCount + 1 self:Bar(args.spellId, timers[args.spellId][annihilateCount] or 37, CL.count:format(args.spellName, annihilateCount)) end function mod:AnnihilateApplied(args) if self:Tank() then local amount = args.amount or 1 self:StackMessage(212492, args.destName, amount, "red", amount > 1 and "warning") -- check sound amount end end do function mod:Stages(args) phase = phase + 1 self:MessageOld("stages", "cyan", "long", args.spellName, args.spellId) if args.spellId == 216389 then -- Icy if self:Mythic() then -- Fel Soul self:Bar(230901, 18) end self:Bar(212587, 18) -- Mark of Frost (timer is the "pre" mark of frost aura applied) self:Bar(212530, self:Mythic() and 28 or 41) -- Replicate: Mark of Frost self:Bar(212735, self:Mythic() and 48 or 71) -- Detonate: Mark of Frost self:Bar(213853, self:Mythic() and 65 or 75, nil, 31687) -- Animate: Mark of Frost, Water Elemental icon self:Bar("stages", self:Mythic() and 75 or 85, self:SpellName(213867), 213867) -- Next: Fiery elseif args.spellId == 213864 then -- Icy after the first one, different timers in mythic if self:Mythic() then -- Fel Soul self:Bar(230901, 15) end self:Bar(212587, 2) -- Mark of Frost (timer is the "pre" mark of frost aura applied) self:Bar(212530, 15) -- Replicate: Mark of Frost self:Bar(212735, self:Mythic() and 35 or 45) -- Detonate: Mark of Frost self:Bar(213853, self:Mythic() and 52 or 62, nil, 31687) -- Animate: Mark of Frost, Water Elemental icon self:Bar("stages", self:Mythic() and 75 or 85, self:SpellName(213867), 213867) -- Next: Fiery elseif args.spellId == 213867 then -- Fiery searingBrandTargets = {} if self:Mythic() then -- Fel Soul self:Bar(230901, 18) end self:Bar(213166, 18) -- Searing Brand self:Bar(213275, self:Mythic() and 40 or 48) -- Detonate: Searing Brand self:Bar(213567, self:Mythic() and 55 or 65) -- Animate: Searing Brand self:Bar("stages", self:Mythic() and 75 or 85, self:SpellName(213869), 213869) -- Next: Magic else -- Magic if self:Mythic() then -- Fel Soul self:Bar(230901, 15) end self:Bar(213852, self:Mythic() and 15 or 16) -- Replicate: Arcane Orb self:Bar(213390, 38) -- Detonate: Arcane Orb self:Bar(213564, 55) -- Animate: Arcane Orb self:Bar("stages", 70, self:SpellName(216389), 216389) -- Next: Frost end end end --[[ Master of Frost ]]-- do local preDebuffApplied = 0 -- The "pre" and actual debuffs for Mark of Frost and Searing Brand are separate -- because of customization (emphasize and stuff). function mod:PreMarkOfFrostApplied(args) if self:Me(args.destGUID) then preDebuffApplied = GetTime() self:TargetMessageOld(args.spellId, args.destName, "yellow", "alert") self:Say(args.spellId) self:Flash(args.spellId) markOfFrostOnMe = true end if not tContains(markOfFrostTargets, args.destName) then markOfFrostTargets[#markOfFrostTargets+1] = args.destName end if not tContains(proxList, args.destName) then proxList[#proxList+1] = args.destName end updateProximity(self) end local list = mod:NewTargetList() function mod:MarkOfFrostApplied(args) list[#list+1] = args.destName if #list == 1 then self:ScheduleTimer("TargetMessageOld", 1, args.spellId, list, "orange") end if self:Me(args.destGUID) then markOfFrostOnMe = true local t = GetTime() if t-preDebuffApplied > 5.5 then self:TargetMessageOld(args.spellId, args.destName, "yellow", "alert") self:Say(args.spellId) self:Flash(args.spellId) end end if not tContains(markOfFrostTargets, args.destName) then markOfFrostTargets[#markOfFrostTargets+1] = args.destName end if not tContains(proxList, args.destName) then proxList[#proxList+1] = args.destName end updateProximity(self) end end function mod:MarkOfFrostRemoved(args) if self:Me(args.destGUID) then markOfFrostOnMe = nil end tDeleteItem(markOfFrostTargets, args.destName) tDeleteItem(proxList, args.destName) if #markOfFrostTargets == 0 then self:CloseProximity(args.spellId) end updateProximity(self) -- Mark of Frost is removed immediately, Frostbitten waits until the debuff expires, use the former for a clearer infobox. frostbittenStacks[args.destName] = nil if next(frostbittenStacks) then self:SetInfoByTable(212647, frostbittenStacks) elseif isInfoOpen then isInfoOpen = false self:CloseInfo(212647) end end function mod:Frostbitten(args) local amount = args.amount or 1 if self:Me(args.destGUID) and amount % 2 == 0 and amount > 5 then self:StackMessage(args.spellId, args.destName, amount, "red", amount > 7 and "warning") end frostbittenStacks[args.destName] = amount if not isInfoOpen then isInfoOpen = true self:OpenInfo(args.spellId, args.spellName) end self:SetInfoByTable(args.spellId, frostbittenStacks) end function mod:DetonateMarkOfFrost(args) self:MessageOld(args.spellId, "red", "alarm") if markOfFrostOnMe then self:Say(args.spellId, 151913) -- "Detonate" end end function mod:AnimateMarkOfFrost(args) self:MessageOld(args.spellId, "red", "info", nil, 31687) -- Water Elemental icon end function mod:ReplicateMarkOfFrost(args) self:MessageOld(args.spellId, "red", "alarm") end do local guid = "" function mod:FrozenTempest(args) guid = args.sourceGUID self:MessageOld(args.spellId, "red") self:CastBar(args.spellId, self:Mythic() and 10 or 12) end function mod:IcyEnchantmentDeath(args) if args.destGUID == guid then self:StopBar(CL.cast:format(self:SpellName(213083))) -- Frozen Tempest end end end --[[ Master of Fire ]]-- do local list = mod:NewTargetList() function mod:PreSearingBrandApplied(args) list[#list+1] = args.destName if #list == 1 then self:ScheduleTimer("TargetMessageOld", 0.3, args.spellId, list, "orange") end if not tContains(searingBrandTargets, args.destName) then searingBrandTargets[#searingBrandTargets+1] = args.destName if self:GetOption(searingBrandMarker) then self:CustomIcon(false, args.destName, #searingBrandTargets) end end if not tContains(proxList, args.destName) then proxList[#proxList+1] = args.destName end if self:Me(args.destGUID) then self:Say(args.spellId) searingBrandOnMe = true end updateProximity(self) end end function mod:SearingBrandApplied(args) if self:Me(args.destGUID) then searingBrandOnMe = true local _, _, _, expires = self:UnitDebuff("player", args.spellId) if expires and expires > 0 then local timeLeft = expires - GetTime() self:TargetBar(args.spellId, timeLeft, args.destName) end end if not tContains(searingBrandTargets, args.destName) then searingBrandTargets[#searingBrandTargets+1] = args.destName if self:GetOption(searingBrandMarker) then self:CustomIcon(false, args.destName, #searingBrandTargets) end end if not tContains(proxList, args.destName) then proxList[#proxList+1] = args.destName end updateProximity(self) end function mod:SearingBrandRemoved(args) if self:Me(args.destGUID) then searingBrandOnMe = nil end tDeleteItem(searingBrandTargets, args.destName) tDeleteItem(proxList, args.destName) if self:GetOption(searingBrandMarker) then self:CustomIcon(false, args.destName) end if #searingBrandTargets == 0 then self:CloseProximity(args.spellId) end updateProximity(self) end function mod:DetonateSearingBrand(args) self:MessageOld(args.spellId, "red", "alarm") if searingBrandOnMe then self:Say(args.spellId, 151913) -- "Detonate" end end function mod:DetonateSearingBrandSuccess() -- At this point there will be no more Mark of Frost targets and you no -- longer need to stay away from Searing Brand targets, so wipe everything! markOfFrostTargets = {} searingBrandTargets = {} proxList = {} self:CloseProximity(213166) -- Searing Brand end do local fieryAddMarks = {} function mod:FieryAddMark(event, unit, guid) if self:MobId(guid) == 107285 and not mobCollector[guid] then for i = 1, 6 do if not fieryAddMarks[i] then self:CustomIcon(false, unit, i) fieryAddMarks[i] = guid mobCollector[guid] = true if i == 6 then self:UnregisterTargetEvents() end return end end end end function mod:AnimateSearingBrand(args) self:MessageOld(args.spellId, "red", "info") if self:GetOption(fieryAddMarker) then fieryAddMarks = {} self:RegisterTargetEvents("FieryAddMark") self:ScheduleTimer("UnregisterTargetEvents", 10) end end end --[[ Master of the Arcane ]]-- function mod:ReplicateArcaneOrb(args) self:MessageOld(args.spellId, "red", "alarm") end function mod:AnimateArcaneOrb(args) self:MessageOld(args.spellId, "red", "info") end do local prev = 0 function mod:Armageddon(args) local t = GetTime() if t-prev > 1 then -- Throttle because 8 adds cast it simultaneously prev = t self:MessageOld(args.spellId, "orange", "info") self:CastBar(args.spellId, self:Mythic() and 15 or 30) end end end --[[ Mythic ]]-- function mod:SeveredSoul() self:MessageOld(230901, "green", "info") self:Bar(230901, 45, CL.over:format(self:SpellName(230901))) -- Fel Soul self:CDBar(230504, phase % 3 == 1 and 18 or phase % 3 == 2 and 11 or 10) -- Decimate if phase % 3 == 0 then -- Magic felLashCount = 1 self:CDBar(230403, timers[230403][felLashCount], CL.count:format(self:SpellName(230403), felLashCount)) -- Fel Lash end end function mod:SeveredSoulRemoved() self:StopBar(230504) self:StopBar(CL.count:format(self:SpellName(230403), felLashCount)) end function mod:Decimate(args) self:MessageOld(args.spellId, "orange") self:CDBar(args.spellId, phase % 3 == 1 and 20.5 or phase % 3 == 2 and 17 or 18) end function mod:FelLash(args) self:MessageOld(args.spellId, "green", "long", CL.count:format(args.spellName, felLashCount)) felLashCount = felLashCount + 1 local timer = timers[args.spellId][felLashCount] if timer then self:Bar(args.spellId, timer, CL.count:format(args.spellName, felLashCount)) end end --[[ Many ground effects, handle it! ]]-- do local prev = 0 function mod:GroundEffectDamage(args) local t = GetTime() if self:Me(args.destGUID) and t-prev > 1.5 then prev = t self:MessageOld(args.spellId, "blue", "alert", CL.underyou:format(args.spellName)) end end end