---@type _, Bastion local Tinkr, Bastion = ... -- Core local RetributionModule = Bastion.Module:New('retribution') local Evaluator = Tinkr.Util.Evaluator local Time = Bastion.CombatTimer local Notifications = Bastion.Notifications -- Targets local Player = Bastion.UnitManager:Get('player') local None = Bastion.UnitManager:Get('none') local Target = Bastion.UnitManager:Get('target') local RebukeTarget = Bastion.UnitManager:CreateCustomUnit('kick', function() local purge = nil Bastion.UnitManager:EnumEnemies(function(unit) if unit:IsDead() then return false end if not Player:CanSee(unit) then return false end if Player:GetDistance(unit) > 40 then return false end if Player:InMelee(unit) and unit:IsInterruptible(5) and Player:IsFacing(unit) then purge = unit return true end return false end) if purge == nil then purge = None end return purge end) -- Spells local AutoAttack = Bastion.SpellBook:GetSpell(6603) local ForgeOfLight = Bastion.SpellBook:GetSpell(259930) local LightsJudgment = Bastion.SpellBook:GetSpell(255647) local Logging = Bastion.SpellBook:GetSpell(167895) local MobileBanking = Bastion.SpellBook:GetSpell(83958) local OverloadElementalDeposit = Bastion.SpellBook:GetSpell(388213) local ArmorSkills = Bastion.SpellBook:GetSpell(76271) local Demonbane = Bastion.SpellBook:GetSpell(255653) local GuildMail = Bastion.SpellBook:GetSpell(83951) local HastyHearth = Bastion.SpellBook:GetSpell(83944) local HolyResistance = Bastion.SpellBook:GetSpell(255651) local Languages = Bastion.SpellBook:GetSpell(79741) local LightsReckoning = Bastion.SpellBook:GetSpell(255652) local MasterRiding = Bastion.SpellBook:GetSpell(90265) local MountUp = Bastion.SpellBook:GetSpell(78633) local TheQuickandtheDead = Bastion.SpellBook:GetSpell(83950) local WeaponSkills = Bastion.SpellBook:GetSpell(76294) local BlessingOfFreedom = Bastion.SpellBook:GetSpell(1044) local BlessingOfSacrifice = Bastion.SpellBook:GetSpell(6940) local Consecration = Bastion.SpellBook:GetSpell(26573) local CrusaderAura = Bastion.SpellBook:GetSpell(32223) local CrusaderStrike = Bastion.SpellBook:GetSpell(35395) local DivineShield = Bastion.SpellBook:GetSpell(642) local DivineSteed = Bastion.SpellBook:GetSpell(190784) local FlashOfLight = Bastion.SpellBook:GetSpell(19750) local HammerOfJustice = Bastion.SpellBook:GetSpell(853) local HammerOfWrath = Bastion.SpellBook:GetSpell(24275) local HandOfReckoning = Bastion.SpellBook:GetSpell(62124) local Intercession = Bastion.SpellBook:GetSpell(391054) local Judgment = Bastion.SpellBook:GetSpell(20271) local LayonHands = Bastion.SpellBook:GetSpell(633) local Rebuke = Bastion.SpellBook:GetSpell(96231) local Redemption = Bastion.SpellBook:GetSpell(7328) local RetributionAura = Bastion.SpellBook:GetSpell(183435) local SenseUndead = Bastion.SpellBook:GetSpell(5502) local Seraphim = Bastion.SpellBook:GetSpell(152262) local ShieldOftheRighteous = Bastion.SpellBook:GetSpell(53600) local WordOfGlory = Bastion.SpellBook:GetSpell(85673) local AspirationOfDivinity = Bastion.SpellBook:GetSpell(385416) local GoldenPath = Bastion.SpellBook:GetSpell(377128) local Incandescence = Bastion.SpellBook:GetSpell(385464) local OfDuskandDawn = Bastion.SpellBook:GetSpell(385125) local Recompense = Bastion.SpellBook:GetSpell(384914) local ZealotsParagon = Bastion.SpellBook:GetSpell(391142) local BladeOfJustice = Bastion.SpellBook:GetSpell(184575) local Crusade = Bastion.SpellBook:GetSpell(231895) local DivineStorm = Bastion.SpellBook:GetSpell(53385) local DivineToll = Bastion.SpellBook:GetSpell(375576) local Exorcism = Bastion.SpellBook:GetSpell(383185) local FinalReckoning = Bastion.SpellBook:GetSpell(343721) local HandOfHindrance = Bastion.SpellBook:GetSpell(183218) local ShieldOfVengeance = Bastion.SpellBook:GetSpell(184662) local TemplarsVerdict = Bastion.SpellBook:GetSpell(85256) local WakeOfAshes = Bastion.SpellBook:GetSpell(255937) local GreaterJudgment = Bastion.SpellBook:GetSpell(231663) local MasteryHandOfLight = Bastion.SpellBook:GetSpell(267316) local AvengingWrath = Bastion.SpellBook:GetSpell(31884) local ExecutionSentence = Bastion.SpellBook:GetSpell(343527) local HolyAvenger = Bastion.SpellBook:GetSpell(105809) local ExecutionersWrath = Bastion.SpellBook:GetSpell(387196) local RadiantDecree = Bastion.SpellBook:GetSpell(384052) local JusticarsVengeance = Bastion.SpellBook:GetSpell(215661) local DivineResonance = Bastion.SpellBook:GetSpell(384027) local Expurgation = Bastion.SpellBook:GetSpell(383344) local VanguardsMomentum = Bastion.SpellBook:GetSpell(383314) local AshesToDust = Bastion.SpellBook:GetSpell(383300) -- Items local AlgetharPuzzleBox = Bastion.ItemBook:GetItem(193701) local RumblingRuby = Bastion.ItemBook:GetItem(194303) local DecorationOfFlame = Bastion.ItemBook:GetItem(194299) -- Powers local HolyPower = Enum.PowerType.HolyPower -- Velocity local movements = {} local lastX, lastY, lastZ C_Timer.NewTicker(0.1, function() local x, y, z = ObjectPosition('player') if lastX and lastY and lastZ then local distance = math.sqrt((x - lastX) ^ 2 + (y - lastY) ^ 2 + (z - lastZ) ^ 2) table.insert(movements, distance) end if #movements > 20 then table.remove(movements, 1) end lastX, lastY, lastZ = x, y, z end) local function GetAverageVelocity() local total = 0 for _, distance in ipairs(movements) do total = total + distance end return total / #movements end local function IsPlayerMoving() return GetAverageVelocity() >= 0.55 end -- calculate the total distance moved over the last 2 seconds -- APLs local DefaultAPL = Bastion.APL:New('default') local CooldownsAPL = Bastion.APL:New('cooldowns') local FinishersAPL = Bastion.APL:New('finishers') local ESFRPoolingAPL = Bastion.APL:New('es_fr_pooling') local ESFRActiveAPL = Bastion.APL:New('es_fr_active') local GeneratorsAPL = Bastion.APL:New('generators') local function TimeToHPG() return math.max( Player:GetGCD(), math.min( Judgment:IsKnown() and Judgment:GetCooldownRemaining() or 999, CrusaderStrike:IsKnown() and CrusaderStrike:GetCooldownRemaining() or 999, BladeOfJustice:IsKnown() and BladeOfJustice:GetCooldownRemaining() or 999, HammerOfWrath:IsKnown() and HammerOfWrath:GetCooldownRemaining() or 999, WakeOfAshes:IsKnown() and WakeOfAshes:GetCooldownRemaining() or 999, DivineToll:IsKnown() and DivineToll:GetCooldownRemaining() or 999 ) ) end -- actions.cooldowns=potion,if=buff.avenging_wrath.up|buff.crusade.up&buff.crusade.stack=10|fight_remains<25 -- NYI -- actions.cooldowns+=/lights_judgment,if=spell_targets.lights_judgment>=2|!raid_event.adds.exists|raid_event.adds.in>75|raid_event.adds.up CooldownsAPL:AddSpell( LightsJudgment:CastableIf(function() return Target:GetEnemies(8) >= 2 end):SetTarget(Target) ) -- actions.cooldowns+=/use_item,name=algethar_puzzle_box,if=(cooldown.avenging_wrath.remains<5&!talent.crusade|cooldown.crusade.remains<5&talent.crusade)&(holy_power>=5&time<5|holy_power>=3&time>5) -- actions.cooldowns+=/use_item,slot=trinket1,if=(buff.avenging_wrath.up|buff.crusade.up&buff.crusade.stack=10)&(!trinket.2.has_cooldown|trinket.2.cooldown.remains|variable.trinket_priority=1)|trinket.1.proc.any_dps.duration>=fight_remains -- actions.cooldowns+=/use_item,slot=trinket2,if=(buff.avenging_wrath.up|buff.crusade.up&buff.crusade.stack=10)&(!trinket.1.has_cooldown|trinket.1.cooldown.remains|variable.trinket_priority=2)|trinket.2.proc.any_dps.duration>=fight_remains -- actions.cooldowns+=/use_item,slot=trinket1,if=!variable.trinket_1_buffs&(trinket.2.cooldown.remains|!variable.trinket_2_buffs|!buff.crusade.up&cooldown.crusade.remains>20|!buff.avenging_wrath.up&cooldown.avenging_wrath.remains>20) -- actions.cooldowns+=/use_item,slot=trinket2,if=!variable.trinket_2_buffs&(trinket.1.cooldown.remains|!variable.trinket_1_buffs|!buff.crusade.up&cooldown.crusade.remains>20|!buff.avenging_wrath.up&cooldown.avenging_wrath.remains>20) CooldownsAPL:AddItem( DecorationOfFlame:UsableIf(function() local result = Player:GetAuras():FindMy(AvengingWrath):IsUp() or (Player:GetAuras():FindMy(Crusade):IsUp() and Player:GetAuras():FindMy(Crusade):GetCount() == 10) return result end):SetTarget(Player) ) -- actions.cooldowns+=/shield_of_vengeance,if=(!talent.execution_sentence|cooldown.execution_sentence.remains<52)&fight_remains>15 CooldownsAPL:AddSpell( ShieldOfVengeance:CastableIf(function() return not ExecutionSentence:IsKnown() or ExecutionSentence:GetCooldownRemaining() < 52 end):SetTarget(Target) ) -- actions.cooldowns+=/avenging_wrath,if=((holy_power>=4&time<5|holy_power>=3&time>5)|talent.holy_avenger&cooldown.holy_avenger.remains=0)&(!talent.seraphim|!talent.final_reckoning|cooldown.seraphim.remains>0) CooldownsAPL:AddSpell( AvengingWrath:CastableIf(function() return ( Player:GetPower(HolyPower) >= 4 and Time:GetTime() < 5 or Player:GetPower(HolyPower) >= 3 and Time:GetTime() > 5) and (not HolyAvenger:IsKnown() or not FinalReckoning:IsKnown() or Seraphim:GetCooldownRemaining() > 0) end):SetTarget(Player) ) -- actions.cooldowns+=/crusade,if=holy_power>=5&time<5|holy_power>=3&time>5 CooldownsAPL:AddSpell( Crusade:CastableIf(function() return Crusade:GetCooldownRemaining() == 0 and (Player:GetPower(HolyPower) >= 5 and Time:GetTime() < 5 or Player:GetPower(HolyPower) >= 3 and Time:GetTime() > 5) end):SetTarget(Player):OnCast(function(spell) Notifications:AddNotification(spell:GetIcon(), spell:GetName(), 10) end) ) -- actions.cooldowns+=/holy_avenger,if=time_to_hpg=0&holy_power<=2&(buff.avenging_wrath.up|talent.crusade&(cooldown.crusade.remains=0|buff.crusade.up)|fight_remains<20) CooldownsAPL:AddSpell( HolyAvenger:CastableIf(function() return TimeToHPG() == 0 and Player:GetPower(HolyPower) <= 2 and ( Player:GetAuras():FindMy(AvengingWrath):IsUp() or Crusade:IsKnown() and (Crusade:GetCooldownRemaining() == 0 or Player:GetAuras():FindMy(Crusade):IsUp()) or Target:TimeToDie() < 20) end):SetTarget(Player) ) -- actions.cooldowns+=/final_reckoning,if=(holy_power>=4&time<8|holy_power>=3&time>=8)&(cooldown.avenging_wrath.remains>gcd|cooldown.crusade.remains&(!buff.crusade.up|buff.crusade.stack>=10))&(time_to_hpg>0|holy_power=5)&(!talent.seraphim|buff.seraphim.up)&(!raid_event.adds.exists|raid_event.adds.up|raid_event.adds.in>40)&(!buff.avenging_wrath.up|holy_power=5|cooldown.hammer_of_wrath.remains) CooldownsAPL:AddSpell( FinalReckoning:CastableIf(function() return (Player:GetPower(HolyPower) >= 4 and Time:GetTime() < 8 or Player:GetPower(HolyPower) >= 3 and Time:GetTime() >= 8) and (AvengingWrath:GetCooldownRemaining() > Player:GetGCD() or Crusade:GetCooldownRemaining() > 0 and (not Player:GetAuras():FindMy(Crusade):IsUp() or Player:GetAuras():FindMy(Crusade):GetCount() >= 10)) and (TimeToHPG() > 0 or Player:GetPower(HolyPower) == 5) and (not Seraphim:IsKnown() or Player:GetAuras():FindMy(Seraphim):IsUp()) and (not Player:GetAuras():FindMy(AvengingWrath):IsUp() or Player:GetPower(HolyPower) == 5 or HammerOfWrath:GetCooldownRemaining() > 0) end):SetTarget(None):OnCast(function(self) self:Click(Target:GetPosition()) end) ) -- actions.finishers=variable,name=ds_castable,value=spell_targets.divine_storm>=2|buff.empyrean_power.up&!debuff.judgment.up&!buff.divine_purpose.up|buff.crusade.up&buff.crusade.stack<10&buff.empyrean_legacy.up&!talent.justicars_vengeance FinishersAPL:AddVariable( 'ds_castable', function() return Player:GetEnemies(8) >= 2 and Player:InMelee(Target) end ) -- actions.finishers+=/seraphim,if= -- ( -- cooldown.avenging_wrath.remains > 15 | cooldown.crusade.remains > 15 -- ) & -- !talent.final_reckoning & -- ( -- !talent.execution_sentence | spell_targets.divine_storm >= 5 -- ) & -- fight_remains < 15 & fight_remains > 5 | buff.crusade.up & buff.crusade.stack < 10 FinishersAPL:AddSpell( Seraphim:CastableIf(function() return (AvengingWrath:GetCooldownRemaining() > 15 or Crusade:GetCooldownRemaining() > 15) and not FinalReckoning:IsKnown() and (not ExecutionSentence:IsKnown() or Player:GetEnemies(8) >= 5) and Target:TimeToDie() < 15 and Target:TimeToDie() > 5 or Player:GetAuras():FindMy(Crusade):IsUp() and Player:GetAuras():FindMy(Crusade):GetCount() < 10 end):SetTarget(Player) ) -- actions.finishers+=/execution_sentence,if=(buff.crusade.down&cooldown.crusade.remains>10|buff.crusade.stack>=3|cooldown.avenging_wrath.remains>10)&(!talent.final_reckoning|cooldown.final_reckoning.remains>10)&target.time_to_die>8&(spell_targets.divine_storm<5|talent.executioners_wrath) FinishersAPL:AddSpell( ExecutionSentence:CastableIf(function() return (not Player:GetAuras():FindMy(Crusade):IsUp() and Crusade:GetCooldownRemaining() > 10 or Player:GetAuras():FindMy(Crusade):GetCount() >= 3 or AvengingWrath:GetCooldownRemaining() > 10) and (not FinalReckoning:IsKnown() or FinalReckoning:GetCooldownRemaining() > 10) and Target:TimeToDie() > 8 and (Target:GetEnemies(8) < 5 or ExecutionersWrath:IsKnown()) end):SetTarget(Target) ) -- actions.finishers+=/radiant_decree,if=(buff.crusade.down&cooldown.crusade.remains>5|buff.crusade.stack>=3|cooldown.avenging_wrath.remains>5)&(!talent.final_reckoning|cooldown.final_reckoning.remains>5) FinishersAPL:AddSpell( RadiantDecree:CastableIf(function() return (not Player:GetAuras():FindMy(Crusade):IsUp() and Crusade:GetCooldownRemaining() > 5 or Player:GetAuras():FindMy(Crusade):GetCount() >= 3 or AvengingWrath:GetCooldownRemaining() > 5) and (not FinalReckoning:IsKnown() or FinalReckoning:GetCooldownRemaining() > 5) end):SetTarget(Target) ) -- actions.finishers+=/divine_storm,if= -- variable.ds_castable & -- ( -- buff.crusade.up & buff.crusade.stack < 10 -- ) & ( -- ( -- !talent.crusade | cooldown.crusade.remains > gcd * 3 -- ) & -- ( -- !talent.execution_sentence | cooldown.execution_sentence.remains > gcd * 6 |cooldown.execution_sentence.remains > gcd* 4 & holy_power >= 4 | target.time_to_die < 8 | spell_targets.divine_storm >= 5 | !talent.seraphim & cooldown.execution_sentence.remains > gcd * 2 -- ) &( -- !talent.final_reckoning | cooldown.final_reckoning.remains>gcd * 6 | cooldown.final_reckoning.remains > gcd * 4 & holy_power >= 4 | !talent.seraphim & cooldown.final_reckoning.remains > gcd * 2 -- ) | -- talent.holy_avenger & cooldown.holy_avenger.remains < gcd * 3 | buff.holy_avenger.up | buff.crusade.up & buff.crusade.stack < 10 -- ) FinishersAPL:AddSpell( DivineStorm:CastableIf(function() return FinishersAPL:GetVariable('ds_castable') and (Player:GetAuras():FindMy(Crusade):IsUp() and Player:GetAuras():FindMy(Crusade):GetCount() < 10) and (not Crusade:IsKnown() or Crusade:GetCooldownRemaining() > 3) and (not ExecutionSentence:IsKnown() or ExecutionSentence:GetCooldownRemaining() > 6 or ExecutionSentence:GetCooldownRemaining() > 4 and Player:GetPower(HolyPower) >= 4 or Target:TimeToDie() < 8 or Target:GetEnemies(8) >= 5 or not Seraphim:IsKnown() and ExecutionSentence:GetCooldownRemaining() > 2) and (not FinalReckoning:IsKnown() or FinalReckoning:GetCooldownRemaining() > 6 or FinalReckoning:GetCooldownRemaining() > 4 and Player:GetPower(HolyPower) >= 4 or not Seraphim:IsKnown() and FinalReckoning:GetCooldownRemaining() > 2) or HolyAvenger:IsKnown() and HolyAvenger:GetCooldownRemaining() < 3 or Player:GetAuras():FindMy(HolyAvenger):IsUp() or Player:GetAuras():FindMy(Crusade):IsUp() and Player:GetAuras():FindMy(Crusade):GetCount() < 10 end):SetTarget(Target) ) -- actions.finishers+=/justicars_vengeance,if= -- (!talent.crusade | cooldown.crusade.remains > gcd*3 ) & -- (!talent.execution_sentence | cooldown.execution_sentence.remains > gcd*6 | cooldown.execution_sentence.remains > gcd * 4 & holy_power >= 4 | target.time_to_die < 8 | !talent.seraphim & cooldown.execution_sentence.remains > gcd * 2 ) & -- (!talent.final_reckoning | cooldown.final_reckoning.remains > gcd* 6 | cooldown.final_reckoning.remains > gcd * 4 & holy_power >= 4 | !talent.seraphim & cooldown.final_reckoning.remains > gcd * 2) | -- talent.holy_avenger & cooldown.holy_avenger.remains < gcd*3 | buff.holy_avenger.up | buff.crusade.up & buff.crusade.stack < 10 FinishersAPL:AddSpell( JusticarsVengeance:CastableIf(function() local a = (not Crusade:IsKnown() or Crusade:GetCooldownRemaining() > Player:GetGCD() * 3) local b = ( not ExecutionSentence:IsKnown() or ExecutionSentence:GetCooldownRemaining() > Player:GetGCD() * 6 or ExecutionSentence:GetCooldownRemaining() > Player:GetGCD() * 4 and Player:GetPower(HolyPower) >= 4 or Target:TimeToDie() < 8 or not Seraphim:IsKnown() and ExecutionSentence:GetCooldownRemaining() > Player:GetGCD() * 2) local c = not FinalReckoning:IsKnown() or ( FinalReckoning:GetCooldownRemaining() > Player:GetGCD() * 6 or FinalReckoning:GetCooldownRemaining() > Player:GetGCD() * 4 and Player:GetPower(HolyPower) >= 4 or not Seraphim:IsKnown() and FinalReckoning:GetCooldownRemaining() > Player:GetGCD() * 2) local d = HolyAvenger:IsKnown() and HolyAvenger:GetCooldownRemaining() < Player:GetGCD() * 3 or Player:GetAuras():FindMy(HolyAvenger):IsUp() or Player:GetAuras():FindMy(Crusade):IsUp() and Player:GetAuras():FindMy(Crusade):GetCount() < 10 local result = (a and b and c) or d return result end):SetTarget(Target) ) -- actions.finishers+=/templars_verdict,if=(!talent.crusade|cooldown.crusade.remains>gcd*3)&(!talent.execution_sentence|cooldown.execution_sentence.remains>gcd*6|cooldown.execution_sentence.remains>gcd*4&holy_power>=4|target.time_to_die<8|!talent.seraphim&cooldown.execution_sentence.remains>gcd*2)&(!talent.final_reckoning|cooldown.final_reckoning.remains>gcd*6|cooldown.final_reckoning.remains>gcd*4&holy_power>=4|!talent.seraphim&cooldown.final_reckoning.remains>gcd*2)|talent.holy_avenger&cooldown.holy_avenger.remains 3) and (not ExecutionSentence:IsKnown() or ExecutionSentence:GetCooldownRemaining() > 6 or ExecutionSentence:GetCooldownRemaining() > 4 and Player:GetPower(HolyPower) >= 4 or Target:TimeToDie() < 8 or not Seraphim:IsKnown() and ExecutionSentence:GetCooldownRemaining() > 2) and (not FinalReckoning:IsKnown() or FinalReckoning:GetCooldownRemaining() > 6 or FinalReckoning:GetCooldownRemaining() > 4 and Player:GetPower(HolyPower) >= 4 or not Seraphim:IsKnown() and FinalReckoning:GetCooldownRemaining() > 2) or HolyAvenger:IsKnown() and HolyAvenger:GetCooldownRemaining() < 3 or Player:GetAuras():FindMy(HolyAvenger):IsUp() or Player:GetAuras():FindMy(Crusade):IsUp() and Player:GetAuras():FindMy(Crusade):GetCount() < 10 end):SetTarget(Target) ) -- actions.es_fr_active+=/call_action_list,name=finishers,if= -- holy_power=5 | debuff.judgment.up | debuff.final_reckoning.up & -- (debuff.final_reckoning.remains < gcd.max | spell_targets.divine_storm >= 2 & !talent.execution_sentence) | -- debuff.execution_sentence.up & debuff.execution_sentence.remains < gcd.max ESFRActiveAPL:AddAPL( FinishersAPL, function() return Player:GetPower(HolyPower) == 5 or Target:GetAuras():Find(Judgment):IsUp() or Target:GetAuras():Find(FinalReckoning):IsUp() and ( Target:GetAuras():Find(FinalReckoning):GetRemainingTime() < Player:GetMaxGCD() or Player:GetEnemies(8) >= 2 and not ExecutionSentence:IsKnown() ) or Target:GetAuras():Find(ExecutionSentence):IsUp() and Target:GetAuras():Find(ExecutionSentence):GetRemainingTime() < Player:GetMaxGCD() end ) -- actions.es_fr_active+=/divine_toll,if=holy_power<=2 ESFRActiveAPL:AddSpell( DivineToll:CastableIf(function() return Player:GetPower(HolyPower) <= 2 end):SetTarget(Player) ) -- actions.es_fr_active+=/wake_of_ashes,if=holy_power<=2&(debuff.final_reckoning.up&debuff.final_reckoning.remains=5&talent.divine_resonance&talent.execution_sentence) ESFRActiveAPL:AddSpell( WakeOfAshes:CastableIf(function() return Player:GetPower(HolyPower) <= 2 and ( Target:GetAuras():Find(FinalReckoning):IsUp() and Target:GetAuras():Find(FinalReckoning):GetRemainingTime() < Player:GetGCD() * 2 and not DivineResonance:IsKnown() or Target:GetAuras():Find(ExecutionSentence):IsUp() and Target:GetAuras():Find(ExecutionSentence):GetRemainingTime() < Player:GetGCD() or Target:GetEnemies(8) >= 5 and DivineResonance:IsKnown() and ExecutionSentence:IsKnown() ) end):SetTarget(Target) ) -- actions.es_fr_active+=/blade_of_justice,if=talent.expurgation&(!talent.divine_resonance&holy_power<=3|holy_power<=2) ESFRActiveAPL:AddSpell( BladeOfJustice:CastableIf(function() return Expurgation:IsKnown() and (not DivineResonance:IsKnown() and Player:GetPower(HolyPower) <= 3 or Player:GetPower(HolyPower) <= 2) end):SetTarget(Target) ) -- actions.es_fr_active+=/judgment,if=!debuff.judgment.up&holy_power>=2 ESFRActiveAPL:AddSpell( Judgment:CastableIf(function() return not Target:GetAuras():Find(Judgment):IsUp() and Player:GetPower(HolyPower) >= 2 end):SetTarget(Target) ) -- actions.es_fr_active+=/call_action_list,name=finishers ESFRActiveAPL:AddAPL( FinishersAPL, function() return true end ) -- actions.es_fr_active+=/wake_of_ashes,if=holy_power<=2 ESFRActiveAPL:AddSpell( WakeOfAshes:CastableIf(function() return Player:GetPower(HolyPower) <= 2 end):SetTarget(Target) ) -- actions.es_fr_active+=/blade_of_justice,if=holy_power<=3 ESFRActiveAPL:AddSpell( BladeOfJustice:CastableIf(function() return Player:GetPower(HolyPower) <= 3 end):SetTarget(Target) ) -- actions.es_fr_active+=/judgment,if=!debuff.judgment.up ESFRActiveAPL:AddSpell( Judgment:CastableIf(function() return not Target:GetAuras():Find(Judgment):IsUp() end):SetTarget(Target) ) -- actions.es_fr_active+=/hammer_of_wrath ESFRActiveAPL:AddSpell( HammerOfWrath:CastableIf(function() return HammerOfWrath:IsKnownAndUsable() end):SetTarget(Target) ) -- actions.es_fr_active+=/crusader_strike ESFRActiveAPL:AddSpell( CrusaderStrike:CastableIf(function() return CrusaderStrike:IsKnownAndUsable() end):SetTarget(Target) ) -- actions.es_fr_active+=/arcane_torrent -- NYI -- actions.es_fr_active+=/exorcism ESFRActiveAPL:AddSpell( Exorcism:CastableIf(function() return Exorcism:IsKnownAndUsable() end):SetTarget(Target) ) -- actions.es_fr_active+=/consecration ESFRActiveAPL:AddSpell( Consecration:CastableIf(function() return Consecration:IsKnownAndUsable() and not IsPlayerMoving() end):SetTarget(Target) ) -- actions.es_fr_pooling=seraphim,if=holy_power=5&(!talent.final_reckoning|cooldown.final_reckoning.remains<=gcd*3)&(!talent.execution_sentence|cooldown.execution_sentence.remains<=gcd*3|talent.final_reckoning) ESFRPoolingAPL:AddSpell( Seraphim:CastableIf(function() return Player:GetPower(HolyPower) == 5 and (not FinalReckoning:IsKnown() or FinalReckoning:GetCooldownRemaining() <= Player:GetGCD() * 3) and ( not ExecutionSentence:IsKnown() or ExecutionSentence:GetCooldownRemaining() <= Player:GetGCD() * 3 or FinalReckoning:IsKnown()) end):SetTarget(Target) ) -- actions.es_fr_pooling+=/call_action_list,name=finishers,if=holy_power=5|debuff.final_reckoning.up|buff.crusade.up&buff.crusade.stack<10 ESFRPoolingAPL:AddAPL( FinishersAPL, function() return Player:GetPower(HolyPower) == 5 or Target:GetAuras():Find(FinalReckoning):IsUp() or Player:GetAuras():FindMy(Crusade):IsUp() and Player:GetAuras():FindMy(Crusade):GetCount() < 10 end ) -- actions.es_fr_pooling+=/hammer_of_wrath,if=talent.vanguards_momentum ESFRPoolingAPL:AddSpell( HammerOfWrath:CastableIf(function() return VanguardsMomentum:IsKnown() end):SetTarget(Target) ) -- actions.es_fr_pooling+=/wake_of_ashes,if=holy_power<=2&talent.ashes_to_dust&(cooldown.crusade.remains|cooldown.avenging_wrath.remains) ESFRPoolingAPL:AddSpell( WakeOfAshes:CastableIf(function() return Player:GetPower(HolyPower) <= 2 and AshesToDust:IsKnown() and (Crusade:GetCooldownRemaining() > 0 or AvengingWrath:GetCooldownRemaining() > 0) end):SetTarget(Target) ) -- actions.es_fr_pooling+=/blade_of_justice,if=holy_power<=3 ESFRPoolingAPL:AddSpell( BladeOfJustice:CastableIf(function() return Player:GetPower(HolyPower) <= 3 end):SetTarget(Target) ) -- actions.es_fr_pooling+=/judgment,if=!debuff.judgment.up ESFRPoolingAPL:AddSpell( Judgment:CastableIf(function() return not Target:GetAuras():Find(Judgment):IsUp() end):SetTarget(Target) ) -- actions.es_fr_pooling+=/hammer_of_wrath ESFRPoolingAPL:AddSpell( HammerOfWrath:CastableIf(function() return HammerOfWrath:IsKnownAndUsable() end):SetTarget(Target) ) -- actions.es_fr_pooling+=/crusader_strike,if=cooldown.crusader_strike.charges_fractional>=1.75&(holy_power<=2|holy_power<=3&cooldown.blade_of_justice.remains>gcd*2|holy_power=4&cooldown.blade_of_justice.remains>gcd*2&cooldown.judgment.remains>gcd*2) ESFRPoolingAPL:AddSpell( CrusaderStrike:CastableIf(function() return CrusaderStrike:GetChargesFractional() >= 1.75 and (Player:GetPower(HolyPower) <= 2 or Player:GetPower(HolyPower) <= 3 and BladeOfJustice:GetCooldownRemaining() > Player:GetGCD() * 2 or Player:GetPower(HolyPower) == 4 and BladeOfJustice:GetCooldownRemaining() > Player:GetGCD() * 2 and Judgment:GetCooldownRemaining() > Player:GetGCD() * 2) end):SetTarget(Target) ) -- actions.es_fr_pooling+=/seraphim,if=!talent.final_reckoning&cooldown.execution_sentence.remains<=gcd*3 ESFRPoolingAPL:AddSpell( Seraphim:CastableIf(function() return not FinalReckoning:IsKnown() and ExecutionSentence:GetCooldownRemaining() <= Player:GetGCD() * 3 end):SetTarget(Target) ) -- actions.es_fr_pooling+=/call_action_list,name=finishers ESFRPoolingAPL:AddAPL( FinishersAPL, function() return true end ) -- actions.es_fr_pooling+=/crusader_strike ESFRPoolingAPL:AddSpell( CrusaderStrike:CastableIf(function() return CrusaderStrike:IsKnownAndUsable() end):SetTarget(Target) ) -- actions.es_fr_pooling+=/arcane_torrent,if=holy_power<=4 -- NYI -- actions.es_fr_pooling+=/exorcism ESFRPoolingAPL:AddSpell( Exorcism:CastableIf(function() return Exorcism:IsKnownAndUsable() end):SetTarget(Target) ) -- actions.es_fr_pooling+=/seraphim,if= -- ( -- !talent.final_reckoning | cooldown.final_reckoning.remains <= gcd * 3 -- ) & ( -- !talent.execution_sentence | cooldown.execution_sentence.remains <= gcd * 3 | talent.final_reckoning -- ) ESFRPoolingAPL:AddSpell( Seraphim:CastableIf(function() return (not FinalReckoning:IsKnown() or FinalReckoning:GetCooldownRemaining() <= Player:GetGCD() * 3) and (not ExecutionSentence:IsKnown() or ExecutionSentence:GetCooldownRemaining() <= Player:GetGCD() * 3 or FinalReckoning:IsKnown()) end):SetTarget(Target) ) -- actions.es_fr_pooling+=/consecration ESFRPoolingAPL:AddSpell( Consecration:CastableIf(function() return Consecration:IsKnownAndUsable() end):SetTarget(Target) ) -- actions.generators=call_action_list,name=finishers,if=holy_power=5|(debuff.judgment.up|holy_power=4)&buff.divine_resonance.up|buff.holy_avenger.up GeneratorsAPL:AddAPL( FinishersAPL, function() return Player:GetPower(HolyPower) == 5 or (Target:GetAuras():Find(Judgment):IsUp() or Player:GetPower(HolyPower) == 4) and Player:GetAuras():FindMy(DivineResonance):IsUp() or Player:GetAuras():FindMy(HolyAvenger):IsUp() end ) -- actions.generators+=/hammer_of_wrath,if=talent.zealots_paragon GeneratorsAPL:AddSpell( HammerOfWrath:CastableIf(function() return ZealotsParagon:IsKnown() end):SetTarget(Target) ) -- actions.generators+=/wake_of_ashes,if=holy_power<=2&talent.ashes_to_dust&(cooldown.avenging_wrath.remains|cooldown.crusade.remains) GeneratorsAPL:AddSpell( WakeOfAshes:CastableIf(function() return Player:GetPower(HolyPower) <= 2 and AshesToDust:IsKnown() and (AvengingWrath:GetCooldownRemaining() > 0 or Crusade:GetCooldownRemaining() > 0) end):SetTarget(Target) ) -- actions.generators+=/divine_toll,if= -- holy_power <= 2 & -- !debuff.judgment.up & -- ( -- !talent.seraphim | buff.seraphim.up -- ) & -- !talent.final_reckoning & -- (!talent.execution_sentence | fight_remains < 8 | spell_targets.divine_storm >= 5 ) & -- (cooldown.avenging_wrath.remains > 15 | cooldown.crusade.remains > 15 | fight_remains < 8) GeneratorsAPL:AddSpell( DivineToll:CastableIf(function() local a = Player:GetPower(HolyPower) <= 2 local b = Target:GetAuras():Find(Judgment):IsDown() local c = (not Seraphim:IsKnown() or Player:GetAuras():FindMy(Seraphim):IsUp()) local d = not FinalReckoning:IsKnown() local e = (not ExecutionSentence:IsKnown() or Target:TimeToDie() < 8 or Player:GetEnemies(8) >= 5) local f = ( AvengingWrath:GetCooldownRemaining() > 15 or Crusade:GetCooldownRemaining() > 15 or Target:TimeToDie() < 8) return a and b and c and e and f end):SetTarget(Player) ) -- actions.generators+=/judgment,if=!debuff.judgment.up&holy_power>=2 GeneratorsAPL:AddSpell( Judgment:CastableIf(function() return Target:GetAuras():Find(Judgment):IsDown() and Player:GetPower(HolyPower) >= 2 end):SetTarget(Target) ) -- actions.generators+=/wake_of_ashes,if=(holy_power=0|holy_power<=2&cooldown.blade_of_justice.remains>gcd*2)&(!raid_event.adds.exists|raid_event.adds.in>20|raid_event.adds.up)&(!talent.seraphim|cooldown.seraphim.remains>5)&(!talent.execution_sentence|cooldown.execution_sentence.remains>15|target.time_to_die<8|spell_targets.divine_storm>=5)&(!talent.final_reckoning|cooldown.final_reckoning.remains>15|fight_remains<8)&(cooldown.avenging_wrath.remains|cooldown.crusade.remains) GeneratorsAPL:AddSpell( WakeOfAshes:CastableIf(function() return (Player:GetPower(HolyPower) == 0 or Player:GetPower(HolyPower) <= 2 and BladeOfJustice:GetCooldownRemaining() > Player:GetGCD() * 2) and (not Seraphim:IsKnown() or Seraphim:GetCooldownRemaining() > 5) and (not ExecutionSentence:IsKnown() or ExecutionSentence:GetCooldownRemaining() > 15 or Target:TimeToDie() < 8 or Player:GetEnemies():GetCount() >= 5) and (not FinalReckoning:IsKnown() or FinalReckoning:GetCooldownRemaining() > 15 or Target:TimeToDie() < 8) and (AvengingWrath:GetCooldownRemaining() > 0 or Crusade:GetCooldownRemaining() > 0) end):SetTarget(Target) ) -- actions.generators+=/call_action_list,name=finishers,if=holy_power>=3&buff.crusade.up&buff.crusade.stack<10 GeneratorsAPL:AddAPL( FinishersAPL, function() return Player:GetPower(HolyPower) >= 3 and Player:GetAuras():FindMy(Crusade):IsUp() and Player:GetAuras():FindMy(Crusade):GetCount() < 10 end ) -- actions.generators+=/exorcism GeneratorsAPL:AddSpell( Exorcism:CastableIf(function() return Exorcism:IsKnownAndUsable() end):SetTarget(Target) ) -- actions.generators+=/judgment,if=!debuff.judgment.up GeneratorsAPL:AddSpell( Judgment:CastableIf(function() return Target:GetAuras():Find(Judgment):IsDown() end):SetTarget(Target) ) -- actions.generators+=/hammer_of_wrath GeneratorsAPL:AddSpell( HammerOfWrath:CastableIf(function() return HammerOfWrath:IsKnownAndUsable() end):SetTarget(Target) ) -- actions.generators+=/blade_of_justice,if=holy_power<=3 GeneratorsAPL:AddSpell( BladeOfJustice:CastableIf(function() return Player:GetPower(HolyPower) <= 3 end):SetTarget(Target) ) -- actions.generators+=/call_action_list,name=finishers,if=(target.health.pct<=20|buff.avenging_wrath.up|buff.crusade.up|buff.empyrean_power.up) GeneratorsAPL:AddAPL( FinishersAPL, function() return Target:GetHealthPercent() <= 20 or Player:GetAuras():FindMy(AvengingWrath):IsUp() or Player:GetAuras():FindMy(Crusade):IsUp() end ) -- actions.generators+=/consecration,if=!consecration.up&spell_targets.divine_storm>=2 GeneratorsAPL:AddSpell( Consecration:CastableIf(function() return Consecration:IsKnownAndUsable() and Player:GetEnemies(8) >= 2 end):SetTarget(Target) ) -- actions.generators+=/crusader_strike,if=cooldown.crusader_strike.charges_fractional>=1.75&(holy_power<=2|holy_power<=3&cooldown.blade_of_justice.remains>gcd*2|holy_power=4&cooldown.blade_of_justice.remains>gcd*2&cooldown.judgment.remains>gcd*2) GeneratorsAPL:AddSpell( CrusaderStrike:CastableIf(function() return CrusaderStrike:IsKnownAndUsable() and CrusaderStrike:GetChargesFractional() >= 1.75 and (Player:GetPower(HolyPower) <= 2 or Player:GetPower(HolyPower) <= 3 and BladeOfJustice:GetCooldownRemaining() > Player:GetGCD() * 2 or Player:GetPower(HolyPower) == 4 and BladeOfJustice:GetCooldownRemaining() > Player:GetGCD() * 2 and Judgment:GetCooldownRemaining() > Player:GetGCD() * 2) end):SetTarget(Target) ) -- actions.generators+=/call_action_list,name=finishers GeneratorsAPL:AddAPL( FinishersAPL, function() return true end ) -- actions.generators+=/consecration,if=!consecration.up GeneratorsAPL:AddSpell( Consecration:CastableIf(function() return Player:GetAuras():FindMy(Consecration):IsDown() end):SetTarget(Target) ) -- actions.generators+=/crusader_strike GeneratorsAPL:AddSpell( CrusaderStrike:CastableIf(function() return CrusaderStrike:IsKnownAndUsable() end):SetTarget(Target) ) -- actions.generators+=/arcane_torrent -- NYI -- actions.generators+=/consecration GeneratorsAPL:AddSpell( Consecration:CastableIf(function() return Consecration:IsKnownAndUsable() end):SetTarget(Target) ) -- actions=auto_attack -- NYI -- actions+=/rebuke DefaultAPL:AddSpell( Rebuke:CastableIf(function(self) return RebukeTarget:Exists() and Player:InMelee(RebukeTarget) and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() end):SetTarget(RebukeTarget):OnCast(function(spell) Notifications:AddNotification(spell:GetIcon(), spell:GetName()) end) ) -- actions+=/call_action_list,name=cooldowns DefaultAPL:AddAPL( CooldownsAPL, function() return true end ) -- actions+=/call_action_list,name=es_fr_pooling,if=(talent.execution_sentence&cooldown.execution_sentence.remains<9&spell_targets.divine_storm<5|talent.final_reckoning&cooldown.final_reckoning.remains<9)&(!buff.crusade.up|buff.crusade.stack=10)&target.time_to_die>8 DefaultAPL:AddAPL( ESFRPoolingAPL, function() return ExecutionSentence:IsKnown() and ExecutionSentence:GetCooldownRemaining() < 9 and Target:GetEnemies(8) < 5 or FinalReckoning:IsKnown() and FinalReckoning:GetCooldownRemaining() < 9 and (not Player:GetAuras():FindMy(Crusade):IsUp() or Player:GetAuras():FindMy(Crusade):GetCount() == 10) and Target:TimeToDie() > 8 end ) -- actions+=/call_action_list,name=es_fr_active,if=debuff.execution_sentence.up|debuff.final_reckoning.up DefaultAPL:AddAPL( ESFRActiveAPL, function() return Target:GetAuras():Find(ExecutionSentence):IsUp() or Target:GetAuras():Find(FinalReckoning):IsUp() end ) -- actions+=/call_action_list,name=generators DefaultAPL:AddAPL( GeneratorsAPL, function() return true end ) local notified = false RetributionModule:Sync(function() if Player:IsAffectingCombat() and not IsMounted() then DefaultAPL:Execute() end end) Bastion:Register(RetributionModule)