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/ElementalShaman.lua

222 lines
7.3 KiB

local Tinkr, Bastion = ...
local ElementalShamanModule = Bastion.Module:New('ElementalShaman')
local Player = Bastion.UnitManager:Get('player')
local Target = Bastion.UnitManager:Get('target')
local Pet = Bastion.UnitManager:Get('pet')
-- Initialize SpellBook
local SpellBook = Bastion.SpellBook:New()
-- Spells
local LightningBolt = SpellBook:GetSpell(188196)
local LavaBurst = SpellBook:GetSpell(51505)
local EarthShock = SpellBook:GetSpell(8042)
local FlameShock = SpellBook:GetSpell(188389)
local Stormkeeper = SpellBook:GetSpell(191634)
local ElementalBlast = SpellBook:GetSpell(117014)
local ChainLightning = SpellBook:GetSpell(188443)
local Earthquake = SpellBook:GetSpell(61882)
local FireElemental = SpellBook:GetSpell(198067)
local StormElemental = SpellBook:GetSpell(192249)
local LiquidMagmaTotem = SpellBook:GetSpell(192222)
local Icefury = SpellBook:GetSpell(210714)
local FrostShock = SpellBook:GetSpell(196840)
local Ascendance = SpellBook:GetSpell(114050)
local PrimordialWave = SpellBook:GetSpell(375982)
local AstralShift = SpellBook:GetSpell(108271)
local WindShear = SpellBook:GetSpell(57994)
local Skyfury = SpellBook:GetSpell(462854)
-- Buffs and Debuffs
local MasterOfTheElements = SpellBook:GetSpell(260734)
local SurgeOfPower = SpellBook:GetSpell(285514)
local LavaSurge = SpellBook:GetSpell(77762)
local Icefury_Buff = SpellBook:GetSpell(210714)
local FlameShock_Debuff = SpellBook:GetSpell(188389)
local MagmaChamber_Buff = SpellBook:GetSpell(381933)
local SplinteredElements_Buff = SpellBook:GetSpell(382043)
local WindGust_Buff = SpellBook:GetSpell(263806)
local EarthShield_Buff = SpellBook:GetSpell(383648)
local LightningShield_Buff = SpellBook:GetSpell(192106)
local PrimordialWave_Buff = SpellBook:GetSpell(375986)
-- Custom Units
local BestTarget = Bastion.UnitManager:CreateCustomUnit('besttarget', function()
local bestTarget = nil
local highestHP = 0
Bastion.UnitManager:EnumEnemies(function(unit)
if unit:IsAffectingCombat() and Player:IsWithinCombatDistance(unit, 40) and Player:CanSee(unit) and Player:IsFacing(unit) then
local hp = unit:GetHP()
if hp > highestHP then
bestTarget = unit
highestHP = hp
end
end
end)
return bestTarget or Target
end)
-- 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 OutOfCombatAPL = Bastion.APL:New('outofcombat')
-- Helper Functions
local function ShouldAoE()
local _, enemies = Bastion.UnitManager:GetEnemiesWithMostEnemies(10)
return #enemies >= 2
end
-- Default APL
DefaultAPL:AddSpell(
PrimordialWave:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(BestTarget)
)
DefaultAPL:AddSpell(
LavaBurst:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and (Player:GetAuras():FindAny(PrimordialWave_Buff):IsUp() or (Player:GetAuras():FindAny(LavaSurge):IsUp() and Player:IsMoving()))
end):SetTarget(BestTarget)
)
DefaultAPL:AddSpell(
EarthShock:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:GetPower() >= 60 and (Player:GetAuras():FindAny(MasterOfTheElements):IsUp() or (Player:GetPower() + self:GetCost()) > Player:GetMaxPower())
end):SetTarget(BestTarget)
)
DefaultAPL:AddSpell(
ElementalBlast:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:GetAuras():FindAny(MasterOfTheElements):IsUp()
end):SetTarget(BestTarget)
)
DefaultAPL:AddSpell(
FlameShock:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and not BestTarget:GetAuras():FindAny(FlameShock_Debuff):IsUp()
end):SetTarget(BestTarget)
)
DefaultAPL:AddSpell(
LightningBolt:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(BestTarget)
)
DefaultAPL:AddSpell(
FrostShock:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and Player:IsMoving()
end):SetTarget(BestTarget)
)
-- AoE APL
AoEAPL:AddSpell(
ChainLightning:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and ShouldAoE()
end):SetTarget(BestTarget)
)
AoEAPL:AddSpell(
Earthquake:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:GetPower() >= 60 and ShouldAoE()
end):SetTarget(Bastion.UnitManager:Get('none')):OnCast(function(self)
local loc = Bastion.UnitManager:FindEnemiesCentroid(10, 40)
if loc then
self:Click(loc)
end
end)
)
-- Cooldown APL
CooldownAPL:AddSpell(
StormElemental:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and not Pet:Exists()
end):SetTarget(Player)
)
CooldownAPL:AddSpell(
FireElemental:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and not StormElemental:IsKnownAndUsable()
end):SetTarget(Player)
)
CooldownAPL:AddSpell(
Stormkeeper:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(Player)
)
CooldownAPL:AddSpell(
LiquidMagmaTotem:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and ShouldAoE()
end):SetTarget(Bastion.UnitManager:Get('none')):OnCast(function(self)
local loc = Bastion.UnitManager:FindEnemiesCentroid(10, 40)
if loc then
self:Click(loc)
end
end)
)
CooldownAPL:AddSpell(
Ascendance:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
end):SetTarget(Player)
)
-- Defensive APL
DefensiveAPL:AddSpell(
AstralShift:CastableIf(function(self)
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and Player:GetHP() < 50
end):SetTarget(Player)
)
-- Interrupt APL
local InterruptAPL = Bastion.APL:New('interrupt')
InterruptAPL:AddSpell(
WindShear:CastableIf(function(self)
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling()
and BestTarget:IsInterruptible()
end):SetTarget(BestTarget)
)
-- Out of Combat APL
-- Module Sync
ElementalShamanModule:Sync(function()
if Player:IsMounted() then
return
end
DefensiveAPL:Execute()
InterruptAPL:Execute()
if Player:IsAffectingCombat() then
CooldownAPL:Execute()
if ShouldAoE() then
AoEAPL:Execute()
else
DefaultAPL:Execute()
end
else
OutOfCombatAPL:Execute()
end
end)
-- Register the ElementalShaman module with Bastion
Bastion:Register(ElementalShamanModule)