diff --git a/HeroRotation_DeathKnight/Blood.lua b/HeroRotation_DeathKnight/Blood.lua index 007acb2fc..49103d8de 100644 --- a/HeroRotation_DeathKnight/Blood.lua +++ b/HeroRotation_DeathKnight/Blood.lua @@ -415,7 +415,7 @@ local function APL() end -- abomination_limb if CDsON() and S.AbominationLimb:IsCastable() then - if Cast(S.AbominationLimb, nil, Settings.CommonsDS.DisplayStyle.Signature, not Target:IsInRange(20)) then return "abomination_limb main 22"; end + if Cast(S.AbominationLimb, nil, Settings.CommonsDS.DisplayStyle.AbominationLimb, not Target:IsInRange(20)) then return "abomination_limb main 22"; end end -- dancing_rune_weapon,if=!buff.dancing_rune_weapon.up if CDsON() and S.DancingRuneWeapon:IsCastable() and (Player:BuffDown(S.DancingRuneWeaponBuff)) then diff --git a/HeroRotation_DeathKnight/DeathKnight.lua b/HeroRotation_DeathKnight/DeathKnight.lua index 8b2f43397..ca764ad70 100755 --- a/HeroRotation_DeathKnight/DeathKnight.lua +++ b/HeroRotation_DeathKnight/DeathKnight.lua @@ -81,7 +81,11 @@ Spell.DeathKnight.Deathbringer = { } Spell.DeathKnight.RideroftheApocalypse = { + -- Talents + AFeastofSouls = Spell(444072), + ApocalypseNow = Spell(444040), -- Buffs + AFeastofSoulsBuff = Spell(440861), MograinesMightBuff = Spell(444505), } @@ -147,6 +151,7 @@ Spell.DeathKnight.Frost = MergeTableByKey(Spell.DeathKnight.Commons, { BreathofSindragosa = Spell(152279), ChillStreak = Spell(305392), ColdHeart = Spell(281208), + EnduringStrength = Spell(377190), Everfrost = Spell(376938), FatalFixation = Spell(405166), Frostscythe = Spell(207230), @@ -166,6 +171,7 @@ Spell.DeathKnight.Frost = MergeTableByKey(Spell.DeathKnight.Commons, { ShatteredFrost = Spell(455993), ShatteringBlade = Spell(207057), SmotheringOffense = Spell(435005), + TheLongWinter = Spell(456240), UnleashedFrenzy = Spell(376905), -- Buffs ChillingRageBuff = Spell(424165), -- Tier 31 2pc diff --git a/HeroRotation_DeathKnight/Frost.lua b/HeroRotation_DeathKnight/Frost.lua index 349b171f5..b3012a70d 100755 --- a/HeroRotation_DeathKnight/Frost.lua +++ b/HeroRotation_DeathKnight/Frost.lua @@ -41,7 +41,7 @@ local OnUseExcludes = { I.Fyralath:ID(), } --- GUI Settings +--- ===== GUI Settings ===== local Everyone = HR.Commons.Everyone local Settings = { General = HR.GUISettings.General, @@ -51,89 +51,192 @@ local Settings = { Frost = HR.GUISettings.APL.DeathKnight.Frost } --- Rotation Var -local no_heal -local UsingRazorice -local UsingFallenCrusader -local VarRWBuffs = S.GatheringStorm:IsAvailable() or S.Everfrost:IsAvailable() -local VarERWPoolingTime = (Settings.Frost.AMSAbsorbPercent > 59) and 25 or 45 +--- ===== Rotation Variables ===== +local VarPillarCD = (S.Icecap:IsAvailable()) and 45 or 60 +local Equip, Trinket1, Trinket2 +local VarTrinket1ID, VarTrinket2ID +local VarTrinket1CD, VarTrinket2CD +local VarTrinket1Exclude, VarTrinket2Exclude local VarTrinket1Sync, VarTrinket2Sync local VarTrinket1Buffs, VarTrinket2Buffs -local VarTrinketPriority -local VarSTPlanning -local VarAddsRemain -local VarRimeBuffs -local VarRPBuffs -local VarCDCheck -local VarFrostscythePriority -local VarOblitPoolingTime -local VarBreathPoolingTime -local VarPoolingRunes -local VarPoolingRP +local VarTrinketPriority, VarDamageTrinketPriority +local VarTrinket1Manual, VarTrinket2Manual +local MainHandLink, OffHandLink +local MainHandRuneforge, OffHandRuneforge +local UsingRazorice, UsingFallenCrusader +local Var2HCheck +local VarRWBuffs = S.GatheringStorm:IsAvailable() or S.BitingCold:IsAvailable() +local VarSTPlanning, VarAddsRemain, VarSendingCDs +local VarRimeBuffs, VarRPBuffs, VarCDCheck +local VarOblitPoolingTime, VarBreathPoolingTime +local VarPoolingRunes, VarPoolingRP +local VarGAPriority, VarBreathDying +local EnemiesMelee, EnemiesMeleeCount local BossFightRemains = 11111 local FightRemains = 11111 local GCDMax local Ghoul = HL.GhoulTable -local EnemiesMelee, EnemiesMeleeCount -HL:RegisterForEvent(function() - BossFightRemains = 11111 - FightRemains = 11111 -end, "PLAYER_REGEN_ENABLED") +--- ===== Trinket Item Objects ===== +local function GetTrinketItems() + Equip = Player:GetEquipment() + Trinket1 = Equip[13] and Item(Equip[13]) or Item(0) + Trinket2 = Equip[14] and Item(Equip[14]) or Item(0) +end +GetTrinketItems() -HL:RegisterForEvent(function() - VarRWBuffs = S.GatheringStorm:IsAvailable() or S.Everfrost:IsAvailable() -end, "SPELLS_CHANGED", "LEARNED_SPELL_IN_TAB") +--- ===== Trinket Variables (from Precombat) ===== +local function SetTrinketVariables() + VarTrinket1ID = Trinket1:ID() + VarTrinket2ID = Trinket2:ID() --- Stun Interrupts List -local StunInterrupts = { - {S.Asphyxiate, "Cast Asphyxiate (Interrupt)", function () return true; end}, -} + local Trinket1Spell = Trinket1:OnUseSpell() + VarTrinket1Range = (Trinket1Spell and Trinket1Spell.MaximumRange > 0 and Trinket1Spell.MaximumRange <= 100) and Trinket1Spell.MaximumRange or 100 + local Trinket2Spell = Trinket2:OnUseSpell() + VarTrinket2Range = (Trinket2Spell and Trinket2Spell.MaximumRange > 0 and Trinket2Spell.MaximumRange <= 100) and Trinket2Spell.MaximumRange or 100 -local MainHandLink = GetInventoryItemLink("player", 16) or "" -local OffHandLink = GetInventoryItemLink("player", 17) or "" -local _, _, MainHandRuneforge = strsplit(":", MainHandLink) -local _, _, OffHandRuneforge = strsplit(":", OffHandLink) -local UsingRazorice = (MainHandRuneforge == "3370" or OffHandRuneforge == "3370") -local UsingFallenCrusader = (MainHandRuneforge == "3368" or OffHandRuneforge == "3368") -local UsingHysteria = (MainHandRuneforge == "6243" or OffHandRuneforge == "6243") -local Var2HCheck = IsEquippedItemType("Two-Hand") -local Equip = Player:GetEquipment() -local Trinket1 = Equip[13] and Item(Equip[13]) or Item(0) -local Trinket2 = Equip[14] and Item(Equip[14]) or Item(0) + VarTrinket1CD = Trinket1:Cooldown() + VarTrinket2CD = Trinket2:Cooldown() -HL:RegisterForEvent(function() + VarTrinket1Exclude = VarTrinket1ID == 193757 or VarTrinket1ID == 194301 + VarTrinket2Exclude = VarTrinket2ID == 193757 or VarTrinket2ID == 194301 + + VarTrinket1Sync = 0.5 + if Trinket1:HasUseBuff() and (S.PillarofFrost:IsAvailable() and not S.BreathofSindragosa:IsAvailable() and (VarTrinket1CD % VarPillarCD == 0) or S.BreathofSindragosa:IsAvailable() and (120 % VarTrinket1CD == 0)) then + VarTrinket1Sync = 1 + end + VarTrinket2Sync = 0.5 + if Trinket2:HasUseBuff() and (S.PillarofFrost:IsAvailable() and not S.BreathofSindragosa:IsAvailable() and (VarTrinket2CD % VarPillarCD == 0) or S.BreathofSindragosa:IsAvailable() and (120 % VarTrinket2CD == 0)) then + VarTrinket2Sync = 1 + end + + VarTrinket1Buffs = Trinket1:HasUseBuff() + VarTrinket2Buffs = Trinket2:HasUseBuff() + + VarTrinketPriority = 1 + -- Note: Using the below buff durations to avoid potential divide by zero errors. + local T1BuffDuration = (Trinket1:BuffDuration() > 0) and Trinket1:BuffDuration() or 1 + local T2BuffDuration = (Trinket2:BuffDuration() > 0) and Trinket2:BuffDuration() or 1 + if not VarTrinket1Buffs and VarTrinket2Buffs and (Trinket2:HasCooldown() and not VarTrinket2Exclude or not Trinket1:HasCooldown()) or VarTrinket2Buffs and ((VarTrinket2CD / T2BuffDuration) * (VarTrinket2Sync)) > ((VarTrinket1CD / T1BuffDuration) * (VarTrinket1Sync) * (1 + ((Trinket1:Level() - Trinket2:Level()) / 100))) then + VarTrinketPriority = 2 + end + + VarDamageTrinketPriority = 1 + if not VarTrinket1Buffs and not VarTrinket2Buffs and Trinket2:Level() >= Trinket1:Level() then + VarDamageTrinketPriority = 2 + end + + VarTrinket1Manual = VarTrinket1ID == I.AlgetharPuzzleBox:ID() + VarTrinket2Manual = VarTrinket2ID == I.AlgetharPuzzleBox:ID() +end +SetTrinketVariables() + +local function SetSpellVariables() + VarStaticObliterateBuffs = S.ArcticAssault:IsAvailable() or S.FrigidExecutioner:IsAvailable() or Var2HCheck + VarBreathRPCost = 1.7 + VarStaticRimeBuffs = S.RageoftheFrozenChampion:IsAvailable() or S.Icebreaker:IsAvailable() + VarBreathRPThreshold = 70 + VarERWBreathRPTrigger = 70 + VarERWBreathRuneTrigger = 3 + VarOblitRunePooling = 4 + VarBreathRimeRPThreshold = 60 +end +SetSpellVariables() + +--- ===== Weapon Variables ===== +local function SetWeaponVariables() MainHandLink = GetInventoryItemLink("player", 16) or "" OffHandLink = GetInventoryItemLink("player", 17) or "" - _, _, MainHandRuneforge = strsplit(":", MainHandLink) - _, _, OffHandRuneforge = strsplit(":", OffHandLink) + MainHandRuneforge = select(3, strsplit(":", MainHandLink)) + OffHandRuneforge = select(3, strsplit(":", OffHandLink)) UsingRazorice = (MainHandRuneforge == "3370" or OffHandRuneforge == "3370") UsingFallenCrusader = (MainHandRuneforge == "3368" or OffHandRuneforge == "3368") Var2HCheck = IsEquippedItemType("Two-Hand") - Equip = Player:GetEquipment() - Trinket1 = Equip[13] and Item(Equip[13]) or Item(0) - Trinket2 = Equip[14] and Item(Equip[14]) or Item(0) +end +SetWeaponVariables() + +--- ===== Stun Interrupts List ===== +local StunInterrupts = { + {S.Asphyxiate, "Cast Asphyxiate (Interrupt)", function () return true; end}, +} + +--- ===== Event Registrations ===== +HL:RegisterForEvent(function() + BossFightRemains = 11111 + FightRemains = 11111 +end, "PLAYER_REGEN_ENABLED") + +HL:RegisterForEvent(function() + VarRWBuffs = S.GatheringStorm:IsAvailable() or S.BitingCold:IsAvailable() + SetTrinketVariables() + SetSpellVariables() +end, "SPELLS_CHANGED", "LEARNED_SPELL_IN_TAB") + +HL:RegisterForEvent(function() + GetTrinketItems() + SetTrinketVariables() + SetWeaponVariables() + SetSpellVariables() end, "PLAYER_EQUIPMENT_CHANGED") --- Helper Functions +--- ===== Helper Functions ===== local function DeathStrikeHeal() return (Settings.General.SoloMode and (Player:HealthPercentage() < Settings.Commons.UseDeathStrikeHP or Player:HealthPercentage() < Settings.Commons.UseDarkSuccorHP and Player:BuffUp(S.DeathStrikeBuff))) end --- Target_if -local function EvaluateTargetIfFilterFyralath(TargetUnit) - return TargetUnit:DebuffRemains(S.MarkofFyralathDebuff) +--- ===== CastTargetIf Filter Functions ===== +local function EvaluateTargetIfFilterFrostStrike(TargetUnit) + -- target_if=max:((talent.shattering_blade&debuff.razorice.stack=5)*5)+(debuff.razorice.stack+1)%(debuff.razorice.remains+1)*death_knight.runeforge.razorice + return (num(S.ShatteringBlade:IsAvailable() and TargetUnit:DebuffStack(S.RazoriceDebuff) == 5) * 5) + (TargetUnit:DebuffStack(S.RazoriceDebuff) + 1) / (TargetUnit:DebuffRemains(S.RazoriceDebuff) + 1) * num(UsingRazorice) end -local function EvaluateTargetIfRazoriceStacks(TargetUnit) - return ((TargetUnit:DebuffStack(S.RazoriceDebuff) + 1) / (TargetUnit:DebuffRemains(S.RazoriceDebuff) + 1) * num(UsingRazorice)) +local function EvaluateTargetIfFilterRazoriceStacks(TargetUnit) + -- target_if=max:(debuff.razorice.stack) + return TargetUnit:DebuffStack(S.RazoriceDebuff) end --- HowlingBlast -local function EvaluateCycleHowlingBlast(TargetUnit) - return (TargetUnit:DebuffDown(S.FrostFeverDebuff)) +local function EvaluateTargetIfFilterRazoriceStacksModified(TargetUnit) + -- target_if=max:(debuff.razorice.stack+1)%(debuff.razorice.remains+1)*death_knight.runeforge.razorice + return (TargetUnit:DebuffStack(S.RazoriceDebuff) + 1) / (TargetUnit:DebuffRemains(S.RazoriceDebuff) + 1) * num(UsingRazorice) end +--- ===== CastTargetIf Condition Functions ===== +local function EvaluateTargetIfFrostStrikeAoE(TargetUnit) + -- if=!variable.pooling_runic_power&debuff.razorice.stack=5&talent.shattering_blade&(talent.shattered_frost|active_enemies<4) + -- Note: Variable, talent, and enemy count checks performed before CastTargetIf. + return TargetUnit:DebuffStack(S.RazoriceDebuff) == 5 +end + +local function EvaluateTargetIfFrostStrikeObliteration(TargetUnit) + -- if=debuff.razorice.stack=5&talent.shattering_blade&talent.a_feast_of_souls&buff.a_feast_of_souls.up&!talent.arctic_assault + -- Note: All but RazoriceDebuff stacks checked before CastTargetIf. + return TargetUnit:DebuffStack(S.RazoriceDebuff) +end + +local function EvaluateTargetIfFrostStrikeObliteration2(TargetUnit) + -- if=(rune<2|variable.rp_buffs|debuff.razorice.stack=5&talent.shattering_blade)&!variable.pooling_runic_power&(!talent.glacial_advance|active_enemies=1|talent.shattered_frost) + -- Note: VarPoolingRP and talent checks performed before CastTargetIf. + return Player:Rune() < 2 or VarRPBuffs or TargetUnit:DebuffStack(S.RazoriceDebuff) == 5 and S.ShatteringBlade:IsAvailable() +end + +local function EvaluateTargetIfGlacialAdvanceAoE(TargetUnit) + -- if=!variable.pooling_runic_power&(variable.ga_priority|debuff.razorice.stack<5) + -- Note: pooling_runic_power check performed before CastTargetIf. + return VarGAPriority or TargetUnit:DebuffStack(S.RazoriceDebuff) < 5 +end + +local function EvaluateTargetIfGlacialAdvanceObliteration(TargetUnit) + -- if=(variable.ga_priority|debuff.razorice.stack<5)&(!death_knight.runeforge.razorice&(debuff.razorice.stack<5|debuff.razorice.remains1)) + return (VarGAPriority or TargetUnit:DebuffStack(S.RazoriceDebuff) < 5) and (not UsingRazorice and (TargetUnit:DebuffStack(S.RazoriceDebuff) < 5 or TargetUnit:DebuffRemains(S.RazoriceDebuff) < Player:GCD() * 3) or ((VarRPBuffs or Player:Rune() < 2) and EnemiesMeleeCount > 1)) +end + +--- ===== CastCycle Functions ===== +local function EvaluateCycleReapersMarkCDs(TargetUnit) + -- target_if=first:!debuff.reapers_mark_debuff.up + return TargetUnit:DebuffDown(S.ReapersMarkDebuff) +end + +--- ===== Rotation Functions ===== local function Precombat() -- flask -- food @@ -149,13 +252,21 @@ local function Precombat() -- variable,name=damage_trinket_priority,op=setif,value=2,value_else=1,condition=!variable.trinket_1_buffs&!variable.trinket_2_buffs&trinket.2.ilvl>=trinket.1.ilvl -- variable,name=trinket_1_manual,value=trinket.1.is.algethar_puzzle_box -- variable,name=trinket_2_manual,value=trinket.2.is.algethar_puzzle_box - -- TODO: Trinket sync/priority stuff. Currently unable to pull trinket CD durations because WoW's API is bad. - -- variable,name=rw_buffs,value=talent.gathering_storm|talent.everfrost - -- Note: Handling during variable declaration and SPELLS_CHANGED/LEARNED_SPELL_IN_TAB events + -- Note: Manual trinkets handled via OnUseExcludes. + -- Note: Moved the above variable definitions to initial profile load, SPELLS_CHANGED, and PLAYER_EQUIPMENT_CHANGED. + -- variable,name=rw_buffs,value=talent.gathering_storm|talent.biting_cold + -- Note: Handling during variable declaration and SPELLS_CHANGED/LEARNED_SPELL_IN_TAB events. -- variable,name=2h_check,value=main_hand.2h - -- Note: Handling during variable declaration and PLAYER_EQUIPMENT_CHANGED events - -- variable,name=erw_pooling_time,op=setif,value=30,value_else=45,condition=death_knight.ams_absorb_percent>0.59 - VarERWPoolingTime = (Settings.Frost.AMSAbsorbPercent > 59) and 30 or 45 + -- Note: Handling during variable declaration and PLAYER_EQUIPMENT_CHANGED events. + -- variable,name=static_obliterate_buffs,value=talent.arctic_assault|talent.frigid_executioner|variable.2h_check + -- variable,name=breath_rp_cost,value=dbc.power.9067.cost_per_tick%10 + -- variable,name=static_rime_buffs,value=talent.rage_of_the_frozen_champion|talent.icebreaker + -- variable,name=breath_rp_threshold,default=70,op=reset + -- variable,name=erw_breath_rp_trigger,default=70,op=reset + -- variable,name=erw_breath_rune_trigger,default=3,op=reset + -- variable,name=oblit_rune_pooling,default=4,op=reset + -- variable,name=breath_rime_rp_threshold,default=60,op=reset + -- Note: Handling the above during variable declaration, PLAYER_EQUIPMENT_CHANGED, and SPELLS_CHANGED/LEARNED_SPELL_IN_TAB. -- Manually added openers: HowlingBlast if at range, RemorselessWinter if in melee if S.HowlingBlast:IsReady() and not Target:IsInRange(8) then if Cast(S.HowlingBlast, nil, nil, not Target:IsSpellInRange(S.HowlingBlast)) then return "howling_blast precombat 2"; end @@ -166,119 +277,77 @@ local function Precombat() end local function AoE() - -- howling_blast,if=buff.rime.react|!dot.frost_fever.ticking - if S.HowlingBlast:IsReady() and (Player:BuffUp(S.RimeBuff) or Target:DebuffDown(S.FrostFeverDebuff)) then - if Cast(S.HowlingBlast, nil, nil, not Target:IsSpellInRange(S.HowlingBlast)) then return "howling_blast aoe 2"; end + -- obliterate,if=buff.killing_machine.react&talent.cleaving_strikes&buff.death_and_decay.up + if S.Obliterate:IsReady() and (Player:BuffUp(S.KillingMachineBuff) and S.CleavingStrikes:IsAvailable() and Player:BuffUp(S.DeathAndDecayBuff)) then + if Cast(S.Obliterate, nil, nil, not Target:IsInMeleeRange(5)) then return "obliterate aoe 2"; end end - -- glacial_advance,if=!variable.pooling_runic_power&variable.rp_buffs - if S.GlacialAdvance:IsReady() and (not VarPoolingRP and VarRPBuffs) then - if Cast(S.GlacialAdvance, nil, nil, not Target:IsInRange(100)) then return "glacial_advance aoe 4"; end + -- howling_blast,if=!dot.frost_fever.ticking + if S.HowlingBlast:IsReady() and (Target:DebuffDown(S.FrostFeverDebuff)) then + if Cast(S.HowlingBlast, nil, nil, not Target:IsSpellInRange(S.HowlingBlast)) then return "howling_blast aoe 4"; end end - -- frostscythe,if=!death_and_decay.ticking&equipped.fyralath_the_dreamrender&(cooldown.rage_of_fyralath_417131.remains<3|!dot.mark_of_fyralath.ticking) - if S.Frostscythe:IsReady() and (Player:BuffDown(S.DeathAndDecayBuff) and I.Fyralath:IsEquipped() and (I.Fyralath:CooldownRemains() < 3 or S.MarkofFyralathDebuff:AuraActiveCount() == 0)) then - if Cast(S.Frostscythe, nil, nil, not Target:IsInMeleeRange(8)) then return "frostscythe aoe 6"; end + -- frost_strike,target_if=max:((talent.shattering_blade&debuff.razorice.stack=5)*5)+(debuff.razorice.stack+1)%(debuff.razorice.remains+1)*death_knight.runeforge.razorice,if=!variable.pooling_runic_power&debuff.razorice.stack=5&talent.shattering_blade&(talent.shattered_frost|active_enemies<4) + if S.FrostStrike:IsReady() and (not VarPoolingRP and S.ShatteringBlade:IsAvailable() and (S.ShatteredFrost:IsAvailable() or EnemiesMeleeCount < 4)) then + if Everyone.CastTargetIf(S.FrostStrike, EnemiesMelee, "max", EvaluateTargetIfFilterFrostStrike, EvaluateTargetIfFrostStrikeAoE, not Target:IsSpellInRange(S.FrostStrike), Settings.Frost.GCDasOffGCD.FrostStrike) then return "frost_strike aoe 6"; end end - -- obliterate,if=buff.killing_machine.react&talent.cleaving_strikes&death_and_decay.ticking&!variable.frostscythe_priority - if S.Obliterate:IsReady() and (Player:BuffUp(S.KillingMachineBuff) and S.CleavingStrikes:IsAvailable() and Player:BuffUp(S.DeathAndDecayBuff) and not VarFrostscythePriority) then - if Cast(S.Obliterate, nil, nil, not Target:IsInMeleeRange(5)) then return "obliterate aoe 8"; end + -- howling_blast,if=buff.rime.react|!dot.frost_fever.ticking + if S.HowlingBlast:IsReady() and (Player:BuffUp(S.RimeBuff) or S.FrostFeverDebuff:AuraActiveCount() < EnemiesMeleeCount) then + if Cast(S.HowlingBlast, nil, nil, not Target:IsSpellInRange(S.HowlingBlast)) then return "howling_blast aoe 8"; end end - -- glacial_advance,if=!variable.pooling_runic_power + -- glacial_advance,target_if=max:(debuff.razorice.stack),if=!variable.pooling_runic_power&(variable.ga_priority|debuff.razorice.stack<5) if S.GlacialAdvance:IsReady() and (not VarPoolingRP) then - if Cast(S.GlacialAdvance, nil, nil, not Target:IsInRange(100)) then return "glacial_advance aoe 10"; end - end - -- frostscythe,if=variable.frostscythe_priority - if S.Frostscythe:IsReady() and (VarFrostscythePriority) then - if Cast(S.Frostscythe, nil, nil, not Target:IsInMeleeRange(8)) then return "frostscythe aoe 12"; end + if Everyone.CastTargetIf(S.GlacialAdvance, EnemiesMelee, "max", EvaluateTargetIfFilterRazoriceStacks, EvaluateTargetIfGlacialAdvanceAoE, not Target:IsInRange(100)) then return "glacial_advance aoe 10"; end end - -- obliterate,if=!variable.frostscythe_priority - if S.Obliterate:IsReady() and (not VarFrostscythePriority) then - if Cast(S.Obliterate, nil, nil, not Target:IsInMeleeRange(5)) then return "obliterate aoe 14"; end + -- obliterate + if S.Obliterate:IsReady() then + if Cast(S.Obliterate, nil, nil, not Target:IsInMeleeRange(5)) then return "obliterate aoe 12"; end end - -- frost_strike,if=!variable.pooling_runic_power&!talent.glacial_advance - if S.FrostStrike:IsReady() and (not VarPoolingRP and not S.GlacialAdvance:IsAvailable()) then - if Cast(S.FrostStrike, Settings.Frost.GCDasOffGCD.FrostStrike, nil, not Target:IsSpellInRange(S.FrostStrike)) then return "frost_strike aoe 16"; end + -- frost_strike,target_if=max:((talent.shattering_blade&debuff.razorice.stack=5)*5)+(debuff.razorice.stack+1)%(debuff.razorice.remains+1)*death_knight.runeforge.razorice,if=!variable.pooling_runic_power + if S.FrostStrike:IsReady() and (not VarPoolingRP) then + if Everyone.CastTargetIf(S.FrostStrike, EnemiesMelee, "max", EvaluateTargetIfFilterFrostStrike, nil, not Target:IsSpellInRange(S.FrostStrike)) then return "frost_strike aoe 14"; end end -- horn_of_winter,if=rune<2&runic_power.deficit>25 if S.HornofWinter:IsCastable() and (Player:Rune() < 2 and Player:RunicPowerDeficit() > 25) then - if Cast(S.HornofWinter, Settings.Frost.GCDasOffGCD.HornOfWinter) then return "horn_of_winter aoe 18"; end + if Cast(S.HornofWinter, Settings.Frost.GCDasOffGCD.HornOfWinter) then return "horn_of_winter aoe 16"; end end -- arcane_torrent,if=runic_power.deficit>25 if CDsON() and S.ArcaneTorrent:IsReady() and (Player:RunicPowerDeficit() > 25) then - if Cast(S.ArcaneTorrent, Settings.CommonsOGCD.OffGCDasOffGCD.Racials) then return "arcane_torrent aoe 20"; end + if Cast(S.ArcaneTorrent, Settings.CommonsOGCD.OffGCDasOffGCD.Racials) then return "arcane_torrent aoe 18"; end end end local function Breath() - -- howling_blast,if=variable.rime_buffs&runic_power>(45-((talent.rage_of_the_frozen_champion*8)+(5*buff.rune_of_hysteria.up))) - if S.HowlingBlast:IsReady() and (VarRimeBuffs and Player:RunicPower() > (45 - (num(S.RageoftheFrozenChampion:IsAvailable()) * 8) + (5 * num(Player:BuffUp(S.RuneofHysteriaBuff))))) then + -- howling_blast,if=variable.rime_buffs&runic_power>(variable.breath_rime_rp_threshold-(talent.rage_of_the_frozen_champion*(dbc.effect.842306.base_value%10))) + -- Note: dbc.effect.842306.base_value as of 11.0.0.55793 is 60. + if S.HowlingBlast:IsReady() and (VarRimeBuffs and Player:RunicPower() > (VarBreathRimeRPThreshold - (num(S.RageoftheFrozenChampion:IsAvailable()) * 6))) then if Cast(S.HowlingBlast, nil, nil, not Target:IsSpellInRange(S.HowlingBlast)) then return "howling_blast breath 2"; end end - -- horn_of_winter,if=rune<2&runic_power.deficit>25+(5*buff.rune_of_hysteria.up) - if S.HornofWinter:IsReady() and (Player:Rune() < 2 and Player:RunicPowerDeficit() > 25 + (5 * num(Player:BuffUp(S.RuneofHysteriaBuff)))) then + -- horn_of_winter,if=rune<2&runic_power.deficit>30&(!buff.empower_rune_weapon.up|variable.breath_dying) + if S.HornofWinter:IsReady() and (Player:Rune() < 2 and Player:RunicPowerDeficit() > 30 and (Player:BuffDown(S.EmpowerRuneWeaponBuff) or VarBreathDying)) then if Cast(S.HornofWinter, Settings.Frost.GCDasOffGCD.HornOfWinter) then return "horn_of_winter breath 4"; end end - -- obliterate,target_if=max:(debuff.razorice.stack+1)%(debuff.razorice.remains+1)*death_knight.runeforge.razorice,if=buff.killing_machine.react&!variable.frostscythe_priority - if S.Obliterate:IsReady() and (Player:BuffUp(S.KillingMachineBuff) and not VarFrostscythePriority) then - if Everyone.CastTargetIf(S.Obliterate, EnemiesMelee, "max", EvaluateTargetIfRazoriceStacks, nil, not Target:IsInMeleeRange(5)) then return "obliterate breath 6"; end - end - -- frostscythe,if=variable.frostscythe_priority&(buff.killing_machine.react|runic_power>45) - if S.Frostscythe:IsReady() and (VarFrostscythePriority and (Player:BuffUp(S.KillingMachineBuff) or Player:RunicPower() > 45)) then - if Cast(S.Frostscythe, nil, nil, not Target:IsInMeleeRange(8)) then return "frostscythe breath 8"; end - end - -- obliterate,target_if=max:(debuff.razorice.stack+1)%(debuff.razorice.remains+1)*death_knight.runeforge.razorice,if=runic_power.deficit>40|buff.pillar_of_frost.up - if S.Obliterate:IsReady() and (Player:RunicPowerDeficit() > 40 or Player:BuffUp(S.PillarofFrostBuff)) then - if Everyone.CastTargetIf(S.Obliterate, EnemiesMelee, "max", EvaluateTargetIfRazoriceStacks, nil, not Target:IsInMeleeRange(5)) then return "obliterate breath 10"; end - end - -- remorseless_winter,if=runic_power<36&rune.time_to_2>runic_power%18 - if S.RemorselessWinter:IsReady() and (Player:RunicPower() < 36 and Player:RuneTimeToX(2) > Player:RunicPower() / 18) then - if Cast(S.RemorselessWinter, nil, nil, not Target:IsInMeleeRange(8)) then return "remorseless_winter breath 12"; end + -- obliterate,target_if=max:(debuff.razorice.stack+1)%(debuff.razorice.remains+1)*death_knight.runeforge.razorice,if=buff.killing_machine.react|runic_power.deficit>20 + if S.Obliterate:IsReady() and (Player:BuffUp(S.KillingMachineBuff) or Player:RunicPowerDeficit() > 20) then + if Everyone.CastTargetIf(S.Obliterate, EnemiesMelee, "max", EvaluateTargetIfFilterRazoriceStacksModified, nil, not Target:IsInMeleeRange(5)) then return "obliterate breath 6"; end end - -- death_and_decay,if=variable.st_planning&talent.unholy_ground&!death_and_decay.ticking&runic_power.deficit>=10|runic_power<36&rune.time_to_2>runic_power%18 - if S.DeathAndDecay:IsReady() and (VarSTPlanning and S.UnholyGround:IsAvailable() and Player:BuffDown(S.DeathAndDecayBuff) and Player:RunicPowerDeficit() >= 10 or Player:RunicPower() < 36 and Player:RuneTimeToX(2) > Player:RunicPower() / 18) then - if Cast(S.DeathAndDecay, Settings.CommonsOGCD.GCDasOffGCD.DeathAndDecay, nil, not Target:IsSpellInRange(S.DeathAndDecay)) then return "death_and_decay breath 14"; end + -- remorseless_winter,if=variable.breath_dying + if S.RemorselessWinter:IsReady() and (VarBreathDying) then + if Cast(S.RemorselessWinter, nil, nil, not Target:IsInMeleeRange(8)) then return "remorseless_winter breath 8"; end end - -- howling_blast,if=runic_power<36&rune.time_to_2>runic_power%18 - if S.HowlingBlast:IsReady() and (Player:RunicPower() < 36 and Player:RuneTimeToX(2) > Player:RunicPower() / 18) then - if Cast(S.HowlingBlast, nil, nil, not Target:IsSpellInRange(S.HowlingBlast)) then return "howling_blast breath 16"; end - end - -- obliterate,target_if=max:(debuff.razorice.stack+1)%(debuff.razorice.remains+1)*death_knight.runeforge.razorice,if=runic_power.deficit>25 - if S.Obliterate:IsReady() and (Player:RunicPowerDeficit() > 25) then - if Everyone.CastTargetIf(S.Obliterate, EnemiesMelee, "max", EvaluateTargetIfRazoriceStacks, nil, not Target:IsInMeleeRange(5)) then return "obliterate breath 18"; end + -- death_and_decay,if=!buff.mograines_might.up&variable.st_planning&talent.unholy_ground&!buff.death_and_decay.up&runic_power.deficit>=10&!talent.obliteration|variable.breath_dying + if S.DeathAndDecay:IsReady() and (Player:BuffDown(S.MograinesMightBuff) and VarSTPlanning and S.UnholyGround:IsAvailable() and Player:BuffDown(S.DeathAndDecayBuff) and Player:RunicPowerDeficit() >= 10 and not S.Obliteration:IsAvailable() or VarBreathDying) then + if Cast(S.DeathAndDecay, Settings.CommonsOGCD.GCDasOffGCD.DeathAndDecay, nil, not Target:IsSpellInRange(S.DeathAndDecay)) then return "death_and_decay breath 10"; end end - -- howling_blast,if=buff.rime.react - if S.HowlingBlast:IsReady() and (Player:BuffUp(S.RimeBuff)) then - if Cast(S.HowlingBlast, nil, nil, not Target:IsSpellInRange(S.HowlingBlast)) then return "howling_blast breath 20"; end + -- howling_blast,if=variable.breath_dying + if S.HowlingBlast:IsReady() and (VarBreathDying) then + if Cast(S.HowlingBlast, nil, nil, not Target:IsSpellInRange(S.HowlingBlast)) then return "howling_blast breath 12"; end end -- arcane_torrent,if=runic_power<60 if S.ArcaneTorrent:IsReady() and (Player:RunicPower() < 60) then - if Cast(S.ArcaneTorrent, Settings.CommonsOGCD.OffGCDasOffGCD.Racials) then return "arcane_torrent breath 22"; end - end -end - -local function BreathOblit() - -- frostscythe,if=buff.killing_machine.up&variable.frostscythe_priority - if S.Frostscythe:IsReady() and (Player:BuffUp(S.KillingMachineBuff) and VarFrostscythePriority) then - if Cast(S.Frostscythe, nil, nil, not Target:IsInMeleeRange(8)) then return "frostscythe breath_oblit 2"; end - end - -- obliterate,target_if=max:(debuff.razorice.stack+1)%(debuff.razorice.remains+1)*death_knight.runeforge.razorice,if=buff.killing_machine.up - if S.Obliterate:IsReady() and (Player:BuffUp(S.KillingMachineBuff)) then - if Everyone.CastTargetIf(S.Obliterate, EnemiesMelee, "max", EvaluateTargetIfRazoriceStacks, nil, not Target:IsInMeleeRange(5)) then return "obliterate breath_oblit 4"; end + if Cast(S.ArcaneTorrent, Settings.CommonsOGCD.OffGCDasOffGCD.Racials) then return "arcane_torrent breath 14"; end end -- howling_blast,if=buff.rime.react if S.HowlingBlast:IsReady() and (Player:BuffUp(S.RimeBuff)) then - if Cast(S.HowlingBlast, nil, nil, not Target:IsSpellInRange(S.HowlingBlast)) then return "howling_blast breath_oblit 6"; end - end - -- howling_blast,if=!buff.killing_machine.up - if S.HowlingBlast:IsReady() and (Player:BuffDown(S.KillingMachineBuff)) then - if Cast(S.HowlingBlast, nil, nil, not Target:IsSpellInRange(S.HowlingBlast)) then return "howling_blast breath_oblit 8"; end - end - -- horn_of_winter,if=runic_power.deficit>25 - if S.HornofWinter:IsReady() and (Player:RunicPowerDeficit() > 25) then - if Cast(S.HornofWinter, Settings.Frost.GCDasOffGCD.HornOfWinter) then return "horn_of_winter breath_oblit 10"; end - end - -- arcane_torrent,if=runic_power.deficit>20 - if S.ArcaneTorrent:IsReady() and (Player:RunicPowerDeficit() > 20) then - if Cast(S.ArcaneTorrent, Settings.CommonsOGCD.OffGCDasOffGCD.Racials) then return "arcane_torrent breath_oblit 12"; end + if Cast(S.HowlingBlast, nil, nil, not Target:IsSpellInRange(S.HowlingBlast)) then return "howling_blast breath 16"; end end end @@ -299,91 +368,97 @@ local function ColdHeart() if S.ChainsofIce:IsReady() and (not S.Obliteration:IsAvailable() and not UsingFallenCrusader and Player:BuffStack(S.ColdHeartBuff) >= 10 and Player:BuffDown(S.PillarofFrostBuff) and S.PillarofFrost:CooldownRemains() > 20) then if Cast(S.ChainsofIce, Settings.CommonsOGCD.GCDasOffGCD.ChainsOfIce, nil, not Target:IsSpellInRange(S.ChainsofIce)) then return "chains_of_ice cold_heart 8"; end end - -- chains_of_ice,if=talent.obliteration&!buff.pillar_of_frost.up&(buff.cold_heart.stack>=14&(buff.unholy_strength.up|buff.chaos_bane.up)|buff.cold_heart.stack>=19|cooldown.pillar_of_frost.remains_expected<3&buff.cold_heart.stack>=14) - if S.ChainsofIce:IsReady() and (S.Obliteration:IsAvailable() and Player:BuffDown(S.PillarofFrostBuff) and (Player:BuffStack(S.ColdHeartBuff) >= 14 and (Player:BuffUp(S.UnholyStrengthBuff)) or Player:BuffStack(S.ColdHeartBuff) >= 19 or S.PillarofFrost:CooldownRemains() < 3 and Player:BuffStack(S.ColdHeartBuff) >= 14)) then + -- chains_of_ice,if=talent.obliteration&!buff.pillar_of_frost.up&(buff.cold_heart.stack>=14&buff.unholy_strength.up|buff.cold_heart.stack>=19|cooldown.pillar_of_frost.remains_expected<3&buff.cold_heart.stack>=14) + if S.ChainsofIce:IsReady() and (S.Obliteration:IsAvailable() and Player:BuffDown(S.PillarofFrostBuff) and (Player:BuffStack(S.ColdHeartBuff) >= 14 and Player:BuffUp(S.UnholyStrengthBuff) or Player:BuffStack(S.ColdHeartBuff) >= 19 or S.PillarofFrost:CooldownRemains() < 3 and Player:BuffStack(S.ColdHeartBuff) >= 14)) then if Cast(S.ChainsofIce, Settings.CommonsOGCD.GCDasOffGCD.ChainsOfIce, nil, not Target:IsSpellInRange(S.ChainsofIce)) then return "chains_of_ice cold_heart 10"; end end end local function Cooldowns() - -- potion,if=(talent.pillar_of_frost&buff.pillar_of_frost.up&(talent.obliteration&buff.pillar_of_frost.remains<6|!talent.obliteration)|!talent.pillar_of_frost&buff.empower_rune_weapon.up|!talent.pillar_of_frost&!talent.empower_rune_weapon|active_enemies>=2&buff.pillar_of_frost.up)|fight_remains<25 - if Settings.Commons.Enabled.Potions and ((S.PillarofFrost:IsAvailable() and Player:BuffUp(S.PillarofFrostBuff) and (S.Obliteration:IsAvailable() and Player:BuffRemains(S.PillarofFrostBuff) < 6 or not S.Obliteration:IsAvailable()) or not S.PillarofFrost:IsAvailable() and Player:BuffUp(S.EmpowerRuneWeaponBuff) or not S.PillarofFrost:IsAvailable() and not S.EmpowerRuneWeapon:IsAvailable() or EnemiesMeleeCount >= 2 and Player:BuffUp(S.PillarofFrostBuff)) or FightRemains < 25) then + -- potion,if=(talent.pillar_of_frost&buff.pillar_of_frost.up|!talent.pillar_of_frost&buff.empower_rune_weapon.up|!talent.pillar_of_frost&!talent.empower_rune_weapon|active_enemies>=2&buff.pillar_of_frost.up)|fight_remains<25 + if Settings.Commons.Enabled.Potions and ((S.PillarofFrost:IsAvailable() and Player:BuffUp(S.PillarofFrostBuff) or not S.PillarofFrost:IsAvailable() and Player:BuffUp(S.EmpowerRuneWeaponBuff) or not S.PillarofFrost:IsAvailable() and not S.EmpowerRuneWeapon:IsAvailable() or EnemiesMeleeCount >= 2 and Player:BuffUp(S.PillarofFrostBuff)) or BossFightRemains < 25) then local PotionSelected = Everyone.PotionSelected() if PotionSelected and PotionSelected:IsReady() then if Cast(PotionSelected, nil, Settings.CommonsDS.DisplayStyle.Potions) then return "potion cooldowns 2"; end end end - -- empower_rune_weapon,if=talent.obliteration&!buff.empower_rune_weapon.up&rune<6&((cooldown.pillar_of_frost.remains_expected<7&buff.bloodlust.up)|((active_enemies>=2&(!raid_event.adds.exists|raid_event.adds.exists&raid_event.adds.remains>12)|variable.st_planning)&cooldown.pillar_of_frost.ready))|fight_remains<20 - if S.EmpowerRuneWeapon:IsCastable() and (S.Obliteration:IsAvailable() and Player:BuffDown(S.EmpowerRuneWeaponBuff) and Player:Rune() < 6 and ((S.PillarofFrost:CooldownRemains() < 7 and Player:BloodlustUp()) or ((EnemiesMeleeCount >= 2 or VarSTPlanning) and S.PillarofFrost:CooldownUp())) or FightRemains < 20) then - if Cast(S.EmpowerRuneWeapon, Settings.CommonsOGCD.GCDasOffGCD.EmpowerRuneWeapon) then return "empower_rune_weapon cooldowns 4"; end + -- abomination_limb,if=talent.obliteration&!buff.pillar_of_frost.up&variable.sending_cds|fight_remains<15 + -- abomination_limb,if=!talent.obliteration&variable.sending_cds + -- Note: Combined the lines. + if S.AbominationLimb:IsCastable() and ((S.Obliteration:IsAvailable() and Player:BuffDown(S.PillarofFrostBuff) and VarSendingCDs or BossFightRemains < 15) or (not S.Obliteration:IsAvailable() and VarSendingCDs)) then + if Cast(S.AbominationLimb, nil, Settings.CommonsDS.DisplayStyle.AbominationLimb, not Target:IsInRange(20)) then return "abomination_limb_talent cooldowns 4"; end end - -- empower_rune_weapon,use_off_gcd=1,if=buff.breath_of_sindragosa.up&!buff.empower_rune_weapon.up&((time<10&buff.bloodlust.up)|(runic_power<70&rune<3&(cooldown.breath_of_sindragosa.remains>variable.erw_pooling_time|full_recharge_time<10))) - if S.EmpowerRuneWeapon:IsCastable() and (Player:BuffUp(S.BreathofSindragosa) and Player:BuffDown(S.EmpowerRuneWeaponBuff) and ((HL.CombatTime() < 10 and Player:BloodlustUp()) or (Player:RunicPower() < 70 and Player:Rune() < 3 and (S.BreathofSindragosa:CooldownRemains() > VarERWPoolingTime or S.EmpowerRuneWeapon:FullRechargeTime() < 10)))) then - if Cast(S.EmpowerRuneWeapon, Settings.CommonsOGCD.GCDasOffGCD.EmpowerRuneWeapon) then return "empower_rune_weapon cooldowns 6"; end + -- chill_streak,if=variable.sending_cds&(!talent.arctic_assault|!buff.pillar_of_frost.up) + if S.ChillStreak:IsReady() and (VarSendingCDs and (not S.ArcticAssault:IsAvailable() or Player:BuffDown(S.PillarofFrostBuff))) then + if Cast(S.ChillStreak, Settings.Frost.GCDasOffGCD.ChillStreak, nil, not Target:IsSpellInRange(S.ChillStreak)) then return "chill_streak cooldowns 6"; end end - -- empower_rune_weapon,use_off_gcd=1,if=!talent.breath_of_sindragosa&!talent.obliteration&!buff.empower_rune_weapon.up&rune<5&(cooldown.pillar_of_frost.remains_expected<7|buff.pillar_of_frost.up|!talent.pillar_of_frost) - if S.EmpowerRuneWeapon:IsCastable() and (not S.BreathofSindragosa:IsAvailable() and not S.Obliteration:IsAvailable() and Player:BuffDown(S.EmpowerRuneWeaponBuff) and Player:Rune() < 5 and (S.PillarofFrostBuff:CooldownRemains() < 7 or Player:BuffUp(S.PillarofFrostBuff) or not S.PillarofFrost:IsAvailable())) then - if Cast(S.EmpowerRuneWeapon, Settings.CommonsOGCD.GCDasOffGCD.EmpowerRuneWeapon) then return "empower_rune_weapon cooldowns 8"; end + -- reapers_mark,target_if=first:!debuff.reapers_mark_debuff.up + if S.ReapersMark:IsReady() then + if Everyone.CastCycle(S.ReapersMark, EnemiesMelee, EvaluateCycleReapersMarkCDs, not Target:IsInMeleeRange(5)) then return "reapers_mark cooldowns 8"; end end - -- abomination_limb,if=talent.obliteration&!buff.pillar_of_frost.up&cooldown.pillar_of_frost.remains<3&(variable.adds_remain|variable.st_planning)|fight_remains<15 - if S.AbominationLimb:IsCastable() and (S.Obliteration:IsAvailable() and Player:BuffDown(S.PillarofFrostBuff) and S.PillarofFrost:CooldownRemains() < 3 and (VarAddsRemain or VarSTPlanning) or FightRemains < 15) then - if Cast(S.AbominationLimb, nil, Settings.CommonsDS.DisplayStyle.Signature, not Target:IsInRange(20)) then return "abomination_limb_talent cooldowns 10"; end + -- remorseless_winter,if=variable.rw_buffs&variable.sending_cds&(!talent.arctic_assault|!buff.pillar_of_frost.up) + if S.RemorselessWinter:IsReady() and (VarRWBuffs and VarSendingCDs and (not S.ArcticAssault:IsAvailable() or Player:BuffDown(S.PillarofFrostBuff))) then + if Cast(S.RemorselessWinter, nil, nil, not Target:IsInMeleeRange(8)) then return "remorseless_winter cooldowns 10"; end end - -- abomination_limb,if=talent.breath_of_sindragosa&(variable.adds_remain|variable.st_planning) - if S.AbominationLimb:IsCastable() and (S.BreathofSindragosa:IsAvailable() and (VarAddsRemain or VarSTPlanning)) then - if Cast(S.AbominationLimb, nil, Settings.CommonsDS.DisplayStyle.Signature, not Target:IsInRange(20)) then return "abomination_limb_talent cooldowns 12"; end + -- empower_rune_weapon,if=talent.obliteration&!talent.breath_of_sindragosa&buff.pillar_of_frost.up|fight_remains<20 + if S.EmpowerRuneWeapon:IsCastable() and (S.Obliteration:IsAvailable() and not S.BreathofSindragosa:IsAvailable() and Player:BuffUp(S.PillarofFrostBuff) or BossFightRemains < 20) then + if Cast(S.EmpowerRuneWeapon, Settings.CommonsOGCD.GCDasOffGCD.EmpowerRuneWeapon) then return "empower_rune_weapon cooldowns 12"; end end - -- abomination_limb,if=!talent.breath_of_sindragosa&!talent.obliteration&(variable.adds_remain|variable.st_planning) - if S.AbominationLimb:IsCastable() and (not S.BreathofSindragosa:IsAvailable() and not S.Obliteration:IsAvailable() and (VarAddsRemain or VarSTPlanning)) then - if Cast(S.AbominationLimb, nil, Settings.CommonsDS.DisplayStyle.Signature, not Target:IsInRange(20)) then return "abomination_limb_talent cooldowns 14"; end + -- empower_rune_weapon,if=buff.breath_of_sindragosa.up&runic_power=2&(!death_and_decay.ticking&talent.cleaving_strikes|!talent.cleaving_strikes|active_enemies<=5) - if S.ChillStreak:IsReady() and (not Player:HasTier(31, 2) and EnemiesMeleeCount >= 2 and (Player:BuffDown(S.DeathAndDecayBuff) and S.CleavingStrikes:IsAvailable() or not S.CleavingStrikes:IsAvailable() or EnemiesMeleeCount <= 5)) then - if Cast(S.ChillStreak, Settings.Frost.GCDasOffGCD.ChillStreak, nil, not Target:IsSpellInRange(S.ChillStreak)) then return "chill_streak cooldowns 18"; end + -- pillar_of_frost,if=talent.obliteration&!talent.breath_of_sindragosa&variable.sending_cds|fight_remains<12 + if S.PillarofFrost:IsCastable() and (S.Obliteration:IsAvailable() and not S.BreathofSindragosa:IsAvailable() and VarSendingCDs or BossFightRemains < 12) then + if Cast(S.PillarofFrost, Settings.Frost.GCDasOffGCD.PillarOfFrost) then return "pillar_of_frost cooldowns 18"; end end - -- pillar_of_frost,if=talent.obliteration&(variable.adds_remain|variable.st_planning)&(buff.empower_rune_weapon.up|cooldown.empower_rune_weapon.remains)|fight_remains<12 - if S.PillarofFrost:IsCastable() and (S.Obliteration:IsAvailable() and (VarAddsRemain or VarSTPlanning) and (Player:BuffUp(S.EmpowerRuneWeaponBuff) or S.EmpowerRuneWeapon:CooldownRemains() > 0) or FightRemains < 12) then + -- pillar_of_frost,if=talent.breath_of_sindragosa&variable.sending_cds&(buff.breath_of_sindragosa.up|cooldown.breath_of_sindragosa.remains>cooldown.pillar_of_frost.duration-20)|fight_remains<12 + if S.PillarofFrost:IsCastable() and (S.BreathofSindragosa:IsAvailable() and VarSendingCDs and (Player:BuffUp(S.BreathofSindragosa) or S.BreathofSindragosa:CooldownRemains() > VarPillarCD - 20) or BossFightRemains < 12) then if Cast(S.PillarofFrost, Settings.Frost.GCDasOffGCD.PillarOfFrost) then return "pillar_of_frost cooldowns 20"; end end - -- pillar_of_frost,if=talent.breath_of_sindragosa&(variable.adds_remain|variable.st_planning)&(!talent.icecap&(runic_power>70|cooldown.breath_of_sindragosa.remains>40)|talent.icecap&(cooldown.breath_of_sindragosa.remains>5))|buff.breath_of_sindragosa.up - if S.PillarofFrost:IsCastable() and (S.BreathofSindragosa:IsAvailable() and (VarAddsRemain or VarSTPlanning) and (not S.Icecap:IsAvailable() and (Player:RunicPower() > 70 or S.BreathofSindragosa:CooldownRemains() > 40) or S.Icecap:IsAvailable() and (S.BreathofSindragosa:CooldownRemains() > 5)) or Player:BuffUp(S.BreathofSindragosa)) then + -- pillar_of_frost,if=!talent.obliteration&!talent.breath_of_sindragosa&variable.sending_cds + if S.PillarofFrost:IsCastable() and (not S.Obliteration:IsAvailable() and not S.BreathofSindragosa:IsAvailable() and VarSendingCDs) then if Cast(S.PillarofFrost, Settings.Frost.GCDasOffGCD.PillarOfFrost) then return "pillar_of_frost cooldowns 22"; end end - -- pillar_of_frost,if=talent.icecap&!talent.obliteration&!talent.breath_of_sindragosa&(variable.adds_remain|variable.st_planning) - if S.PillarofFrost:IsCastable() and (S.Icecap:IsAvailable() and not S.Obliteration:IsAvailable() and not S.BreathofSindragosa:IsAvailable() and (VarAddsRemain or VarSTPlanning)) then - if Cast(S.PillarofFrost, Settings.Frost.GCDasOffGCD.PillarOfFrost) then return "pillar_of_frost cooldowns 24"; end + -- breath_of_sindragosa,if=!buff.breath_of_sindragosa.up&cooldown.empower_rune_weapon.remains_expected<15&runic_power>variable.breath_rp_threshold&(variable.adds_remain|variable.st_planning|fight_remains<30) + if S.BreathofSindragosa:IsReady() and (Player:BuffDown(S.BreathofSindragosa) and S.EmpowerRuneWeapon:CooldownRemains() < 15 and Player:RunicPower() > VarBreathRPThreshold and (VarAddsRemain or VarSTPlanning or BossFightRemains < 30)) then + if Cast(S.BreathofSindragosa, Settings.Frost.GCDasOffGCD.BreathOfSindragosa, nil, not Target:IsInRange(12)) then return "breath_of_sindragosa cooldowns 24"; end end - -- breath_of_sindragosa,if=!buff.breath_of_sindragosa.up&(runic_power>50&cooldown.empower_rune_weapon.ready|runic_power>60&cooldown.empower_rune_weapon.remains_expected<30|runic_power>80&cooldown.empower_rune_weapon.remains_expected>30)&(variable.adds_remain|variable.st_planning|fight_remains<30) - if S.BreathofSindragosa:IsReady() and (Player:BuffDown(S.BreathofSindragosa) and (Player:RunicPower() > 50 and S.EmpowerRuneWeapon:CooldownUp() or Player:RunicPower() > 60 and S.EmpowerRuneWeapon:CooldownRemains() < 30 or Player:RunicPower() > 80 and S.EmpowerRuneWeapon:CooldownRemains() > 30) and (VarAddsRemain or VarSTPlanning or FightRemains < 30)) then - if Cast(S.BreathofSindragosa, Settings.Frost.GCDasOffGCD.BreathOfSindragosa, nil, not Target:IsInRange(12)) then return "breath_of_sindragosa cooldowns 26"; end + -- frostwyrms_fury,if=hero_tree.rider_of_the_apocalypse&talent.apocalypse_now&(!talent.breath_of_sindragosa&variable.sending_cds|buff.breath_of_sindragosa.up&buff.pillar_of_frost.up)|fight_remains<20 + if S.FrostwyrmsFury:IsCastable() and (Player:HeroTreeID() == 32 and S.ApocalypseNow:IsAvailable() and (not S.BreathofSindragosa:IsAvailable() and VarSendingCDs or Player:BuffUp(S.BreathofSindragosa) and Player:BuffUp(S.PillarofFrostBuff)) or BossFightRemains < 20) then + if Cast(S.FrostwyrmsFury, Settings.Frost.GCDasOffGCD.FrostwyrmsFury, nil, not Target:IsInRange(40)) then return "frostwyrms_fury cooldowns 26"; end end - -- frostwyrms_fury,if=active_enemies=1&(talent.pillar_of_frost&buff.pillar_of_frost.remains15+raid_event.adds.duration|talent.absolute_zero&raid_event.adds.in>15+raid_event.adds.duration))|fight_remains<3 - if S.FrostwyrmsFury:IsCastable() and (EnemiesMeleeCount == 1 and (S.PillarofFrost:IsAvailable() and Player:BuffRemains(S.PillarofFrostBuff) < Player:GCD() * 2 and Player:BuffUp(S.PillarofFrostBuff) and not S.Obliteration:IsAvailable() or not S.PillarofFrost:IsAvailable()) or FightRemains < 3) then + -- frostwyrms_fury,if=!talent.apocalypse_now&active_enemies=1&(talent.pillar_of_frost&buff.pillar_of_frost.up&!talent.obliteration|!talent.pillar_of_frost)&(!raid_event.adds.exists|(raid_event.adds.in>15+raid_event.adds.duration|talent.absolute_zero&raid_event.adds.in>15+raid_event.adds.duration))|fight_remains<3 + if S.FrostwyrmsFury:IsCastable() and (not S.ApocalypseNow:IsAvailable() and EnemiesMeleeCount == 1 and (S.PillarofFrost:IsAvailable() and Player:BuffUp(S.PillarofFrostBuff) and not S.Obliteration:IsAvailable() or not S.PillarofFrost:IsAvailable()) or BossFightRemains < 3) then if Cast(S.FrostwyrmsFury, Settings.Frost.GCDasOffGCD.FrostwyrmsFury, nil, not Target:IsInRange(40)) then return "frostwyrms_fury cooldowns 28"; end end - -- frostwyrms_fury,if=active_enemies>=2&(talent.pillar_of_frost&buff.pillar_of_frost.up|raid_event.adds.exists&raid_event.adds.up&raid_event.adds.in>cooldown.pillar_of_frost.remains_expected-raid_event.adds.in-raid_event.adds.duration)&(buff.pillar_of_frost.remains= 2 and (S.PillarofFrost:IsAvailable() and Player:BuffUp(S.PillarofFrostBuff)) and (Player:BuffRemains(S.PillarofFrostBuff) < Player:GCD() * 2)) then + -- frostwyrms_fury,if=!talent.apocalypse_now&active_enemies>=2&(talent.pillar_of_frost&buff.pillar_of_frost.up|raid_event.adds.exists&raid_event.adds.up&raid_event.adds.in>cooldown.pillar_of_frost.remains_expected-raid_event.adds.in-raid_event.adds.duration) + if S.FrostwyrmsFury:IsCastable() and (not S.ApocalypseNow:IsAvailable() and EnemiesMeleeCount >= 2 and (S.PillarofFrost:IsAvailable() and Player:BuffUp(S.PillarofFrostBuff))) then if Cast(S.FrostwyrmsFury, Settings.Frost.GCDasOffGCD.FrostwyrmsFury, nil, not Target:IsInRange(40)) then return "frostwyrms_fury cooldowns 30"; end end - -- frostwyrms_fury,if=talent.obliteration&(talent.pillar_of_frost&buff.pillar_of_frost.up&!variable.2h_check|!buff.pillar_of_frost.up&variable.2h_check&cooldown.pillar_of_frost.remains|!talent.pillar_of_frost)&((buff.pillar_of_frost.remains5&target.time_to_pct_35<5&active_enemies<=2&(talent.obliteration&(buff.pillar_of_frost.up&!buff.killing_machine.react&rune>2|!buff.pillar_of_frost.up)|talent.breath_of_sindragosa&(buff.breath_of_sindragosa.up&runic_power>50|!buff.breath_of_sindragosa.up)|!talent.breath_of_sindragosa&!talent.obliteration) - if S.SoulReaper:IsReady() and (FightRemains > 5 and (Target:TimeToX(35) < 5 or Target:HealthPercentage() <= 35) and EnemiesMeleeCount <= 2 and (S.Obliteration:IsAvailable() and (Player:BuffUp(S.PillarofFrostBuff) and Player:BuffDown(S.KillingMachineBuff) and Player:Rune() > 2 or Player:BuffDown(S.PillarofFrostBuff)) or S.BreathofSindragosa:IsAvailable() and (Player:BuffUp(S.BreathofSindragosa) and Player:RunicPower() > 50 or Player:BuffDown(S.BreathofSindragosa)) or not S.BreathofSindragosa:IsAvailable() and not S.Obliteration:IsAvailable())) then + -- soul_reaper,if=fight_remains>5&target.time_to_pct_35<5&target.time_to_pct_0>5&active_enemies<=2&(talent.obliteration&(buff.pillar_of_frost.up&!buff.killing_machine.react&rune>2|!buff.pillar_of_frost.up)|talent.breath_of_sindragosa&(buff.breath_of_sindragosa.up&runic_power>50|!buff.breath_of_sindragosa.up)|!talent.breath_of_sindragosa&!talent.obliteration) + if S.SoulReaper:IsReady() and (FightRemains > 5 and Target:TimeToX(35) < 5 and Target:TimeToX(0) > 5 and EnemiesMeleeCount <= 2 and (S.Obliteration:IsAvailable() and (Player:BuffUp(S.PillarofFrostBuff) and Player:BuffDown(S.KillingMachineBuff) and Player:Rune() > 2 or Player:BuffDown(S.PillarofFrostBuff)) or S.BreathofSindragosa:IsAvailable() and (Player:BuffUp(S.BreathofSindragosa) and Player:RunicPower() > 50 or Player:BuffDown(S.BreathofSindragosa)) or not S.BreathofSindragosa:IsAvailable() and not S.Obliteration:IsAvailable())) then if Cast(S.SoulReaper, nil, nil, not Target:IsInMeleeRange(5)) then return "soul_reaper cooldowns 36"; end end - -- any_dnd,if=!death_and_decay.ticking&variable.adds_remain&(buff.pillar_of_frost.up&buff.pillar_of_frost.remains>5&buff.pillar_of_frost.remains<11|!buff.pillar_of_frost.up&cooldown.pillar_of_frost.remains>10|fight_remains<11)&(active_enemies>5|talent.cleaving_strikes&active_enemies>=2) - if S.DeathAndDecay:IsReady() and (Player:BuffDown(S.DeathAndDecayBuff) and VarAddsRemain and (Player:BuffUp(S.PillarofFrostBuff) and Player:BuffRemains(S.PillarofFrostBuff) > 5 and Player:BuffRemains(S.PillarofFrostBuff) < 11 or Player:BuffDown(S.PillarofFrostBuff) and S.PillarofFrost:CooldownRemains() > 10 or FightRemains < 11) and (EnemiesMeleeCount > 5 or S.CleavingStrikes:IsAvailable() and EnemiesMeleeCount >= 2)) then - if Cast(S.DeathAndDecay, Settings.CommonsOGCD.GCDasOffGCD.DeathAndDecay) then return "death_and_decay cooldowns 38"; end + -- frostscythe,if=!buff.killing_machine.up&(!talent.arctic_assault|!buff.pillar_of_frost.up) + if S.Frostscythe:IsReady() and (Player:BuffDown(S.KillingMachineBuff) and (not S.ArcticAssault:IsAvailable() or Player:BuffDown(S.PillarofFrostBuff))) then + if Cast(S.Frostscythe, nil, nil, not Target:IsInMeleeRange(8)) then return "frostscythe cooldowns 38"; end + end + -- any_dnd,if=!buff.death_and_decay.up&!buff.mograines_might.up&variable.adds_remain&(buff.pillar_of_frost.up&buff.killing_machine.react&(talent.enduring_strength|buff.pillar_of_frost.remains>5)|!buff.pillar_of_frost.up&(cooldown.death_and_decay.charges=2|cooldown.pillar_of_frost.remains>cooldown.death_and_decay.duration)|!talent.the_long_winter&cooldown.pillar_of_frost.remains5|talent.cleaving_strikes&active_enemies>=2) + if S.DeathAndDecay:IsReady() and (Player:BuffDown(S.DeathAndDecayBuff) and Player:BuffDown(S.MograinesMightBuff) and VarAddsRemain and (Player:BuffUp(S.PillarofFrostBuff) and Player:BuffUp(S.KillingMachineBuff) and (S.EnduringStrength:IsAvailable() or Player:BuffRemains(S.PillarofFrostBuff) > 5) or Player:BuffDown(S.PillarofFrostBuff) and (S.DeathAndDecay:Charges() == 2 or S.PillarofFrost:CooldownRemains() > S.DeathAndDecay:Cooldown()) or not S.TheLongWinter:IsAvailable() and S.PillarofFrost:CooldownRemains() < Player:GCD() * 2 or BossFightRemains < 11) and (EnemiesMeleeCount > 5 or S.CleavingStrikes:IsAvailable() and EnemiesMeleeCount >= 2)) then + if Cast(S.DeathAndDecay, Settings.CommonsOGCD.GCDasOffGCD.DeathAndDecay) then return "death_and_decay cooldowns 40"; end end end @@ -392,119 +467,103 @@ local function HighPrioActions() -- Note: Not handling external buffs. -- mind_freeze,if=target.debuff.casting.react local ShouldReturn = Everyone.Interrupt(S.MindFreeze, Settings.CommonsDS.DisplayStyle.Interrupts, StunInterrupts); if ShouldReturn then return ShouldReturn; end - if Settings.Commons.UseAMSAMZOffensively and CDsON() then - -- antimagic_shell,if=runic_power.deficit>40&death_knight.first_ams_cast