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.

384 lines
15 KiB

local mod = DBM:NewMod(2429, "DBM-CastleNathria", nil, 1190)
local L = mod:GetLocalizedStrings()
mod:SetRevision("20220908201246")
mod:SetCreatureID(165066)
mod:SetEncounterID(2418)
mod:SetUsedIcons(1, 2, 3)
mod:SetHotfixNoticeRev(20210126000000)--2021, 01, 03
mod:SetMinSyncRevision(20210126000000)
--mod.respawnTime = 29
mod:RegisterCombat("combat")
mod:RegisterEventsInCombat(
"SPELL_CAST_START 335114 334404 334971 334797 334757 334852",
"SPELL_CAST_SUCCESS 334945 334797",
"SPELL_AURA_APPLIED 334971 334860 334945 334852 335111 335112 335113 334504",
"SPELL_AURA_APPLIED_DOSE 334971 334860",
"SPELL_AURA_REMOVED 334945 334860 334852 335111 335112 335113",
"SPELL_AURA_REMOVED_DOSE 334860",
"UNIT_DIED"
)
--TODO, handling of mythic Sinseeker buffs by detecting which hound buffs it currently has (by using phase probably)
--TODO, energy tracker on nameplates for https://shadowlands.wowhead.com/spell=335303/unyielding
--TODO, continue watching timers, see if lfr and heroic follow same behavior as normal, or mythic.
--[[
(ability.id = 335114 or ability.id = 334404 or ability.id = 334971 or ability.id = 334797 or ability.id = 334757 or ability.id = 334852) and type = "begincast"
or ability.id = 334945 and type = "cast"
or (target.id = 165067 or target.id = 169457 or target.id = 169458) and type = "death"
--]]
--Huntsman Altimor
mod:AddTimerLine(DBM:EJ_GetSectionInfo(22309))
local warnPhase = mod:NewPhaseChangeAnnounce(2, nil, nil, nil, nil, nil, 2)
local warnSinseeker = mod:NewTargetNoFilterAnnounce(335114, 4)
local warnSpreadshot = mod:NewSpellAnnounce(334404, 3)
local specWarnSinseeker = mod:NewSpecialWarningYouPos(335114, nil, nil, nil, 3, 2)
local yellSinseeker = mod:NewShortPosYell(335114)
local yellSinseekerFades = mod:NewIconFadesYell(335114)
local timerSinseekerCD = mod:NewCDCountTimer(49, 335114, nil, nil, nil, 3)
local timerSpreadshotCD = mod:NewCDTimer(11.8, 334404, nil, nil, nil, 2, nil, DBM_COMMON_L.HEALER_ICON)
--local berserkTimer = mod:NewBerserkTimer(600)
mod:AddRangeFrameOption("5/6/10")
mod:AddSetIconOption("SetIconOnSinSeeker", 335114, true, false, {1, 2, 3})--335111 335112 335113
--Hunting Gargon
----Margore
mod:AddTimerLine(DBM:EJ_GetSectionInfo(22312))
local warnJaggedClaws = mod:NewStackAnnounce(334971, 2, nil, "Tank|Healer")
local warnViciousLunge = mod:NewTargetNoFilterAnnounce(334945, 3, nil, nil, 262783)
local specWarnJaggedClaws = mod:NewSpecialWarningStack(334971, nil, 2, nil, nil, 1, 6)
local specWarnJaggedClawsTaunt = mod:NewSpecialWarningTaunt(334971, nil, nil, nil, 1, 2)
local specWarnViciousLunge = mod:NewSpecialWarningYou(334945, nil, 262783, nil, 3, 2)
local yellViciousLunge = mod:NewYell(334945, 262783, nil, nil, "YELL")
local yellViciousLungeFades = mod:NewFadesYell(334945, 262783, nil, nil, "YELL")
local timerJaggedClawsCD = mod:NewCDTimer(10.9, 334971, nil, "Tank", nil, 5, nil, DBM_COMMON_L.TANK_ICON)--22.1, 23.4, 11.0
local timerViciousLungeCD = mod:NewCDTimer(25.5, 334945, 262783, nil, nil, 3)--Shortname Lunge
----Bargast
mod:AddTimerLine(DBM:EJ_GetSectionInfo(22311))
local specWarnRipSoul = mod:NewSpecialWarningDefensive(334797, nil, nil, nil, 1, 2)
local specWarnRipSoulHealer = mod:NewSpecialWarningTarget(334797, "Healer", nil, nil, 1, 2)
local specWarnShadesofBargast = mod:NewSpecialWarningSwitch(334757, false, nil, 2, 1, 2)
local timerRipSoulCD = mod:NewCDTimer(30, 334797, nil, "Tank|Healer", nil, 5, nil, DBM_COMMON_L.TANK_ICON..DBM_COMMON_L.HEALER_ICON)
local timerShadesofBargastCD = mod:NewCDTimer(60.1, 334757, nil, nil, nil, 1, nil, DBM_COMMON_L.DAMAGE_ICON)--60-63 at least
mod:AddSetIconOption("SetIconOnShades", 334757, true, true, {4, 5})
----Hecutis
mod:AddTimerLine(DBM:EJ_GetSectionInfo(22310))
local warnCrushingStone = mod:NewStackAnnounce(334860, 2, nil, "Tank|Healer")
local warnPetrifyingHowl = mod:NewTargetAnnounce(334852, 3, nil, nil, 135241)--Shortname "Howl"
local specWarnPetrifyingHowl = mod:NewSpecialWarningMoveAway(334852, nil, nil, nil, 1, 2)
local yellPetrifyingHowl = mod:NewYell(334852, 135241)--Shortname "Howl"
local yellPetrifyingHowlFades = mod:NewFadesYell(334852, 135241)--Shortname "Howl"
local timerPetrifyingHowlCD = mod:NewCDTimer(20.6, 334852, 135241, nil, nil, 3)--20-26 Shortname "Howl"
mod.vb.sinSeekerCount = 0
mod.vb.activeSeekers = 0
--NYI, more data needed to substanciate
local spreadShotTimers = {
[1] = {6.5, 30.3, 18.2},
[2] = {11.7, 32.7, 12.2, 12.1},
[3] = {12.4, 23.1, 43.6},
}
local playerSinSeeker = false
local transitionwindow = 0--0 false, 1 true, 2 sinseeker activated while it was 1
local updateRangeFrame
do
local function debuffFilter(uId)
if DBM:UnitDebuff(uId, 335111, 335112, 335113) then
return true
end
end
updateRangeFrame = function(self, force)
if not self.Options.RangeFrame then return end
if DBM:UnitDebuff("player", 334852) then--Petrifying Howl
DBM.RangeCheck:Show(10)
elseif DBM:UnitDebuff("player", 334945) then--Vicious Lunge
DBM.RangeCheck:Show(6)
elseif force or (self:IsMythic() and self.vb.phase == 3 and self.vb.activeSeekers > 0) then--Mythic Sinseeker spread mechanic
if playerSinSeeker then
DBM.RangeCheck:Show(5)--Show everyone
else
DBM.RangeCheck:Show(5, debuffFilter)--Only show players affected with sinseeker
end
else
DBM.RangeCheck:Hide()
end
end
end
local function updateAllTimers(self)
DBM:Debug("updateAllTimers running", 3)
--All phase abilities
if timerSpreadshotCD:GetRemaining() < 8.6 then
local elapsed, total = timerSpreadshotCD:GetTime()
local extend = 8.6 - (total-elapsed)
DBM:Debug("timerSpreadshotCD extended by: "..extend, 2)
timerSpreadshotCD:Stop()
timerSpreadshotCD:Update(elapsed, total+extend)
end
local phase = self.vb.phase
if phase == 1 then
if timerJaggedClawsCD:GetRemaining() < 9.7 then
local elapsed, total = timerJaggedClawsCD:GetTime()
local extend = 9.7 - (total-elapsed)
DBM:Debug("timerJaggedClawsCD extended by: "..extend, 2)
timerJaggedClawsCD:Stop()
timerJaggedClawsCD:Update(elapsed, total+extend)
end
elseif phase == 2 then
if timerRipSoulCD:GetRemaining() < 8.5 then
local elapsed, total = timerRipSoulCD:GetTime()
local extend = 8.5 - (total-elapsed)
DBM:Debug("timerRipSoulCD extended by: "..extend, 2)
timerRipSoulCD:Stop()
timerRipSoulCD:Update(elapsed, total+extend)
end
elseif phase == 3 then
if timerPetrifyingHowlCD:GetRemaining() < 9.7 then
local elapsed, total = timerPetrifyingHowlCD:GetTime()
local extend = 9.7 - (total-elapsed)
DBM:Debug("timerPetrifyingHowlCD extended by: "..extend, 2)
timerPetrifyingHowlCD:Stop()
timerPetrifyingHowlCD:Update(elapsed, total+extend)
end
end
end
function mod:OnCombatStart(delay)
transitionwindow = 0
self:SetStage(1)
self.vb.sinSeekerCount = 0
self.vb.activeSeekers = 0
playerSinSeeker = false
timerSpreadshotCD:Start(6-delay)
timerSinseekerCD:Start(28.8-delay, 1)
--Margore on pull on heroic testing, but can this change?
timerJaggedClawsCD:Start(10.1-delay)
timerViciousLungeCD:Start(18.1-delay)--SUCCESS of debuff, not Command Margore-335119
-- berserkTimer:Start(-delay)--Confirmed normal and heroic
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 == 335114 then
self.vb.sinSeekerCount = self.vb.sinSeekerCount + 1
--Mythic, Dog1: 49, Dog2: 60, Dog3: 50, dogs dead: 39.9
--Normal, Dog1: 50-51, Dog2: 60-61, Dog3: 50-51, dogs dead: 24.3
local timer = self:IsMythic() and (self.vb.phase == 4 and 25 or 60.2) or (self.vb.phase == 4 and 24.3 or 49.1)--self.vb.phase == 2 and 61.1 or
timerSinseekerCD:Start(timer, self.vb.sinSeekerCount+1)
if self.vb.phase == 3 and self:IsMythic() then
updateRangeFrame(self, true)--Force show during cast so it's up a little early
end
if transitionwindow == 1 then
transitionwindow = 2
end
updateAllTimers(self)
elseif spellId == 334404 and self.vb.phase < 4 then--It's no longer every 6 seconds in P4, it's every 3.7, that's too much spam for any warning
warnSpreadshot:Show()
timerSpreadshotCD:Start(11.8)--More work required to determin causes of longer ones
elseif spellId == 334971 then
timerJaggedClawsCD:Start()
elseif spellId == 334797 then
if self:IsTanking("player", nil, nil, true, args.sourceGUID) then
specWarnRipSoul:Show()
specWarnRipSoul:Play("defensive")
end
timerRipSoulCD:Start()
elseif spellId == 334757 then
specWarnShadesofBargast:Show()
specWarnShadesofBargast:Play("targetchange")
timerShadesofBargastCD:Start()
if self.Options.SetIconOnShades then
self:ScanForMobs(171557, 1, 4, 2, nil, 15, "SetIconOnShades")--Start at 4 ascending up
end
timerSpreadshotCD:Stop()--At very least halts timer, not sure what restart time is since sinseeker restart will automatically alter it anyways
elseif spellId == 334852 then
timerPetrifyingHowlCD:Start(self:IsMythic() and 30 or 20.6)
timerSpreadshotCD:Stop()
timerSpreadshotCD:Start(14.3)--Resets spreadshot to 14.3
end
end
function mod:SPELL_CAST_SUCCESS(args)
local spellId = args.spellId
if spellId == 334945 then--Vicious Lunge, First event with target information, it's where we sync timers to
timerViciousLungeCD:Start()
timerSpreadshotCD:Stop()
timerSpreadshotCD:Start(11.8)--Resets bosses spreadshot timer
elseif spellId == 334797 then
specWarnRipSoulHealer:Show(args.destName)
specWarnRipSoulHealer:Play("healfull")
end
end
function mod:SPELL_AURA_APPLIED(args)
local spellId = args.spellId
if spellId == 334971 then
local uId = DBM:GetRaidUnitId(args.destName)
if self:IsTanking(uId) then
local amount = args.amount or 1
if amount >= 2 then
if args:IsPlayer() then
specWarnJaggedClaws:Show(amount)
specWarnJaggedClaws:Play("stackhigh")
else
local _, _, _, _, _, expireTime = DBM:UnitDebuff("player", spellId)
local remaining
if expireTime then
remaining = expireTime-GetTime()
end
if (not remaining or remaining and remaining < 10.9) and not UnitIsDeadOrGhost("player") and not self:IsHealer() then
specWarnJaggedClawsTaunt:Show(args.destName)
specWarnJaggedClawsTaunt:Play("tauntboss")
else
warnJaggedClaws:Show(args.destName, amount)
end
end
else
warnJaggedClaws:Show(args.destName, amount)
end
end
elseif spellId == 334860 then
local amount = args.amount or 1
if amount % 5 == 0 then
warnCrushingStone:Show(args.destName, amount)
end
elseif spellId == 334945 then
if args:IsPlayer() then
specWarnViciousLunge:Show()
specWarnViciousLunge:Play("gathershare")
yellViciousLunge:Yell()
yellViciousLungeFades:Countdown(spellId)
updateRangeFrame(self)
else
warnViciousLunge:Show(args.destName)
end
elseif spellId == 334852 then
warnPetrifyingHowl:CombinedShow(0.3, args.destName)
if args:IsPlayer() then
specWarnPetrifyingHowl:Show()
specWarnPetrifyingHowl:Play("scatter")
yellPetrifyingHowl:Yell()
yellPetrifyingHowlFades:Countdown(spellId)
updateRangeFrame(self)
end
elseif spellId == 335111 or spellId == 335112 or spellId == 335113 then
self.vb.activeSeekers = self.vb.activeSeekers + 1
local icon = spellId == 335111 and 1 or spellId == 335112 and 2 or spellId == 335113 and 3
if self.Options.SetIconOnSinSeeker then
self:SetIcon(args.destName, icon)
end
if args:IsPlayer() then
playerSinSeeker = true
specWarnSinseeker:Show(self:IconNumToTexture(icon))
specWarnSinseeker:Play("mm"..icon)
yellSinseeker:Yell(icon, icon)
yellSinseekerFades:Countdown(spellId, nil, icon)
end
warnSinseeker:CombinedShow(spellId == 335113 and 0.1 or 2.5, args.destName)
elseif spellId == 334504 then
local cid = self:GetCIDFromGUID(args.sourceGUID)
if cid == 169457 then--Bargast
self:SetStage(2)
warnPhase:Show(DBM_CORE_L.AUTO_ANNOUNCE_TEXTS.stage:format(2))
warnPhase:Play("ptwo")
--Start Next Dog
--timerSpreadshotCD:Start()--Used instantly
timerSinseekerCD:Stop()
timerRipSoulCD:Start(10)
timerShadesofBargastCD:Start(17.5)
timerSinseekerCD:Start(31.8, self.vb.sinSeekerCount+1)
transitionwindow = 0
elseif cid == 169457 then--Bargast
self:SetStage(3)
warnPhase:Show(DBM_CORE_L.AUTO_ANNOUNCE_TEXTS.stage:format(3))
warnPhase:Play("pthree")
--Start Next Dog
timerSpreadshotCD:Start(6.3)
timerPetrifyingHowlCD:Start(13.9)
timerSinseekerCD:Stop()
if transitionwindow == 2 then--Cast within transition window
--It was cast going into phase change, which causes it to incurr it's full 50 second cd on this event
timerSinseekerCD:Start(50, self.vb.sinSeekerCount+1)
else
timerSinseekerCD:Start(28.3, self.vb.sinSeekerCount+1)--Need fresh transcriptor log to verify this
end
transitionwindow = 0
end
end
end
mod.SPELL_AURA_APPLIED_DOSE = mod.SPELL_AURA_APPLIED
function mod:SPELL_AURA_REMOVED(args)
local spellId = args.spellId
if spellId == 334945 then
if args:IsPlayer() then
yellViciousLungeFades:Cancel()
updateRangeFrame(self)
end
elseif spellId == 334860 then
local amount = args.amount or 1
if amount % 5 == 0 then
warnCrushingStone:Show(args.destName, amount)
end
elseif spellId == 334852 then
if args:IsPlayer() then
yellPetrifyingHowlFades:Cancel()
updateRangeFrame(self)
end
elseif spellId == 335111 or spellId == 335112 or spellId == 335113 then
self.vb.activeSeekers = self.vb.activeSeekers - 1
if args:IsPlayer() then
playerSinSeeker = false
yellSinseekerFades:Cancel()
end
if self.Options.SetIconOnSinSeeker then
self:SetIcon(args.destName, 0)
end
if self.vb.activeSeekers == 0 and self.vb.phase == 3 and self:IsMythic() then
updateRangeFrame(self)
end
end
end
mod.SPELL_AURA_REMOVED_DOSE = mod.SPELL_AURA_REMOVED
--https://ptr.wowhead.com/npc=173112/pierced-soul
function mod:UNIT_DIED(args)
local cid = self:GetCIDFromGUID(args.destGUID)
if cid == 165067 then--margore
transitionwindow = 1
timerSpreadshotCD:Stop()--Boss stops using this rest of fight? Might be a bug
timerJaggedClawsCD:Stop()
timerViciousLungeCD:Stop()
elseif cid == 169457 then--bargast
transitionwindow = 1
timerRipSoulCD:Stop()
timerShadesofBargastCD:Stop()
timerSpreadshotCD:Stop()
elseif cid == 169458 then--hecutis
timerPetrifyingHowlCD:Stop()
timerSpreadshotCD:Stop()
--Start Phase 4 stuff because no hunters bond here, still has a small chance to clip sinseeker timer that got off at end of phase 3
self:SetStage(4)
warnPhase:Show(DBM_CORE_L.AUTO_ANNOUNCE_TEXTS.stage:format(4))
warnPhase:Play("pfour")
--New timer starts, except when it doesn't and it just casts 60 seconds after phase 3 version
timerSinseekerCD:Stop()
timerSinseekerCD:Start(6.2, self.vb.sinSeekerCount+1)
end
end