|
|
|
@ -28,6 +28,8 @@ local PrimordialWave = SpellBook:GetSpell(375982) |
|
|
|
|
local AstralShift = SpellBook:GetSpell(108271) |
|
|
|
|
local WindShear = SpellBook:GetSpell(57994) |
|
|
|
|
local Skyfury = SpellBook:GetSpell(462854) |
|
|
|
|
local LightningShield = SpellBook:GetSpell(192106) |
|
|
|
|
local EarthShield = SpellBook:GetSpell(974) |
|
|
|
|
|
|
|
|
|
-- Buffs and Debuffs |
|
|
|
|
local MasterOfTheElements = SpellBook:GetSpell(260734) |
|
|
|
@ -60,12 +62,28 @@ local BestTarget = Bastion.UnitManager:CreateCustomUnit('besttarget', function() |
|
|
|
|
return bestTarget or Target |
|
|
|
|
end) |
|
|
|
|
|
|
|
|
|
local InterruptTarget = Bastion.UnitManager:CreateCustomUnit('interrupttarget', function() |
|
|
|
|
local target = nil |
|
|
|
|
Bastion.UnitManager:EnumEnemies(function(unit) |
|
|
|
|
if unit:IsAffectingCombat() and unit:GetDistance(Player) <= 30 and Player:CanSee(unit) |
|
|
|
|
and unit:IsCasting() and unit:IsInterruptible() then |
|
|
|
|
local castPercentage = unit:GetChannelOrCastPercentComplete() |
|
|
|
|
if castPercentage >= 30 and castPercentage <= 80 then |
|
|
|
|
target = unit |
|
|
|
|
return true |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
end) |
|
|
|
|
return target or Bastion.UnitManager:Get('none') |
|
|
|
|
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') |
|
|
|
|
local InterruptAPL = Bastion.APL:New('interrupt') |
|
|
|
|
|
|
|
|
|
-- Helper Functions |
|
|
|
|
local function ShouldAoE() |
|
|
|
@ -73,6 +91,18 @@ local function ShouldAoE() |
|
|
|
|
return #enemies >= 2 |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
local function NeedSkyfury() |
|
|
|
|
-- Check if any party member (including the player) needs Skyfury |
|
|
|
|
local needsBuff = false |
|
|
|
|
Bastion.UnitManager:EnumFriends(function(unit) |
|
|
|
|
if unit:IsAlive() and not unit:GetAuras():FindAny(Skyfury):IsUp() then |
|
|
|
|
needsBuff = true |
|
|
|
|
return true -- This will break the enumeration loop |
|
|
|
|
end |
|
|
|
|
end) |
|
|
|
|
return needsBuff |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
-- Default APL |
|
|
|
|
DefaultAPL:AddSpell( |
|
|
|
|
PrimordialWave:CastableIf(function(self) |
|
|
|
@ -120,6 +150,25 @@ DefaultAPL:AddSpell( |
|
|
|
|
end):SetTarget(BestTarget) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
-- OutOfCombat APL |
|
|
|
|
OutOfCombatAPL:AddSpell( |
|
|
|
|
Skyfury:CastableIf(function(self) |
|
|
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and NeedSkyfury() |
|
|
|
|
end):SetTarget(Player) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
OutOfCombatAPL:AddSpell( |
|
|
|
|
EarthShield:CastableIf(function(self) |
|
|
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and not Player:GetAuras():FindAny(EarthShield_Buff):IsUp() |
|
|
|
|
end):SetTarget(Player) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
OutOfCombatAPL:AddSpell( |
|
|
|
|
LightningShield:CastableIf(function(self) |
|
|
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and not Player:GetAuras():FindAny(LightningShield_Buff):IsUp() |
|
|
|
|
end):SetTarget(Player) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
-- AoE APL |
|
|
|
|
AoEAPL:AddSpell( |
|
|
|
|
ChainLightning:CastableIf(function(self) |
|
|
|
@ -133,7 +182,7 @@ AoEAPL:AddSpell( |
|
|
|
|
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) |
|
|
|
|
local loc = Bastion.UnitManager:FindEnemiesCentroid(10, 39) |
|
|
|
|
if loc then |
|
|
|
|
self:Click(loc) |
|
|
|
|
end |
|
|
|
@ -185,26 +234,25 @@ DefensiveAPL:AddSpell( |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
-- 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) |
|
|
|
|
local target = InterruptTarget |
|
|
|
|
local randomInterruptPercent = math.random(50, 90) |
|
|
|
|
return target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and target:IsCasting() and target:IsInterruptible() |
|
|
|
|
and target:GetChannelOrCastPercentComplete() >= randomInterruptPercent |
|
|
|
|
end):SetTarget(InterruptTarget) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
-- Out of Combat APL |
|
|
|
|
|
|
|
|
|
-- Module Sync |
|
|
|
|
ElementalShamanModule:Sync(function() |
|
|
|
|
if Player:IsMounted() then |
|
|
|
|
return |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
DefensiveAPL:Execute() |
|
|
|
|
InterruptAPL:Execute() |
|
|
|
|
|
|
|
|
|
if Player:IsAffectingCombat() then |
|
|
|
|
DefensiveAPL:Execute() |
|
|
|
|
InterruptAPL:Execute() |
|
|
|
|
CooldownAPL:Execute() |
|
|
|
|
|
|
|
|
|
if ShouldAoE() then |
|
|
|
|