From e0b3d7afe6fbbdbb2b47a196b873cfc8abeb792e Mon Sep 17 00:00:00 2001 From: Emlembow <36314674+Emlembow@users.noreply.github.com> Date: Sun, 25 Aug 2024 21:18:33 -0700 Subject: [PATCH] Auto-commit: changes committed --- GuadrianDruid.lua | 249 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100644 GuadrianDruid.lua diff --git a/GuadrianDruid.lua b/GuadrianDruid.lua new file mode 100644 index 0000000..056882b --- /dev/null +++ b/GuadrianDruid.lua @@ -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) \ No newline at end of file