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.

602 lines
20 KiB

--------------------------------------------------------------------------------
-- Module Declaration
--
local mod, CL = BigWigs:NewBoss("The Coven of Shivarra", 1712, 1986)
if not mod then return end
mod:RegisterEnableMob(122468, 122467, 122469, 125436) -- Noura, Asara, Diima, Thu'raya
mod.engageId = 2073
mod.respawnTime = 21
--------------------------------------------------------------------------------
-- Locals
--
local chilledBloodTime = 0
local chilledBloodList = {}
local chilledBloodMaxAbsorb = 1
local bloodBarPlacement = 0
local tormentIcons = {
AmanThul = 139, -- Renew
Norgannon = 245910, -- Army
Khazgoroth = 245671, -- Flames
Golganneth = 421, -- Chain Lightning
}
local upcomingTorments = {}
--------------------------------------------------------------------------------
-- Localization
--
local L = mod:GetLocale()
if L then
L.torment_of_the_titans = mod:SpellName(-16138) -- Torment of the Titans
L.torment_of_the_titans_desc = "The Shivvara will force the titan souls to use their abilities against the players."
L.torment_of_the_titans_icon = 245910 -- Spectral Army of Norgannon
L.timeLeft = "%.1fs"
L.torment = "Torment: %s"
L.nextTorment = "Next Torment: |cffffffff%s|r"
L.tormentHeal = "Heal/DoT"
L.tormentLightning = "Lightning" -- short for Chain Lightning
L.tormentArmy = "Army"
L.tormentFlames = "Flames"
end
--------------------------------------------------------------------------------
-- Initialization
--
local chilledBloodMarker = mod:AddMarkerOption(false, "player", 1, 245586, 1, 2, 5)
local cosmicGlareMarker = mod:AddMarkerOption(false, "player", 3, 250912, 3,4)
function mod:GetOptions()
return {
--[[ General ]]--
"stages",
"berserk",
"infobox",
253203, -- Shivan Pact
"torment_of_the_titans",
--[[ Noura, Mother of Flame ]]--
{244899, "TANK"}, -- Fiery Strike
245627, -- Whirling Saber
{253520, "SAY", "SAY_COUNTDOWN"}, -- Fulminating Pulse
--[[ Asara, Mother of Night ]]--
246329, -- Shadow Blades
252861, -- Storm of Darkness
--[[ Diima, Mother of Gloom ]]--
{245518, "TANK_HEALER"}, -- Flashfreeze
{245586, "INFOBOX"}, -- Chilled Blood
chilledBloodMarker,
253650, -- Orb of Frost
--[[ Thu'raya, Mother of the Cosmos (Mythic) ]]--
250648, -- Touch of the Cosmos
{250757, "SAY", "SAY_COUNTDOWN", "FLASH"}, -- Cosmic Glare
cosmicGlareMarker,
},{
["stages"] = "general",
[244899] = -15967, -- Noura, Mother of Flame
[246329] = -15968, -- Asara, Mother of Night
[245518] = -15969, -- Diima, Mother of Gloom
[250648] = -16398, -- Thu'raya, Mother of the Cosmos
}
end
function mod:OnBossEnable()
--[[ General ]]--
self:RegisterUnitEvent("UNIT_TARGETABLE_CHANGED", nil, "boss1", "boss2", "boss3", "boss4")
self:Log("SPELL_AURA_APPLIED", "ShivanPact", 253203)
self:RegisterEvent("CHAT_MSG_RAID_BOSS_EMOTE")
self:RegisterUnitEvent("UNIT_SPELLCAST_SUCCEEDED", nil, "boss1", "boss2", "boss3", "boss4")
self:Log("SPELL_CAST_SUCCESS", "TormentofAmanThul", 250335)
self:Log("SPELL_CAST_SUCCESS", "TormentofKhazgoroth", 250333)
self:Log("SPELL_CAST_SUCCESS", "TormentofGolganneth", 249793)
self:Log("SPELL_CAST_SUCCESS", "TormentofNorgannon", 250334)
--[[ Noura, Mother of Flame ]]--
self:Log("SPELL_AURA_APPLIED", "FieryStrike", 244899)
self:Log("SPELL_AURA_APPLIED_DOSE", "FieryStrike", 244899)
self:Log("SPELL_CAST_SUCCESS", "FieryStrikeSuccess", 244899)
self:Log("SPELL_CAST_START", "WhirlingSaber", 245627)
self:Log("SPELL_AURA_APPLIED", "FulminatingPulse", 253520)
self:Log("SPELL_AURA_REMOVED", "FulminatingPulseRemoved", 253520)
--[[ Asara, Mother of Night ]]--
self:Log("SPELL_CAST_SUCCESS", "ShadowBlades", 246329)
self:Log("SPELL_CAST_START", "StormofDarkness", 252861)
--[[ Diima, Mother of Gloom ]]--
self:Log("SPELL_CAST_SUCCESS", "FlashfreezeSuccess", 245518)
self:Log("SPELL_AURA_APPLIED", "Flashfreeze", 245518)
self:Log("SPELL_AURA_APPLIED_DOSE", "Flashfreeze", 245518)
self:Log("SPELL_AURA_APPLIED", "ChilledBlood", 245586)
self:Log("SPELL_AURA_REMOVED", "ChilledBloodRemoved", 245586)
self:Log("SPELL_CAST_START", "OrbofFrost", 253650)
--[[ Thu'raya, Mother of the Cosmos (Mythic) ]]--
self:Log("SPELL_CAST_START", "TouchoftheCosmos", 250648)
self:Log("SPELL_AURA_APPLIED", "CosmicGlare", 250757)
self:Log("SPELL_AURA_REMOVED", "CosmicGlareRemoved", 250757)
--[[ Ground effects ]]--
self:Log("SPELL_DAMAGE", "WhirlingSaberDamage", 245629, 245634) -- Initial impact, standing in it
self:Log("SPELL_MISSED", "WhirlingSaberDamage", 245629, 245634)
self:Log("SPELL_AURA_APPLIED", "StormOfDarknessDamage", 253020)
self:Log("SPELL_PERIODIC_DAMAGE", "StormOfDarknessDamage", 253020)
self:Log("SPELL_PERIODIC_MISSED", "StormOfDarknessDamage", 253020)
end
function mod:OnEngage()
chilledBloodTime = 0
bloodBarPlacement = 0
chilledBloodList = {}
chilledBloodMaxAbsorb = 1
upcomingTorments = {}
self:Bar(245627, 8.5) -- Whirling Saber
self:Bar(244899, 12.1) -- Fiery Strike
if not self:Easy() then
self:Bar(253520, 20.6) -- Fulminating Pulse
end
self:Bar(246329, 12.1) -- Shadow Blades
if not self:Easy() then
self:Bar(252861, 27.9) -- Storm of Darkness
end
self:CDBar("torment_of_the_titans", 82, L.torment_of_the_titans, L.torment_of_the_titans_icon)
self:CDBar("stages", 190, -15969, "achievement_boss_argus_shivan") -- Diima, Mother of Gloom
self:Berserk(720)
end
--------------------------------------------------------------------------------
-- Event Handlers
--
local updateInfoBox
do
local tormentMarkup = {
AmanThul = {color = "|cff81c784", text = "tormentHeal", icon = GetSpellTexture(tormentIcons.AmanThul)},
Norgannon = {color = "|cff9575cd", text = "tormentArmy", icon = GetSpellTexture(tormentIcons.Norgannon)},
Khazgoroth = {color = "|cffe57373", text = "tormentFlames", icon = GetSpellTexture(tormentIcons.Khazgoroth)},
Golganneth = {color = "|cff4fc3f7", text = "tormentLightning", icon = GetSpellTexture(tormentIcons.Golganneth)},
}
local sort, min, sortFunc = table.sort, math.min, function(a, b)
return a[2] > b[2]
end
function updateInfoBox()
local showTorments = next(upcomingTorments)
local showChilledBlood = mod:CheckOption(245586, "INFOBOX")
local bloodOffset = 0
-- Torment
if showTorments then
mod:OpenInfo("infobox", L.nextTorment:format(""))
local nextTorment = tormentMarkup[upcomingTorments[1]]
local data = ("|T%s:15:15:0:0:64:64:4:60:4:60|t%s%s|r"):format(nextTorment.icon, nextTorment.color, L[nextTorment.text])
mod:SetInfo("infobox", 1, data)
bloodOffset = 2
end
-- Chilled Blood
if showChilledBlood then
local timeLeft = chilledBloodTime - GetTime()
if #chilledBloodList > 0 and timeLeft > 0 then
if not showTorments then
mod:OpenInfo("infobox", mod:SpellName(245586))
end
bloodBarPlacement = bloodOffset+1
mod:SetInfo("infobox", bloodBarPlacement, "|cffffffff" .. mod:SpellName(245586))
mod:SetInfo("infobox", bloodOffset+2, L.timeLeft:format(timeLeft))
mod:SetInfoBar("infobox", bloodBarPlacement, timeLeft/10)
sort(chilledBloodList, sortFunc)
for i = 1, min((8-bloodOffset)/2, 3) do
if chilledBloodList[i] then
local player = chilledBloodList[i][1]
local icon = GetRaidTargetIndex(player)
mod:SetInfo("infobox", bloodOffset+1+i*2, (icon and ("|T13700%d:0|t"):format(icon) or "") .. mod:ColorName(player))
mod:SetInfo("infobox", bloodOffset+2+i*2, mod:AbbreviateNumber(chilledBloodList[i][2]))
mod:SetInfoBar("infobox", bloodOffset+1+i*2, chilledBloodList[i][2] / chilledBloodMaxAbsorb)
else
mod:SetInfo("infobox", bloodOffset+1+i*2, "")
mod:SetInfo("infobox", bloodOffset+2+i*2, "")
mod:SetInfoBar("infobox", bloodOffset+1+i*2, 0)
end
end
else
showChilledBlood = nil
end
end
if not showChilledBlood and not showTorments then
mod:CloseInfo("infobox")
end
end
end
--[[ General ]]--
function mod:UNIT_TARGETABLE_CHANGED(_, unit)
if self:MobId(self:UnitGUID(unit)) == 122468 then -- Noura
if UnitCanAttack("player", unit) then
self:MessageOld("stages", "green", "long", -15967, false) -- Noura, Mother of Flame
self:Bar(245627, 8.9) -- Whirling Saber
self:Bar(244899, 12.5) -- Fiery Strike
if not self:Easy() then
self:Bar(253520, 21.1) -- Fulminating Pulse
end
self:StopBar(-15967) -- Noura, Mother of Flame
if self:Mythic() then
self:CDBar("stages", 46, -15968, "achievement_boss_argus_shivan") -- Asara, Mother of Night
end
else
self:StopBar(244899) -- Fiery Strike
self:StopBar(245627) -- Whirling Saber
self:StopBar(253520) -- Fulminating Pulse
end
elseif self:MobId(self:UnitGUID(unit)) == 122467 then -- Asara
if UnitCanAttack("player", unit) then
self:MessageOld("stages", "green", "long", -15968, false) -- Asara, Mother of Night
self:Bar(246329, 12.6) -- Shadow Blades
if not self:Easy() then
self:Bar(252861, 28.4) -- Storm of Darkness
end
self:StopBar(-15968) -- Asara, Mother of Night
else
self:StopBar(246329) -- Shadow Blades
self:StopBar(252861) -- Storm of Darkness
end
elseif self:MobId(self:UnitGUID(unit)) == 122469 then -- Diima
if UnitCanAttack("player", unit) then
self:MessageOld("stages", "green", "long", -15969, false) -- Diima, Mother of Gloom
self:Bar(245586, 8) -- Chilled Blood
self:Bar(245518, 12.2) -- Flashfreeze
if not self:Easy() then
self:Bar(253650, 30) -- Orb of Frost
end
self:StopBar(-15969) -- Diima, Mother of Gloom
if self:Mythic() then
self:CDBar("stages", 46, -16398, "achievement_boss_argus_shivan") -- Thu'raya, Mother of the Cosmos
else
self:CDBar("stages", 185, -15967, "achievement_boss_argus_shivan") -- Noura, Mother of Flame
end
else
self:StopBar(245518) -- Flashfreeze
self:StopBar(245586) -- Chilled Blood
self:StopBar(253650) -- Orb of Frost
end
elseif self:MobId(self:UnitGUID(unit)) == 125436 then -- Thu'raya
if UnitCanAttack("player", unit) then
self:MessageOld("stages", "green", "long", -16398, false) -- Thu'raya, Mother of the Cosmos
self:Bar(250757, 5.2) -- Cosmic Glare
self:StopBar(-16398) -- Thu'raya, Mother of the Cosmos
self:CDBar("stages", 142, -15967, "achievement_boss_argus_shivan") -- Noura, Mother of Flame
else
self:StopBar(250757) -- Cosmic Glare
end
end
end
do
local prev = 0
function mod:ShivanPact(args)
local t = GetTime()
if t-prev > 1.5 then
prev = t
self:MessageOld(args.spellId, "red", "info")
end
end
end
function mod:CHAT_MSG_RAID_BOSS_EMOTE(_, msg)
if msg:find("250095", nil, true) then -- Machinations of Aman'thul
self:MessageOld("torment_of_the_titans", "orange", nil, CL.soon:format(L.torment:format(L.tormentHeal)), tormentIcons["AmanThul"])
elseif msg:find("245671", nil, true) then -- Flames of Khaz'goroth
self:MessageOld("torment_of_the_titans", "orange", nil, CL.soon:format(L.torment:format(L.tormentFlames)), tormentIcons["Khazgoroth"])
elseif msg:find("246763", nil, true) then -- Fury of Golganneth
self:MessageOld("torment_of_the_titans", "orange", nil, CL.soon:format(L.torment:format(L.tormentLightning)), tormentIcons["Golganneth"])
elseif msg:find("245910", nil, true) then -- Spectral Army of Norgannon
self:MessageOld("torment_of_the_titans", "orange", nil, CL.soon:format(L.torment:format(L.tormentArmy)), tormentIcons["Norgannon"])
end
end
do
local tormentLocaleLookup = {
["AmanThul"] = "tormentHeal",
["Norgannon"] = "tormentArmy",
["Khazgoroth"] = "tormentFlames",
["Golganneth"] = "tormentLightning",
}
function mod:UNIT_SPELLCAST_SUCCEEDED(_, _, _, spellId)
local announceNextTorment = nil
if spellId == 253949 then -- Machinations of Aman'thul
self:StopBar(L.torment:format(L.tormentHeal))
tDeleteItem(upcomingTorments, "AmanThul")
self:MessageOld("torment_of_the_titans", "red", "warning", L.torment:format(L.tormentHeal), tormentIcons["AmanThul"])
updateInfoBox()
announceNextTorment = true
elseif spellId == 253881 then -- Flames of Khaz'goroth
self:StopBar(L.torment:format(L.tormentFlames))
tDeleteItem(upcomingTorments, "Khazgoroth")
self:MessageOld("torment_of_the_titans", "red", "warning", L.torment:format(L.tormentFlames), tormentIcons["Khazgoroth"])
updateInfoBox()
announceNextTorment = true
elseif spellId == 253951 then -- Fury of Golganneth
self:StopBar(L.torment:format(L.tormentLightning))
tDeleteItem(upcomingTorments, "Golganneth")
self:MessageOld("torment_of_the_titans", "red", "warning", L.torment:format(L.tormentLightning), tormentIcons["Golganneth"])
updateInfoBox()
announceNextTorment = true
elseif spellId == 253950 then -- Spectral Army of Norgannon
self:StopBar(L.torment:format(L.tormentArmy))
tDeleteItem(upcomingTorments, "Norgannon")
self:MessageOld("torment_of_the_titans", "red", "warning", L.torment:format(L.tormentArmy), tormentIcons["Norgannon"])
updateInfoBox()
announceNextTorment = true
end
if announceNextTorment and #upcomingTorments == 1 then
local nextTorment = upcomingTorments[1]
self:ScheduleTimer("MessageOld", 5, "torment_of_the_titans", "cyan", "info", L.nextTorment:format(L[tormentLocaleLookup[nextTorment]]), tormentIcons[nextTorment])
end
end
end
function mod:TormentofAmanThul()
self:StopBar(L.torment_of_the_titans)
upcomingTorments[#upcomingTorments+1] = "AmanThul"
if #upcomingTorments == 1 then
self:MessageOld("torment_of_the_titans", "cyan", "info", L.nextTorment:format(L.tormentHeal), tormentIcons["AmanThul"])
end
self:Bar("torment_of_the_titans", 90, L.torment:format(L.tormentHeal), tormentIcons["AmanThul"])
updateInfoBox()
end
function mod:TormentofKhazgoroth()
self:StopBar(L.torment_of_the_titans)
upcomingTorments[#upcomingTorments+1] = "Khazgoroth"
if #upcomingTorments == 1 then
self:MessageOld("torment_of_the_titans", "cyan", "info", L.nextTorment:format(L.tormentFlames), tormentIcons["Khazgoroth"])
end
self:Bar("torment_of_the_titans", 90, L.torment:format(L.tormentFlames), tormentIcons["Khazgoroth"])
updateInfoBox()
end
function mod:TormentofGolganneth()
self:StopBar(L.torment_of_the_titans)
upcomingTorments[#upcomingTorments+1] = "Golganneth"
if #upcomingTorments == 1 then
self:MessageOld("torment_of_the_titans", "cyan", "info", L.nextTorment:format(L.tormentLightning), tormentIcons["Golganneth"])
end
self:Bar("torment_of_the_titans", 90, L.torment:format(L.tormentLightning), tormentIcons["Golganneth"])
updateInfoBox()
end
function mod:TormentofNorgannon()
self:StopBar(L.torment_of_the_titans)
upcomingTorments[#upcomingTorments+1] = "Norgannon"
if #upcomingTorments == 1 then
self:MessageOld("torment_of_the_titans", "cyan", "info", L.nextTorment:format(L.tormentArmy), tormentIcons["Norgannon"])
end
self:Bar("torment_of_the_titans", 90, L.torment:format(L.tormentArmy), tormentIcons["Norgannon"])
updateInfoBox()
end
--[[ Noura, Mother of Flame ]]--
function mod:FieryStrike(args)
local amount = args.amount or 1
if self:Me(args.destGUID) or amount > 2 then -- Swap above 2, always display stacks on self
self:StackMessage(args.spellId, args.destName, amount, "cyan", "info")
end
end
function mod:FieryStrikeSuccess(args)
self:Bar(args.spellId, 10.9)
end
function mod:WhirlingSaber(args)
self:MessageOld(args.spellId, "yellow", "alert", CL.incoming:format(args.spellName))
self:Bar(args.spellId, 35.3)
end
do
local playerList = mod:NewTargetList()
function mod:FulminatingPulse(args)
if self:Me(args.destGUID) then
self:Say(args.spellId)
self:SayCountdown(args.spellId, 10)
self:PlaySound(args.spellId, "alarm")
end
playerList[#playerList+1] = args.destName
self:TargetsMessage(args.spellId, "red", playerList, 3)
if #playerList == 1 then
self:Bar(args.spellId, 40.1)
end
end
function mod:FulminatingPulseRemoved(args)
if self:Me(args.destGUID) then
self:CancelSayCountdown(args.spellId)
end
end
end
--[[ Asara, Mother of Night ]]--
function mod:ShadowBlades(args)
self:MessageOld(args.spellId, "yellow", "alert")
self:CDBar(args.spellId, 29.2)
end
function mod:StormofDarkness(args)
self:MessageOld(args.spellId, "red", "alarm")
self:Bar(args.spellId, 58.5)
end
--[[ Diima, Mother of Gloom ]]--
function mod:Flashfreeze(args)
local amount = args.amount or 1
if self:Me(args.destGUID) then
self:StackMessage(args.spellId, args.destName, amount, "blue", "info")
end
end
function mod:FlashfreezeSuccess(args)
self:Bar(args.spellId, 10.9)
end
do
local playerList = mod:NewTargetList()
local function UpdateChilledBloodInfoBoxTimeLeft()
if chilledBloodList[1] then
local timeLeft = chilledBloodTime - GetTime()
mod:SetInfoBar("infobox", bloodBarPlacement, timeLeft/10)
mod:SetInfo("infobox", bloodBarPlacement+1, L.timeLeft:format(timeLeft))
mod:SimpleTimer(UpdateChilledBloodInfoBoxTimeLeft, 0.1)
end
end
do
local CombatLogGetCurrentEventInfo = CombatLogGetCurrentEventInfo
function mod:UpdateChilledBloodInfoBoxAbsorbs()
local _, subEvent, _, _, _, _, _, _, destName, _, _, spellId, _, _, _, _, _, _, _, _, _, absorbed = CombatLogGetCurrentEventInfo()
if subEvent == "SPELL_HEAL_ABSORBED" and spellId == 245586 then -- Chilled Blood
for i = 1, #chilledBloodList do
if chilledBloodList[i][1] == destName then
chilledBloodList[i][2] = chilledBloodList[i][2] - absorbed
updateInfoBox()
break
end
end
end
end
end
function mod:ChilledBlood(args)
playerList[#playerList+1] = args.destName
chilledBloodList[#chilledBloodList+1] = {args.destName, args.amount}
if self:Healer() then -- Always play a sound for healers
self:PlaySound(args.spellId, "alarm", nil, playerList)
elseif self:Me() then
self:PlaySound(args.spellId, "alarm")
end
self:TargetsMessage(args.spellId, "green", playerList, 3)
if #playerList == 1 then
chilledBloodTime = GetTime() + 10
chilledBloodMaxAbsorb = args.amount
self:Bar(args.spellId, 25.5)
if self:CheckOption(args.spellId, "INFOBOX") then
self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED", "UpdateChilledBloodInfoBoxAbsorbs")
self:SimpleTimer(UpdateChilledBloodInfoBoxTimeLeft, 0.1)
end
end
if self:GetOption(chilledBloodMarker) then
self:CustomIcon(false, args.destName, #playerList > 2 and 5 or #playerList) -- Icons: 1, 2, 5
end
updateInfoBox()
end
function mod:ChilledBloodRemoved(args)
for i = #chilledBloodList, 1, -1 do
if chilledBloodList[i][1] == args.destName then
tremove(chilledBloodList, i)
end
end
if not chilledBloodList[1] then
self:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
end
if self:GetOption(chilledBloodMarker) then
self:CustomIcon(false, args.destName)
end
updateInfoBox()
end
end
function mod:OrbofFrost(args)
self:MessageOld(args.spellId, "yellow", "alert")
self:Bar(args.spellId, 30.4)
end
--[[ Thu'raya, Mother of the Cosmos (Mythic) ]]--
function mod:TouchoftheCosmos(args)
if self:Interrupter() then
self:MessageOld(args.spellId, "orange", "alarm")
end
end
do
local playerList = mod:NewTargetList()
function mod:CosmicGlare(args)
if self:Me(args.destGUID) then
self:Flash(args.spellId)
self:Say(args.spellId)
self:SayCountdown(args.spellId, 4)
self:PlaySound(args.spellId, "alarm")
end
playerList[#playerList+1] = args.destName
self:TargetsMessage(args.spellId, "yellow", playerList, 2)
if #playerList == 1 then
self:CDBar(args.spellId, 15)
if self:GetOption(cosmicGlareMarker) then
self:CustomIcon(false, args.destName, 3)
end
elseif self:GetOption(cosmicGlareMarker) then
self:CustomIcon(false, args.destName, 4)
end
end
end
function mod:CosmicGlareRemoved(args)
if self:Me(args.destGUID) then
self:CancelSayCountdown(args.spellId)
end
if self:GetOption(cosmicGlareMarker) then
self:CustomIcon(false, args.destName)
end
end
--[[ Ground effects ]]--
do
local prev = 0
function mod:WhirlingSaberDamage(args)
if self:Me(args.destGUID) then
local t = GetTime()
if t-prev > 1.5 then
prev = t
self:MessageOld(245627, "blue", "alert", CL.underyou:format(args.spellName))
end
end
end
end
do
local prev = 0
function mod:StormOfDarknessDamage(args)
if self:Me(args.destGUID) then
local t = GetTime()
if t-prev > 1.5 then
prev = t
self:MessageOld(252861, "blue", "alert", CL.underyou:format(args.spellName))
end
end
end
end