You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

845 lines
30 KiB

-- GLOBALS: INLINE_TANK_ICON, INLINE_HEALER_ICON, INLINE_DAMAGER_ICON
--------------------------------------------------------------------------------
-- TODO List:
-- Rift Activating Timer
--------------------------------------------------------------------------------
-- Module Declaration
--
local mod, CL = BigWigs:NewBoss("Kil'jaeden", 1676, 1898)
if not mod then return end
mod:RegisterEnableMob(117269)
mod.engageId = 2051
mod.respawnTime = 30
--------------------------------------------------------------------------------
-- Locals
--
local stage = 1
local inIntermission = nil
local singularityCount = 1
local armageddonCount = 1
local focusedDreadflameCount = 1
local burstingDreadflameCount = 1
local felclawsCount = 1
local flamingOrbCount = 1
local wailingCounter = 1
local obeliskCount = 1
local darknessCount = 1
local currentZoom = 0
local focusedTarget = nil
local resetMinimap = nil
local timerMinimap = nil
local mobCollector = {}
local timersLFR = {
[240910] = { -- Armageddon
{10, 22, 42, 22, 30}, -- Stage 1
{56, 27.7, 56.7, 26.7, 12.2, 18.9, 18.9}, -- Stage 2
},
[238430] = { -- Bursting Dreadflame
{7.7, 17, 13.4, 17}, -- Stage 1 (Intermission)
{58.2, 53.3, 61.1, 56.7}, -- Stage 2
{42, 25, 70}, -- Stage 3, 25/70 Repeating
},
}
local timersNormal = {
[240910] = { -- Armageddon
{10, 64}, -- Stage 1
{50.4, 45, 31, 35, 31, 78}, -- Stage 2
},
[235059] = { -- Rupturing Singularity
{58, 56}, -- Stage 1
{73.5, 81}, -- Stage 2
},
[238430] = { -- Bursting Dreadflame
{7.7, 46}, -- Stage 1 (Intermission)
{52.4, 48, 55, 50}, -- Stage 2
{42, 25, 70}, -- Stage 3, 25/70 Repeating
},
[238505] = { -- Focused Dreadflame
{24.6, 13.4}, -- Stage 1 (Intermission)
{76.4, 99}, -- Stage 2
{80, 95, 95}, -- Stage 3, 95 Repeating
},
}
local timersHeroic = {
[240910] = { -- Armageddon
{10, 64}, -- Stage 1
{50.4, 76, 35, 31}, -- Stage 2
},
[235059] = { -- Rupturing Singularity
{58, 56}, -- Stage 1
{73.5, 26, 55, 44}, -- Stage 2
},
[238430] = { -- Bursting Dreadflame
{7.7, 46}, -- Stage 1 (Intermission)
{52.4, 48, 55, 50}, -- Stage 2
{42, 25, 70}, -- Stage 3, 25/70 Repeating
},
[238505] = { -- Focused Dreadflame
{24.6, 13.4}, -- Stage 1 (Intermission)
{30.4, 46, 53, 46}, -- Stage 2
{80, 95, 95}, -- Stage 3, 95 Repeating
},
}
local timersMythic = {
[240910] = { -- Armageddon
{11, 54.0, 38}, -- Stage 1
{18.4, 32, 45, 33, 36, 36, 47, 32, 45}, -- Stage 2
},
[235059] = { -- Rupturing Singularity
{55, 25, 25, 28}, -- Stage 1
{21.5, 50, 67, 78, 84}, -- Stage 2
},
[238430] = { -- Bursting Dreadflame
{10.1, 79}, -- Stage 1 (Intermission)
{52.4, 50.0, 45.0, 48.0, 86, 50}, -- Stage 2
{30, 52, 43} -- Stage 3, 52/43 Repeating
},
[238505] = { -- Focused Dreadflame
{28.7, 38.9}, -- Stage 1 (Intermission)
{30.4, 44, 47, 138, 44}, -- Stage 2
{48, 36, 59}, -- Stage 3, 36/59 Repeating
},
}
local wailingMythicTimers = {49.4, 60.0, 169.1, 60.0}
local timers = mod:Mythic() and timersMythic or mod:Heroic() and timersHeroic or mod:Normal() and timersNormal or mod:LFR() and timersLFR
--------------------------------------------------------------------------------
-- Localization
--
local L = mod:GetLocale()
if L then
L.singularityImpact = "Singularity Impact"
L.obeliskExplosion = "Obelisk Explosion"
L.obeliskExplosion_desc = "Timer for the Obelisk Explosion"
L.obeliskExplosion_icon = -15543
L.darkness = "Darkness" -- Shorter name for Darkness of a Thousand Souls (238999)
L.reflectionErupting = "Reflection: Erupting" -- Shorter name for Shadow Reflection: Erupting (236710)
L.reflectionWailing = "Reflection: Wailing" -- Shorter name for Shadow Reflection: Wailing (236378)
L.reflectionHopeless = "Reflection: Hopeless" -- Shorter name for Shadow Reflection: Hopeless (237590)
L.rupturingKnock = "Rupturing Singularity Knockback"
L.rupturingKnock_desc = "Show a timer for the knockback"
L.rupturingKnock_icon = 235059
L.meteorImpact = mod:SpellName(182580)
L.meteorImpact_desc = "Show a timer for the Meteors landing"
L.meteorImpact_icon = 240910
L.countx = "%s (%dx)"
L.shadowsoul = "Shadowsoul Health Tracker"
L.shadowsoul_desc = "Show the info box displaying the current health of the 5 Shadowsoul adds."
L.shadowsoul_icon = 241702
L.custom_on_track_illidan = "Automatically Track Humanoids"
L.custom_on_track_illidan_desc = "If you are a hunter or a feral druid, this option will automatically enable tracking of humanoids so you can track Illidan."
L.custom_on_track_illidan_icon = 19883
L.custom_on_zoom_in = "Automatically Zoom Minimap"
L.custom_on_zoom_in_desc = "This feature will set the minimap zoom to level 4 to make it easier to track Illidan, and then restore it to your previous level once the stage has ended."
L.custom_on_zoom_in_icon = 131220
end
--------------------------------------------------------------------------------
-- Initialization
--
local eruptingMarker = mod:AddMarkerOption(false, "player", 3, 236710, 3, 4, 5) -- Skip marks 1 + 2 for visibility
local shadowsoulMarker = mod:AddMarkerOption(false, "npc", 1, -15397, 1, 2, 3, 4, 5) -- Shadowsoul
function mod:GetOptions()
return {
"stages",
"berserk",
{239932, "TANK"}, -- Felclaws
235059, -- Rupturing Singularity
"rupturingKnock",
240910, -- Armageddon
"meteorImpact",
{236710, "SAY", "SAY_COUNTDOWN", "FLASH"}, -- Shadow Reflection: Erupting
eruptingMarker,
{238430, "SAY", "SAY_COUNTDOWN", "FLASH"}, -- Bursting Dreadflame
{238505, "SAY", "SAY_COUNTDOWN", "ICON", "PROXIMITY"}, -- Focused Dreadflame
{236378, "SAY", "SAY_COUNTDOWN", "FLASH"}, -- Shadow Reflection: Wailing
241564, -- Sorrowful Wail
241721, -- Illidan's Sightless Gaze
{"shadowsoul", "INFOBOX"}, -- Shadowsoul
shadowsoulMarker,
"custom_on_track_illidan",
"custom_on_zoom_in",
238999, -- Darkness of a Thousand Souls
-15543, -- Demonic Obelisk
"obeliskExplosion",
243982, -- Tear Rift
244856, -- Flaming Orb
240262, -- Burning
{237590, "SAY", "SAY_COUNTDOWN", "FLASH"}, -- Shadow Reflection: Hopeless
},{
["stages"] = "general",
[239932] = -14921, -- Stage One: The Betrayer
[238430] = -15221, -- Intermission: Eternal Flame
[236378] = -15229, -- Stage Two: Reflected Souls
[241721] = -15394, -- Intermission: Deceiver's Veil
[238999] = -15255, -- Stage Three: Darkness of A Thousand Souls
[237590] = "mythic", -- Mythic
}
end
function mod:OnBossEnable()
-- General
self:RegisterUnitEvent("UNIT_SPELLCAST_SUCCEEDED", nil, "boss1", "boss2", "boss3", "boss4", "boss5")
self:RegisterEvent("CHAT_MSG_RAID_BOSS_EMOTE")
self:Log("SPELL_AURA_APPLIED", "GroundEffectDamage", 240262) -- Burning (Flaming Orb)
self:Log("SPELL_PERIODIC_DAMAGE", "GroundEffectDamage", 240262)
self:Log("SPELL_PERIODIC_MISSED", "GroundEffectDamage", 240262)
-- Stage One: The Betrayer
self:Log("SPELL_CAST_START", "Felclaws", 239932)
self:Log("SPELL_AURA_APPLIED", "FelclawsApplied", 239932)
self:Log("SPELL_CAST_START", "Armageddon", 240910)
self:Log("SPELL_CAST_SUCCESS", "ArmageddonSuccess", 240910)
self:Log("SPELL_AURA_APPLIED", "ShadowReflectionErupting", 236710) -- Shadow Reflection: Erupting
self:Log("SPELL_AURA_REMOVED", "ShadowReflectionEruptingRemoved", 236710) -- Shadow Reflection: Erupting
self:Log("SPELL_AURA_REMOVED", "LingeringEruptionRemoved", 243536) -- Lingering Eruption, Mythic, Remove marks later than the normal debuff
-- Intermission: Eternal Flame
self:Log("SPELL_AURA_APPLIED", "NetherGale", 244834) -- Intermission Start
self:Log("SPELL_CAST_START", "FocusedDreadflame", 238502) -- Focused Dreadflame
self:Log("SPELL_CAST_SUCCESS", "FocusedDreadflameSuccess", 238502) -- Focused Dreadflame
self:Log("SPELL_CAST_SUCCESS", "BurstingDreadflame", 238430) -- Bursting Dreadflame
self:Log("SPELL_AURA_REMOVED", "NetherGaleRemoved", 244834) -- Intermission End
-- Stage Two: Reflected Souls
self:Log("SPELL_AURA_APPLIED", "ShadowReflectionWailing", 236378) -- Shadow Reflection: Wailing
self:Log("SPELL_AURA_REMOVED", "ShadowReflectionWailingRemoved", 236378) -- Shadow Reflection: Wailing
self:Log("SPELL_CAST_SUCCESS", "SorrowfulWail", 241564) -- Sorrowful Wail
self:Death("WailingReflectionDeath", 119107) -- Wailing Add
-- Intermission: Deceiver's Veil
self:Log("SPELL_CAST_START", "DeceiversVeilCast", 241983) -- Deceiver's Veil Cast
self:Log("SPELL_AURA_APPLIED", "IllidansSightlessGaze", 241721) -- Illidan's Sightless Gaze
self:Log("SPELL_AURA_REFRESH", "IllidansSightlessGaze", 241721) -- Illidan's Sightless Gaze
self:Log("SPELL_AURA_REMOVED", "IllidansSightlessGazeRemoved", 241721) -- Illidan's Sightless Gaze
self:Log("SPELL_AURA_REMOVED", "DeceiversVeilRemoved", 241983) -- Deceiver's Veil Over
-- Stage Three: Darkness of A Thousand Souls
self:Log("SPELL_CAST_START", "DarknessofaThousandSouls", 238999) -- Darkness of a Thousand Souls
self:Log("SPELL_CAST_START", "TearRift", 243982) -- Tear Rift
self:Log("SPELL_CAST_SUCCESS", "DemonicObelisk", 239785) -- Demonic Obelisk
-- Mythic
self:Log("SPELL_AURA_APPLIED", "ShadowReflectionHopeless", 237590) -- Shadow Reflection: Hopeless
self:Log("SPELL_AURA_REMOVED", "ShadowReflectionHopelessRemoved", 237590) -- Shadow Reflection: Hopeless
end
function mod:OnEngage()
stage = 1
inIntermission = nil
singularityCount = 1
focusedDreadflameCount = 1
burstingDreadflameCount = 1
armageddonCount = 1
felclawsCount = 1
flamingOrbCount = 1
obeliskCount = 1
wailingCounter = 1
darknessCount = 1
currentZoom = 0
focusedTarget = nil
timerMinimap = nil
timers = self:Mythic() and timersMythic or self:Heroic() and timersHeroic or self:Normal() and timersNormal or self:LFR() and timersLFR
mobCollector = {}
self:Bar(240910, timers[240910][stage][armageddonCount], CL.count:format(self:SpellName(240910), armageddonCount)) -- Armageddon
if not self:Easy() then
self:Bar(236710, self:Mythic() and 18.5 or 20, INLINE_DAMAGER_ICON.." "..L.reflectionErupting) -- Shadow Reflection: Erupting
end
self:Bar(239932, 25) -- Felclaws
if not self:LFR() then
self:Bar(235059, timers[235059][stage][singularityCount], CL.count:format(self:SpellName(235059), singularityCount)) -- Rupturing Singularity
end
if self:Mythic() then
self:Bar(236378, 55, INLINE_TANK_ICON.." "..CL.count:format(L.reflectionWailing, wailingCounter)) -- Shadow Reflection: Wailing
self:Berserk(840)
else
self:Berserk(600)
end
end
function mod:OnWipe()
if inIntermission and stage == 2 then
resetMinimap(self)
end
end
--------------------------------------------------------------------------------
-- Event Handlers
--
-- General
function mod:CHAT_MSG_RAID_BOSS_EMOTE(_, msg, _, _, _, target)
if msg:find("238502", nil, true) then -- Focused Dreadflame Target
self:TargetMessageOld(238505, target, "yellow", "alarm", nil, nil, true)
self:TargetBar(238505, 5, target)
self:PrimaryIcon(238505, target)
local guid = self:UnitGUID(target)
focusedTarget = guid
if self:Me(guid) then
self:Say(238505)
self:SayCountdown(238505, 5)
end
if not self:Easy() then
self:OpenProximity(238505, 5)
end
-- Schedule fake success in case the target uses invis, etc
self:ScheduleTimer("FocusedDreadflameSuccess", 5.5)
elseif msg:find("235059", nil, true) then -- Rupturing Singularity
self:MessageOld(235059, "orange", "warning", CL.count:format(self:SpellName(235059), singularityCount))
self:Bar("rupturingKnock", 9.85, CL.count:format(L.singularityImpact, singularityCount), 235059)
singularityCount = singularityCount + 1
local timer = 0
if inIntermission then -- Intermission timer
if self:Mythic() and stage == 2 then
timer = singularityCount % 2 == 1 and 20 or 10
elseif self:Easy() or singularityCount > 2 or self:Mythic() then
return -- Only time for 2 during intermission, and only on Heroic + -- They happen in Mythic but do not all trigger a raid warning
else
timer = 30
end
else
timer = timers[235059][stage][singularityCount]
end
self:Bar(235059, timer, CL.count:format(self:SpellName(235059), singularityCount))
end
end
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
function mod:UNIT_SPELLCAST_SUCCEEDED(_, _, _, spellId)
if spellId == 244856 then -- Flaming Orb
self:MessageOld(spellId, "yellow", "alert", CL.count:format(self:SpellName(spellId), flamingOrbCount))
flamingOrbCount = (flamingOrbCount % (self:Mythic() and 3 or 2)) + 1
self:Bar(spellId, self:Mythic() and (flamingOrbCount == 2 and 15.0 or flamingOrbCount == 3 and 16.0 or 64) or flamingOrbCount == 2 and 30 or 64, CL.count:format(self:SpellName(spellId), flamingOrbCount))
end
end
-- Stage One: The Betrayer
function mod:Felclaws(args)
self:MessageOld(args.spellId, "red", "alarm", CL.casting:format(args.spellName))
end
function mod:FelclawsApplied(args)
self:MessageOld(args.spellId, "red", "info")
felclawsCount = felclawsCount + 1
if self:Mythic() and stage == 3 then
self:Bar(args.spellId, felclawsCount % 4 == 0 and 29 or felclawsCount % 4 == 1 and 16 or 24)
elseif self:LFR() then
self:Bar(args.spellId, stage == 2 and 27.7 or 25)
elseif stage == 3 and felclawsCount % 4 == 1 then
self:Bar(args.spellId, 20)
else
self:Bar(args.spellId, 24)
end
self:TargetBar(args.spellId, 11.5, args.destName)
end
function mod:Armageddon(args)
self:MessageOld(args.spellId, "red", "warning", CL.count:format(args.spellName, armageddonCount))
armageddonCount = armageddonCount + 1
local timer = 0
if inIntermission then -- Intermission timer
if armageddonCount == 2 then
timer = self:Mythic() and 58.9 or 29.4
else
return -- Only time for 2 during intermission
end
else
timer = timers[args.spellId][stage][armageddonCount]
end
self:Bar(args.spellId, timer, CL.count:format(args.spellName, armageddonCount))
end
function mod:ArmageddonSuccess(args)
self:Bar("meteorImpact", 8, CL.count:format(L.meteorImpact, armageddonCount-1), args.spellId) -- Meteor Impact
end
do
local playerList = mod:NewTargetList()
function mod:ShadowReflectionErupting(args)
playerList[#playerList+1] = args.destName
if self:Me(args.destGUID) then
self:Flash(args.spellId)
self:Say(args.spellId, self:Easy() and L.reflectionErupting or CL.count_rticon:format(L.reflectionErupting, #playerList, #playerList+2))
self:SayCountdown(args.spellId, 8)
end
if #playerList == 1 then
self:Bar(args.spellId, 8, INLINE_DAMAGER_ICON.." "..CL.adds)
if stage == 2 and not self:Mythic() then
self:Bar(args.spellId, self:LFR() and 124.4 or 112, INLINE_DAMAGER_ICON.." "..L.reflectionErupting)
elseif self:Mythic() and stage == 1 then
self:Bar(args.spellId, 109, INLINE_DAMAGER_ICON.." "..L.reflectionErupting)
end
self:ScheduleTimer("TargetMessageOld", 0.3, args.spellId, playerList, "orange", "alert", L.reflectionErupting)
end
if self:GetOption(eruptingMarker) then
self:CustomIcon(false, args.destName, #playerList+2) -- Skip marks 1 + 2 for visibility
end
end
function mod:ShadowReflectionEruptingRemoved(args)
if self:Me(args.destGUID) then
self:CancelSayCountdown(args.spellId)
end
if self:GetOption(eruptingMarker) and not self:Mythic() then -- Don't remove icons in Mythic
self:CustomIcon(false, args.destName)
end
end
function mod:LingeringEruptionRemoved(args) -- Mythic only, Remove icons after this debuff instead
if self:GetOption(eruptingMarker) then
self:CustomIcon(false, args.destName)
end
end
end
-- Intermission: Eternal Flame
function mod:NetherGale(args)
self:MessageOld("stages", "green", "long", CL.intermission, false)
self:StopBar(CL.count:format(self:SpellName(240910), armageddonCount)) -- Armageddon
self:StopBar(CL.count:format(self:SpellName(235059), singularityCount)) -- Rupturing Singularity
self:StopBar(INLINE_DAMAGER_ICON.." "..L.reflectionErupting) -- Shadow Reflection: Erupting
self:StopBar(239932) -- Felclaws
self:StopBar(INLINE_TANK_ICON.." "..CL.count:format(L.reflectionWailing, wailingCounter)) -- Shadow Reflection: Wailing
inIntermission = true
singularityCount = 1
armageddonCount = 1
focusedDreadflameCount = 1
felclawsCount = 1
wailingCounter = 1
-- First Intermission
self:CDBar(240910, self:Mythic() and 6.5 or 6.1, CL.count:format(self:SpellName(240910), armageddonCount)) -- Armageddon
self:CDBar(238430, timers[238430][stage][burstingDreadflameCount]) -- Bursting Dreadflame
if not self:Easy() then -- During intermission only on Heroic +
self:CDBar(235059, self:Mythic() and 14 or 13.3, CL.count:format(self:SpellName(235059), singularityCount)) -- Rupturing Singularity
end
if not self:LFR() then
self:CDBar(238505, timers[238505][stage][focusedDreadflameCount]) -- Focused Dreadflame
end
self:CDBar("stages", self:Mythic() and 94.8 or 60.2, CL.intermission, args.spellId) -- Intermission Duration
end
function mod:FocusedDreadflame()
focusedDreadflameCount = focusedDreadflameCount + 1
self:Bar(238505, timers[238505][stage][stage == 3 and (focusedDreadflameCount % 2 == 0 and 2 or 3) or focusedDreadflameCount])
end
function mod:FocusedDreadflameSuccess()
if focusedTarget then
focusedTarget = nil
self:PrimaryIcon(238505)
self:CloseProximity(238505)
end
end
do
local playerList = mod:NewTargetList()
function mod:BurstingDreadflame(args)
if self:Me(args.destGUID) then
self:Flash(args.spellId)
self:Say(args.spellId)
self:SayCountdown(args.spellId, 5)
end
playerList[#playerList+1] = args.destName
if #playerList == 1 then
self:ScheduleTimer("TargetMessageOld", 0.3, args.spellId, playerList, "red", "warning")
burstingDreadflameCount = burstingDreadflameCount + 1
self:Bar(args.spellId, timers[args.spellId][stage][stage == 3 and (burstingDreadflameCount % 2 == 0 and 2 or 3) or burstingDreadflameCount])
end
end
end
function mod:NetherGaleRemoved() -- Stage 2
inIntermission = nil
stage = 2
self:MessageOld("stages", "green", "long", CL.stage:format(stage), false)
focusedDreadflameCount = 1
burstingDreadflameCount = 1
singularityCount = 1
armageddonCount = 1
felclawsCount = 1
self:Bar(239932, 10.4) -- Felclaws
self:Bar(236710, self:Mythic() and 164 or 13.9, INLINE_DAMAGER_ICON.." "..L.reflectionErupting) -- Shadow Reflection: Erupting
if not self:Easy() then
self:Bar(236378, self:Mythic() and 49.4 or 48.4, INLINE_TANK_ICON.." "..CL.count:format(L.reflectionWailing, wailingCounter)) -- Shadow Reflection: Wailing
end
self:Bar(240910, timers[240910][stage][armageddonCount], CL.count:format(self:SpellName(240910), armageddonCount)) -- Armageddon
self:Bar(238430, timers[238430][stage][burstingDreadflameCount]) -- Bursting Dreadflame
if not self:LFR() then
self:Bar(238505, timers[238505][stage][focusedDreadflameCount]) -- Focused Dreadflame
self:Bar(235059, timers[235059][stage][singularityCount], CL.count:format(self:SpellName(235059), singularityCount)) -- Rupturing Singularity
end
if self:Mythic() then
self:Bar(237590, 27, INLINE_HEALER_ICON.." "..L.reflectionHopeless) -- Shadow Reflection: Hopeless
end
end
-- Stage Two: Reflected Souls
do
function mod:ShadowReflectionWailing(args)
self:TargetMessageOld(args.spellId, args.destName, "orange", "alert", CL.count:format(L.reflectionWailing, wailingCounter), nil, true)
self:Bar(args.spellId, 7, INLINE_TANK_ICON.." "..CL.add)
wailingCounter = wailingCounter + 1
local timer = 114
if self:Mythic() and stage == 2 then
timer = wailingMythicTimers[wailingCounter]
end
self:Bar(args.spellId, timer, INLINE_TANK_ICON.." "..CL.count:format(L.reflectionWailing, wailingCounter)) -- Not seen 2nd add in P1
if self:Me(args.destGUID) then
self:Flash(args.spellId)
self:Say(args.spellId, L.reflectionWailing)
self:SayCountdown(args.spellId, 7)
end
end
function mod:ShadowReflectionWailingRemoved(args)
if self:Me(args.destGUID) then
self:CancelSayCountdown(args.spellId)
end
self:Bar(241564, 15.8) -- Sorrowful Wail cast
end
function mod:SorrowfulWail(args)
self:MessageOld(args.spellId, "yellow", "alarm")
self:Bar(args.spellId, 15.8)
end
function mod:WailingReflectionDeath()
self:StopBar(241564) -- Sorrowful Wail
end
end
-- Intermission: Deceiver's Veil
do
local decieversAddMarks = {} -- Marks we set
local addMaxHP = -1
local addDmg = {} -- Damage done per add
local addMarks = {} -- Current marks on each add
function mod:ShadowsoulScanner(event, unit)
local guid = self:UnitGUID(unit)
if self:MobId(guid) == 121193 and not mobCollector[guid] then
for i = 1, 5 do
if not decieversAddMarks[i] then
if self:GetOption(shadowsoulMarker) then
self:CustomIcon(false, unit, i)
end
decieversAddMarks[i] = guid
mobCollector[guid] = true
if i == 5 then
self:UnregisterTargetEvents()
end
break
end
end
local maxHp = UnitHealthMax(unit)
if addMaxHP == -1 then
addMaxHP = maxHp
end
addDmg[guid] = maxHp - UnitHealth(unit)
local icon = GetRaidTargetIndex(unit)
if icon and icon > 0 and icon < 9 then
addMarks[guid] = icon
end
end
end
local marks = {
[0x00000001] = 1, -- COMBATLOG_OBJECT_RAIDTARGET1
[0x00000002] = 2, -- COMBATLOG_OBJECT_RAIDTARGET2
[0x00000004] = 3, -- COMBATLOG_OBJECT_RAIDTARGET3
[0x00000008] = 4, -- COMBATLOG_OBJECT_RAIDTARGET4
[0x00000010] = 5, -- COMBATLOG_OBJECT_RAIDTARGET5
[0x00000020] = 6, -- COMBATLOG_OBJECT_RAIDTARGET6
[0x00000040] = 7, -- COMBATLOG_OBJECT_RAIDTARGET7
[0x00000080] = 8, -- COMBATLOG_OBJECT_RAIDTARGET8
}
local timer = nil
local function updateInfoBox(self)
if addMaxHP < 0 then return end -- no max hp yet
local i = 1
for guid, dmg in pairs(addDmg) do
if i > 5 then break end -- safety
local percentage = (addMaxHP - dmg) / addMaxHP
if percentage > 0 then
if addMarks[guid] then
self:SetInfo("shadowsoul", i*2-1, ("%s |T13700%d:0|t"):format(CL.count:format(CL.add, i), addMarks[guid]))
else
self:SetInfo("shadowsoul", i*2-1, CL.count:format(CL.add, i))
end
self:SetInfo("shadowsoul", i*2, ("%.0f%%"):format(percentage*100))
else
self:SetInfo("shadowsoul", i*2-1, "")
self:SetInfo("shadowsoul", i*2, "")
end
self:SetInfoBar("shadowsoul", i*2, percentage)
i = i + 1
end
end
local function damageToMob(guid, dmg, overkill, raidFlags)
addMarks[guid] = marks[raidFlags]
if overkill > 0 then
addDmg[guid] = addMaxHP
else
addDmg[guid] = (addDmg[guid] or 0) + dmg
end
end
function mod:IntermissionAddDamage(args)
if addDmg[args.destGUID] then
-- :Log isn't designed for _DAMAGE events, so we'll have to switch some things around:
-- - extraSpellId is the amount of damage inflicted
-- - extraSpellName is the amount of overkill
damageToMob(args.destGUID, args.extraSpellId, args.extraSpellName, args.destRaidFlags)
end
end
function mod:IntermissionAddDamageSwing(args)
if addDmg[args.destGUID] then
-- :Log isn't designed for _DAMAGE events, so we'll have to switch some things around:
-- - spellId is the amount of damage inflicted
-- - spellName is the amount of overkill
damageToMob(args.destGUID, args.spellId, args.spellName, args.destRaidFlags)
end
end
local function loopTracking(self, n)
local _, _, active = GetTrackingInfo(n)
if not active then
SetTracking(n, true)
else
self:CancelTimer(timerMinimap)
timerMinimap = nil
end
end
function mod:DeceiversVeilCast() -- Intermission 2
inIntermission = true
self:MessageOld("stages", "green", "long", CL.intermission, false)
self:StopBar(CL.count:format(self:SpellName(240910), armageddonCount)) -- Armageddon
self:StopBar(INLINE_DAMAGER_ICON.." "..L.reflectionErupting) -- Shadow Reflection: Erupting
self:StopBar(INLINE_TANK_ICON.." "..CL.count:format(L.reflectionWailing, wailingCounter)) -- Shadow Reflection: Wailing
self:StopBar(239932) -- Felclaws
self:StopBar(238430) -- Bursting Dreadflame
self:StopBar(238505) -- Focused Dreadflame
self:StopBar(CL.count:format(self:SpellName(235059), singularityCount)) -- Rupturing Singularity
self:StopBar(INLINE_HEALER_ICON.." "..L.reflectionHopeless) -- Shadow Reflection: Hopeless
singularityCount = 1
if self:Mythic() then
self:Bar(235059, 19.1, CL.count:format(self:SpellName(235059), singularityCount)) -- Rupturing Singularity
end
local shadowsoulOption = self:CheckOption("shadowsoul", "INFOBOX")
if self:GetOption(shadowsoulMarker) or shadowsoulOption then
decieversAddMarks = {}
if shadowsoulOption then
addDmg = {}
addMarks = {}
addMaxHP = -1
self:Log("SPELL_DAMAGE", "IntermissionAddDamage", "*")
self:Log("SPELL_PERIODIC_DAMAGE", "IntermissionAddDamage", "*")
self:Log("RANGE_DAMAGE", "IntermissionAddDamage", "*")
self:Log("SWING_DAMAGE", "IntermissionAddDamageSwing", "*")
self:OpenInfo("shadowsoul", self:SpellName(-15397)) -- Shadowsoul
for i = 1, 5 do
self:SetInfo("shadowsoul", i*2-1, CL.count:format(CL.add, i))
self:SetInfo("shadowsoul", i*2, "100%")
end
timer = self:ScheduleRepeatingTimer(updateInfoBox, 0.1, self)
end
self:RegisterTargetEvents("ShadowsoulScanner")
end
if self:GetOption("custom_on_track_illidan") then
local trackHumanoids = self:SpellName(19883)
for i = 1, GetNumTrackingTypes() do
local name = GetTrackingInfo(i)
if name == trackHumanoids then
timerMinimap = self:ScheduleRepeatingTimer(loopTracking, 0.1, self, i)
break
end
end
end
if self:GetOption("custom_on_zoom_in") then
currentZoom = Minimap:GetZoom() or 0
Minimap:SetZoom(4)
end
end
function resetMinimap(self)
if timerMinimap then
self:CancelTimer(timerMinimap)
timerMinimap = nil
end
if self:GetOption("custom_on_track_illidan") then
local trackHumanoids = self:SpellName(19883)
for i = 1, GetNumTrackingTypes() do
local name = GetTrackingInfo(i)
if name == trackHumanoids then
SetTracking(i, false)
break
end
end
end
if self:GetOption("custom_on_zoom_in") then
Minimap:SetZoom(currentZoom)
end
end
function mod:DeceiversVeilRemoved() -- Stage 3
stage = 3
inIntermission = nil
darknessCount = 1
focusedDreadflameCount = 1
burstingDreadflameCount = 1
flamingOrbCount = 1
felclawsCount = 1
resetMinimap(self)
local shadowsoulOption = self:CheckOption("shadowsoul", "INFOBOX")
if self:GetOption(shadowsoulMarker) or shadowsoulOption then
self:UnregisterTargetEvents()
if shadowsoulOption then
self:CloseInfo("shadowsoul")
self:RemoveLog("SPELL_DAMAGE", "*")
self:RemoveLog("SPELL_PERIODIC_DAMAGE", "*")
self:RemoveLog("RANGE_DAMAGE", "*")
self:RemoveLog("SWING_DAMAGE", "*")
if timer then
self:CancelTimer(timer)
timer = nil
end
end
end
self:MessageOld("stages", "green", "long", CL.stage:format(stage), false)
self:Bar(238999, 2, CL.count:format(L.darkness, darknessCount)) -- Darkness of a Thousand Souls
self:Bar(239932, 11) -- Felclaws
self:Bar(243982, 15) -- Tear Rift
if not self:Easy() then
self:Bar(244856, self:Mythic() and 40 or 30, CL.count:format(self:SpellName(244856), flamingOrbCount)) -- Flaming Orb
end
self:Bar(238430, timers[238430][stage][burstingDreadflameCount]) -- Bursting Dreadflame
if not self:LFR() then
self:Bar(238505, timers[238505][stage][focusedDreadflameCount]) -- Focused Dreadflame
end
end
end
do
local prev = 0
function mod:IllidansSightlessGaze(args)
local t = GetTime()
if self:Me(args.destGUID) then
if t-prev > 1.5 then
prev = t
self:MessageOld(args.spellId, "blue", "long", CL.you:format(args.spellName))
end
self:Bar(args.spellId, 20)
end
end
end
function mod:IllidansSightlessGazeRemoved(args)
if stage == 2 and self:Me(args.destGUID) then -- Don't warn in p3
self:MessageOld(args.spellId, "blue", "alert", CL.removed:format(args.spellName))
end
end
-- Stage Three: Darkness of A Thousand Souls
function mod:DarknessofaThousandSouls(args)
self:MessageOld(args.spellId, "orange", "long", CL.casting:format(CL.count:format(args.spellName, darknessCount)))
self:CastBar(args.spellId, 9, CL.count:format(L.darkness, darknessCount))
darknessCount = darknessCount + 1
self:Bar(args.spellId, darknessCount == 2 and 90 or 95, CL.count:format(L.darkness, darknessCount))
self:StartObeliskTimer(darknessCount == 2 and 25 or 28)
end
do
local prev = 0
function mod:DemonicObelisk()
local t = GetTime()
if t-prev > 1.5 then
prev = t
self:CastBar("obeliskExplosion", 5, L.obeliskExplosion, -15543)
end
end
end
function mod:StartObeliskTimer(t)
local obeliskCounter = self:Mythic() and (obeliskCount+2) or self:Heroic() and (darknessCount+1) or darknessCount -- Mythic: 3-4-5-6-7... Heroic: 3-3-4-4-5... Normal: 2-2-3-3-4...
self:Bar(-15543, t, L.countx:format(self:SpellName(-15543), obeliskCounter))
self:ScheduleTimer("MessageOld", t, -15543, "yellow", "info", CL.spawned:format(L.countx:format(self:SpellName(-15543), obeliskCounter)))
self:ScheduleTimer("CastBar", t, "obeliskExplosion", 13, L.obeliskExplosion, -15543) -- will get readjusted in :DemonicObelisk()
obeliskCount = obeliskCount + 1
if obeliskCount % 2 == 0 then
self:ScheduleTimer("StartObeliskTimer", t, 36)
end
end
function mod:TearRift(args)
self:MessageOld(args.spellId, "red", "alarm")
self:Bar(args.spellId, obeliskCount == 1 and 90 or 95)
end
-- Mythic
do
local playerList = mod:NewTargetList()
function mod:ShadowReflectionHopeless(args)
if self:Me(args.destGUID) then
self:Flash(args.spellId)
self:Say(args.spellId, L.reflectionHopeless)
self:SayCountdown(args.spellId, 8)
end
playerList[#playerList+1] = args.destName
if #playerList == 1 then
self:Bar(args.spellId, 196.0, INLINE_HEALER_ICON.." "..L.reflectionHopeless)
self:Bar(args.spellId, 8, INLINE_HEALER_ICON.." "..CL.adds)
self:ScheduleTimer("TargetMessageOld", 0.3, args.spellId, playerList, "orange", "alert", L.reflectionHopeless)
end
end
function mod:ShadowReflectionHopelessRemoved(args)
if self:Me(args.destGUID) then
self:CancelSayCountdown(args.spellId)
end
end
end