---@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)