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.
249 lines
7.3 KiB
249 lines
7.3 KiB
5 months ago
|
local Tinkr, Bastion = ...
|
||
|
|
||
|
local GuardianModule = Bastion.Module:New('GuardianDruid')
|
||
|
local Player = Bastion.UnitManager:Get('player')
|
||
|
local Target = Bastion.UnitManager:Get('target')
|
||
|
local SpellBook = Bastion.SpellBook:New()
|
||
|
|
||
|
-- Spells
|
||
|
local Moonfire = SpellBook:GetSpell(8921)
|
||
|
local Thrash = SpellBook:GetSpell(77758)
|
||
|
local Ironfur = SpellBook:GetSpell(192081)
|
||
|
local Maul = SpellBook:GetSpell(6807)
|
||
|
local Mangle = SpellBook:GetSpell(33917)
|
||
|
local Swipe = SpellBook:GetSpell(213771)
|
||
|
local LunarBeam = SpellBook:GetSpell(204066)
|
||
|
local Raze = SpellBook:GetSpell(391286)
|
||
|
local Barkskin = SpellBook:GetSpell(22812)
|
||
|
local Incarnation = SpellBook:GetSpell(102558)
|
||
|
local RageOfTheSleeper = SpellBook:GetSpell(200851)
|
||
|
local HeartOfTheWild = SpellBook:GetSpell(319454)
|
||
|
local FrenziedRegeneration = SpellBook:GetSpell(22842)
|
||
|
local SkullBash = SpellBook:GetSpell(106839)
|
||
|
local IncapacitatingRoar = SpellBook:GetSpell(99)
|
||
|
|
||
|
-- Forms
|
||
|
local BearForm = SpellBook:GetSpell(5487)
|
||
|
local CatForm = SpellBook:GetSpell(768)
|
||
|
local TravelForm = SpellBook:GetSpell(783)
|
||
|
|
||
|
-- Buffs
|
||
|
local MoonfireDot = SpellBook:GetSpell(164812)
|
||
|
local ThrashDot = SpellBook:GetSpell(192090)
|
||
|
local IronfurBuff = SpellBook:GetSpell(192081)
|
||
|
local ToothAndClawBuff = SpellBook:GetSpell(135286)
|
||
|
local GalacticGuardianBuff = SpellBook:GetSpell(213708)
|
||
|
local IncarnationBuff = SpellBook:GetSpell(102558)
|
||
|
local BearFormBuff = SpellBook:GetSpell(5487)
|
||
|
local CatFormBuff = SpellBook:GetSpell(768)
|
||
|
local TravelFormBuff = SpellBook:GetSpell(783)
|
||
|
|
||
|
-- Create APLs
|
||
|
local DefaultAPL = Bastion.APL:New('default')
|
||
|
local AoEAPL = Bastion.APL:New('aoe')
|
||
|
local CooldownAPL = Bastion.APL:New('cooldown')
|
||
|
local DefensiveAPL = Bastion.APL:New('defensive')
|
||
|
local StanceAPL = Bastion.APL:New('stance')
|
||
|
local InterruptAPL = Bastion.APL:New('interrupt')
|
||
|
|
||
|
-- Helper functions
|
||
|
local function GetLowestThrashStack()
|
||
|
local lowestStack = 5
|
||
|
local lowestDuration = 100
|
||
|
local enemiesInRange = 0
|
||
|
Bastion.UnitManager:EnumEnemies(function(unit)
|
||
|
if unit:IsAffectingCombat() and unit:GetDistance(Player) <= 8 then
|
||
|
enemiesInRange = enemiesInRange + 1
|
||
|
local aura = unit:GetAuras():FindMy(ThrashDot)
|
||
|
local stacks = aura:GetCount()
|
||
|
local duration = aura:GetRemainingTime()
|
||
|
if stacks < lowestStack then
|
||
|
lowestStack = stacks
|
||
|
lowestDuration = duration
|
||
|
elseif stacks == lowestStack and duration < lowestDuration then
|
||
|
lowestDuration = duration
|
||
|
end
|
||
|
end
|
||
|
end)
|
||
|
return lowestStack, enemiesInRange, lowestDuration
|
||
|
end
|
||
|
|
||
|
local function IsInCombatForm()
|
||
|
return Player:GetAuras():FindMy(BearFormBuff):IsUp() or Player:GetAuras():FindMy(CatFormBuff):IsUp()
|
||
|
end
|
||
|
|
||
|
local function IsInTravelForm()
|
||
|
return Player:GetAuras():FindMy(TravelFormBuff):IsUp()
|
||
|
end
|
||
|
|
||
|
-- Stance Management APL
|
||
|
StanceAPL:AddSpell(
|
||
|
BearForm:CastableIf(function(self)
|
||
|
return not IsInTravelForm() and Player:IsAffectingCombat() and not Player:GetAuras():FindMy(BearFormBuff):IsUp()
|
||
|
end):SetTarget(Player)
|
||
|
)
|
||
|
|
||
|
StanceAPL:AddSpell(
|
||
|
TravelForm:CastableIf(function(self)
|
||
|
return not IsInTravelForm() and not Player:IsAffectingCombat() and Player:IsOutdoors() and not Player:GetAuras():FindMy(TravelFormBuff):IsUp()
|
||
|
end):SetTarget(Player)
|
||
|
)
|
||
|
|
||
|
StanceAPL:AddSpell(
|
||
|
CatForm:CastableIf(function(self)
|
||
|
return not IsInTravelForm() and not Player:IsAffectingCombat() and Player:IsIndoors() and not Player:GetAuras():FindMy(CatFormBuff):IsUp()
|
||
|
end):SetTarget(Player)
|
||
|
)
|
||
|
|
||
|
-- Cooldown APL
|
||
|
CooldownAPL:AddSpell(
|
||
|
Incarnation:CastableIf(function(self)
|
||
|
return not Player:GetAuras():FindMy(IncarnationBuff):IsUp()
|
||
|
end):SetTarget(Player)
|
||
|
)
|
||
|
|
||
|
CooldownAPL:AddSpell(
|
||
|
RageOfTheSleeper:CastableIf(function(self)
|
||
|
return true
|
||
|
end):SetTarget(Player)
|
||
|
)
|
||
|
|
||
|
CooldownAPL:AddSpell(
|
||
|
LunarBeam:CastableIf(function(self)
|
||
|
return true
|
||
|
end):SetTarget(Target)
|
||
|
)
|
||
|
|
||
|
CooldownAPL:AddSpell(
|
||
|
HeartOfTheWild:CastableIf(function(self)
|
||
|
return true
|
||
|
end):SetTarget(Player)
|
||
|
)
|
||
|
|
||
|
-- Defensive APL
|
||
|
DefensiveAPL:AddSpell(
|
||
|
Ironfur:CastableIf(function(self)
|
||
|
return Player:GetPower() >= 40 or (Player:GetPower() >= 25 and Player:GetAuras():FindMy(IronfurBuff):GetRemainingTime() < 2)
|
||
|
end):SetTarget(Player)
|
||
|
)
|
||
|
|
||
|
DefensiveAPL:AddSpell(
|
||
|
Barkskin:CastableIf(function(self)
|
||
|
return Player:GetHP() <= 70
|
||
|
end):SetTarget(Player)
|
||
|
)
|
||
|
|
||
|
DefensiveAPL:AddSpell(
|
||
|
FrenziedRegeneration:CastableIf(function(self)
|
||
|
return Player:GetHP() <= 60
|
||
|
end):SetTarget(Player)
|
||
|
)
|
||
|
|
||
|
-- Interrupt APL
|
||
|
InterruptAPL:AddSpell(
|
||
|
SkullBash:CastableIf(function(self)
|
||
|
return Target:IsInterruptible()
|
||
|
end):SetTarget(Target)
|
||
|
)
|
||
|
|
||
|
InterruptAPL:AddSpell(
|
||
|
IncapacitatingRoar:CastableIf(function(self)
|
||
|
return Player:GetEnemies(10) > 1 and not Target:IsInterruptible()
|
||
|
end):SetTarget(Player)
|
||
|
)
|
||
|
|
||
|
-- Default APL (Single Target)
|
||
|
DefaultAPL:AddSpell(
|
||
|
Mangle:CastableIf(function(self)
|
||
|
return self:IsInRange(Target)
|
||
|
end):SetTarget(Target)
|
||
|
)
|
||
|
|
||
|
DefaultAPL:AddSpell(
|
||
|
Thrash:CastableIf(function(self)
|
||
|
local lowestStack, enemiesInRange, lowestDuration = GetLowestThrashStack()
|
||
|
return lowestStack < 5 or lowestDuration < 4.5
|
||
|
end):SetTarget(Player)
|
||
|
)
|
||
|
|
||
|
DefaultAPL:AddSpell(
|
||
|
Moonfire:CastableIf(function(self)
|
||
|
return self:IsInRange(Target) and (
|
||
|
Player:GetAuras():FindMy(GalacticGuardianBuff):IsUp() or
|
||
|
not Target:GetAuras():FindMy(MoonfireDot):IsUp() or
|
||
|
Target:GetAuras():FindMy(MoonfireDot):GetRemainingTime() < 3
|
||
|
)
|
||
|
end):SetTarget(Target)
|
||
|
)
|
||
|
|
||
|
DefaultAPL:AddSpell(
|
||
|
Maul:CastableIf(function(self)
|
||
|
return self:IsInRange(Target) and (Player:GetAuras():FindMy(ToothAndClawBuff):IsUp() or Player:GetPower() >= 90)
|
||
|
end):SetTarget(Target)
|
||
|
)
|
||
|
|
||
|
DefaultAPL:AddSpell(
|
||
|
Swipe:CastableIf(function(self)
|
||
|
return self:IsInRange(Target)
|
||
|
end):SetTarget(Target)
|
||
|
)
|
||
|
|
||
|
-- AoE APL
|
||
|
AoEAPL:AddSpell(
|
||
|
Thrash:CastableIf(function(self)
|
||
|
local lowestStack, enemiesInRange, lowestDuration = GetLowestThrashStack()
|
||
|
return lowestStack < 5 or lowestDuration < 4.5
|
||
|
end):SetTarget(Player)
|
||
|
)
|
||
|
|
||
|
AoEAPL:AddSpell(
|
||
|
Swipe:CastableIf(function(self)
|
||
|
return Player:GetEnemies(8) > 0
|
||
|
end):SetTarget(Target)
|
||
|
)
|
||
|
|
||
|
AoEAPL:AddSpell(
|
||
|
Mangle:CastableIf(function(self)
|
||
|
return self:IsInRange(Target)
|
||
|
end):SetTarget(Target)
|
||
|
)
|
||
|
|
||
|
AoEAPL:AddSpell(
|
||
|
Moonfire:CastableIf(function(self)
|
||
|
return self:IsInRange(Target) and (
|
||
|
Player:GetAuras():FindMy(GalacticGuardianBuff):IsUp() or
|
||
|
not Target:GetAuras():FindMy(MoonfireDot):IsUp() or
|
||
|
Target:GetAuras():FindMy(MoonfireDot):GetRemainingTime() < 3
|
||
|
)
|
||
|
end):SetTarget(Target)
|
||
|
)
|
||
|
|
||
|
AoEAPL:AddSpell(
|
||
|
Raze:CastableIf(function(self)
|
||
|
return self:IsInRange(Target) and Player:GetAuras():FindMy(ToothAndClawBuff):IsUp()
|
||
|
end):SetTarget(Target)
|
||
|
)
|
||
|
|
||
|
-- Main rotation logic
|
||
|
GuardianModule:Sync(function()
|
||
|
if IsInTravelForm() then
|
||
|
return -- Do nothing if in Travel Form
|
||
|
end
|
||
|
|
||
|
StanceAPL:Execute()
|
||
|
|
||
|
if not Player:IsAffectingCombat() then return end
|
||
|
|
||
|
-- Combat rotations
|
||
|
InterruptAPL:Execute()
|
||
|
DefensiveAPL:Execute()
|
||
|
CooldownAPL:Execute()
|
||
|
|
||
|
if Player:GetEnemies(8) >= 3 then
|
||
|
AoEAPL:Execute()
|
||
|
else
|
||
|
DefaultAPL:Execute()
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
Bastion:Register(GuardianModule)
|