local Tinkr, _Bastion = ... ---@type Bastion local Bastion = _Bastion local ProtModule = Bastion.Module:New('paladin_protection') local Player = Bastion.UnitManager:Get('player') local Target = Bastion.UnitManager:Get('target') local None = Bastion.UnitManager:Get('none') local CrusaderAura = Bastion.SpellBook:GetSpell(32223) local DevoAura = Bastion.SpellBook:GetSpell(465) local Consecrate = Bastion.SpellBook:GetSpell(26573) local ConsecrateAura = Bastion.SpellBook:GetSpell(188370) local Judgement = Bastion.SpellBook:GetSpell(275779) local AvengersShield = Bastion.SpellBook:GetSpell(31935) local OfDuskAndDawn = Bastion.SpellBook:GetSpell(385125) local BlessingOfTheDusk = Bastion.SpellBook:GetSpell(385126) local BlessingOfTheDawn = Bastion.SpellBook:GetSpell(337747) local ShieldOfTheRighteous = Bastion.SpellBook:GetSpell(53600) local BlessedHammer = Bastion.SpellBook:GetSpell(204019) local AutoAttack = Bastion.SpellBook:GetSpell(6603) local WoG = Bastion.SpellBook:GetSpell(85673) local ShinningLight = Bastion.SpellBook:GetSpell(327510) local HolyPower = Enum.PowerType.HolyPower ---@type Rebuke local Rebuke = Tinkr:require("scripts/bastion/scripts/paladin/shared/rebuke", Bastion) ---@type HammerOfWrath local HammerOfWrath = Tinkr:require("scripts/bastion/scripts/paladin/shared/hammer-of-wrath", Bastion) local AvengersShieldTarget = Bastion.UnitManager:CreateCustomUnit('avengersshield', function() local target = nil Bastion.UnitManager:EnumEnemies(function(unit) if unit:IsDead() then return false end if not Player:CanSee(unit) then return false end if not Player:IsFacing(unit) then return false end if not AvengersShield:IsInRange(unit) then return false end if unit:IsCastingOrChanneling() then target = unit return true end return false end) if target == nil then if Target:Exists() then target = Target else target = None end end return target end) local WoGTarget = Bastion.UnitManager:CreateCustomUnit('wordofglory', function() if not WoG:IsKnownAndUsable() then return None end local lowest = nil local lowestHP = math.huge Bastion.UnitManager:EnumFriends(function(unit) if unit:IsDead() then return false end if WoG:IsInRange(unit) then return false end if not Player:CanSee(unit) then return false end if not unit:GetHealthPercent() <= 55 then return false end local hp = unit:GetHP() if hp < lowestHP then lowest = unit lowestHP = hp end return false end) if not lowest then lowest = None end return lowest end) ---@return boolean local function CombatRotation() -- Attack the target is auto attack isnt active. if AutoAttack:IsKnownAndUsable() and not IsCurrentSpell(AutoAttack:GetID()) and Player:InMelee(Target) and not Target:IsDead() then AutoAttack:Cast(Target) end -- Kick Rebuke() -- Cast Consecrate if an enemy is in range, and the player isnt moving. if Consecrate:IsKnownAndUsable() and not Player:IsMoving() and not Player:GetAuras():FindMy(ConsecrateAura):IsUp() and Player:GetEnemies(10) >= 1 then return Consecrate:Cast(Player) end if WoG:IsKnownAndUsable() and Player:GetAuras():FindMy(ShinningLight):IsUp() and Player:GetHealthPercent() <= 51 and not Player:IsCastingOrChanneling() then return WoG:Cast(Player) end -- Handle SoR specially if DuskAndDawn is known. if OfDuskAndDawn:IsKnown() then local HpToSor = 3 if Player:GetAuras():FindMy(BlessingOfTheDusk):IsUp() and Player:GetAuras():FindMy(BlessingOfTheDawn):GetRemainingTime() < 9 then HpToSor = 5 end if Player:GetPower(HolyPower) > 3 then HpToSor = 5 end if Player:GetPower(HolyPower) == HpToSor and ShieldOfTheRighteous:IsKnownAndUsable() and ShieldOfTheRighteous:IsInRange(Target) and not Player:IsCastingOrChanneling() then ShieldOfTheRighteous:Cast(Target) end else -- If Dusk And Dawn isnt known, rip SoR normally. if ShieldOfTheRighteous:IsKnownAndUsable() and ShieldOfTheRighteous:IsInRange(Target) and not Player:IsCastingOrChanneling() then ShieldOfTheRighteous:Cast(Target) end end -- Avengers shield with higher prio than Judgement in AOE. Prefer targets that are casting. if Player:GetEnemies(10) > 1 and AvengersShield:IsKnownAndUsable() and AvengersShieldTarget:Exists() then return AvengersShield:Cast(AvengersShieldTarget) end -- Judgement if Judgement:IsKnownAndUsable() and Player:GetPower(HolyPower) < 5 and Target:Exists() and Judgement:IsInRange(Target) then return Judgement:Cast(Target) end -- Hammer of Wrath if HammerOfWrath() then return true end -- Avengers shield with lower prio than Judgement in ST. Prefer targets that are casting. if Player:GetEnemies(10) == 1 and AvengersShield:IsKnownAndUsable() and AvengersShieldTarget:Exists() then return AvengersShield:Cast(AvengersShieldTarget) end -- Blessed Hammer if there are more than 1 enemy in 10 yds. if BlessedHammer:IsKnownAndUsable() and Player:GetPower(HolyPower) < 5 and Player:GetEnemies(10) >= 1 then return BlessedHammer:Cast(Player) end if Player:GetAuras():FindMy(ShinningLight):IsUp() and WoGTarget:Exists() and not Player:IsCastingOrChanneling() then return WoG:Cast(WoGTarget) end -- Refresh Consecrate if we've got nothing else to cast. if Consecrate:IsKnownAndUsable() and Player:GetEnemies(10) >= 1 and not Player:IsMoving() then return Consecrate:Cast(Player) end return false end ---@return boolean local function OutOfCombatRotation() return false end local isRunning = false ProtModule:Sync(function() if not isRunning then Bastion:Print('Prot Paladin Started') isRunning = true end if not Player:IsAlive() then return false end -- Cast Crusader Aura if talented and the player is mounted. if Player:IsMounted() and CrusaderAura:IsKnownAndUsable() and not Player:GetAuras():FindMy(CrusaderAura):IsUp() and not Player:IsCastingOrChanneling() then return CrusaderAura:Cast(Player) end -- Cast Devo Aura if the player is not mounted. if not Player:IsMounted() and DevoAura:IsKnownAndUsable() and not Player:GetAuras():FindMy(DevoAura):IsUp() and not Player:IsCastingOrChanneling() then return DevoAura:Cast(Player) end if Player:IsAffectingCombat() then -- Combat Rotation return CombatRotation() else -- Out Of Combat Rotation return OutOfCombatRotation() end end) Bastion:Register(ProtModule)