From e59adea75639652a187a6e421856de99a9e7fec1 Mon Sep 17 00:00:00 2001 From: sundance Date: Mon, 30 Jan 2023 14:53:25 +0200 Subject: [PATCH] add base enhancement shaman --- scripts/enhancement.lua | 901 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 901 insertions(+) create mode 100644 scripts/enhancement.lua diff --git a/scripts/enhancement.lua b/scripts/enhancement.lua new file mode 100644 index 0000000..387c94b --- /dev/null +++ b/scripts/enhancement.lua @@ -0,0 +1,901 @@ +---@type _, Bastion +local Tinkr, Bastion = ... + +-- Core +local EnhancementModule = Bastion.Module:New('enhancement') +local Evaluator = Tinkr.Util.Evaluator +local Time = Bastion.CombatTimer +local Notifications = Bastion.Notifications +local UnitManager = Bastion.UnitManager + +-- Targets +local Player = Bastion.UnitManager:Get('player') +local None = Bastion.UnitManager:Get('none') +local Target = Bastion.UnitManager:Get('target') + +-- Spells +local Ascendance = Bastion.SpellBook:GetSpell(114051) +local AshenCatalyst = Bastion.SpellBook:GetSpell(390370) +local ChainLightning = Bastion.SpellBook:GetSpell(188443) +local ConvergingStorms = Bastion.SpellBook:GetSpell(384363) +local CrashingStorms = Bastion.SpellBook:GetSpell(334308) +local CrashLightning = Bastion.SpellBook:GetSpell(187874) +local DeeplyRootedElements = Bastion.SpellBook:GetSpell(378270) +local DoomWinds = Bastion.SpellBook:GetSpell(384352) +local EarthElemental = Bastion.SpellBook:GetSpell(198103) +local EarthShield = Bastion.SpellBook:GetSpell(974) +local ElementalBlast = Bastion.SpellBook:GetSpell(117014) +local ElementalSpirits = Bastion.SpellBook:GetSpell(262624) +local FeralSpirit = Bastion.SpellBook:GetSpell(51533) +local FireNova = Bastion.SpellBook:GetSpell(333974) +local FlameShock = Bastion.SpellBook:GetSpell(188389) +local FlametongueWeapon = Bastion.SpellBook:GetSpell(318038) +local FrostShock = Bastion.SpellBook:GetSpell(196840) +local Hailstorm = Bastion.SpellBook:GetSpell(334195) +local HotHand = Bastion.SpellBook:GetSpell(201900) +local IceStrike = Bastion.SpellBook:GetSpell(342240) +local LashingFlames = Bastion.SpellBook:GetSpell(334046) +local LavaBurst = Bastion.SpellBook:GetSpell(51505) +local LavaLash = Bastion.SpellBook:GetSpell(60103) +local LightningBolt = Bastion.SpellBook:GetSpell(188196) +local LightningShield = Bastion.SpellBook:GetSpell(192106) +local MaelstromWeapon = Bastion.SpellBook:GetSpell(187880) +local MoltenAssault = Bastion.SpellBook:GetSpell(334033) +local OverflowingMaelstrom = Bastion.SpellBook:GetSpell(384149) +local PrimordialWave = Bastion.SpellBook:GetSpell(375982) +local SplinteredElements = Bastion.SpellBook:GetSpell(382042) +local Stormstrike = Bastion.SpellBook:GetSpell(17364) +local Sundering = Bastion.SpellBook:GetSpell(197214) +local SwirlingMaelstrom = Bastion.SpellBook:GetSpell(384359) +local ThorimsInvocation = Bastion.SpellBook:GetSpell(384444) +local WindfuryTotem = Bastion.SpellBook:GetSpell(8512) +local WindfuryWeapon = Bastion.SpellBook:GetSpell(33757) +local Windstrike = Bastion.SpellBook:GetSpell(115356) +local MaelstromOfElements = Bastion.SpellBook:GetSpell(394677) +local EarthenWeapon = Bastion.SpellBook:GetSpell(392375) +local LegacyOfTheFrostWitch = Bastion.SpellBook:GetSpell(335901) + +local WindfuryWeaponEnchant = 5401 +local FlametongueWeaponEnchant = 5400 + +-- Internal +local TILightningBolt = false +local TIChainLightning = false + +-- Powers +local Maelstrom = Enum.PowerType.Maelstrom + +-- APLs +local NonCombatAPL = Bastion.APL:New('resting') +local DefaultAPL = Bastion.APL:New('default') +local MultiTargetAPL = Bastion.APL:New('multi') +local SingleTargetAPL = Bastion.APL:New('single') + +-- Special Functionality + +---Get the amount of time remaining for a weapon enchant. +---@param spell number +---@return number +local function WeaponEnchantRemaining(spell, mainhand) + local hasMainHandEnchant, mainHandExpiration, mainHandCharges, mainHandEnchantID, hasOffHandEnchant, offHandExpiration, offHandCharges, offHandEnchantID = GetWeaponEnchantInfo() + + if mainhand then + if hasMainHandEnchant == false then return 0 end + if spell == mainHandEnchantID then + return mainHandExpiration - GetTime() + end + else + if hasOffHandEnchant == false then return 0 end + if spell == offHandEnchantID then + return offHandExpiration - GetTime() + end + end + + return 0 +end + +---@param spell Spell +---@return number +local function ActiveDot(spell) + return UnitManager:GetNumEnemiesWithDebuff(spell) +end + +---@param spell Spell +---@return number +local function TotemDurationRemaining(spell) + for index = 1, MAX_TOTEMS do + local arg1, totemName, startTime, duration, icon = GetTotemInfo(index) + if totemName == spell:GetName() then + return duration - (GetTime() - startTime) + end + end + return 0 +end + +-- # Executed every time the actor is available. + +-- prepull +-- actions=bloodlust,line_cd=600 +-- actions+=/potion,if=(talent.ascendance.enabled&raid_event.adds.in>=90&cooldown.ascendance.remains<10)|(talent.doom_winds.enabled&buff.doom_winds.up)|(!talent.doom_winds.enabled&!talent.ascendance.enabled&talent.feral_spirit.enabled&buff.feral_spirit.up)|(!talent.doom_winds.enabled&!talent.ascendance.enabled&!talent.feral_spirit.enabled)|active_enemies>1|fight_remains<30 + +-- actions+=/auto_attack + +-- items +-- actions+=/use_item,name=the_first_sigil,if=(talent.ascendance.enabled&raid_event.adds.in>=90&cooldown.ascendance.remains<10)|(talent.hot_hand.enabled&buff.molten_weapon.up)|buff.icy_edge.up|(talent.stormflurry.enabled&buff.crackling_surge.up)|active_enemies>1|fight_remains<30 +-- actions+=/use_item,name=cache_of_acquired_treasures,if=buff.acquired_sword.up|fight_remains<25 +-- actions+=/use_item,name=scars_of_fraternal_strife,if=!buff.scars_of_fraternal_strife_4.up|fight_remains<31|raid_event.adds.in<16|active_enemies>1 +-- actions+=/use_items,slots=trinket1,if=!variable.trinket1_is_weird +-- actions+=/use_items,slots=trinket2,if=!variable.trinket2_is_weird + +-- racials +-- actions+=/blood_fury,if=!talent.ascendance.enabled|buff.ascendance.up|cooldown.ascendance.remains>50 +-- actions+=/berserking,if=!talent.ascendance.enabled|buff.ascendance.up +-- actions+=/fireblood,if=!talent.ascendance.enabled|buff.ascendance.up|cooldown.ascendance.remains>50 +-- actions+=/ancestral_call,if=!talent.ascendance.enabled|buff.ascendance.up|cooldown.ascendance.remains>50 + + +NonCombatAPL:AddSpell( + WindfuryWeapon:CastableIf(function(spell) + return WindfuryWeapon:IsKnownAndUsable() and WeaponEnchantRemaining(WindfuryWeaponEnchant, true) < (60 * 10) + end):SetTarget(Player) +) + +NonCombatAPL:AddSpell( + FlametongueWeapon:CastableIf(function(spell) + return FlametongueWeapon:IsKnownAndUsable() and + WeaponEnchantRemaining(FlametongueWeaponEnchant, false) < (60 * 10) + end):SetTarget(Player) +) + +NonCombatAPL:AddSpell( + LightningShield:CastableIf(function(spell) + return LightningShield:IsKnownAndUsable() and not Player:GetAuras():FindMy(LightningShield):IsUp() + end):SetTarget(Player) +) + +NonCombatAPL:AddSpell( + EarthShield:CastableIf(function(spell) + return EarthShield:IsKnownAndUsable() and not Player:GetAuras():FindMy(EarthShield):IsUp() + end):SetTarget(Player) +) + +-- actions+=/feral_spirit +DefaultAPL:AddSpell( + FeralSpirit:CastableIf(function(spell) + return spell:IsKnownAndUsable() + end):SetTarget(Player) +) + +-- actions+=/ascendance,if=(ti_lightning_bolt&active_enemies=1&raid_event.adds.in>=90)|(ti_chain_lightning&active_enemies>1) +DefaultAPL:AddSpell( + Ascendance:CastableIf(function(spell) + return TILightningBolt and Player:GetEnemies(20) == 1 or TIChainLightning and Player:GetEnemies(20) > 1 + end):SetTarget(Player) +) + +-- actions+=/doom_winds,if=raid_event.adds.in>=90|active_enemies>1 +DefaultAPL:AddSpell( + DoomWinds:CastableIf(function(spell) + return Player:GetEnemies(20) > 1 + end):SetTarget(Player) +) + +-- # If_only_one_enemy,_priority_follows_the_'single'_action_list. +-- actions+=/call_action_list,name=single,if=active_enemies=1 +DefaultAPL:AddAPL(SingleTargetAPL, function() + return Player:GetEnemies(20) == 1 +end) + +-- # On_multiple_enemies,_the_priority_follows_the_'aoe'_action_list. +-- actions+=/call_action_list,name=aoe,if=active_enemies>1 +DefaultAPL:AddAPL(MultiTargetAPL, function() + return Player:GetEnemies(20) > 1 +end) + +-- # Multi target action priority list +-- actions.aoe=crash_lightning,if=buff.doom_winds.up|!buff.crash_lightning.up +MultiTargetAPL:AddSpell( + CrashLightning:CastableIf(function(spell) + return Player:GetAuras():FindMy(DoomWinds):IsUp() or not Player:GetAuras():FindMy(CrashLightning):IsUp() + end):SetTarget(Player) +) + +-- actions.aoe+=/lightning_bolt,if=(active_dot.flame_shock=active_enemies|active_dot.flame_shock=6)&buff.primordial_wave.up&buff.maelstrom_weapon.stack>=(5+5*talent.overflowing_maelstrom.enabled)&(!buff.splintered_elements.up|fight_remains<=12|raid_event.adds.remains<=gcd) +MultiTargetAPL:AddSpell( + LightningBolt:CastableIf(function(spell) + return ( + ActiveDot(FlameShock) == Player:GetEnemies(20) or + ActiveDot(FlameShock) == 6) and Player:GetAuras():FindMy(PrimordialWave):IsUp() + and + Player:GetAuras():FindMy(MaelstromWeapon):GetCount() >= + (5 + 5 * (OverflowingMaelstrom:IsKnown() and 1 or 0) + ) and + ( + not Player:GetAuras():FindMy(SplinteredElements):IsUp() or Target:TimeToDie() <= 12 or + Player:GetEnemies(20) <= 1) + end):SetTarget(Target):OnCast(function(spell) + TILightningBolt = true + TIChainLightning = false + end) +) + +-- actions.aoe+=/sundering,if=buff.doom_winds.up +MultiTargetAPL:AddSpell( + Sundering:CastableIf(function(spell) + return Player:GetAuras():FindMy(DoomWinds):IsUp() + end):SetTarget(Player) +) + +-- actions.aoe+=/fire_nova,if=active_dot.flame_shock=6|(active_dot.flame_shock>=4&active_dot.flame_shock=active_enemies) +MultiTargetAPL:AddSpell( + FireNova:CastableIf(function(spell) + return ActiveDot(FlameShock) == 6 or + (ActiveDot(FlameShock) >= 4 and ActiveDot(FlameShock) == Player:GetEnemies(20)) + end):SetTarget(Player) +) + +-- actions.aoe+=/primordial_wave,target_if=min:dot.flame_shock.remains,cycle_targets=1,if=!buff.primordial_wave.up +-- target_if=min:dot.flame_shock.remains,cycle_targets=1 +local PrimordialWaveTarget = Bastion.UnitManager:CreateCustomUnit('primordial', function() + local target = nil + local max = math.huge + + Bastion.UnitManager:EnumEnemies(function(unit) + if Player:IsFacing(unit) then + local remains = unit:GetAuras():Find(FlameShock):GetRemainingTime() + if remains < max then + target = unit + max = remains + end + end + + return false + end) + + if target == nil then + target = None + end + + return target +end) + +-- if=!buff.primordial_wave.up +MultiTargetAPL:AddSpell( + PrimordialWave:CastableIf(function(spell) + return not Player:GetAuras():FindMy(PrimordialWave):IsUp() + end):SetTarget(PrimordialWaveTarget) +) + +-- actions.aoe+=/windstrike,if=talent.thorims_invocation.enabled&ti_chain_lightning&buff.maelstrom_weapon.stack>1 +MultiTargetAPL:AddSpell( + Windstrike:CastableIf(function(spell) + return ThorimsInvocation:IsKnown() and TIChainLightning and + Player:GetAuras():FindMy(MaelstromWeapon):GetCount() > 1 + end):SetTarget(Target) +) + +-- actions.aoe+=/lava_lash,target_if=min:debuff.lashing_flames.remains,cycle_targets=1,if=talent.lashing_flames.enabled&dot.flame_shock.ticking&(active_dot.flame_shock=4 +MultiTargetAPL:AddSpell( + FireNova:CastableIf(function(spell) + return ActiveDot(FlameShock) >= 4 + end):SetTarget(Target) +) + +-- actions.aoe+=/lava_lash,target_if=min:debuff.lashing_flames.remains,cycle_targets=1,if=talent.lashing_flames.enabled +-- target_if=min:debuff.lashing_flames.remains,cycle_targets=1 +MultiTargetAPL:AddSpell( + LavaLash:CastableIf(function(spell) + return LashingFlames:IsKnown() + end):SetTarget(LavaLashTarget) +) + +-- actions.aoe+=/fire_nova,if=active_dot.flame_shock>=3 +MultiTargetAPL:AddSpell( + FireNova:CastableIf(function(spell) + return ActiveDot(FlameShock) >= 3 + end):SetTarget(Target) +) + +-- actions.aoe+=/elemental_blast,if=(!talent.elemental_spirits.enabled|(talent.elemental_spirits.enabled&(charges=max_charges|buff.feral_spirit.up)))&buff.maelstrom_weapon.stack=10&(!talent.crashing_storms.enabled|active_enemies<=3) +MultiTargetAPL:AddSpell( + ElementalBlast:CastableIf(function(spell) + return (not ElementalSpirits:IsKnown() or (ElementalSpirits:IsKnown() and + (ElementalBlast:GetCharges() == ElementalBlast:GetMaxCharges() or + Player:GetAuras():FindMy(FeralSpirit):IsUp()))) and + Player:GetAuras():FindMy(MaelstromWeapon):GetCount() == 10 and + (not CrashingStorms:IsKnown() or Player:GetEnemies(20) <= 3) + end):SetTarget(Target) +) + +-- actions.aoe+=/chain_lightning,if=buff.maelstrom_weapon.stack=10 +MultiTargetAPL:AddSpell( + ChainLightning:CastableIf(function(spell) + return Player:GetAuras():FindMy(MaelstromWeapon):GetCount() == 10 + end):SetTarget(Target):OnCast(function(spell) + TIChainLightning = true + TILightningBolt = false + end) +) + +-- actions.aoe+=/crash_lightning,if=buff.cl_crash_lightning.up +MultiTargetAPL:AddSpell( + CrashLightning:CastableIf(function(spell) + return Player:GetAuras():FindMy(CrashLightning):IsUp() + end):SetTarget(Target) +) + +-- actions.aoe+=/lava_lash,if=buff.crash_lightning.up&buff.ashen_catalyst.stack=8 +MultiTargetAPL:AddSpell( + LavaLash:CastableIf(function(spell) + return Player:GetAuras():FindMy(CrashLightning):IsUp() and + Player:GetAuras():FindMy(AshenCatalyst):GetCount() == 8 + end):SetTarget(Target) +) + +-- actions.aoe+=/windstrike,if=buff.crash_lightning.up +MultiTargetAPL:AddSpell( + Windstrike:CastableIf(function(spell) + return Player:GetAuras():FindMy(CrashLightning):IsUp() + end):SetTarget(Target) +) + +-- actions.aoe+=/stormstrike,if=buff.crash_lightning.up&(buff.converging_storms.stack=6|(set_bonus.tier29_2pc&buff.maelstrom_of_elements.down&buff.maelstrom_weapon.stack<=5)) +MultiTargetAPL:AddSpell( + Stormstrike:CastableIf(function(spell) + return Player:GetAuras():FindMy(CrashLightning):IsUp() and + (Player:GetAuras():FindMy(ConvergingStorms):GetCount() == 6 or + (Player:GetAuras():FindMy(MaelstromOfElements):IsDown() and + Player:GetAuras():FindMy(MaelstromWeapon):GetCount() <= 5)) + end):SetTarget(Target) +) + +-- actions.aoe+=/lava_lash,if=buff.crash_lightning.up,if=talent.molten_assault.enabled +MultiTargetAPL:AddSpell( + LavaLash:CastableIf(function(spell) + return Player:GetAuras():FindMy(CrashLightning):IsUp() and MoltenAssault:IsKnown() + end):SetTarget(Target) +) + +-- actions.aoe+=/ice_strike,if=buff.crash_lightning.up,if=talent.swirling_maelstrom.enabled +MultiTargetAPL:AddSpell( + IceStrike:CastableIf(function(spell) + return Player:GetAuras():FindMy(CrashLightning):IsUp() and SwirlingMaelstrom:IsKnown() + end):SetTarget(Target) +) + +-- actions.aoe+=/stormstrike,if=buff.crash_lightning.up +MultiTargetAPL:AddSpell( + Stormstrike:CastableIf(function(spell) + return Player:GetAuras():FindMy(CrashLightning):IsUp() + end):SetTarget(Target) +) + +-- actions.aoe+=/ice_strike,if=buff.crash_lightning.up +MultiTargetAPL:AddSpell( + IceStrike:CastableIf(function(spell) + return Player:GetAuras():FindMy(CrashLightning):IsUp() + end):SetTarget(Target) +) + +-- actions.aoe+=/lava_lash,if=buff.crash_lightning.up +MultiTargetAPL:AddSpell( + LavaLash:CastableIf(function(spell) + return Player:GetAuras():FindMy(CrashLightning):IsUp() + end):SetTarget(Target) +) + +-- actions.aoe+=/elemental_blast,if=(!talent.elemental_spirits.enabled|(talent.elemental_spirits.enabled&(charges=max_charges|buff.feral_spirit.up)))&buff.maelstrom_weapon.stack>=5&(!talent.crashing_storms.enabled|active_enemies<=3) +MultiTargetAPL:AddSpell( + ElementalBlast:CastableIf(function(spell) + return (not ElementalSpirits:IsKnown() or (ElementalSpirits:IsKnown() and + (ElementalBlast:GetCharges() == ElementalBlast:GetMaxCharges() or + Player:GetAuras():FindMy(FeralSpirit):IsUp()))) and + Player:GetAuras():FindMy(MaelstromWeapon):GetCount() >= 5 and + (not CrashingStorms:IsKnown() or Player:GetEnemies(20) <= 3) + end):SetTarget(Target) +) + +-- actions.aoe+=/fire_nova,if=active_dot.flame_shock>=2 +MultiTargetAPL:AddSpell( + FireNova:CastableIf(function(spell) + return Player:GetAuras():FindMy(FlameShock):GetCount() >= 2 + end):SetTarget(Target) +) + +-- actions.aoe+=/crash_lightning +MultiTargetAPL:AddSpell( + CrashLightning:CastableIf(function(spell) + return CrashLightning:IsKnownAndUsable() + end):SetTarget(Target) +) + +-- actions.aoe+=/windstrike +MultiTargetAPL:AddSpell( + Windstrike:CastableIf(function(spell) + return Windstrike:IsKnownAndUsable() + end):SetTarget(Target) +) + +-- actions.aoe+=/lava_lash,if=talent.molten_assault.enabled +MultiTargetAPL:AddSpell( + LavaLash:CastableIf(function(spell) + return MoltenAssault:IsKnown() + end):SetTarget(Target) +) + +-- actions.aoe+=/ice_strike,if=talent.swirling_maelstrom.enabled +MultiTargetAPL:AddSpell( + IceStrike:CastableIf(function(spell) + return SwirlingMaelstrom:IsKnown() + end):SetTarget(Target) +) + +-- actions.aoe+=/stormstrike +MultiTargetAPL:AddSpell( + Stormstrike:CastableIf(function(spell) + return Stormstrike:IsKnownAndUsable() + end):SetTarget(Target) +) + +-- actions.aoe+=/ice_strike +MultiTargetAPL:AddSpell( + IceStrike:CastableIf(function(spell) + return IceStrike:IsKnownAndUsable() + end):SetTarget(Target) +) + +-- actions.aoe+=/lava_lash +MultiTargetAPL:AddSpell( + LavaLash:CastableIf(function(spell) + return LavaLash:IsKnownAndUsable() + end):SetTarget(Target) +) + +-- actions.aoe+=/flame_shock,target_if=refreshable,cycle_targets=1 +MultiTargetAPL:AddSpell( + FlameShock:CastableIf(function(spell) + return FlameShock:IsKnownAndUsable() -- refreshable + end):SetTarget(Target) +) + +-- actions.aoe+=/frost_shock +MultiTargetAPL:AddSpell( + FrostShock:CastableIf(function(spell) + return FrostShock:IsKnownAndUsable() + end):SetTarget(Target) +) + +-- actions.aoe+=/chain_lightning,if=buff.maelstrom_weapon.stack>=5 +MultiTargetAPL:AddSpell( + ChainLightning:CastableIf(function(spell) + return Player:GetAuras():FindMy(MaelstromWeapon):GetCount() >= 5 + end):SetTarget(Target):OnCast(function(spell) + TIChainLightning = true + TILightningBolt = false + end) +) + +-- actions.aoe+=/earth_elemental +MultiTargetAPL:AddSpell( + EarthElemental:CastableIf(function(spell) + return EarthElemental:IsKnownAndUsable() + end):SetTarget(Target) +) + +-- actions.aoe+=/windfury_totem,if=buff.windfury_totem.remains<30 +MultiTargetAPL:AddSpell( + WindfuryTotem:CastableIf(function(spell) + return WindfuryTotem:IsKnownAndUsable() and + TotemDurationRemaining(WindfuryTotem) < 30 + end):SetTarget(Target) +) + +-- # Single target action priority list +-- actions.single=windstrike,if=talent.thorims_invocation.enabled&buff.maelstrom_weapon.stack>=1 +SingleTargetAPL:AddSpell( + Windstrike:CastableIf(function(spell) + return ThorimsInvocation:IsKnown() and + Player:GetAuras():FindMy(MaelstromWeapon):GetCount() >= 1 + end):SetTarget(Target) +) + +-- actions.single+=/lava_lash,if=buff.hot_hand.up|buff.ashen_catalyst.stack=8|(buff.ashen_catalyst.stack>=5&buff.maelstrom_of_elements.up&buff.maelstrom_weapon.stack<=6) +SingleTargetAPL:AddSpell( + LavaLash:CastableIf(function(spell) + return Player:GetAuras():FindMy(HotHand):IsUp() or + Player:GetAuras():FindMy(AshenCatalyst):GetCount() == 8 or + (Player:GetAuras():FindMy(AshenCatalyst):GetCount() >= 5 and + Player:GetAuras():FindMy(MaelstromOfElements):IsUp() and + Player:GetAuras():FindMy(MaelstromWeapon):GetCount() <= 6) + end):SetTarget(Target) +) + +-- actions.single+=/windfury_totem,if=!buff.windfury_totem.up +SingleTargetAPL:AddSpell( + WindfuryTotem:CastableIf(function(spell) + return WindfuryTotem:IsKnownAndUsable() and + TotemDurationRemaining(WindfuryTotem) == 0 + end):SetTarget(Target) +) + +-- actions.single+=/stormstrike,if=buff.doom_winds.up +SingleTargetAPL:AddSpell( + Stormstrike:CastableIf(function(spell) + return Stormstrike:IsKnownAndUsable() and + Player:GetAuras():FindMy(DoomWinds):IsUp() + end):SetTarget(Target) +) + +-- actions.single+=/crash_lightning,if=buff.doom_winds.up +SingleTargetAPL:AddSpell( + CrashLightning:CastableIf(function(spell) + return CrashLightning:IsKnownAndUsable() and + Player:GetAuras():FindMy(DoomWinds):IsUp() + end):SetTarget(Target) +) + +-- actions.single+=/ice_strike,if=buff.doom_winds.up +SingleTargetAPL:AddSpell( + IceStrike:CastableIf(function(spell) + return IceStrike:IsKnownAndUsable() and + Player:GetAuras():FindMy(DoomWinds):IsUp() + end):SetTarget(Target) +) + +-- actions.single+=/sundering,if=buff.doom_winds.up +SingleTargetAPL:AddSpell( + Sundering:CastableIf(function(spell) + return Sundering:IsKnownAndUsable() and + Player:GetAuras():FindMy(DoomWinds):IsUp() + end):SetTarget(Target) +) + +-- actions.single+=/primordial_wave,if=buff.primordial_wave.down&(raid_event.adds.in>42|raid_event.adds.in<6) +SingleTargetAPL:AddSpell( + PrimordialWave:CastableIf(function(spell) + return PrimordialWave:IsKnownAndUsable() and + not Player:GetAuras():FindMy(PrimordialWave):IsUp() + end):SetTarget(Target) +) + +-- actions.single+=/flame_shock,if=!ticking +SingleTargetAPL:AddSpell( + FlameShock:CastableIf(function(spell) + return FlameShock:IsKnownAndUsable() and + not Target:GetAuras():FindMy(FlameShock):IsUp() + end):SetTarget(Target) +) + +-- actions.single+=/lightning_bolt,if=buff.maelstrom_weapon.stack>=5&buff.primordial_wave.up&raid_event.adds.in>buff.primordial_wave.remains&(!buff.splintered_elements.up|fight_remains<=12) +SingleTargetAPL:AddSpell( + LightningBolt:CastableIf(function(spell) + return Player:GetAuras():FindMy(MaelstromWeapon):GetCount() >= 5 and + Player:GetAuras():FindMy(PrimordialWave):IsUp() and + not Player:GetAuras():FindMy(SplinteredElements):IsUp() + end):SetTarget(Target):OnCast(function(spell) + TIChainLightning = false + TILightningBolt = true + end) +) + +-- actions.single+=/elemental_blast,if=talent.elemental_spirits.enabled&(charges=max_charges|buff.feral_spirit.up)&buff.maelstrom_weapon.stack>=8 +SingleTargetAPL:AddSpell( + ElementalBlast:CastableIf(function(spell) + return ElementalBlast:IsKnownAndUsable() and + ElementalSpirits:IsKnown() and + ElementalBlast:GetCharges() == ElementalBlast:GetMaxCharges() and + Player:GetAuras():FindMy(MaelstromWeapon):GetCount() >= 8 + end):SetTarget(Target) +) + +-- actions.single+=/ice_strike,if=talent.hailstorm.enabled +SingleTargetAPL:AddSpell( + IceStrike:CastableIf(function(spell) + return IceStrike:IsKnownAndUsable() and + Hailstorm:IsKnown() + end):SetTarget(Target) +) + +-- actions.single+=/stormstrike,if=set_bonus.tier29_2pc&buff.maelstrom_of_elements.down&buff.maelstrom_weapon.stack<=5 +SingleTargetAPL:AddSpell( + Stormstrike:CastableIf(function(spell) + return Stormstrike:IsKnownAndUsable() and + Player:GetAuras():FindMy(MaelstromOfElements):IsDown() and + Player:GetAuras():FindMy(MaelstromWeapon):GetCount() <= 5 + end):SetTarget(Target) +) + +-- actions.single+=/frost_shock,if=buff.hailstorm.up +SingleTargetAPL:AddSpell( + FrostShock:CastableIf(function(spell) + return FrostShock:IsKnownAndUsable() and + Player:GetAuras():FindMy(Hailstorm):IsUp() + end):SetTarget(Target) +) + +-- actions.single+=/lava_lash,if=talent.molten_assault.enabled&dot.flame_shock.refreshable +SingleTargetAPL:AddSpell( + LavaLash:CastableIf(function(spell) + return LavaLash:IsKnownAndUsable() and + MoltenAssault:IsKnown() and + true -- Target:GetAuras():FindMy(FlameShock):IsRefreshable() + end):SetTarget(Target) +) + +-- actions.single+=/windstrike,if=talent.deeply_rooted_elements.enabled|buff.earthen_weapon.up|buff.legacy_of_the_frost_witch.up +SingleTargetAPL:AddSpell( + Windstrike:CastableIf(function(spell) + return Windstrike:IsKnownAndUsable() and + (DeeplyRootedElements:IsKnown() or + Player:GetAuras():FindMy(EarthenWeapon):IsUp() or + Player:GetAuras():FindMy(LegacyOfTheFrostWitch):IsUp()) + end):SetTarget(Target) +) + +-- actions.single+=/stormstrike,if=talent.deeply_rooted_elements.enabled|buff.earthen_weapon.up|buff.legacy_of_the_frost_witch.up +SingleTargetAPL:AddSpell( + Stormstrike:CastableIf(function(spell) + return Stormstrike:IsKnownAndUsable() and + (DeeplyRootedElements:IsKnown() or + Player:GetAuras():FindMy(EarthenWeapon):IsUp() or + Player:GetAuras():FindMy(LegacyOfTheFrostWitch):IsUp()) + end):SetTarget(Target) +) + +-- actions.single+=/elemental_blast,if=(talent.elemental_spirits.enabled&buff.maelstrom_weapon.stack=10)|(!talent.elemental_spirits.enabled&buff.maelstrom_weapon.stack>=5) +SingleTargetAPL:AddSpell( + ElementalBlast:CastableIf(function(spell) + return ElementalBlast:IsKnownAndUsable() and + ((ElementalSpirits:IsKnown() and + Player:GetAuras():FindMy(MaelstromWeapon):GetCount() == 10) or + (not ElementalSpirits:IsKnown() and + Player:GetAuras():FindMy(MaelstromWeapon):GetCount() >= 5)) + end):SetTarget(Target) +) + +-- actions.single+=/lava_burst,if=buff.maelstrom_weapon.stack>=5 +SingleTargetAPL:AddSpell( + LavaBurst:CastableIf(function(spell) + return LavaBurst:IsKnownAndUsable() and + Player:GetAuras():FindMy(MaelstromWeapon):GetCount() >= 5 + end):SetTarget(Target) +) + +-- actions.single+=/lightning_bolt,if=buff.maelstrom_weapon.stack=10&buff.primordial_wave.down +SingleTargetAPL:AddSpell( + LightningBolt:CastableIf(function(spell) + return LightningBolt:IsKnownAndUsable() and + Player:GetAuras():FindMy(MaelstromWeapon):GetCount() == 10 and + Player:GetAuras():FindMy(PrimordialWave):IsDown() + end):SetTarget(Target) +) + +-- actions.single+=/windstrike +SingleTargetAPL:AddSpell( + Windstrike:CastableIf(function(spell) + return Windstrike:IsKnownAndUsable() + end):SetTarget(Target) +) + +-- actions.single+=/stormstrike +SingleTargetAPL:AddSpell( + Stormstrike:CastableIf(function(spell) + return Stormstrike:IsKnownAndUsable() + end):SetTarget(Target) +) + +-- actions.single+=/windfury_totem,if=buff.windfury_totem.remains<10 +SingleTargetAPL:AddSpell( + WindfuryTotem:CastableIf(function(spell) + return WindfuryTotem:IsKnownAndUsable() and + TotemDurationRemaining(WindfuryTotem) < 10 + end):SetTarget(Target) +) + +-- actions.single+=/ice_strike +SingleTargetAPL:AddSpell( + IceStrike:CastableIf(function(spell) + return IceStrike:IsKnownAndUsable() + end):SetTarget(Target) +) + +-- actions.single+=/lava_lash +SingleTargetAPL:AddSpell( + LavaLash:CastableIf(function(spell) + return LavaLash:IsKnownAndUsable() + end):SetTarget(Target) +) + +-- actions.single+=/elemental_blast,if=talent.elemental_spirits.enabled&(charges=max_charges|buff.feral_spirit.up)&buff.maelstrom_weapon.stack>=5 +SingleTargetAPL:AddSpell( + ElementalBlast:CastableIf(function(spell) + return ElementalBlast:IsKnownAndUsable() and + ElementalSpirits:IsKnown() and + (ElementalBlast:GetCharges() == ElementalBlast:GetMaxCharges() or + Player:GetAuras():FindMy(FeralSpirit):IsUp()) and + Player:GetAuras():FindMy(MaelstromWeapon):GetCount() >= 5 + end):SetTarget(Target) +) + +-- actions.single+=/bag_of_tricks +-- NYI + +-- actions.single+=/lightning_bolt,if=buff.maelstrom_weapon.stack>=5&buff.primordial_wave.down +SingleTargetAPL:AddSpell( + LightningBolt:CastableIf(function(spell) + return LightningBolt:IsKnownAndUsable() and + Player:GetAuras():FindMy(MaelstromWeapon):GetCount() >= 5 and + Player:GetAuras():FindMy(PrimordialWave):IsDown() + end):SetTarget(Target) +) + +-- actions.single+=/sundering,if=raid_event.adds.in>=40 +SingleTargetAPL:AddSpell( + Sundering:CastableIf(function(spell) + return Sundering:IsKnownAndUsable() + end):SetTarget(Target) +) + +-- actions.single+=/fire_nova,if=talent.swirling_maelstrom.enabled&active_dot.flame_shock +SingleTargetAPL:AddSpell( + FireNova:CastableIf(function(spell) + return FireNova:IsKnownAndUsable() and + SwirlingMaelstrom:IsKnown() and + Target:GetAuras():FindMy(FlameShock):IsUp() + end):SetTarget(Target) +) + +-- actions.single+=/frost_shock +SingleTargetAPL:AddSpell( + FrostShock:CastableIf(function(spell) + return FrostShock:IsKnownAndUsable() + end):SetTarget(Target) +) + +-- actions.single+=/crash_lightning +SingleTargetAPL:AddSpell( + CrashLightning:CastableIf(function(spell) + return CrashLightning:IsKnownAndUsable() + end):SetTarget(Target) +) + +-- actions.single+=/fire_nova,if=active_dot.flame_shock +SingleTargetAPL:AddSpell( + FireNova:CastableIf(function(spell) + return FireNova:IsKnownAndUsable() and + Target:GetAuras():FindMy(FlameShock):IsUp() + end):SetTarget(Target) +) + +-- actions.single+=/earth_elemental +SingleTargetAPL:AddSpell( + EarthElemental:CastableIf(function(spell) + return EarthElemental:IsKnownAndUsable() + end):SetTarget(Target) +) + +-- actions.single+=/flame_shock +SingleTargetAPL:AddSpell( + FlameShock:CastableIf(function(spell) + return FlameShock:IsKnownAndUsable() and + Target:GetAuras():FindMy(FlameShock):IsDown() + end):SetTarget(Target) +) + +-- actions.single+=/windfury_totem,if=buff.windfury_totem.remains<30 +SingleTargetAPL:AddSpell( + WindfuryTotem:CastableIf(function(spell) + return WindfuryTotem:IsKnownAndUsable() and + TotemDurationRemaining(WindfuryTotem) < 30 + end):SetTarget(Target) +) + +EnhancementModule:Sync(function() + if not Player:IsAffectingCombat() and not IsMounted() then + NonCombatAPL:Execute() + end + + if Player:IsAffectingCombat() and not IsMounted() then + DefaultAPL:Execute() + end +end) + +Bastion:Register(EnhancementModule)