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.

334 lines
11 KiB

5 years ago
--------------------------------------------------------------------------------
-- 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