local mod = DBM:NewMod(2394, "DBM-CastleNathria", nil, 1190) local L = mod:GetLocalizedStrings() mod:SetRevision("20210224082525") mod:SetCreatureID(164407) mod:SetEncounterID(2399) mod:SetUsedIcons(1) mod:SetHotfixNoticeRev(20210119000000)--2021, 01, 19 mod:SetMinSyncRevision(20201228000000) mod.respawnTime = 29 mod:RegisterCombat("combat") mod:RegisterEventsInCombat( "SPELL_CAST_START 332318", "SPELL_CAST_SUCCESS 332687", "SPELL_AURA_APPLIED 331209 331314 342420 335470 340817 341250", "SPELL_AURA_REMOVED 331209 331314 342419 342420 340817", -- "SPELL_PERIODIC_DAMAGE", -- "SPELL_PERIODIC_MISSED", "SPELL_ENERGIZE 346269", "UNIT_SPELLCAST_SUCCEEDED boss1" ) --TODO, this straght up needs an updateAllTimers function like archimonde to be perfect, especially around hateful gaze/impact stun --The timers COULD be perfected, I'm just not sure it's worth the effort to since the variations are all predictable (based around spell queuing or delayed by impact stun) --I'll return to perfecting timers if things don't change on live and can analylize dozens more logs to verify patterns --[[ (ability.id = 332318) and type = "begincast" or ability.id = 332687 and type = "cast" or (ability.id = 335470 or ability.id = 335470 or ability.id = 331209) and type = "applydebuff" or ability.id = 346269 or ability.id = 331314 or (ability.id = 342420 or ability.id = 340817) and type = "applydebuff" --]] local warnHatefulGaze = mod:NewTargetCountAnnounce(331209, 4, nil, nil, nil, nil, nil, nil, true) local warnStunnedImpact = mod:NewTargetNoFilterAnnounce(331314, 1) --local warnChainLink = mod:NewTargetAnnounce(342419, 3)--Targetting debuff local warnChainSlam = mod:NewTargetCountAnnounce(335470, 3, nil, nil, nil, nil, nil, nil, true) local warnGruesomeRage = mod:NewTargetNoFilterAnnounce(341250, 4) local specWarnHatefulGaze = mod:NewSpecialWarningMoveTo(331209, nil, nil, nil, 3, 2) local specWarnHeedlessCharge = mod:NewSpecialWarningSoon(331212, nil, nil, nil, 2, 2) local yellHatefulGaze = mod:NewShortYell(331209) local yellHatefulGazeFades = mod:NewShortFadesYell(331209) local specWarnChainLink = mod:NewSpecialWarningMoveTo(335300, nil, nil, nil, 1, 2) local yellChainLink = mod:NewIconRepeatYell(335300, DBM_CORE_L.AUTO_YELL_ANNOUNCE_TEXT.shortyell, false, 2) local specWarnChainSlam = mod:NewSpecialWarningYou(335470, nil, nil, nil, 1, 2) local specWarnChainSlamPartner = mod:NewSpecialWarningTarget(335470, nil, nil, nil, 1, 2) local yellChainSlam = mod:NewShortYell(335470, nil, nil, nil, "YELL") local yellChainSlamFades = mod:NewShortFadesYell(335470, nil, nil, nil, "YELL") local specWarnDestructiveStomp = mod:NewSpecialWarningRun(332318, "Melee", 247733, nil, 4, 2) local specWarnColossalRoar = mod:NewSpecialWarningSpell(332687, nil, 226056, nil, 2, 2) local specWarnFallingRubble = mod:NewSpecialWarningDodge(332572, nil, nil, nil, 2, 2) local specWarnSiesmicShift = mod:NewSpecialWarningMoveAway(340817, nil, nil, nil, 2, 2, 4) --local specWarnGTFO = mod:NewSpecialWarningGTFO(270290, nil, nil, nil, 1, 8) --All timers outside of stun and gaze will use keep arg so timers remain visible if they come off CD during gaze stun local timerHatefulGazeCD = mod:NewCDCountTimer(68.9, 331209, nil, nil, nil, 3, nil, DBM_CORE_L.IMPORTANT_ICON, nil, 1, 4) local timerStunnedImpact = mod:NewBuffActiveTimer(12, 331314, nil, nil, nil, 5, nil, DBM_CORE_L.DAMAGE_ICON) local timerChainLinkCD = mod:NewCDCountTimer(68.9, 335300, nil, nil, nil, 3, nil, nil, true) local timerChainSlamCD = mod:NewCDCountTimer(68.9, 335354, nil, nil, nil, 3, nil, DBM_CORE_L.HEROIC_ICON, true) local timerDestructiveStompCD = mod:NewCDCountTimer(44.3, 332318, 247733, nil, nil, 3, nil, nil, true) local timerFallingRubbleCD = mod:NewCDCountTimer(68.9, 332572, nil, nil, nil, 3, nil, nil, true) local timerColossalRoarCD = mod:NewCDCountTimer(31.9, 332687, 226056, nil, nil, 2, nil, nil, true) local timerSiesmicShiftCD = mod:NewCDCountTimer(34, 340817, nil, nil, nil, 3, nil, DBM_CORE_L.MYTHIC_ICON, true)--Mythic --local berserkTimer = mod:NewBerserkTimer(600) mod:AddRangeFrameOption(5, 340817) mod:AddSetIconOption("SetIconGaze", 331209, true, false, {1}) mod.vb.gazeCount = 0 mod.vb.stompCount = 0 mod.vb.roarCount = 0 mod.vb.linkCount = 0 mod.vb.chainSlamCount = 0 mod.vb.rubbleCount = 0 mod.vb.shiftCount = 0 local ChainLinkTargets = {} local playerName = UnitName("player") local playerPartner = nil local SiesmicTimers = {18.1, 25.4, 29.3, 12.3, 25.5, 30.1, 12.6, 25.5, 30.1, 12.3, 25.4, 30.1, 13.5, 25.5, 28.8} -- 30.1 13.5 31.3 local function ChainLinkYellRepeater(self, text, runTimes) yellChainLink:Yell(text) runTimes = runTimes + 1 if runTimes < 3 then self:Schedule(2, ChainLinkYellRepeater, self, text, runTimes) end end function mod:OnCombatStart(delay) self.vb.gazeCount = 0 self.vb.stompCount = 0 self.vb.roarCount = 0 self.vb.linkCount = 0 self.vb.chainSlamCount = 0 self.vb.rubbleCount = 0 playerPartner = nil table.wipe(ChainLinkTargets) --Roar cast instantly on pull, no timer needed if self:IsLFR() then timerFallingRubbleCD:Start(12.1-delay, 1)--Unknown, not in combat log timerDestructiveStompCD:Start(18.5-delay, 1) timerHatefulGazeCD:Start(51.3-delay, 1) else timerChainLinkCD:Start(4.7-delay, 1) timerFallingRubbleCD:Start(12.5-delay, 1) timerDestructiveStompCD:Start(18.2-delay, 1) timerHatefulGazeCD:Start(50.1-delay, 1) if self:IsHard() then timerChainSlamCD:Start(28.3-delay, 1) if self:IsMythic() then self.vb.shiftCount = 0 timerSiesmicShiftCD:Start(18.1, 1) end end end -- berserkTimer:Start(-delay) end function mod:OnCombatEnd() if self.Options.RangeFrame then DBM.RangeCheck:Hide() end end function mod:SPELL_CAST_START(args) local spellId = args.spellId if spellId == 332318 then self.vb.stompCount = self.vb.stompCount + 1 specWarnDestructiveStomp:Show() specWarnDestructiveStomp:Play("justrun") --Heroic --pull:18.2, 25.9, 44.6, 25.5, 44.9, 25.5, 45.0, 25.3, 44.0", -- [2] --Mythic --pull:18.6, 25.5, 43.4, 25.5, 43.8, 25.5, 43.7", -- [2] if self.vb.stompCount % 2 == 0 then timerDestructiveStompCD:Start(43, self.vb.stompCount+1) else timerDestructiveStompCD:Start(25, self.vb.stompCount+1)--LFR is only about .5 seconds slower, so not worth nitpick end end end function mod:SPELL_CAST_SUCCESS(args) local spellId = args.spellId if spellId == 332687 then self.vb.roarCount = self.vb.roarCount + 1 specWarnColossalRoar:Show() specWarnColossalRoar:Play("aesoon") timerColossalRoarCD:Start(self:IsLFR() and 33.2 or 31.9, self.vb.roarCount+1) end end function mod:SPELL_AURA_APPLIED(args) local spellId = args.spellId if spellId == 331209 then self.vb.gazeCount = self.vb.gazeCount + 1 timerHatefulGazeCD:Start(self:IsLFR() and 70.3 or 67.3, self.vb.gazeCount+1) if self.Options.SetIconGaze then self:SetIcon(args.destName, 1) end if args:IsPlayer() then specWarnHatefulGaze:Show(DBM_CORE_L.PILLAR) specWarnHatefulGaze:Play("targetyou") yellHatefulGaze:Yell() yellHatefulGazeFades:Countdown(spellId) else specWarnHeedlessCharge:Show() specWarnHeedlessCharge:Play("farfromline") warnHatefulGaze:Show(self.vb.gazeCount, args.destName) end elseif spellId == 331314 then warnStunnedImpact:Show(args.destName) timerStunnedImpact:Start() elseif spellId == 342420 then--spellId == 342419 or --Combat log order is all 342419 first, then all 342420 --Update, both spell Ids now have source and des names, so can just ignore one spell Id entirely and apply source/dest to check for pairs ChainLinkTargets[#ChainLinkTargets + 1] = args.sourceName -- warnChainLink:CombinedShow(0.3, args.destName) local icon = #ChainLinkTargets--Generate icon on the evens, because then we can divide it by 2 to assign raid icon to that pair local playerIsInPair = false if args.sourceName == playerName then specWarnChainLink:Show(args.destName) specWarnChainLink:Play("gather") playerIsInPair = true playerPartner = args.destName elseif args.destName == playerName then specWarnChainLink:Show(args.sourceName) specWarnChainLink:Play("gather") playerIsInPair = true playerPartner = args.sourceName end if playerIsInPair then --need to account for up to 30 people (15 pairs) if icon == 9 then icon = "(°,,°)" elseif icon == 10 then icon = "(•_•)" elseif icon == 11 then icon = "(ಥ﹏ಥ)" elseif icon == 12 then icon = "(ツ)" elseif icon == 13 then icon = "ʕ•ᴥ•ʔ" elseif icon == 14 then icon = "ಠ_ಠ" elseif icon == 15 then icon = "(͡°͜°)" end self:Unschedule(ChainLinkYellRepeater) if type(icon) == "number" then icon = DBM_CORE_L.AUTO_YELL_CUSTOM_POSITION:format(icon, "") end self:Schedule(2, ChainLinkYellRepeater, self, icon, 0) yellChainLink:Yell(icon) end elseif spellId == 335470 then if args:IsPlayer() then specWarnChainSlam:Show() specWarnChainSlam:Play("targetyou") yellChainSlam:Yell() yellChainSlamFades:Countdown(4)--Can't auto pull from spellId elseif playerPartner and playerPartner == args.destName then specWarnChainSlamPartner:Show(args.destName) specWarnChainSlamPartner:Play("gathershare") else warnChainSlam:Show(self.vb.chainSlamCount, args.destName) end --Chain slam always extends Colossal Roar by a very precise amount if timerColossalRoarCD:GetRemaining(self.vb.roarCount+1) < 7.25 then local elapsed, total = timerColossalRoarCD:GetTime(self.vb.roarCount+1) local extend = 7.25 - (total-elapsed) DBM:Debug("timerColossalRoarCD extended by: "..extend, 2) timerColossalRoarCD:Stop() timerColossalRoarCD:Update(elapsed, total+extend, self.vb.roarCount+1) end elseif spellId == 341250 then warnGruesomeRage:Show(args.destName) elseif spellId == 340817 then if self:AntiSpam(8, 9) then self.vb.shiftCount = self.vb.shiftCount + 1 local timer = SiesmicTimers[self.vb.shiftCount+1] if timer then timerSiesmicShiftCD:Start(timer, self.vb.shiftCount+1) local timerAfter = SiesmicTimers[self.vb.shiftCount+2] if not timerAfter then--Disable timer keeping if we're out of timer data beind THIS timer timerSiesmicShiftCD:SetSTKeep(false, self.vb.shiftCount+1) end end end if args:IsPlayer() then specWarnSiesmicShift:Show() specWarnSiesmicShift:Play("range5") if self.Options.RangeFrame then DBM.RangeCheck:Show(5) end end end end function mod:SPELL_AURA_REMOVED(args) local spellId = args.spellId if spellId == 331209 then if args:IsPlayer() then yellHatefulGazeFades:Cancel() end if self.Options.SetIconGaze then self:SetIcon(args.destName, 0) end elseif spellId == 331314 then timerStunnedImpact:Stop(args.destName) elseif spellId == 342419 or spellId == 342420 then--Both spellIds checked on purpose here for personal removal if args:IsPlayer() then self:Unschedule(ChainLinkYellRepeater) playerPartner = nil end elseif spellId == 340817 then if args:IsPlayer() then if self.Options.RangeFrame then DBM.RangeCheck:Hide() end end end end --[[ function mod:SPELL_PERIODIC_DAMAGE(_, _, _, _, destGUID, _, _, _, spellId, spellName) if spellId == 270290 and destGUID == UnitGUID("player") and self:AntiSpam(2, 2) then specWarnGTFO:Show(spellName) specWarnGTFO:Play("watchfeet") end end mod.SPELL_PERIODIC_MISSED = mod.SPELL_PERIODIC_DAMAGE --]] function mod:SPELL_ENERGIZE(_, _, _, _, _, _, _, _, spellId, _, _, amount) if spellId == 346269 then timerHatefulGazeCD:Stop()--Boss immediately full energy so terminate timer/countdown immediately --TODO, also adjust other timers instead of just using KeepTime? --Might be annoying work to do for something that shouldn't happen in a properly executed fight end end function mod:UNIT_SPELLCAST_SUCCEEDED(uId, _, spellId) if spellId == 335300 then--Chain link table.wipe(ChainLinkTargets) self.vb.linkCount = self.vb.linkCount + 1 timerChainLinkCD:Start(67.7, self.vb.linkCount+1)--67.7-69.1 elseif spellId == 341193 then--or spellId == 341103 self.vb.rubbleCount = self.vb.rubbleCount + 1 specWarnFallingRubble:Show(self.vb.rubbleCount) specWarnFallingRubble:Play("watchstep") timerFallingRubbleCD:Start(67.8, self.vb.rubbleCount+1) elseif spellId == 335354 then--Chain Slam self.vb.chainSlamCount = self.vb.chainSlamCount + 1 timerChainSlamCD:Start(68.9, self.vb.chainSlamCount+1) end end