-------------------------------------------------------------------------------- -- 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 threatNeutralizationCount = 1 local obliterateCount = 1 local sunderCount = 1 local normalTimers = { [350496] = {5, 11.8, 24.5, 14.6, 11.8}, -- Threat Neutralization (Bombs) [352833] = {18, 32.7}, -- Disintegration } local heroicTimers = { [350496] = {0, 12, 12, 26, 12}, -- Threat Neutralization (Bombs) [352833] = {7, 39.5}, -- Disintegration } -- 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 -- } local timers = mod:Heroic() and heroicTimers or normalTimers -------------------------------------------------------------------------------- -- 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 350735, -- Elimination Pattern 355352, -- Obliterate 350732, -- Sunder 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_AURA_REMOVED", "EnergizingLinkRemoved", 352385) self:Log("SPELL_ENERGIZE", "EnergizeCore", 356093) 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", "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 threatNeutralizationCount = 1 obliterateCount = 1 sunderCount = 1 self:CDBar(352660, 4, L.sentry) -- Form Sentry self:CDBar(352833, 15.8, CL.count:format(CL.laser, disintergrationCount)) -- Disintegration self:CDBar(350735, 25) -- Elimination Pattern self:CDBar(350496, 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 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 do local linkedCore = nil local scheduled = nil function mod:SetLinkTimer() local coreUnit = self:GetBossId(linkedCore) if coreUnit then local linkTimer = ceil(UnitPower(coreUnit) / 5) - 1 -- 5 energy/s (first tick immediately) self:CDBar(352589, linkTimer, CL.count:format(self:SpellName(352589), meltdownCount)) -- Meltdown end if scheduled then self:CancelTimer(scheduled) scheduled = nil end end 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") linkedCore = args.sourceGUID self:SetLinkTimer() self:CDBar(352660, self:Easy() and 11.7 or 19, L.sentry) -- Form Sentry self:CDBar(352833, timers[352833][disintergrationCount], CL.count:format(CL.laser, disintergrationCount)) -- Disintegration 5.5-8s self:CDBar(350735, 28.5) -- Elimination Pattern --self:CDBar(350496, 0, CL.count:format(CL.bombs, threatNeutralizationCount)) -- Threat Neutralization end end function mod:EnergizingLinkRemoved(args) if self:MobId(args.destGUID) == 175731 then -- On the boss linkedCore = nil end end function mod:EnergizeCore(args) if not scheduled then scheduled = self:ScheduleTimer("SetLinkTimer", 0.1) end 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) 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)) -- Ressetting here as he might cast the first spell before the link event is fired -- 150.423 Guardian of the First Ones begins casting Threat Neutralization -- 150.652 Guardian of the First Ones is afflicted by Energizing Link from Energy Core 2 disintergrationCount = 1 threatNeutralizationCount = 1 obliterateCount = 1 sunderCount = 1 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.count:format(args.spellName, obliterateCount)) self:PlaySound(args.spellId, "warning") obliterateCount = obliterateCount + 1 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, self:Tank() and "warning" or "alarm") sunderCount = sunderCount + 1 if sunderCount == 2 then self:Bar(args.spellId, 8, CL.count:format(args.spellName, sunderCount)) end end function mod:SunderApplied(args) if self:Tank() or self:Me(args.destGUID) then 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 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 if meltdownCount > 1 then -- Only happens once before first Link self:CDBar(args.spellId, timers[args.spellId][disintergrationCount], CL.count:format(CL.laser, disintergrationCount)) -- 25~30 end end function mod:FormSentry(args) self:Message(args.spellId, "yellow", CL.incoming:format(L.sentry)) self:PlaySound(args.spellId, "long") self:StopBar(L.sentry) 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 if meltdownCount > 1 or threatNeutralizationCount == 2 then -- Only happens 2x before first Link self:CDBar(350496, timers[350496][threatNeutralizationCount], CL.count:format(CL.bombs, threatNeutralizationCount)) end 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