parent
be415a57cf
commit
e0b3d7afe6
@ -0,0 +1,249 @@ |
|||||||
|
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) |
Loading…
Reference in new issue