From 80d93b9313d888664280fa5c95599890c8bc1a2d Mon Sep 17 00:00:00 2001 From: HawkCorrigan Date: Sat, 14 Feb 2026 14:12:00 +0100 Subject: [PATCH] [ele] add an apl --- engine/class_modules/apl/apl_shaman.cpp | 110 +++++++++++------------- engine/class_modules/sc_shaman.cpp | 13 +-- 2 files changed, 51 insertions(+), 72 deletions(-) diff --git a/engine/class_modules/apl/apl_shaman.cpp b/engine/class_modules/apl/apl_shaman.cpp index 89ec0121b47..8033bbefdf1 100644 --- a/engine/class_modules/apl/apl_shaman.cpp +++ b/engine/class_modules/apl/apl_shaman.cpp @@ -42,27 +42,24 @@ void elemental( player_t* p ) precombat->add_action( "snapshot_stats", "Snapshot raid buffed stats before combat begins and pre-potting is done." ); precombat->add_action( "flametongue_weapon" ); precombat->add_action( "lightning_shield" ); + precombat->add_action( + "variable,name=mael_cap,value=100+50*talent.swelling_maelstrom+25*talent.primordial_capacity" ); precombat->add_action( "thunderstrike_ward" ); - precombat->add_action( "variable,name=mael_cap,value=100+50*talent.swelling_maelstrom+25*talent.primordial_capacity" ); - precombat->add_action( "variable,name=trinket_1_buffs,value=(trinket.1.has_use_buff|trinket.1.is.funhouse_lens)" ); - precombat->add_action( "variable,name=trinket_2_buffs,value=(trinket.2.has_use_buff|trinket.2.is.funhouse_lens)" ); precombat->add_action( "stormkeeper" ); default_->add_action( "spiritwalkers_grace,moving=1,if=movement.distance>6", "Enable more movement." ); default_->add_action( "wind_shear", "Interrupt of casts." ); - default_->add_action( "blood_fury,if=!talent.ascendance|buff.ascendance.up|cooldown.ascendance.remains>50" ); - default_->add_action( "berserking,if=!talent.ascendance|buff.ascendance.up" ); - default_->add_action( "fireblood,if=!talent.ascendance|buff.ascendance.up|cooldown.ascendance.remains>50" ); - default_->add_action( "ancestral_call,if=!talent.ascendance|buff.ascendance.up|cooldown.ascendance.remains>50" ); - default_->add_action( "use_item,slot=trinket1,use_off_gcd=1,if=variable.trinket_1_buffs&(cooldown.ascendance.remains>trinket.1.cooldown.duration-5|buff.ascendance.remains>12|fight_remains<21)", "Normal buff trinkets" ); - default_->add_action( "use_item,slot=trinket2,use_off_gcd=1,if=variable.trinket_2_buffs&(cooldown.ascendance.remains>trinket.2.cooldown.duration-5|buff.ascendance.remains>12|fight_remains<21)" ); - default_->add_action( "use_item,slot=main_hand,use_off_gcd=1,if=(buff.fury_of_storms.up|!talent.fury_of_the_storms|cooldown.stormkeeper.remains>10)&cooldown.ascendance.remains>15|buff.ascendance.remains>12", "Normal weapons" ); - default_->add_action( "use_item,slot=trinket1,use_off_gcd=1,if=!variable.trinket_1_buffs&(cooldown.ascendance.remains>20|trinket.2.cooldown.remains>20)", "Dmg trinkets" ); - default_->add_action( "use_item,slot=trinket2,use_off_gcd=1,if=!variable.trinket_2_buffs&(cooldown.ascendance.remains>20|trinket.1.cooldown.remains>20)" ); + default_->add_action( "blood_fury" ); + default_->add_action( "berserking" ); + default_->add_action( "fireblood" ); + default_->add_action( "ancestral_call" ); + default_->add_action( "use_item,slot=trinket1,use_off_gcd=1", "Normal buff trinkets" ); + default_->add_action( "use_item,slot=trinket2,use_off_gcd=1" ); + default_->add_action( "use_item,slot=main_hand,use_off_gcd=1", "Normal weapons" ); + default_->add_action( "use_item,slot=trinket1,use_off_gcd=1", "Dmg trinkets" ); + default_->add_action( "use_item,slot=trinket2,use_off_gcd=1" ); default_->add_action( "lightning_shield,if=buff.lightning_shield.down" ); default_->add_action( "natures_swiftness" ); - default_->add_action( "invoke_external_buff,name=power_infusion,if=buff.ascendance.up|cooldown.ascendance.remains>30", "Use Power Infusion on Cooldown." ); - default_->add_action( "potion,if=buff.bloodlust.up|buff.ascendance.remains>12|fight_remains<31" ); default_->add_action( "run_action_list,name=aoe,if=spell_targets.chain_lightning>=2" ); default_->add_action( "run_action_list,name=single_target" ); @@ -71,17 +68,9 @@ void elemental( player_t* p ) aoe->add_action( "ancestral_swiftness" ); aoe->add_action( "flame_shock,if=active_dot.flame_shock=0&spell_targets.chain_lightning<=3&cooldown.ascendance.remains>10" ); aoe->add_action( "voltaic_blaze,if=active_dot.flame_shock=0|talent.purging_flames" ); - aoe->add_action( "ascendance,if=cooldown.stormkeeper>10" ); + aoe->add_action( "ascendance,if=cooldown.stormkeeper.remains>10" ); aoe->add_action( "tempest,target_if=min:debuff.lightning_rod.remains,if=buff.tempest.stack=2" ); - aoe->add_action( "earthquake,if=(maelstrom>variable.mael_cap-10*(spell_targets.chain_lightning+1)|buff.master_of_the_elements.up|buff.ascendance.up&buff.ascendance.remains<3|fight_remains<5)&(buff.echoes_of_great_sundering.up|!talent.echoes_of_great_sundering&(!talent.elemental_blast|active_enemies>1+3*talent.tempest))", "Spend if you are close to cap, Master of the Elements buff is up or Ascendance is about to expire." ); - aoe->add_action( "elemental_blast,target_if=min:debuff.lightning_rod.remains,if=(maelstrom>variable.mael_cap-10*(spell_targets.chain_lightning+1)|buff.master_of_the_elements.up|buff.ascendance.up&buff.ascendance.remains<3|fight_remains<5)" ); - aoe->add_action( "earth_shock,target_if=min:debuff.lightning_rod.remains,if=(maelstrom>variable.mael_cap-10*(spell_targets.chain_lightning+1)|buff.master_of_the_elements.up|buff.ascendance.up&buff.ascendance.remains<3|fight_remains<5)" ); - aoe->add_action( "earthquake,if=talent.lightning_rod&lightning_rod1+3*talent.tempest))", "Spend to spread Lightning Rod if Tempest or Stormkeeper is up." ); - aoe->add_action( "elemental_blast,target_if=min:debuff.lightning_rod.remains,if=talent.lightning_rod&lightning_rodadd_action( "earth_shock,target_if=min:debuff.lightning_rod.remains,if=talent.lightning_rod&lightning_rodadd_action( "lava_burst,target_if=dot.flame_shock.remains,if=cooldown_react&buff.lava_surge.up&!buff.master_of_the_elements.up&talent.master_of_the_elements&active_enemies<=3", "[2-3t] Use Lava Surge procs to buff with MotE on 2-3 targets." ); - aoe->add_action( "lava_burst,target_if=dot.flame_shock.remains>2,if=!buff.master_of_the_elements.up&talent.master_of_the_elements&(buff.stormkeeper.up|buff.tempest.up|maelstrom>82-10*talent.eye_of_the_storm|maelstrom>52-5*talent.eye_of_the_storm&(buff.echoes_of_great_sundering_eb.up|!talent.elemental_blast))&active_enemies<=3&!talent.lightning_rod&talent.call_of_the_ancestors", "[2-3t]{Farseer} Use all Lava Bursts to buff spenders, SK_CL and Tempest with MotE on 2-3 targets if not talented into Lightning Rod." ); - aoe->add_action( "lava_burst,target_if=dot.flame_shock.remains>2,if=!buff.master_of_the_elements.up&active_enemies=2", "[2t] Use all Lava Bursts to buff with MotE on 2 targets." ); + aoe->add_action( "earthquake" ); aoe->add_action( "lava_burst,target_if=dot.flame_shock.remains>2,if=buff.purging_flames.up&(buff.ascendance.up&buff.ascendance.remains<3|buff.lava_surge.up)", "AoE Lava Burst goes brrrrr." ); aoe->add_action( "lightning_bolt,if=buff.stormkeeper.up&!buff.call_of_the_ancestors.up&spell_targets.chain_lightning=2" ); aoe->add_action( "chain_lightning" ); @@ -94,12 +83,12 @@ void elemental( player_t* p ) single_target->add_action( "ancestral_swiftness" ); single_target->add_action( "flame_shock,if=active_dot.flame_shock=0&!buff.master_of_the_elements.up", "Apply Flame shock if it is not up." ); - aoe->add_action( "voltaic_blaze,if=active_dot.flame_shock=0" ); + single_target->add_action( "voltaic_blaze,if=active_dot.flame_shock=0" ); - single_target->add_action( "ascendance,if=cooldown.stormkeeper>10" ); + single_target->add_action( "ascendance,if=cooldown.stormkeeper.remains>10" ); single_target->add_action( "elemental_blast,if=maelstrom>variable.mael_cap-15|buff.master_of_the_elements.up", "Spend if close to overcaping or MotE buff is up. Friendship ended with Echoes of Great Sundering." ); single_target->add_action( "earth_shock,if=maelstrom>variable.mael_cap-15|buff.master_of_the_elements.up" ); - single_target->add_action( "lava_burst,target_if=dot.flame_shock.remains>=2,if=!buff.master_of_the_elements.up&(buff.lava_surge.up|buff.tempest.up|buff.stormkeeper.up|cooldown.lava_burst.charges_fractional>1.8|maelstrom>variable.mael_cap-30|(maelstrom>52-5*talent.eye_of_the_storm*(1+talent.elemental_blast)+30*talent.elemental_blast)", "Use Lava Burst to proc Master of the Elements." ); + single_target->add_action( "lava_burst,target_if=dot.flame_shock.remains>=2,if=!buff.master_of_the_elements.up" ); single_target->add_action( "tempest" ); single_target->add_action( "lightning_bolt", "Filler spell. Always available. Always the bottom line." ); single_target->add_action( "flame_shock,moving=1,target_if=refreshable" ); @@ -113,56 +102,50 @@ void elemental( player_t* p ) //elemental_ptr_apl_start void elemental_ptr( player_t* p ) { - action_priority_list_t* default_ = p->get_action_priority_list( "default" ); - action_priority_list_t* precombat = p->get_action_priority_list( "precombat" ); - action_priority_list_t* aoe = p->get_action_priority_list( "aoe" ); + action_priority_list_t* default_ = p->get_action_priority_list( "default" ); + action_priority_list_t* precombat = p->get_action_priority_list( "precombat" ); + action_priority_list_t* aoe = p->get_action_priority_list( "aoe" ); action_priority_list_t* single_target = p->get_action_priority_list( "single_target" ); precombat->add_action( "snapshot_stats", "Snapshot raid buffed stats before combat begins and pre-potting is done." ); precombat->add_action( "flametongue_weapon" ); precombat->add_action( "lightning_shield" ); + precombat->add_action( + "variable,name=mael_cap,value=100+50*talent.swelling_maelstrom+25*talent.primordial_capacity" ); precombat->add_action( "thunderstrike_ward" ); - precombat->add_action( "variable,name=mael_cap,value=100+50*talent.swelling_maelstrom+25*talent.primordial_capacity" ); - precombat->add_action( "variable,name=trinket_1_buffs,value=(trinket.1.has_use_buff|trinket.1.is.funhouse_lens)" ); - precombat->add_action( "variable,name=trinket_2_buffs,value=(trinket.2.has_use_buff|trinket.2.is.funhouse_lens)" ); precombat->add_action( "stormkeeper" ); default_->add_action( "spiritwalkers_grace,moving=1,if=movement.distance>6", "Enable more movement." ); default_->add_action( "wind_shear", "Interrupt of casts." ); - default_->add_action( "blood_fury,if=!talent.ascendance|buff.ascendance.up|cooldown.ascendance.remains>50" ); - default_->add_action( "berserking,if=!talent.ascendance|buff.ascendance.up" ); - default_->add_action( "fireblood,if=!talent.ascendance|buff.ascendance.up|cooldown.ascendance.remains>50" ); - default_->add_action( "ancestral_call,if=!talent.ascendance|buff.ascendance.up|cooldown.ascendance.remains>50" ); - default_->add_action( "use_item,slot=trinket1,use_off_gcd=1,if=variable.trinket_1_buffs&(cooldown.ascendance.remains>trinket.1.cooldown.duration-5|buff.ascendance.remains>12|fight_remains<21)", "Normal buff trinkets" ); - default_->add_action( "use_item,slot=trinket2,use_off_gcd=1,if=variable.trinket_2_buffs&(cooldown.ascendance.remains>trinket.2.cooldown.duration-5|buff.ascendance.remains>12|fight_remains<21)" ); - default_->add_action( "use_item,slot=main_hand,use_off_gcd=1,if=(buff.fury_of_storms.up|!talent.fury_of_the_storms|cooldown.stormkeeper.remains>10)&cooldown.ascendance.remains>15|buff.ascendance.remains>12", "Normal weapons" ); - default_->add_action( "use_item,slot=trinket1,use_off_gcd=1,if=!variable.trinket_1_buffs&(cooldown.ascendance.remains>20|trinket.2.cooldown.remains>20)", "Dmg trinkets" ); - default_->add_action( "use_item,slot=trinket2,use_off_gcd=1,if=!variable.trinket_2_buffs&(cooldown.ascendance.remains>20|trinket.1.cooldown.remains>20)" ); + default_->add_action( "blood_fury" ); + default_->add_action( "berserking" ); + default_->add_action( "fireblood" ); + default_->add_action( "ancestral_call" ); + default_->add_action( "use_item,slot=trinket1,use_off_gcd=1", "Normal buff trinkets" ); + default_->add_action( "use_item,slot=trinket2,use_off_gcd=1" ); + default_->add_action( "use_item,slot=main_hand,use_off_gcd=1", "Normal weapons" ); + default_->add_action( "use_item,slot=trinket1,use_off_gcd=1", "Dmg trinkets" ); + default_->add_action( "use_item,slot=trinket2,use_off_gcd=1" ); default_->add_action( "lightning_shield,if=buff.lightning_shield.down" ); default_->add_action( "natures_swiftness" ); - default_->add_action( "invoke_external_buff,name=power_infusion,if=buff.ascendance.up|cooldown.ascendance.remains>30", "Use Power Infusion on Cooldown." ); - default_->add_action( "potion,if=buff.bloodlust.up|buff.ascendance.remains>12|fight_remains<31" ); default_->add_action( "run_action_list,name=aoe,if=spell_targets.chain_lightning>=2" ); default_->add_action( "run_action_list,name=single_target" ); aoe->add_action( "fire_elemental" ); aoe->add_action( "stormkeeper" ); aoe->add_action( "ancestral_swiftness" ); - aoe->add_action( "flame_shock,if=active_dot.flame_shock=0&spell_targets.chain_lightning<=3&cooldown.ascendance.remains>10" ); + aoe->add_action( + "flame_shock,if=active_dot.flame_shock=0&spell_targets.chain_lightning<=3&cooldown.ascendance.remains>10" ); aoe->add_action( "voltaic_blaze,if=active_dot.flame_shock=0|talent.purging_flames" ); - aoe->add_action( "ascendance,if=cooldown.stormkeeper>10" ); + aoe->add_action( "ascendance,if=cooldown.stormkeeper.remains>10" ); aoe->add_action( "tempest,target_if=min:debuff.lightning_rod.remains,if=buff.tempest.stack=2" ); - aoe->add_action( "earthquake,if=(maelstrom>variable.mael_cap-10*(spell_targets.chain_lightning+1)|buff.master_of_the_elements.up|buff.ascendance.up&buff.ascendance.remains<3|fight_remains<5)&(buff.echoes_of_great_sundering.up|!talent.echoes_of_great_sundering&(!talent.elemental_blast|active_enemies>1+3*talent.tempest))", "Spend if you are close to cap, Master of the Elements buff is up or Ascendance is about to expire." ); - aoe->add_action( "elemental_blast,target_if=min:debuff.lightning_rod.remains,if=(maelstrom>variable.mael_cap-10*(spell_targets.chain_lightning+1)|buff.master_of_the_elements.up|buff.ascendance.up&buff.ascendance.remains<3|fight_remains<5)" ); - aoe->add_action( "earth_shock,target_if=min:debuff.lightning_rod.remains,if=(maelstrom>variable.mael_cap-10*(spell_targets.chain_lightning+1)|buff.master_of_the_elements.up|buff.ascendance.up&buff.ascendance.remains<3|fight_remains<5)" ); - aoe->add_action( "earthquake,if=talent.lightning_rod&lightning_rod1+3*talent.tempest))", "Spend to spread Lightning Rod if Tempest or Stormkeeper is up." ); - aoe->add_action( "elemental_blast,target_if=min:debuff.lightning_rod.remains,if=talent.lightning_rod&lightning_rodadd_action( "earth_shock,target_if=min:debuff.lightning_rod.remains,if=talent.lightning_rod&lightning_rodadd_action( "lava_burst,target_if=dot.flame_shock.remains,if=cooldown_react&buff.lava_surge.up&!buff.master_of_the_elements.up&talent.master_of_the_elements&active_enemies<=3", "[2-3t] Use Lava Surge procs to buff with MotE on 2-3 targets." ); - aoe->add_action( "lava_burst,target_if=dot.flame_shock.remains>2,if=!buff.master_of_the_elements.up&talent.master_of_the_elements&(buff.stormkeeper.up|buff.tempest.up|maelstrom>82-10*talent.eye_of_the_storm|maelstrom>52-5*talent.eye_of_the_storm&(buff.echoes_of_great_sundering_eb.up|!talent.elemental_blast))&active_enemies<=3&!talent.lightning_rod&talent.call_of_the_ancestors", "[2-3t]{Farseer} Use all Lava Bursts to buff spenders, SK_CL and Tempest with MotE on 2-3 targets if not talented into Lightning Rod." ); - aoe->add_action( "lava_burst,target_if=dot.flame_shock.remains>2,if=!buff.master_of_the_elements.up&active_enemies=2", "[2t] Use all Lava Bursts to buff with MotE on 2 targets." ); - aoe->add_action( "lava_burst,target_if=dot.flame_shock.remains>2,if=buff.purging_flames.up&(buff.ascendance.up&buff.ascendance.remains<3|buff.lava_surge.up)", "AoE Lava Burst goes brrrrr." ); - aoe->add_action( "lightning_bolt,if=buff.stormkeeper.up&!buff.call_of_the_ancestors.up&spell_targets.chain_lightning=2" ); + aoe->add_action( "earthquake" ); + aoe->add_action( + "lava_burst,target_if=dot.flame_shock.remains>2,if=buff.purging_flames.up&(buff.ascendance.up&buff.ascendance." + "remains<3|buff.lava_surge.up)", + "AoE Lava Burst goes brrrrr." ); + aoe->add_action( + "lightning_bolt,if=buff.stormkeeper.up&!buff.call_of_the_ancestors.up&spell_targets.chain_lightning=2" ); aoe->add_action( "chain_lightning" ); aoe->add_action( "flame_shock,moving=1,target_if=refreshable" ); aoe->add_action( "voltaic_blaze,moving=1,target_if=refreshable" ); @@ -171,14 +154,17 @@ void elemental_ptr( player_t* p ) single_target->add_action( "fire_elemental" ); single_target->add_action( "stormkeeper" ); single_target->add_action( "ancestral_swiftness" ); - single_target->add_action( "flame_shock,if=active_dot.flame_shock=0&!buff.master_of_the_elements.up", "Apply Flame shock if it is not up." ); + single_target->add_action( "flame_shock,if=active_dot.flame_shock=0&!buff.master_of_the_elements.up", + "Apply Flame shock if it is not up." ); - aoe->add_action( "voltaic_blaze,if=active_dot.flame_shock=0" ); + single_target->add_action( "voltaic_blaze,if=active_dot.flame_shock=0" ); - single_target->add_action( "ascendance,if=cooldown.stormkeeper>10" ); - single_target->add_action( "elemental_blast,if=maelstrom>variable.mael_cap-15|buff.master_of_the_elements.up", "Spend if close to overcaping or MotE buff is up. Friendship ended with Echoes of Great Sundering." ); + single_target->add_action( "ascendance,if=cooldown.stormkeeper.remains>10" ); + single_target->add_action( + "elemental_blast,if=maelstrom>variable.mael_cap-15|buff.master_of_the_elements.up", + "Spend if close to overcaping or MotE buff is up. Friendship ended with Echoes of Great Sundering." ); single_target->add_action( "earth_shock,if=maelstrom>variable.mael_cap-15|buff.master_of_the_elements.up" ); - single_target->add_action( "lava_burst,target_if=dot.flame_shock.remains>=2,if=!buff.master_of_the_elements.up&(buff.lava_surge.up|buff.tempest.up|buff.stormkeeper.up|cooldown.lava_burst.charges_fractional>1.8|maelstrom>variable.mael_cap-30|(maelstrom>52-5*talent.eye_of_the_storm*(1+talent.elemental_blast)+30*talent.elemental_blast)", "Use Lava Burst to proc Master of the Elements." ); + single_target->add_action( "lava_burst,target_if=dot.flame_shock.remains>=2,if=!buff.master_of_the_elements.up" ); single_target->add_action( "tempest" ); single_target->add_action( "lightning_bolt", "Filler spell. Always available. Always the bottom line." ); single_target->add_action( "flame_shock,moving=1,target_if=refreshable" ); diff --git a/engine/class_modules/sc_shaman.cpp b/engine/class_modules/sc_shaman.cpp index 620b466e58c..d99c2fddd00 100644 --- a/engine/class_modules/sc_shaman.cpp +++ b/engine/class_modules/sc_shaman.cpp @@ -1412,6 +1412,7 @@ struct shaman_t : public parse_player_effects_t const spell_data_t* maelstrom; const spell_data_t* lava_surge; const spell_data_t* inundate; + const spell_data_t* stormkeeper_2; // charges // Enhancement const spell_data_t* critical_strikes; @@ -8221,8 +8222,7 @@ struct stormkeeper_t : public shaman_spell_t } p()->summon_ancestor(); - - p()->buff.stormkeeper->trigger(2); + p()->buff.stormkeeper->trigger( 2 ); //p()->spec.stormkeeper_2->charges() ); p()->buff.mid1_ele_2pc->trigger(); @@ -10458,6 +10458,7 @@ void shaman_t::init_spells() spec.lightning_bolt_2 = find_rank_spell( "Lightning Bolt", "Rank 2" ); spec.lava_burst_2 = find_rank_spell( "Lava Burst", "Rank 2" ); spec.inundate = find_specialization_spell( "Inundate" ); + spec.stormkeeper_2 = find_spell( 383009 ); // Enhancement spec.critical_strikes = find_specialization_spell( "Critical Strikes" ); @@ -13488,14 +13489,6 @@ struct shaman_module_t : public module_t void register_hotfixes() const override { - // This is gross but the current value for the stormkeeper spell - // when resolved is 0 and not 2, but this achieves the end goal - // so whatever man - /* hotfix::register_spell( "Shaman", "2024-09-06", "Manually set Stormkeeper max stacks", 191634 ) - .field( "max_stack" ) - .operation( hotfix::HOTFIX_SET ) - .modifier( 3 ) - .verification_value( 0.0 );*/ hotfix::register_effect( "Shaman", "2025-10-19", "Manually add Label to Enhancement 12.0 4PC set bonus", 1276472 ) .field( "misc_value2" )