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.
333 lines
11 KiB
333 lines
11 KiB
--------------------------------------------------------------------------------
|
|
-- Module Declaration
|
|
--
|
|
|
|
local mod, CL = BigWigs:NewBoss("Guardian of the First Ones", 2450, 2446)
|
|
if not mod then return end
|
|
mod:RegisterEnableMob(175731) -- Guardian of the First Ones
|
|
mod:SetEncounterID(2436)
|
|
mod:SetRespawnTime(30)
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Locals
|
|
--
|
|
|
|
local shieldOnYou = false
|
|
local tankList = {}
|
|
local meltdownCount = 1
|
|
local disintergrationCount = 1
|
|
local purgeCount = 1
|
|
local sentryCount = 1
|
|
local threatNeutralizationCount = 1
|
|
local mythicTimers = {
|
|
[350496] = {8.2, 12.3, 18.3, 23.2, 18.4, 23.3, 23.1, 18.4, 18.2, 23.2, 24.4, 17.1, 17.1, 24.4, 23.2, 17.1, 17.3, 23.1}, -- Threat Neutralization
|
|
[352833] = {15.7, 56.2, 33.4, 49.8, 33.1, 44.9, 31.8, 31.7, 25.9, 31.6}, -- Disintegration
|
|
}
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Localization
|
|
--
|
|
|
|
local L = mod:GetLocale()
|
|
if L then
|
|
L.custom_on_stop_timers = "Always show ability bars"
|
|
L.custom_on_stop_timers_desc = "The Guardian can delay its abilities. When this option is enabled, the bars for those abilities will stay on your screen."
|
|
|
|
L.sentry = mod:SpellName(298200) -- Form Sentry (Sentry)
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Initialization
|
|
--
|
|
|
|
local threatNeutralizationMarker = mod:AddMarkerOption(false, "player", 1, 350496, 1, 2, 3) -- Threat Neutralization
|
|
function mod:GetOptions()
|
|
return {
|
|
"custom_on_stop_timers",
|
|
-- Energy Cores
|
|
352385, -- Energizing Link
|
|
350455, -- Unstable Energy
|
|
352394, -- Radiant Energy
|
|
{352589, "EMPHASIZE"}, -- Meltdown
|
|
-- The Guardian
|
|
352538, -- Purging Protocol
|
|
355352, -- Obliterate
|
|
{350732, "TANK"}, -- Sunder
|
|
{350734, "TANK"}, -- Smash
|
|
352833, -- Disintegration
|
|
352660, -- Form Sentry
|
|
347359, -- Suppression Field
|
|
{350496, "SAY", "SAY_COUNTDOWN", "ME_ONLY_EMPHASIZE"}, -- Threat Neutralization
|
|
threatNeutralizationMarker,
|
|
},{
|
|
[352385] = self:SpellName(-23254), -- Energy Cores
|
|
[352538] = self.displayName, -- The Guardian
|
|
},{
|
|
[352385] = CL.link, -- Energizing Link (Link)
|
|
[350455] = CL.no:format(CL.shield), -- Unstable Energy (No Shield)
|
|
[352394] = CL.shield, -- Radiant Energy (Shield)
|
|
[352833] = CL.laser, -- Disintegration (Laser)
|
|
[352660] = L.sentry, -- Form Sentry (Sentry)
|
|
[350496] = CL.bombs, -- Threat Neutralization (Bombs)
|
|
}
|
|
end
|
|
|
|
function mod:OnBossEnable()
|
|
-- Energy Cores
|
|
self:Log("SPELL_AURA_APPLIED", "EnergizingLinkApplied", 352385)
|
|
self:Log("SPELL_PERIODIC_DAMAGE", "UnstableEnergyDamage", 350455)
|
|
self:Log("SPELL_PERIODIC_MISSED", "UnstableEnergyDamage", 350455)
|
|
self:Log("SPELL_AURA_APPLIED", "RadiantEnergyApplied", 352394)
|
|
self:Log("SPELL_AURA_REMOVED", "RadiantEnergyRemoved", 352394)
|
|
self:Log("SPELL_CAST_START", "Meltdown", 352589)
|
|
|
|
-- The Guardian
|
|
self:Log("SPELL_CAST_START", "PurgingProtocol", 352538)
|
|
self:Log("SPELL_CAST_SUCCESS", "PurgingProtocolSuccess", 352538)
|
|
|
|
self:Log("SPELL_CAST_START", "Obliterate", 355352)
|
|
self:Log("SPELL_CAST_START", "Sunder", 350732)
|
|
self:Log("SPELL_AURA_APPLIED", "SunderApplied", 350732)
|
|
self:Log("SPELL_CAST_START", "Smash", 350734)
|
|
self:Log("SPELL_CAST_START", "Disintegration", 352833)
|
|
self:Log("SPELL_CAST_START", "FormSentry", 352660)
|
|
self:Log("SPELL_AURA_APPLIED", "SuppressionField", 347359)
|
|
self:Log("SPELL_PERIODIC_DAMAGE", "SuppressionField", 347359)
|
|
self:Log("SPELL_PERIODIC_MISSED", "SuppressionField", 347359)
|
|
self:Log("SPELL_CAST_START", "ThreatNeutralization", 356090)
|
|
self:Log("SPELL_AURA_APPLIED", "ThreatNeutralizationApplied", 350496)
|
|
self:Log("SPELL_AURA_REMOVED", "ThreatNeutralizationRemoved", 350496)
|
|
|
|
self:RegisterMessage("BigWigs_BarCreated", "BarCreated")
|
|
self:RegisterEvent("GROUP_ROSTER_UPDATE")
|
|
self:GROUP_ROSTER_UPDATE()
|
|
end
|
|
|
|
function mod:OnEngage()
|
|
shieldOnYou = false
|
|
meltdownCount = 1
|
|
disintergrationCount = 1
|
|
purgeCount = 1
|
|
sentryCount = 1
|
|
threatNeutralizationCount = 1
|
|
|
|
self:CDBar(352660, 5.6, CL.count:format(L.sentry, sentryCount)) -- Form Sentry
|
|
self:CDBar(352833, self:Mythic() and mythicTimers[352833][disintergrationCount] or 15.8, CL.count:format(CL.laser, disintergrationCount)) -- Disintegration
|
|
self:CDBar(350732, 25) -- Sunder
|
|
self:CDBar(350496, self:Mythic() and mythicTimers[350496][threatNeutralizationCount] or 38, CL.count:format(CL.bombs, threatNeutralizationCount)) -- Threat Neutralization
|
|
local purgeTimer = UnitPower("boss1")
|
|
self:Bar(352538, purgeTimer, CL.count:format(self:SpellName(352538), purgeCount)) -- Purging Protocol
|
|
-- XXX In heroic the first cast is (always?) delayed by 3s due to a laser cast
|
|
end
|
|
|
|
--------------------------------------------------------------------------------
|
|
-- Event Handlers
|
|
--
|
|
|
|
do
|
|
local abilitysToPause = {
|
|
[350496] = true, -- Threat Neutralization
|
|
[352538] = true, -- Purging Protocol
|
|
[352660] = true, -- Form Sentry
|
|
[352833] = true, -- Disintegration
|
|
}
|
|
|
|
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
|
|
|
|
-- Energy Cores
|
|
|
|
function mod:EnergizingLinkApplied(args)
|
|
if self:MobId(args.destGUID) == 175731 then -- On the boss
|
|
self:StopBar(CL.count:format(self:SpellName(352538), purgeCount)) -- Purging Protocol
|
|
self:Message(args.spellId, "cyan", CL.onboss:format(CL.link))
|
|
self:PlaySound(args.spellId, "info")
|
|
local coreUnit = self:GetBossId(args.sourceGUID)
|
|
local linkTimer = ceil(UnitPower(coreUnit) / 4) - 1 -- 4 energy/s (first tick immediately)
|
|
self:Bar(352589, linkTimer, CL.count:format(self:SpellName(352589), meltdownCount)) -- Meltdown
|
|
end
|
|
end
|
|
|
|
do
|
|
local prev = 0
|
|
function mod:UnstableEnergyDamage(args)
|
|
if not shieldOnYou and self:Me(args.destGUID) then -- warn when taking damage without shield
|
|
local t = args.time
|
|
if t-prev > 2 then
|
|
prev = t
|
|
self:PlaySound(args.spellId, "warning")
|
|
self:PersonalMessage(args.spellId, CL.no:format(CL.shield))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function mod:RadiantEnergyApplied(args)
|
|
if self:Me(args.destGUID) then
|
|
shieldOnYou = true
|
|
self:Message(args.spellId, "green", CL.you:format(CL.shield))
|
|
self:PlaySound(args.spellId, "info")
|
|
end
|
|
end
|
|
|
|
function mod:RadiantEnergyRemoved(args)
|
|
if self:Me(args.destGUID) then
|
|
shieldOnYou = false
|
|
self:Message(args.spellId, "red", CL.removed:format(CL.shield))
|
|
self:PlaySound(args.spellId, "info")
|
|
end
|
|
end
|
|
|
|
function mod:Meltdown(args)
|
|
self:Message(args.spellId, "orange", CL.count:format(args.spellName, meltdownCount))
|
|
self:PlaySound(args.spellId, "alert")
|
|
self:CastBar(args.spellId, 6, CL.count:format(args.spellName, meltdownCount))
|
|
meltdownCount = meltdownCount + 1
|
|
|
|
purgeCount = 1
|
|
local bossUnit = self:GetBossId(175731)
|
|
if bossUnit then
|
|
local purgeTimer = UnitPower(bossUnit) -- 1 energy/s
|
|
self:CDBar(352538, purgeTimer, CL.count:format(self:SpellName(352538), purgeCount)) -- Purging Protocol
|
|
end
|
|
end
|
|
|
|
-- The Guardian
|
|
|
|
function mod:PurgingProtocol(args) -- XXX rename?
|
|
self:Message(args.spellId, "red", CL.count:format(args.spellName, purgeCount))
|
|
self:PlaySound(args.spellId, "long")
|
|
self:CastBar(args.spellId, 5, CL.count:format(args.spellName, purgeCount))
|
|
end
|
|
|
|
function mod:PurgingProtocolSuccess(args) -- He can cancel his own cast with the tank combo, increment counter here instead.
|
|
purgeCount = purgeCount + 1
|
|
end
|
|
|
|
function mod:GROUP_ROSTER_UPDATE() -- Compensate for quitters (LFR)
|
|
tankList = {}
|
|
for unit in self:IterateGroup() do
|
|
if self:Tank(unit) then
|
|
tankList[#tankList+1] = unit
|
|
end
|
|
end
|
|
end
|
|
|
|
function mod:Obliterate(args)
|
|
self:Message(args.spellId, "red", CL.casting:format(args.spellName)) -- Purple?
|
|
self:PlaySound(args.spellId, "warning")
|
|
end
|
|
|
|
function mod:Sunder(args)
|
|
local bossUnit = self:GetBossId(args.sourceGUID)
|
|
for i = 1, #tankList do
|
|
local unit = tankList[i]
|
|
if bossUnit and self:Tanking(bossUnit, unit) then
|
|
self:TargetMessage(args.spellId, "purple", self:UnitName(unit), CL.casting:format(args.spellName))
|
|
break
|
|
elseif i == #tankList then
|
|
self:Message(args.spellId, "purple", CL.casting:format(args.spellName))
|
|
end
|
|
end
|
|
self:PlaySound(args.spellId, "warning")
|
|
--self:Bar(350734, 3) -- Smash
|
|
end
|
|
|
|
function mod:SunderApplied(args)
|
|
self:TargetMessage(args.spellId, "purple", args.destName)
|
|
local bossUnit = self:GetBossId(args.sourceGUID)
|
|
if bossUnit and self:Tank() and not self:Me(args.destGUID) and not self:Tanking(bossUnit) then
|
|
self:PlaySound(args.spellId, "warning") -- Not taunted? Play again.
|
|
end
|
|
end
|
|
|
|
function mod:Smash(args)
|
|
local bossUnit = self:GetBossId(args.sourceGUID)
|
|
for i = 1, #tankList do
|
|
local unit = tankList[i]
|
|
if bossUnit and self:Tanking(bossUnit, unit) then
|
|
self:TargetMessage(args.spellId, "purple", self:UnitName(unit), CL.casting:format(args.spellName))
|
|
break
|
|
elseif i == #tankList then
|
|
self:Message(args.spellId, "purple", CL.casting:format(args.spellName))
|
|
end
|
|
end
|
|
self:PlaySound(args.spellId, "alarm")
|
|
end
|
|
|
|
function mod:Disintegration(args)
|
|
self:Message(args.spellId, "red", CL.count:format(CL.laser, disintergrationCount))
|
|
self:PlaySound(args.spellId, "alert")
|
|
self:StopBar(CL.count:format(CL.laser, disintergrationCount))
|
|
disintergrationCount = disintergrationCount + 1
|
|
self:CDBar(args.spellId, self:Mythic() and mythicTimers[args.spellId][disintergrationCount] or 25.4, CL.count:format(CL.laser, disintergrationCount)) -- 25~30
|
|
end
|
|
|
|
function mod:FormSentry(args)
|
|
self:Message(args.spellId, "yellow", CL.incoming:format(CL.count:format(L.sentry, sentryCount)))
|
|
self:PlaySound(args.spellId, "long")
|
|
self:StopBar(CL.count:format(L.sentry, sentryCount))
|
|
sentryCount = sentryCount + 1
|
|
self:CDBar(args.spellId, 25.6, CL.count:format(L.sentry, sentryCount)) -- 25~30
|
|
end
|
|
|
|
do
|
|
local prev = 0
|
|
function mod:SuppressionField(args)
|
|
if self:Me(args.destGUID) then
|
|
local t = args.time
|
|
if t-prev > 2 then
|
|
prev = t
|
|
self:PlaySound(args.spellId, "underyou")
|
|
self:PersonalMessage(args.spellId, "underyou")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
do
|
|
local playerList = {}
|
|
function mod:ThreatNeutralization()
|
|
playerList = {}
|
|
self:Message(350496, "orange", CL.casting:format(CL.count:format(CL.bombs, threatNeutralizationCount)))
|
|
self:StopBar(CL.count:format(CL.bombs, threatNeutralizationCount))
|
|
threatNeutralizationCount = threatNeutralizationCount + 1
|
|
self:CDBar(350496, self:Mythic() and mythicTimers[350496][threatNeutralizationCount] or 32, CL.count:format(CL.bombs, threatNeutralizationCount)) -- 32~39
|
|
end
|
|
|
|
function mod:ThreatNeutralizationApplied(args)
|
|
local count = #playerList+1
|
|
playerList[count] = args.destName
|
|
playerList[args.destName] = count -- Set raid marker
|
|
if self:Me(args.destGUID) then
|
|
self:Say(args.spellId, CL.bomb)
|
|
self:SayCountdown(args.spellId, 4)
|
|
self:PlaySound(args.spellId, "warning")
|
|
end
|
|
self:NewTargetsMessage(args.spellId, "yellow", playerList, nil, CL.count:format(CL.bomb, threatNeutralizationCount-1))
|
|
self:CustomIcon(threatNeutralizationMarker, args.destName, count)
|
|
end
|
|
end
|
|
|
|
function mod:ThreatNeutralizationRemoved(args)
|
|
if self:Me(args.destGUID) then
|
|
self:CancelSayCountdown(args.spellId)
|
|
end
|
|
|
|
self:CustomIcon(threatNeutralizationMarker, args.destName)
|
|
end
|
|
|