Basic rotations that work
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
OkRotations/DiscPriest.lua

331 lines
12 KiB

local Tinkr, Bastion = ...
local DiscPriestModule = Bastion.Module:New('DiscPriest')
local Player = Bastion.UnitManager:Get('player')
local Target = Bastion.UnitManager:Get('target')
-- Initialize SpellBook
local SpellBook = Bastion.SpellBook:New()
-- Spells
local PowerWordShield = SpellBook:GetSpell(17)
local Penance = SpellBook:GetSpell(47540)
local PowerWordRadiance = SpellBook:GetSpell(194509)
local Shadowfiend = SpellBook:GetSpell(34433)
local Mindbender = SpellBook:GetSpell(123040)
local Rapture = SpellBook:GetSpell(47536)
local PainSuppression = SpellBook:GetSpell(33206)
local PowerWordBarrier = SpellBook:GetSpell(62618)
local Schism = SpellBook:GetSpell(214621)
local ShadowCovenant = SpellBook:GetSpell(314867)
local MindBlast = SpellBook:GetSpell(8092)
local ShadowWordDeath = SpellBook:GetSpell(32379)
local Smite = SpellBook:GetSpell(585)
local FlashHeal = SpellBook:GetSpell(2061)
local Renew = SpellBook:GetSpell(139)
local Fade = SpellBook:GetSpell(586)
local DesperatePrayer = SpellBook:GetSpell(19236)
local VoidwraithTalent = SpellBook:GetSpell(406786)
local Voidwraith = SpellBook:GetSpell(406786)
-- Buffs and Debuffs
local Atonement = SpellBook:GetSpell(194384)
local PowerOfTheDarkSide = SpellBook:GetSpell(198068)
local ShadowCovenantBuff = SpellBook:GetSpell(322105)
local WeakenedSoul = SpellBook:GetSpell(6788)
-- Custom Units
local Lowest = Bastion.UnitManager:CreateCustomUnit('lowest', function(unit)
local lowest = nil
local lowestHP = math.huge
Bastion.UnitManager:EnumFriends(function(unit)
if unit:IsDead() or Player:GetDistance(unit) > 40 or not Player:CanSee(unit) then
return false
end
local hp = unit:GetHP()
if hp < lowestHP then
lowest = unit
lowestHP = hp
end
end)
return lowest or Player
end)
local Tank = Bastion.UnitManager:CreateCustomUnit('tank', function(unit)
local tank = nil
Bastion.UnitManager:EnumFriends(function(unit)
if Player:GetDistance(unit) > 40 or not Player:CanSee(unit) or unit:IsDead() then
return false
end
if unit:IsTank() then
tank = unit
return true
end
end)
return tank or Player
end)
local AtoneTarget = Bastion.UnitManager:CreateCustomUnit('atonetarget', function(unit)
local target = nil
local lowestAtonementTime = math.huge
Bastion.UnitManager:EnumFriends(function(unit)
if unit:IsDead() or Player:GetDistance(unit) > 40 or not Player:CanSee(unit) then
return false
end
local atonementBuff = unit:GetAuras():FindMy(Atonement)
if not atonementBuff:IsUp() then
if unit:GetHP() >= 70 and unit:GetHP() <= 90 then
target = unit
return true
end
elseif atonementBuff:GetRemainingTime() < lowestAtonementTime then
target = unit
lowestAtonementTime = atonementBuff:GetRemainingTime()
end
end)
return target or Player
end)
-- Target the highest HP enemy for DPS APL
local HighestHPTarget = Bastion.UnitManager:CreateCustomUnit('highesthptarget', function(unit)
local target = nil
local highestHP = 0
Bastion.UnitManager:EnumEnemies(function(unit)
if unit:IsAffectingCombat() and Player:IsWithinCombatDistance(unit, 40) and Player:CanSee(unit) then
local hp = unit:GetHP()
if hp > highestHP then
target = unit
highestHP = hp
end
end
end)
return target or Target
end)
-- APLs
local DefaultAPL = Bastion.APL:New('default')
local CooldownAPL = Bastion.APL:New('cooldown')
local DefensiveAPL = Bastion.APL:New('defensive')
local DpsAPL = Bastion.APL:New('dps')
-- Helper Functions
local function ShouldUseRadiance()
local countWithoutAtonement = 0
Bastion.UnitManager:EnumFriends(function(unit)
if not unit:IsDead() and Player:GetDistance(unit) <= 40 and Player:CanSee(unit) and not unit:GetAuras():FindMy(Atonement):IsUp() then
countWithoutAtonement = countWithoutAtonement + 1
end
end)
return countWithoutAtonement >= 3
end
-- Default APL
DefaultAPL:AddSpell(
PowerWordShield:CastableIf(function(self)
return AtoneTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and not AtoneTarget:GetAuras():FindMy(PowerWordShield):IsUp()
and not AtoneTarget:GetAuras():FindMy(WeakenedSoul):IsUp()
end):SetTarget(AtoneTarget)
)
DefaultAPL:AddSpell(
PowerWordRadiance:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and ShouldUseRadiance()
end):SetTarget(Player)
)
DefaultAPL:AddSpell(
Penance:CastableIf(function(self)
return AtoneTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and not AtoneTarget:GetAuras():FindMy(Atonement):IsUp()
end):SetTarget(AtoneTarget)
)
DefaultAPL:AddSpell(
Renew:CastableIf(function(self)
return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Lowest:GetHP() < 90 and not Lowest:GetAuras():FindMy(Renew):IsUp()
end):SetTarget(Lowest)
)
DefaultAPL:AddSpell(
FlashHeal:CastableIf(function(self)
return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Lowest:GetHP() < 70 and not Lowest:GetAuras():FindMy(Atonement):IsUp()
end):SetTarget(Lowest)
)
-- Cooldown APL
CooldownAPL:AddSpell(
Rapture:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:GetPartyHPAround(40, 75) >= 3
end):SetTarget(Player)
)
CooldownAPL:AddSpell(
PowerWordBarrier:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:GetPartyHPAround(40, 70) >= 3
end):SetTarget(Player)
)
CooldownAPL:AddSpell(
ShadowCovenant:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:GetPartyHPAround(40, 80) >= 3
end):SetTarget(Player)
)
CooldownAPL:AddSpell(
Shadowfiend:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and not VoidwraithTalent:IsKnownAndUsable()
end):SetTarget(HighestHPTarget)
)
CooldownAPL:AddSpell(
Voidwraith:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(HighestHPTarget)
)
-- Defensive APL
DefensiveAPL:AddSpell(
Fade:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:GetHP() < 90
end):SetTarget(Player)
)
DefensiveAPL:AddSpell(
DesperatePrayer:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:GetHP() < 50
end):SetTarget(Player)
)
DefensiveAPL:AddSpell(
PainSuppression:CastableIf(function(self)
return Tank:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Tank:GetHP() < 40
end):SetTarget(Tank)
)
-- DPS APL
DpsAPL:AddSpell(
Schism:CastableIf(function(self)
return HighestHPTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:IsWithinCombatDistance(HighestHPTarget, 40)
end):SetTarget(HighestHPTarget)
)
DpsAPL:AddSpell(
Penance:CastableIf(function(self)
return HighestHPTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:IsWithinCombatDistance(HighestHPTarget, 40)
end):SetTarget(HighestHPTarget)
)
DpsAPL:AddSpell(
MindBlast:CastableIf(function(self)
return HighestHPTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:IsWithinCombatDistance(HighestHPTarget, 40)
end):SetTarget(HighestHPTarget)
)
DpsAPL:AddSpell(
ShadowWordDeath:CastableIf(function(self)
return HighestHPTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and HighestHPTarget:GetHP() < 20 and Player:IsWithinCombatDistance(HighestHPTarget, 40)
end):SetTarget(HighestHPTarget)
)
DpsAPL:AddSpell(
Smite:CastableIf(function(self)
return HighestHPTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:IsWithinCombatDistance(HighestHPTarget, 40)
end):SetTarget(HighestHPTarget)
)
-- Module Sync
DiscPriestModule:Sync(function()
if Player:IsMounted() then
return
end
-- Prioritize Defensive APL
DefensiveAPL:Execute()
if Player:IsAffectingCombat() then
-- Prioritize cooldowns if necessary
CooldownAPL:Execute()
-- Apply Atonement to targets before proceeding with DPS
if AtoneTarget:Exists() and not AtoneTarget:GetAuras():FindMy(Atonement):IsUp() then
if not AtoneTarget:GetAuras():FindMy(PowerWordShield):IsUp() and not AtoneTarget:GetAuras():FindMy(WeakenedSoul):IsUp() then
PowerWordShield:Cast(AtoneTarget)
elseif AtoneTarget:GetHP() <= 90 and not AtoneTarget:GetAuras():FindMy(Renew):IsUp() then
Renew:Cast(AtoneTarget)
elseif AtoneTarget:GetHP() <= 80 then
FlashHeal:Cast(AtoneTarget)
elseif AtoneTarget:GetAuras():FindMy(Atonement):IsUp() and Penance:IsKnownAndUsable() then
Penance:Cast(AtoneTarget)
end
end
-- Execute Default and DPS APLs
DefaultAPL:Execute()
DpsAPL:Execute()
else
-- Out of combat healing and preparation
if AtoneTarget:Exists() and not AtoneTarget:GetAuras():FindMy(Atonement):IsUp() then
if not AtoneTarget:GetAuras():FindMy(PowerWordShield):IsUp() and not AtoneTarget:GetAuras():FindMy(WeakenedSoul):IsUp() then
PowerWordShield:Cast(AtoneTarget)
elseif AtoneTarget:GetHP() <= 90 and not AtoneTarget:GetAuras():FindMy(Renew):IsUp() then
Renew:Cast(AtoneTarget)
elseif AtoneTarget:GetHP() <= 80 then
FlashHeal:Cast(AtoneTarget)
elseif AtoneTarget:GetAuras():FindMy(Atonement):IsUp() and Penance:IsKnownAndUsable() then
Penance:Cast(AtoneTarget)
end
end
-- Top off teammates' health to 100%
Bastion.UnitManager:EnumFriends(function(unit)
if unit:GetHP() < 100 and Player:CanSee(unit) and Player:GetDistance(unit) <= 40 then
if not unit:GetAuras():FindMy(WeakenedSoul):IsUp() and PowerWordShield:IsKnownAndUsable() then
PowerWordShield:Cast(unit)
elseif FlashHeal:IsKnownAndUsable() then
FlashHeal:Cast(unit)
elseif Renew:IsKnownAndUsable() and not unit:GetAuras():FindMy(Renew):IsUp() then
Renew:Cast(unit)
end
end
end)
-- Prepare for combat by applying buffs and debuffs
if Target:Exists() and Target:IsEnemy() and PurgeTheWicked:IsKnownAndUsable() and not Player:IsCastingOrChanneling() then
if not Target:GetAuras():FindMy(PurgeTheWickedDebuff):IsUp() and Player:IsWithinCombatDistance(Target, 40) then
PurgeTheWicked:Cast(Target)
end
end
end
end)
-- Register the DiscPriest module with Bastion
Bastion:Register(DiscPriestModule)