|
|
|
@ -3,52 +3,40 @@ local Tinkr, Bastion = ... |
|
|
|
|
local RestoShamanModule = Bastion.Module:New('RestoShaman') |
|
|
|
|
local Player = Bastion.UnitManager:Get('player') |
|
|
|
|
local Target = Bastion.UnitManager:Get('target') |
|
|
|
|
|
|
|
|
|
-- Initialize SpellBook |
|
|
|
|
local SpellBook = Bastion.SpellBook:New() |
|
|
|
|
|
|
|
|
|
-- Spells |
|
|
|
|
local WaterShield = SpellBook:GetSpell(52127) |
|
|
|
|
local EarthShield = SpellBook:GetSpell(974) |
|
|
|
|
local HealingRain = SpellBook:GetSpell(73920) |
|
|
|
|
local Riptide = SpellBook:GetSpell(61295) |
|
|
|
|
local CloudburstTotem = SpellBook:GetSpell(157153) |
|
|
|
|
local HealingStreamTotem = SpellBook:GetSpell(5394) |
|
|
|
|
local PrimordialWave = SpellBook:GetSpell(375982) |
|
|
|
|
local UnleashLife = SpellBook:GetSpell(73685) |
|
|
|
|
local Downpour = SpellBook:GetSpell(207778) |
|
|
|
|
local ChainHeal = SpellBook:GetSpell(1064) |
|
|
|
|
local HealingWave = SpellBook:GetSpell(77472) |
|
|
|
|
local HealingSurge = SpellBook:GetSpell(8004) |
|
|
|
|
local Wellspring = SpellBook:GetSpell(197995) |
|
|
|
|
local HealingWave = SpellBook:GetSpell(77472) |
|
|
|
|
local ChainHeal = SpellBook:GetSpell(1064) |
|
|
|
|
local HealingRain = SpellBook:GetSpell(73920) |
|
|
|
|
local Downpour = SpellBook:GetSpell(207778) |
|
|
|
|
local HealingStreamTotem = SpellBook:GetSpell(5394) |
|
|
|
|
local CloudburstTotem = SpellBook:GetSpell(157153) |
|
|
|
|
local SpiritLinkTotem = SpellBook:GetSpell(98008) |
|
|
|
|
local HealingTideTotem = SpellBook:GetSpell(108280) |
|
|
|
|
local AncestralGuidance = SpellBook:GetSpell(108281) |
|
|
|
|
local ManaTideTotem = SpellBook:GetSpell(16191) |
|
|
|
|
local Ascendance = SpellBook:GetSpell(114052) |
|
|
|
|
local NaturesSwiftness = SpellBook:GetSpell(378081) |
|
|
|
|
local EarthenWallTotem = SpellBook:GetSpell(198838) |
|
|
|
|
local PurifySpirit = SpellBook:GetSpell(77130) |
|
|
|
|
local LightningBolt = SpellBook:GetSpell(403) |
|
|
|
|
local ChainLightning = SpellBook:GetSpell(421) |
|
|
|
|
local FlameShock = SpellBook:GetSpell(188389) |
|
|
|
|
local Wellspring = SpellBook:GetSpell(197995) |
|
|
|
|
local UnleashLife = SpellBook:GetSpell(73685) |
|
|
|
|
local PrimordialWave = SpellBook:GetSpell(375982) |
|
|
|
|
local LavaBurst = SpellBook:GetSpell(51505) |
|
|
|
|
local FlameShock = SpellBook:GetSpell(188389) |
|
|
|
|
local WindShear = SpellBook:GetSpell(57994) |
|
|
|
|
local LightningBolt = SpellBook:GetSpell(403) |
|
|
|
|
|
|
|
|
|
-- Buffs |
|
|
|
|
local TidalWaves = SpellBook:GetSpell(53390) |
|
|
|
|
local HighTide = SpellBook:GetSpell(288675) |
|
|
|
|
|
|
|
|
|
-- Totem timers |
|
|
|
|
local cloudburstTotemEnd = 0 |
|
|
|
|
local healingStreamTotemEnd = 0 |
|
|
|
|
local earthenWallTotemEnd = 0 |
|
|
|
|
local spiritLinkTotemEnd = 0 |
|
|
|
|
local healingTideTotemEnd = 0 |
|
|
|
|
local WaterShieldBuff = SpellBook:GetSpell(52127) |
|
|
|
|
local EarthShieldBuff = SpellBook:GetSpell(383648) |
|
|
|
|
local UnleashLifeBuff = SpellBook:GetSpell(73685) |
|
|
|
|
|
|
|
|
|
-- Custom Units |
|
|
|
|
local Lowest = Bastion.UnitManager:CreateCustomUnit('lowest', function(unit) |
|
|
|
|
local Lowest = Bastion.UnitManager:CreateCustomUnit('lowest', function() |
|
|
|
|
local lowest = nil |
|
|
|
|
local lowestHP = math.huge |
|
|
|
|
local lowestHP = 100 |
|
|
|
|
|
|
|
|
|
Bastion.UnitManager:EnumFriends(function(unit) |
|
|
|
|
if unit:IsDead() or Player:GetDistance(unit) > 40 or not Player:CanSee(unit) then |
|
|
|
@ -65,285 +53,211 @@ local Lowest = Bastion.UnitManager:CreateCustomUnit('lowest', function(unit) |
|
|
|
|
return lowest or Player |
|
|
|
|
end) |
|
|
|
|
|
|
|
|
|
-- APLs |
|
|
|
|
local PrePullAPL = Bastion.APL:New('prepull') |
|
|
|
|
local DefaultAPL = Bastion.APL:New('default') |
|
|
|
|
local CooldownAPL = Bastion.APL:New('cooldown') |
|
|
|
|
local DamageAPL = Bastion.APL:New('damage') |
|
|
|
|
local BestTarget = Bastion.UnitManager:CreateCustomUnit('besttarget', function() |
|
|
|
|
local bestTarget = nil |
|
|
|
|
local highestHP = 0 |
|
|
|
|
|
|
|
|
|
-- Debug function |
|
|
|
|
local function Debug(message) |
|
|
|
|
-- print("[RestoShaman Debug]: " .. message) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
-- Helper Functions |
|
|
|
|
local function IsTotemActive(totemEnd) |
|
|
|
|
return GetTime() < totemEnd |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
local function UpdateTotemTimer(totemEnd, duration) |
|
|
|
|
return GetTime() + duration |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
local function ShouldUseCloudburstTotem() |
|
|
|
|
return not IsTotemActive(cloudburstTotemEnd) and (Player:GetEnemies(10) >= 3 or Player:GetPartyHPAround(30, 80) >= 3) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
local function ShouldUseHealingStreamTotem() |
|
|
|
|
return not IsTotemActive(healingStreamTotemEnd) and not CloudburstTotem:IsKnownAndUsable() |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
local function ShouldUseEarthenWallTotem() |
|
|
|
|
return not IsTotemActive(earthenWallTotemEnd) and Player:GetPartyHPAround(40, 80) >= 3 |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
local function ShouldUseSpiritLinkTotem() |
|
|
|
|
return not IsTotemActive(spiritLinkTotemEnd) and Player:GetPartyHPAround(40, 60) >= 3 |
|
|
|
|
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 |
|
|
|
|
|
|
|
|
|
local function ShouldUseHealingTideTotem() |
|
|
|
|
return not IsTotemActive(healingTideTotemEnd) and Player:GetPartyHPAround(40, 70) >= 3 |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
local function GetRiptideCount() |
|
|
|
|
local count = 0 |
|
|
|
|
Bastion.UnitManager:EnumFriends(function(unit) |
|
|
|
|
if unit:GetAuras():FindMy(Riptide):IsUp() then |
|
|
|
|
count = count + 1 |
|
|
|
|
end |
|
|
|
|
end) |
|
|
|
|
return count |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
local function ShouldUseAscendance() |
|
|
|
|
return Player:GetPartyHPAround(40, 70) >= 3 and CloudburstTotem:GetTimeSinceLastCast() < 3 |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
local function GetTanks() |
|
|
|
|
local tanks = {} |
|
|
|
|
Bastion.UnitManager:EnumFriends(function(unit) |
|
|
|
|
if unit:IsTank() and not unit:IsDead() and Player:CanSee(unit) and Player:GetDistance(unit) <= 40 then |
|
|
|
|
table.insert(tanks, unit) |
|
|
|
|
end |
|
|
|
|
return bestTarget or Target |
|
|
|
|
end) |
|
|
|
|
Debug("Found " .. #tanks .. " tanks") |
|
|
|
|
return tanks |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
local function ApplyEarthShield() |
|
|
|
|
local tanks = GetTanks() |
|
|
|
|
for _, tank in ipairs(tanks) do |
|
|
|
|
if not tank:GetAuras():FindMy(EarthShield):IsUp() then |
|
|
|
|
Debug("Applying Earth Shield to " .. tank:GetName()) |
|
|
|
|
return EarthShield:Cast(tank) |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
Debug("No tanks need Earth Shield") |
|
|
|
|
-- APLs |
|
|
|
|
local DefaultAPL = Bastion.APL:New('default') |
|
|
|
|
local CooldownAPL = Bastion.APL:New('cooldown') |
|
|
|
|
local DefensiveAPL = Bastion.APL:New('defensive') |
|
|
|
|
local DpsAPL = Bastion.APL:New('dps') |
|
|
|
|
local InterruptAPL = Bastion.APL:New('interrupt') |
|
|
|
|
|
|
|
|
|
-- Helper Functions |
|
|
|
|
local function GetPlayerManaPercent() |
|
|
|
|
return (UnitPower("player", Enum.PowerType.Mana) / UnitPowerMax("player", Enum.PowerType.Mana)) * 100 |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
local function NeedsHealing(unit, threshold) |
|
|
|
|
return unit:GetHP() < threshold |
|
|
|
|
local function NeedsUrgentHealing() |
|
|
|
|
return Lowest:GetHP() < 70 or Player:GetPartyHPAround(30, 80) >= 3 |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
-- Pre-Pull APL |
|
|
|
|
PrePullAPL:AddSpell( |
|
|
|
|
WaterShield:CastableIf(function(self) |
|
|
|
|
return Player:Exists() and self:IsKnownAndUsable() and not Player:GetAuras():FindMy(WaterShield):IsUp() |
|
|
|
|
-- Modify the EarthShield spell in the DefaultAPL |
|
|
|
|
DefaultAPL:AddSpell( |
|
|
|
|
EarthShield:CastableIf(function(self) |
|
|
|
|
local playerShield = Player:GetAuras():FindMy(EarthShieldBuff) |
|
|
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and |
|
|
|
|
(not playerShield:IsUp() or playerShield:GetRemainingTime() < 30) |
|
|
|
|
end):SetTarget(Player) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
-- Default APL |
|
|
|
|
DefaultAPL:AddSpell( |
|
|
|
|
CloudburstTotem:CastableIf(function(self) |
|
|
|
|
return Player:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and ShouldUseCloudburstTotem() |
|
|
|
|
end):SetTarget(Player):OnCast(function() |
|
|
|
|
cloudburstTotemEnd = UpdateTotemTimer(cloudburstTotemEnd, 15) |
|
|
|
|
end) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
DefaultAPL:AddSpell( |
|
|
|
|
HealingStreamTotem:CastableIf(function(self) |
|
|
|
|
return Player:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and ShouldUseHealingStreamTotem() |
|
|
|
|
end):SetTarget(Player):OnCast(function() |
|
|
|
|
healingStreamTotemEnd = UpdateTotemTimer(healingStreamTotemEnd, 15) |
|
|
|
|
end) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
DefaultAPL:AddSpell( |
|
|
|
|
Riptide:CastableIf(function(self) |
|
|
|
|
return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and NeedsHealing(Lowest, 90) |
|
|
|
|
end):SetTarget(Lowest) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
DefaultAPL:AddSpell( |
|
|
|
|
PrimordialWave:CastableIf(function(self) |
|
|
|
|
return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and NeedsHealing(Lowest, 85) |
|
|
|
|
and Lowest:GetHP() < 95 and not Lowest:GetAuras():FindMy(TidalWaves):IsUp() |
|
|
|
|
end):SetTarget(Lowest) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
DefaultAPL:AddSpell( |
|
|
|
|
UnleashLife:CastableIf(function(self) |
|
|
|
|
return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and NeedsHealing(Lowest, 80) |
|
|
|
|
and Lowest:GetHP() < 80 |
|
|
|
|
end):SetTarget(Lowest) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
DefaultAPL:AddSpell( |
|
|
|
|
HealingRain:CastableIf(function(self) |
|
|
|
|
return Player:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and Player:GetPartyHPAround(30, 85) >= 6 and not Player:IsMoving() |
|
|
|
|
end):SetTarget(Player) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
DefaultAPL:AddSpell( |
|
|
|
|
Downpour:CastableIf(function(self) |
|
|
|
|
return Player:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and Player:GetPartyHPAround(30, 80) >= 3 |
|
|
|
|
end):SetTarget(Player) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
DefaultAPL:AddSpell( |
|
|
|
|
ChainHeal:CastableIf(function(self) |
|
|
|
|
HealingSurge:CastableIf(function(self) |
|
|
|
|
return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and (Player:GetAuras():FindMy(HighTide):IsUp() or Player:GetAuras():FindMy(NaturesSwiftness):IsUp()) |
|
|
|
|
and not Player:IsMoving() and NeedsHealing(Lowest, 75) |
|
|
|
|
and Lowest:GetHP() < 70 and Player:GetAuras():FindMy(TidalWaves):IsUp() |
|
|
|
|
end):SetTarget(Lowest) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
DefaultAPL:AddSpell( |
|
|
|
|
HealingWave:CastableIf(function(self) |
|
|
|
|
return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and Player:GetAuras():FindMy(TidalWaves):IsUp() and not Player:IsMoving() |
|
|
|
|
and NeedsHealing(Lowest, 85) |
|
|
|
|
and Lowest:GetHP() < 85 |
|
|
|
|
end):SetTarget(Lowest) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
DefaultAPL:AddSpell( |
|
|
|
|
HealingSurge:CastableIf(function(self) |
|
|
|
|
return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and NeedsHealing(Lowest, 70) |
|
|
|
|
end):SetTarget(Lowest) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
DefaultAPL:AddSpell( |
|
|
|
|
PurifySpirit:CastableIf(function(self) |
|
|
|
|
return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and Lowest:GetAuras():HasAnyDispelableAura(PurifySpirit) |
|
|
|
|
ChainHeal:CastableIf(function(self) |
|
|
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and Player:GetPartyHPAround(40, 85) >= 3 |
|
|
|
|
end):SetTarget(Lowest) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
-- Cooldown APL |
|
|
|
|
CooldownAPL:AddSpell( |
|
|
|
|
SpiritLinkTotem:CastableIf(function(self) |
|
|
|
|
return Player:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and ShouldUseSpiritLinkTotem() |
|
|
|
|
end):SetTarget(Player):OnCast(function() |
|
|
|
|
spiritLinkTotemEnd = UpdateTotemTimer(spiritLinkTotemEnd, 6) |
|
|
|
|
end) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
CooldownAPL:AddSpell( |
|
|
|
|
HealingTideTotem:CastableIf(function(self) |
|
|
|
|
return Player:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and ShouldUseHealingTideTotem() |
|
|
|
|
end):SetTarget(Player):OnCast(function() |
|
|
|
|
healingTideTotemEnd = UpdateTotemTimer(healingTideTotemEnd, 10) |
|
|
|
|
end) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
CooldownAPL:AddSpell( |
|
|
|
|
AncestralGuidance:CastableIf(function(self) |
|
|
|
|
return Player:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and Player:GetPartyHPAround(40, 75) >= 3 |
|
|
|
|
CloudburstTotem:CastableIf(function(self) |
|
|
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and Player:GetPartyHPAround(40, 80) >= 3 |
|
|
|
|
end):SetTarget(Player) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
CooldownAPL:AddSpell( |
|
|
|
|
ManaTideTotem:CastableIf(function(self) |
|
|
|
|
return Player:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and Player:GetPP() <= 80 |
|
|
|
|
HealingStreamTotem:CastableIf(function(self) |
|
|
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and not CloudburstTotem:IsKnownAndUsable() and Player:GetPartyHPAround(40, 90) >= 2 |
|
|
|
|
end):SetTarget(Player) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
CooldownAPL:AddSpell( |
|
|
|
|
Ascendance:CastableIf(function(self) |
|
|
|
|
return Player:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and ShouldUseAscendance() |
|
|
|
|
SpiritLinkTotem:CastableIf(function(self) |
|
|
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and Player:GetPartyHPAround(30, 70) >= 3 |
|
|
|
|
end):SetTarget(Player) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
CooldownAPL:AddSpell( |
|
|
|
|
NaturesSwiftness:CastableIf(function(self) |
|
|
|
|
return Lowest:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and NeedsHealing(Lowest, 50) |
|
|
|
|
end):SetTarget(Lowest) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
CooldownAPL:AddSpell( |
|
|
|
|
EarthenWallTotem:CastableIf(function(self) |
|
|
|
|
return Player:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() and ShouldUseEarthenWallTotem() |
|
|
|
|
end):SetTarget(Player):OnCast(function() |
|
|
|
|
earthenWallTotemEnd = UpdateTotemTimer(earthenWallTotemEnd, 15) |
|
|
|
|
end) |
|
|
|
|
AncestralGuidance:CastableIf(function(self) |
|
|
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and Player:GetPartyHPAround(40, 75) >= 3 |
|
|
|
|
end):SetTarget(Player) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
CooldownAPL:AddSpell( |
|
|
|
|
Wellspring:CastableIf(function(self) |
|
|
|
|
return Player:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and Player:GetPartyHPAround(30, 85) >= 3 |
|
|
|
|
Ascendance:CastableIf(function(self) |
|
|
|
|
return self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and Player:GetPartyHPAround(40, 60) >= 3 |
|
|
|
|
end):SetTarget(Player) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
-- Damage APL |
|
|
|
|
DamageAPL:AddSpell( |
|
|
|
|
-- DPS APL |
|
|
|
|
DpsAPL:AddSpell( |
|
|
|
|
FlameShock:CastableIf(function(self) |
|
|
|
|
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and not Target:GetAuras():FindMy(FlameShock):IsUp() |
|
|
|
|
end):SetTarget(Target) |
|
|
|
|
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and not BestTarget:GetAuras():FindMy(FlameShock):IsUp() |
|
|
|
|
end):SetTarget(BestTarget) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
DamageAPL:AddSpell( |
|
|
|
|
DpsAPL:AddSpell( |
|
|
|
|
LavaBurst:CastableIf(function(self) |
|
|
|
|
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and Target:GetAuras():FindMy(FlameShock):IsUp() |
|
|
|
|
end):SetTarget(Target) |
|
|
|
|
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and BestTarget:GetAuras():FindMy(FlameShock):IsUp() |
|
|
|
|
end):SetTarget(BestTarget) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
DamageAPL:AddSpell( |
|
|
|
|
ChainLightning:CastableIf(function(self) |
|
|
|
|
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and Player:GetEnemies(10) > 2 |
|
|
|
|
end):SetTarget(Target) |
|
|
|
|
DpsAPL:AddSpell( |
|
|
|
|
LightningBolt:CastableIf(function(self) |
|
|
|
|
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
end):SetTarget(BestTarget) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
DamageAPL:AddSpell( |
|
|
|
|
LightningBolt:CastableIf(function(self) |
|
|
|
|
return Target:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
end):SetTarget(Target) |
|
|
|
|
-- Interrupt APL |
|
|
|
|
InterruptAPL:AddSpell( |
|
|
|
|
WindShear:CastableIf(function(self) |
|
|
|
|
return BestTarget:Exists() and self:IsKnownAndUsable() and not Player:IsCastingOrChanneling() |
|
|
|
|
and BestTarget:IsCasting() and BestTarget:IsInterruptible() |
|
|
|
|
and BestTarget:GetChannelOrCastPercentComplete() >= 50 |
|
|
|
|
end):SetTarget(BestTarget) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
-- Module Sync |
|
|
|
|
-- Modify the out of combat Earth Shield logic in the Module Sync function |
|
|
|
|
RestoShamanModule:Sync(function() |
|
|
|
|
if Player:IsMounted() then |
|
|
|
|
return |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
-- Out of combat healing and buffs |
|
|
|
|
if not Player:IsAffectingCombat() then |
|
|
|
|
-- Reset totem timers when leaving combat |
|
|
|
|
cloudburstTotemEnd = 0 |
|
|
|
|
healingStreamTotemEnd = 0 |
|
|
|
|
earthenWallTotemEnd = 0 |
|
|
|
|
spiritLinkTotemEnd = 0 |
|
|
|
|
healingTideTotemEnd = 0 |
|
|
|
|
|
|
|
|
|
if not Player:GetAuras():FindMy(WaterShield):IsUp() then |
|
|
|
|
if not Player:GetAuras():FindMy(WaterShieldBuff):IsUp() then |
|
|
|
|
WaterShield:Cast(Player) |
|
|
|
|
elseif not Player:GetAuras():FindMy(EarthShieldBuff):IsUp() then |
|
|
|
|
EarthShield:Cast(Player) |
|
|
|
|
elseif Lowest:GetHP() < 90 then |
|
|
|
|
DefaultAPL:Execute() |
|
|
|
|
end |
|
|
|
|
return |
|
|
|
|
end |
|
|
|
|
ApplyEarthShield() |
|
|
|
|
elseif Player:IsAffectingCombat() then |
|
|
|
|
ApplyEarthShield() |
|
|
|
|
|
|
|
|
|
-- In combat |
|
|
|
|
InterruptAPL:Execute() |
|
|
|
|
|
|
|
|
|
if NeedsUrgentHealing() then |
|
|
|
|
CooldownAPL:Execute() |
|
|
|
|
DefaultAPL:Execute() |
|
|
|
|
else |
|
|
|
|
if GetPlayerManaPercent() > 80 and BestTarget:Exists() then |
|
|
|
|
DpsAPL:Execute() |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
-- Use damage abilities when healing isn't needed |
|
|
|
|
if Player:GetPP() > 80 and Player:GetPartyHPAround(40, 95) == 0 then |
|
|
|
|
DamageAPL:Execute() |
|
|
|
|
if Riptide:GetCharges() >= 2 then |
|
|
|
|
Bastion.UnitManager:EnumFriends(function(unit) |
|
|
|
|
if unit:GetHP() < 95 and not unit:GetAuras():FindMy(TidalWaves):IsUp() then |
|
|
|
|
Riptide:Cast(unit) |
|
|
|
|
return true -- Stop enumerating after casting |
|
|
|
|
end |
|
|
|
|
end) |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
if HealingWave:IsKnownAndUsable() and Lowest:GetHP() < 90 then |
|
|
|
|
HealingWave:Cast(Lowest) |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
|
|
|
|
|
-- AoE Healing |
|
|
|
|
if Player:GetPartyHPAround(30, 85) >= 4 then |
|
|
|
|
if HealingRain:IsKnownAndUsable() then |
|
|
|
|
local loc = Bastion.UnitManager:FindFriendsCentroid(10, 40) |
|
|
|
|
if loc then |
|
|
|
|
HealingRain:Cast(Player):OnCast(function(self) |
|
|
|
|
self:Click(loc) |
|
|
|
|
end) |
|
|
|
|
end |
|
|
|
|
elseif Downpour:IsKnownAndUsable() then |
|
|
|
|
local loc = Bastion.UnitManager:FindFriendsCentroid(10, 40) |
|
|
|
|
if loc then |
|
|
|
|
Downpour:Cast(Player):OnCast(function(self) |
|
|
|
|
self:Click(loc) |
|
|
|
|
end) |
|
|
|
|
end |
|
|
|
|
elseif Wellspring:IsKnownAndUsable() then |
|
|
|
|
Wellspring:Cast(Player) |
|
|
|
|
end |
|
|
|
|
end |
|
|
|
|
end) |
|
|
|
|