--------------------------------------------------------------------------------
-- Module Declaration
--
local mod , CL = BigWigs : NewBoss ( " Remnant of Ner'zhul " , 2450 , 2444 )
if not mod then return end
mod : RegisterEnableMob ( 175729 , 177117 ) -- Remnant of Ner'zhul, Orb of Torment
mod : SetEncounterID ( 2432 )
mod : SetRespawnTime ( 50 )
--------------------------------------------------------------------------------
-- Locals
--
local nextShatterWarning = 83
local mobCollector = { }
local orbMarkerIcon = 7
local prevBombsRemoved = 0
local shatterCount = 0
local malevolenceCount = 1
local orbOfTormentCount = 1
local graspOfMaliceCount = 1
--------------------------------------------------------------------------------
-- Localization
--
local L = mod : GetLocale ( )
if L then
L.custom_on_stop_timers = " Always show ability bars "
L.custom_on_stop_timers_desc = " Remnant of Ner'zhul can delay its abilities. When this option is enabled, the bars for those abilities will stay on your screen. "
L.slow = mod : SpellName ( 31589 ) -- Slow
L.cones = " Cones " -- Grasp of Malice
L.orbs = " Orbs " -- Orb of Torment
L.orb = " Orb " -- Orb of Torment
end
--------------------------------------------------------------------------------
-- Initialization
--
local malevolenceMarker = mod : AddMarkerOption ( false , " player " , 1 , 350469 , 1 , 2 , 3 ) -- Malevolence
local malevolenceCageMarker = mod : AddMarkerOption ( false , " npc " , 8 , - 23767 , 8 ) -- Rattlecage of Agony
local orbMarker = mod : AddMarkerOption ( false , " npc " , 7 , 350676 , 7 , 6 , 5 , 4 ) -- Rattlecage of Agony
function mod : GetOptions ( )
return {
" custom_on_stop_timers " ,
350676 , -- Orb of Torment
orbMarker ,
350073 , -- Torment
350388 , -- Sorrowful Procession
{ 350469 , " SAY " , " SAY_COUNTDOWN " , " ME_ONLY_EMPHASIZE " } , -- Malevolence
malevolenceMarker ,
malevolenceCageMarker ,
350489 , -- Lingering Malevolence
{ 349890 , " SAY " , " SAY_COUNTDOWN " } , -- Suffering
355123 , -- Grasp of Malice
351066 , -- Shatter
} , {
} , {
[ 350676 ] = L.orbs , -- Orb of Torment (Orbs)
[ 350388 ] = L.slow , -- Thermal Lament (Slow)
[ 350469 ] = CL.bombs , -- Malevolence (Bombs)
[ 349890 ] = CL.beam , -- Suffering (Beam)
[ 355123 ] = L.cones , -- Grasp of Malice (Cones)
}
end
function mod : OnBossEnable ( )
self : RegisterUnitEvent ( " UNIT_SPELLCAST_SUCCEEDED " , nil , " boss1 " )
self : Log ( " SPELL_AURA_APPLIED " , " TormentApplied " , 350073 )
self : Log ( " SPELL_AURA_APPLIED " , " SorrowfulProcessionApplied " , 350388 )
self : Log ( " SPELL_CAST_START " , " MalevolenceStart " , 350469 )
self : Log ( " SPELL_CAST_SUCCESS " , " MalevolenceSuccess " , 350469 )
self : Log ( " SPELL_AURA_APPLIED " , " MalevolenceApplied " , 350469 )
self : Log ( " SPELL_AURA_REMOVED " , " MalevolenceRemoved " , 350469 )
self : Log ( " SPELL_AURA_APPLIED " , " RattlecageMalevolenceApplied " , 355151 )
self : Log ( " SPELL_AURA_REMOVED " , " RattlecageMalevolenceRemoved " , 355151 )
self : Log ( " SPELL_CAST_START " , " Suffering " , 350894 )
self : Log ( " SPELL_AURA_APPLIED " , " SufferingApplied " , 349890 )
self : Log ( " SPELL_CAST_START " , " GraspOfMalice " , 355123 )
self : Log ( " SPELL_CAST_START " , " Shatter " , 351066 , 351067 , 351073 ) -- 1st, 2nd, 3rd Armor Piece
self : Log ( " SPELL_AURA_APPLIED " , " GroundDamage " , 350489 ) -- Lingering Malevolence
self : Log ( " SPELL_PERIODIC_DAMAGE " , " GroundDamage " , 350489 )
self : Log ( " SPELL_PERIODIC_MISSED " , " GroundDamage " , 350489 )
self : RegisterMessage ( " BigWigs_BarCreated " , " BarCreated " )
end
function mod : OnEngage ( )
nextShatterWarning = 83
shatterCount = 0
mobCollector = { }
orbMarkerIcon = 7
malevolenceCount = 1
orbOfTormentCount = 1
graspOfMaliceCount = 1
self : CDBar ( 350676 , 13 , CL.count : format ( L.orbs , orbOfTormentCount ) ) -- Orb of Torment
self : CDBar ( 349890 , 20.3 , CL.beam ) -- Suffering
self : CDBar ( 350469 , 26 , CL.count : format ( CL.bombs , malevolenceCount ) ) -- Malevolence
self : CDBar ( 355123 , 39 , CL.count : format ( L.cones , graspOfMaliceCount ) ) -- Grasp of Malice
self : RegisterUnitEvent ( " UNIT_HEALTH " , nil , " boss1 " )
end
--------------------------------------------------------------------------------
-- Event Handlers
--
function mod : UNIT_HEALTH ( event , unit )
if self : GetHealth ( unit ) < nextShatterWarning then -- Shatter at 80/60/30
self : Message ( 351066 , " green " , CL.soon : format ( self : SpellName ( 351066 ) ) , false ) -- Shatter
self : PlaySound ( 351066 , " info " )
if nextShatterWarning == 83 then
nextShatterWarning = 63
elseif nextShatterWarning == 63 then
nextShatterWarning = 33
elseif nextShatterWarning == 33 then
self : UnregisterUnitEvent ( event , unit )
end
end
end
do
local abilitysToPause = {
[ 350676 ] = true , -- Orb of Torment (Orbs)
[ 350469 ] = true , -- Malevolence (Bombs)
[ 355123 ] = true , -- Grasp of Malice (Cones)
[ 349890 ] = true , -- Suffering (Beam)
}
local castPattern = CL.cast : gsub ( " %%s " , " .+ " )
local function stopAtZeroSec ( bar )
if bar.remaining < 0.15 then -- Pause at 0.0
bar : SetDuration ( 0.01 ) -- Make the bar look full
bar : Start ( )
bar : Pause ( )
bar : SetTimeVisibility ( false )
end
end
function mod : BarCreated ( _ , _ , bar , _ , key , text )
if self : GetOption ( " custom_on_stop_timers " ) and abilitysToPause [ key ] and not text : match ( castPattern ) then
bar : AddUpdateFunction ( stopAtZeroSec )
end
end
end
function mod : OrbMarking ( event , unit , guid )
if not mobCollector [ guid ] and self : MobId ( guid ) == 177117 then -- Orb of Torment
mobCollector [ guid ] = true
self : CustomIcon ( orbMarker , unit , orbMarkerIcon )
orbMarkerIcon = orbMarkerIcon - 1
end
end
function mod : UNIT_SPELLCAST_SUCCEEDED ( _ , _ , _ , spellId )
if spellId == 350676 then -- Orb of Torment
orbMarkerIcon = 7
self : RegisterTargetEvents ( " OrbMarking " )
self : StopBar ( CL.count : format ( L.orbs , orbOfTormentCount ) )
self : Message ( spellId , " yellow " , CL.count : format ( L.orbs , orbOfTormentCount ) )
orbOfTormentCount = orbOfTormentCount + 1
self : PlaySound ( spellId , " alert " )
self : CDBar ( spellId , self : Mythic ( ) and 32 or 42.5 , CL.count : format ( L.orbs , orbOfTormentCount ) )
end
end
function mod : TormentApplied ( args )
if self : Me ( args.destGUID ) then
self : PersonalMessage ( args.spellId )
self : PlaySound ( args.spellId , " alarm " )
end
end
function mod : SorrowfulProcessionApplied ( args )
if self : Me ( args.destGUID ) then
self : PersonalMessage ( args.spellId , L.orb )
self : PlaySound ( args.spellId , " info " )
end
end
do
local playerList , onMe = { } , false
function mod : MalevolenceStart ( args )
playerList = { }
onMe = false
self : Message ( args.spellId , " yellow " , CL.incoming : format ( CL.bombs ) )
end
local function onMeSound ( )
if not onMe then
mod : PlaySound ( 350469 , " alert " ) -- so alert seems to be the "move around!" sound
end
end
function mod : MalevolenceSuccess ( args )
self : StopBar ( CL.count : format ( CL.bombs , malevolenceCount ) )
malevolenceCount = malevolenceCount + 1
self : CDBar ( args.spellId , shatterCount == 3 and 42 or 32 , CL.count : format ( CL.bombs , malevolenceCount ) )
self : SimpleTimer ( onMeSound , 0.3 )
end
function mod : MalevolenceApplied ( args )
local count = # playerList + 1
playerList [ count ] = args.destName
playerList [ args.destName ] = count -- Set raid marker
if self : Me ( args.destGUID ) then
onMe = 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 , CL.bomb )
self : Say ( args.spellId , CL.bomb )
self : SayCountdown ( args.spellId , timeLeft )
self : PlaySound ( args.spellId , " warning " )
end
end
self : NewTargetsMessage ( args.spellId , " orange " , playerList , 2 , CL.bomb )
self : CustomIcon ( malevolenceMarker , args.destName , count )
end
function mod : MalevolenceRemoved ( args )
prevBombsRemoved = args.time
if self : Me ( args.destGUID ) then
self : StopBar ( CL.bomb , args.destName )
self : CancelSayCountdown ( args.spellId )
end
self : CustomIcon ( malevolenceMarker , args.destName )
end
function mod : RattlecageMalevolenceApplied ( args )
local unit = self : GetBossId ( args.destGUID )
if unit then
local _ , _ , _ , expires = self : UnitBuff ( unit , args.spellId )
local timeLeft = expires - GetTime ( )
self : CastBar ( 350469 , timeLeft , CL.bomb )
self : CustomIcon ( malevolenceCageMarker , unit , 8 )
end
end
function mod : RattlecageMalevolenceRemoved ( args )
self : StopBar ( CL.cast : format ( CL.bomb ) )
end
end
do
local function printTarget ( self , name , guid )
if self : Me ( guid ) then
self : PlaySound ( 349890 , " warning " )
self : Say ( 349890 , CL.beam )
self : SayCountdown ( 349890 , 3 , nil , 2 )
else
self : PlaySound ( 349890 , " alert " )
end
self : TargetMessage ( 349890 , " purple " , name , CL.beam )
end
function mod : Suffering ( args )
self : GetBossTarget ( printTarget , 0.1 , args.sourceGUID )
self : CDBar ( 349890 , self : Mythic ( ) and 17 or 21.5 , CL.beam )
local cd = 13
if self : BarTimeLeft ( CL.count : format ( CL.bombs , malevolenceCount ) ) < cd then
self : CDBar ( 350469 , cd , CL.count : format ( CL.bombs , malevolenceCount ) ) -- Malevolence
end
if self : BarTimeLeft ( CL.count : format ( L.cones , graspOfMaliceCount ) ) < cd then
self : CDBar ( 355123 , cd , CL.count : format ( L.cones , graspOfMaliceCount ) ) -- Grasp of Malice
end
end
end
function mod : SufferingApplied ( args )
if self : Me ( args.destGUID ) and not self : Tank ( ) then -- Non-tank player warnings
self : PersonalMessage ( args.spellId )
self : PlaySound ( args.spellId , " alarm " )
elseif self : Tank ( ) and self : Tank ( args.destName ) then -- Tank warnings
self : TargetMessage ( args.spellId , " purple " , args.destName )
local bossUnit = self : GetBossId ( args.sourceGUID )
if bossUnit and not self : Me ( args.destGUID ) and not self : Tanking ( bossUnit ) then
self : PlaySound ( args.spellId , " warning " ) -- Swap
elseif self : Me ( args.destGUID ) then
self : PlaySound ( args.spellId , " alarm " )
end
end
end
function mod : GraspOfMalice ( args )
self : StopBar ( CL.count : format ( L.cones , graspOfMaliceCount ) )
self : Message ( args.spellId , " yellow " , CL.count : format ( L.cones , graspOfMaliceCount ) )
graspOfMaliceCount = graspOfMaliceCount + 1
self : PlaySound ( args.spellId , " alert " )
self : CDBar ( args.spellId , shatterCount == 3 and 35 or ( self : Mythic ( ) and 30 or 24 ) , CL.count : format ( L.cones , graspOfMaliceCount ) )
end
function mod : Shatter ( args )
shatterCount = shatterCount + 1
self : Message ( 351066 , " cyan " , CL.count : format ( args.spellName , shatterCount ) )
self : PlaySound ( 351066 , " long " )
self : CDBar ( 350676 , 32 , CL.count : format ( L.orbs , orbOfTormentCount ) ) -- Orb of Torment
if shatterCount == 3 then
self : CDBar ( 350469 , 29 , CL.count : format ( CL.bombs , malevolenceCount ) ) -- Malevolence
self : CDBar ( 355123 , 45 , CL.count : format ( L.cones , graspOfMaliceCount ) ) -- Grasp of Malice
else
local cd = 7
if self : BarTimeLeft ( CL.count : format ( CL.bombs , malevolenceCount ) ) < cd then
self : CDBar ( 350469 , cd , CL.count : format ( CL.bombs , malevolenceCount ) ) -- Malevolence
end
if self : BarTimeLeft ( CL.count : format ( L.cones , graspOfMaliceCount ) ) < cd then
self : CDBar ( 355123 , cd , CL.count : format ( L.cones , graspOfMaliceCount ) ) -- Grasp of Malice
end
end
end
do
local prev = 0
function mod : GroundDamage ( args )
if self : Me ( args.destGUID ) then
local t = args.time
if t - prev > 2 and t - prevBombsRemoved > 0.5 then -- Don't warn every time bomb is removed
prev = t
self : PlaySound ( args.spellId , " underyou " )
self : PersonalMessage ( args.spellId , " underyou " )
end
end
end
end