Protection Paladin Rotation Enhancements

Changes:
- Added new spells: HandOfReckoning, EyeOfTyr, DivineSteed, and Rebuke.
- Introduced helper functions: GetEnemiesInRange(range) and GetLowestThreatEnemy().
- Added new APLs for Interrupt and Threat Management.
- Enhanced main rotation logic with dynamic target selection and threat management.
- Defensive APL improvements, including the addition of EyeOfTyr for damage reduction.

Improvements:
- Incorporated range checks (IsWithinCombatDistance) for more accurate spell casting.
- Improved HammerOfWrath conditions for better usage based on target health and active buffs.
- Optimized Default APL for better resource management and cooldown handling.

Bug Fixes:
- Fixed target selection issues when current target is dead or out of range.
- Improved performance by refining spell casting logic and target selection.

Miscellaneous:
- Added mount detection to pause rotation while mounted.
- Enhanced code structure, readability, and added more comments for better understanding.
main
Emlembow 5 months ago
parent deb58bc7a7
commit de2e88029e
  1. BIN
      .DS_Store
  2. 145
      ProtPaladin.lua

BIN
.DS_Store vendored

Binary file not shown.

@ -10,120 +10,183 @@ local ShieldOfTheRighteous = SpellBook:GetSpell(53600)
local Judgment = SpellBook:GetSpell(275779)
local HammerOfWrath = SpellBook:GetSpell(24275)
local AvengersShield = SpellBook:GetSpell(31935)
local HammerOfTheRighteous = SpellBook:GetSpell(53595)
local BlessedHammer = SpellBook:GetSpell(204019)
local WordOfGlory = SpellBook:GetSpell(85673)
local GuardianOfAncientKings = SpellBook:GetSpell(86659)
local ArdentDefender = SpellBook:GetSpell(31850)
local AvengingWrath = SpellBook:GetSpell(31884)
local LayOnHands = SpellBook:GetSpell(633)
local DivineShield = SpellBook:GetSpell(642)
local HandOfReckoning = SpellBook:GetSpell(62124)
local EyeOfTyr = SpellBook:GetSpell(387174)
local DivineSteed = SpellBook:GetSpell(190784)
local Rebuke = SpellBook:GetSpell(96231)
-- Buffs
local ConsecrationBuff = SpellBook:GetSpell(188370)
local ShiningLightBuff = SpellBook:GetSpell(327510)
-- Helper Functions
local function GetEnemiesInRange(range)
local count = 0
Bastion.UnitManager:EnumEnemies(function(unit)
if unit:GetDistance(Player) <= range and unit:IsAffectingCombat() then
count = count + 1
end
end)
return count
end
local function GetLowestThreatEnemy()
local lowestThreatUnit = nil
local lowestThreat = math.huge
Bastion.UnitManager:EnumEnemies(function(unit)
if unit:IsAffectingCombat() and unit:GetDistance(Player) <= 30 then
local _, _, scaledPercent = UnitDetailedThreatSituation(Player:GetOMToken(), unit:GetOMToken())
if scaledPercent and scaledPercent < lowestThreat then
lowestThreatUnit = unit
lowestThreat = scaledPercent
end
end
end)
return lowestThreatUnit
end
-- Create APLs
local DefaultAPL = Bastion.APL:New('default')
local CooldownAPL = Bastion.APL:New('cooldown')
local DefensiveAPL = Bastion.APL:New('defensive')
local InterruptAPL = Bastion.APL:New('interrupt')
local ThreatAPL = Bastion.APL:New('threat')
-- Defensive APL
DefensiveAPL:AddSpell(
ShieldOfTheRighteous:CastableIf(function(self)
return self:IsKnownAndUsable() and Player:GetPower() >= 3 and Player:GetHP() < 80
end):SetTarget(Player)
-- Interrupt APL
InterruptAPL:AddSpell(
Rebuke:CastableIf(function(self)
return self:IsKnownAndUsable() and Target:IsCasting() and Target:IsInterruptible() and Player:IsWithinCombatDistance(Target, 5)
end):SetTarget(Target)
)
DefensiveAPL:AddSpell(
WordOfGlory:CastableIf(function(self)
return self:IsKnownAndUsable() and (Player:GetPower() >= 3 or Player:GetAuras():FindMy(ShiningLightBuff):IsUp()) and Player:GetHP() < 50
end):SetTarget(Player)
InterruptAPL:AddSpell(
AvengersShield:CastableIf(function(self)
return self:IsKnownAndUsable() and Target:IsCasting() and Target:IsInterruptible() and Rebuke:GetCooldownRemaining() > 0 and Player:IsWithinCombatDistance(Target, 30)
end):SetTarget(Target)
)
-- Threat Management APL
ThreatAPL:AddSpell(
HandOfReckoning:CastableIf(function(self)
return self:IsKnownAndUsable() and Target:GetDistance(Player) > 10 and Target:GetDistance(Player) <= 30
end):SetTarget(Target)
)
ThreatAPL:AddSpell(
AvengersShield:CastableIf(function(self)
return self:IsKnownAndUsable() and GetEnemiesInRange(30) > 1 and Player:IsWithinCombatDistance(Target, 30)
end):SetTarget(Target)
)
-- Defensive APL
DefensiveAPL:AddSpell(
GuardianOfAncientKings:CastableIf(function(self)
return self:IsKnownAndUsable() and Player:GetHP() < 40
ShieldOfTheRighteous:CastableIf(function(self)
return self:IsKnownAndUsable() and Player:GetPower() >= 3 and Player:GetHP() < 80 and Player:IsWithinCombatDistance(Target, 5)
end):SetTarget(Player)
)
DefensiveAPL:AddSpell(
ArdentDefender:CastableIf(function(self)
return self:IsKnownAndUsable() and Player:GetHP() < 30
WordOfGlory:CastableIf(function(self)
return self:IsKnownAndUsable() and (Player:GetPower() >= 3 or Player:GetAuras():FindMy(ShiningLightBuff):IsUp()) and Player:GetHP() < 50
end):SetTarget(Player)
)
DefensiveAPL:AddSpell(
LayOnHands:CastableIf(function(self)
return self:IsKnownAndUsable() and Player:GetHP() < 20
EyeOfTyr:CastableIf(function(self)
return self:IsKnownAndUsable() and Player:GetHP() < 60 and GetEnemiesInRange(8) >= 3
end):SetTarget(Player)
)
-- Cooldown APL
CooldownAPL:AddSpell(
AvengingWrath:CastableIf(function(self)
return self:IsKnownAndUsable() and Player:GetEnemies(8) >= 3
return self:IsKnownAndUsable() and GetEnemiesInRange(8) >= 3
end):SetTarget(Player)
)
-- Default APL
DefaultAPL:AddSpell(
Consecration:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:GetAuras():FindMy(ConsecrationBuff):IsUp()
return self:IsKnownAndUsable() and not Player:GetAuras():FindMy(ConsecrationBuff):IsUp() and Player:IsWithinCombatDistance(Target, 8)
end):SetTarget(Player)
)
DefaultAPL:AddSpell(
ShieldOfTheRighteous:CastableIf(function(self)
return self:IsKnownAndUsable() and Player:GetPower() >= 3
return self:IsKnownAndUsable() and Player:GetPower() >= 3 and Player:IsWithinCombatDistance(Target, 5)
end):SetTarget(Player)
)
DefaultAPL:AddSpell(
AvengersShield:CastableIf(function(self)
return self:IsKnownAndUsable() and Player:GetEnemies(8) >= 3
return self:IsKnownAndUsable() and Player:IsWithinCombatDistance(Target, 30)
end):SetTarget(Target)
)
DefaultAPL:AddSpell(
Judgment:CastableIf(function(self)
return self:IsKnownAndUsable()
return self:IsKnownAndUsable() and Player:IsWithinCombatDistance(Target, 30)
end):SetTarget(Target)
)
DefaultAPL:AddSpell(
HammerOfWrath:CastableIf(function(self)
return self:IsKnownAndUsable()
end):SetTarget(Target)
)
DefaultAPL:AddSpell(
AvengersShield:CastableIf(function(self)
return self:IsKnownAndUsable()
return self:IsKnownAndUsable() and (Target:GetHP() <= 20 or Player:GetAuras():FindMy(AvengingWrath):IsUp()) and Player:IsWithinCombatDistance(Target, 30)
end):SetTarget(Target)
)
DefaultAPL:AddSpell(
BlessedHammer:CastableIf(function(self)
return self:IsKnownAndUsable()
end):SetTarget(Target)
)
DefaultAPL:AddSpell(
HammerOfTheRighteous:CastableIf(function(self)
return self:IsKnownAndUsable() and not BlessedHammer:IsKnown()
return self:IsKnownAndUsable() and Player:IsWithinCombatDistance(Target, 5)
end):SetTarget(Target)
)
DefaultAPL:AddSpell(
Consecration:CastableIf(function(self)
return self:IsKnownAndUsable()
return self:IsKnownAndUsable() and Player:IsWithinCombatDistance(Target, 8)
end):SetTarget(Player)
)
-- Main rotation logic
ProtPaladinModule:Sync(function()
if not Player:IsAffectingCombat() then return end
-- Check if the player is mounted
if IsMounted() or Player:IsMounted() then
return -- Exit the function if mounted, pausing the rotation
end
if not Player:IsAffectingCombat() then
if not Target:Exists() or Target:IsDead() then
Bastion.UnitManager:EnumEnemies(function(unit)
if unit:IsAlive() and unit:GetDistance(Player) <= 30 then
Target = unit
return true
end
end)
end
return
end
-- Dynamic target selection and threat management
local lowestThreatEnemy = GetLowestThreatEnemy()
if lowestThreatEnemy then
Target = lowestThreatEnemy
elseif not Target:Exists() or Target:IsDead() or Target:GetDistance(Player) > 30 then
Bastion.UnitManager:EnumEnemies(function(unit)
if unit:IsAlive() and unit:GetDistance(Player) <= 30 and unit:IsAffectingCombat() then
Target = unit
return true
end
end)
end
InterruptAPL:Execute()
ThreatAPL:Execute()
DefensiveAPL:Execute()
CooldownAPL:Execute()
DefaultAPL:Execute()

Loading…
Cancel
Save