-
Notifications
You must be signed in to change notification settings - Fork 767
[Mage] Arcane 12.1 changes + set bonus #11527
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Lucasmingus
wants to merge
6
commits into
simulationcraft:midnight
Choose a base branch
from
Lucasmingus:arcane-set-implementation
base: midnight
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+162
−14
Open
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
ec54ccf
[Mage] 12.1 changes + set bonus
Lucasmingus 3a87104
separate aoe spell for prismatic bolt
Lucasmingus 5151301
use impact_action to simplify
Lucasmingus 7d89cf9
use num_targets_hit on pulse + addressed reverb echo bug with impetus…
Lucasmingus b8453f4
use background
Lucasmingus 3268bb6
address newest changes to orb mastery
Lucasmingus File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -276,11 +276,13 @@ struct mage_t final : public player_t | |
| buff_t* arcane_salvo; | ||
| buff_t* arcane_surge; | ||
| buff_t* clearcasting; | ||
| buff_t* cumulative_power; | ||
| buff_t* enlightened; | ||
| buff_t* evocation; | ||
| buff_t* intuition; | ||
| buff_t* overpowered_missiles; | ||
| buff_t* presence_of_mind; | ||
| buff_t* prismatic_bolt; | ||
|
|
||
|
|
||
| // Fire | ||
|
|
@@ -580,7 +582,8 @@ struct mage_t final : public player_t | |
| player_talent_t impetus; | ||
|
|
||
| // Row 8 | ||
| player_talent_t touch_of_the_archmage_1; | ||
| player_talent_t touch_of_the_archmage_1; // TODO: Remove everything related to Touch of the Archmage when 12.1 goes live | ||
| player_talent_t prismatic_bolt_1; | ||
| player_talent_t evocation; | ||
| player_talent_t mana_adept; | ||
| player_talent_t enlightened; | ||
|
|
@@ -589,12 +592,14 @@ struct mage_t final : public player_t | |
|
|
||
| // Row 9 | ||
| player_talent_t touch_of_the_archmage_2; | ||
| player_talent_t prismatic_bolt_2; | ||
| player_talent_t prodigious_savant; | ||
| player_talent_t eureka; | ||
| player_talent_t arcane_singularity; | ||
|
|
||
| // Row 10 | ||
| player_talent_t touch_of_the_archmage_3; | ||
| player_talent_t prismatic_bolt_3; | ||
| player_talent_t charged_missiles; | ||
| player_talent_t high_voltage; | ||
| player_talent_t overflowing_insight; | ||
|
|
@@ -2632,6 +2637,9 @@ struct arcane_orb_bolt_t final : public arcane_mage_spell_t | |
| if ( p()->state.eureka || type == ao_type::ORB_MASTERY ) | ||
| am *= 1.0 + p()->talents.eureka->effectN( 1 ).percent(); | ||
|
|
||
| if ( type == ao_type::ORB_MASTERY ) | ||
| am *= p()->talents.orb_mastery->effectN( 2 ).percent(); | ||
|
|
||
| return am; | ||
| } | ||
| }; | ||
|
|
@@ -2655,7 +2663,9 @@ struct arcane_orb_t final : public custom_state_spell_t<arcane_mage_spell_t, arc | |
| parse_options( options_str ); | ||
| may_miss = false; | ||
| aoe = -1; | ||
| triggers.clearcasting = type == ao_type::NORMAL; | ||
| // TODO: Remove version check when 12.1 goes live (ORB_MASTERY part only) | ||
| triggers.clearcasting = type == ao_type::NORMAL || | ||
| ( type == ao_type::ORB_MASTERY && p->dbc->wowv() >= wowv_t{ 12, 1, 0 } ); | ||
|
|
||
| std::string_view bolt_name; | ||
| switch ( type ) | ||
|
|
@@ -2687,28 +2697,39 @@ struct arcane_orb_t final : public custom_state_spell_t<arcane_mage_spell_t, arc | |
|
|
||
| if ( p->talents.orb_mastery.ok() ) | ||
| { | ||
| cost_reductions = { p->buffs.clearcasting }; | ||
| // TODO: Remove version check when 12.1 goes live | ||
| if ( p->dbc->wowv() < wowv_t{ 12, 1, 0 } ) | ||
| cost_reductions = { p->buffs.clearcasting }; | ||
| orb_mastery = get_action<arcane_orb_t>( "orb_mastery_arcane_orb", p, "", ao_type::ORB_MASTERY ); | ||
| add_child( orb_mastery ); | ||
| } | ||
| } | ||
|
|
||
| void snapshot_state( action_state_t* s, result_amount_type rt ) override | ||
| { | ||
| cast_state( s )->data.eureka = p()->talents.orb_mastery.ok() && p()->talents.eureka.ok() && clearcasting_snapshot; | ||
| // TODO: Remove version check when 12.1 goes live | ||
| cast_state( s )->data.eureka = p()->talents.orb_mastery.ok() && p()->talents.eureka.ok() && | ||
| ( p()->dbc->wowv() >= wowv_t{ 12, 1, 0 } || clearcasting_snapshot ); | ||
| custom_state_spell_t::snapshot_state( s, rt ); | ||
| } | ||
|
|
||
| void execute() override | ||
| { | ||
| triggers.clearcasting = !background; | ||
| if ( orb_mastery && p()->buffs.clearcasting->check() ) | ||
| // TODO: Remove version check when 12.1 goes live | ||
| if ( p()->dbc->wowv() < wowv_t{ 12, 1, 0 } ) | ||
| triggers.clearcasting = !background; | ||
|
|
||
| // TODO: Remove version check when 12.1 goes live (pre-12.1 requires CC to fire) | ||
| if ( orb_mastery && ( p()->dbc->wowv() >= wowv_t{ 12, 1, 0 } || p()->buffs.clearcasting->check() ) ) | ||
| { | ||
| int count = as<int>( p()->talents.orb_mastery->effectN( 1 ).base_value() ); | ||
| make_repeating_event( *sim, 150_ms, [ this, t = target ] { orb_mastery->execute_on_target( t ); }, count ); | ||
| clearcasting_snapshot = true; | ||
| // Orb Mastery's execution prevents Clearcasting from being triggered with the initial Orb cast -- behaves identically to Barrage with Orb Barrage. | ||
| triggers.clearcasting = false; | ||
| if ( p()->dbc->wowv() < wowv_t{ 12, 1, 0 } ) | ||
| { | ||
| clearcasting_snapshot = true; | ||
| // Orb Mastery's execution prevents Clearcasting from being triggered with the initial Orb cast. | ||
| triggers.clearcasting = false; | ||
| } | ||
| } | ||
|
|
||
| custom_state_spell_t::execute(); | ||
|
|
@@ -2811,6 +2832,14 @@ struct arcane_barrage_t final : public arcane_mage_spell_t | |
| p()->buffs.intuition->expire(); | ||
|
|
||
| int salvo = p()->buffs.arcane_salvo->check(); | ||
|
|
||
| if ( p()->talents.prismatic_bolt_1.ok() && salvo > 0 ) | ||
| { | ||
| double chance = salvo * p()->talents.prismatic_bolt_1->effectN( 1 ).percent(); | ||
| if ( rng().roll( chance ) ) | ||
| p()->buffs.prismatic_bolt->trigger(); | ||
| } | ||
|
|
||
| if ( p()->buffs.arcane_soul->check() ) | ||
| { | ||
| p()->trigger_clearcasting( 1.0, true, true ); | ||
|
|
@@ -2927,13 +2956,16 @@ struct arcane_blast_t final : public arcane_mage_spell_t | |
|
|
||
| if ( p()->buffs.presence_of_mind->up() ) | ||
| p()->buffs.presence_of_mind->decrement(); | ||
|
|
||
| p()->buffs.cumulative_power->expire(); | ||
| } | ||
|
|
||
| double action_multiplier() const override | ||
| { | ||
| double am = arcane_mage_spell_t::action_multiplier(); | ||
|
|
||
| am *= arcane_charge_multiplier(); | ||
| am *= 1.0 + p()->buffs.cumulative_power->check_stack_value(); | ||
|
|
||
| return am; | ||
| } | ||
|
|
@@ -2945,6 +2977,72 @@ struct arcane_blast_t final : public arcane_mage_spell_t | |
|
|
||
| return arcane_mage_spell_t::execute_time(); | ||
| } | ||
|
|
||
| bool ready() override | ||
| { | ||
| // Arcane Blast is upgraded into Prismatic Bolt while the buff is up. | ||
| if ( p()->buffs.prismatic_bolt->check() ) | ||
| return false; | ||
|
|
||
| return arcane_mage_spell_t::ready(); | ||
| } | ||
| }; | ||
|
|
||
| // The aoe part of Prismatic Bolt is its own spell (1295939) | ||
| struct prismatic_bolt_aoe_t final : public arcane_mage_spell_t | ||
| { | ||
| prismatic_bolt_aoe_t( std::string_view n, mage_t* p ) : | ||
| arcane_mage_spell_t( n, p, p->find_spell( 1295939 ) ) | ||
| { | ||
| background = true; | ||
| aoe = -1; | ||
| reduced_aoe_targets = p->find_spell( 1295924 )->effectN( 4 ).base_value(); | ||
| target_filter_callback = secondary_targets_only(); | ||
| } | ||
| }; | ||
|
|
||
| struct prismatic_bolt_t final : public arcane_mage_spell_t | ||
| { | ||
| prismatic_bolt_t( std::string_view n, mage_t* p, std::string_view options_str ) : | ||
| arcane_mage_spell_t( n, p, p->find_spell( 1295924 ) ) | ||
| { | ||
| parse_options( options_str ); | ||
| triggers.clearcasting = triggers.spellfire_sphere = triggers.mana_cascade = true; | ||
|
|
||
| impact_action = get_action<prismatic_bolt_aoe_t>( "prismatic_bolt_aoe", p ); | ||
| add_child( impact_action ); | ||
| } | ||
|
|
||
| bool ready() override | ||
| { | ||
| if ( !p()->buffs.prismatic_bolt->check() ) | ||
| return false; | ||
|
|
||
| return arcane_mage_spell_t::ready(); | ||
| } | ||
|
|
||
| void execute() override | ||
| { | ||
| arcane_mage_spell_t::execute(); | ||
|
|
||
| p()->buffs.prismatic_bolt->expire(); | ||
| p()->buffs.cumulative_power->expire(); | ||
|
|
||
| p()->trigger_arcane_charge( as<int>( data().effectN( 3 ).base_value() ) ); | ||
| p()->trigger_arcane_salvo( salvo_source, as<int>( p()->talents.expanded_mind->effectN( 3 ).base_value() ) ); | ||
|
|
||
| if ( p()->talents.prismatic_bolt_2.ok() ) | ||
| p()->trigger_clearcasting( p()->talents.prismatic_bolt_2->effectN( 1 ).percent() ); | ||
| } | ||
|
|
||
| double action_multiplier() const override | ||
| { | ||
| double am = arcane_mage_spell_t::action_multiplier(); | ||
|
|
||
| am *= 1.0 + p()->buffs.cumulative_power->check_stack_value(); | ||
|
|
||
| return am; | ||
| } | ||
| }; | ||
|
|
||
| struct arcane_explosion_t final : public arcane_mage_spell_t | ||
|
|
@@ -2976,7 +3074,10 @@ struct arcane_pulse_t final : public arcane_mage_spell_t | |
| parse_options( options_str ); | ||
| aoe = -1; | ||
| triggers.clearcasting = triggers.spellfire_sphere = triggers.mana_cascade = !echo; | ||
| reduced_aoe_targets = data().effectN( 3 ).base_value(); | ||
| // With the 12.1 PTR, pulse went from having 3 effects to 2, removing 'energize (1240466)' | ||
| // The reduced-AoE-targets threshold effect went from effect #3 (live 12.0.7) to effect #2 (12.1 PTR) | ||
| // TODO: Remove check when 12.1 goes live | ||
| reduced_aoe_targets = data().effectN( p->dbc->wowv() >= wowv_t{ 12, 1, 0 } ? 2 : 3 ).base_value(); | ||
|
|
||
| if ( echo ) | ||
| { | ||
|
|
@@ -2997,19 +3098,42 @@ struct arcane_pulse_t final : public arcane_mage_spell_t | |
| { | ||
| double c = arcane_mage_spell_t::cost_pct_multiplier(); | ||
|
|
||
| c *= 1.0 + p()->buffs.arcane_charge->check() * p()->buffs.arcane_charge->data().effectN( 5 ).percent(); | ||
| // TODO: Remove when 12.1 goes live | ||
| if ( p()->dbc->wowv() < wowv_t{ 12, 1, 0 } ) | ||
| { | ||
| c *= 1.0 + p()->buffs.arcane_charge->check() * p()->buffs.arcane_charge->data().effectN( 5 ).percent(); | ||
| } | ||
|
|
||
| return c; | ||
| } | ||
|
|
||
| void execute() override | ||
| { | ||
| p()->benefits.arcane_charge.arcane_pulse->update(); | ||
| // TODO: Remove check when 12.1 goes live | ||
| if ( p()->dbc->wowv() < wowv_t{ 12, 1, 0 } ) | ||
| { | ||
| p()->benefits.arcane_charge.arcane_pulse->update(); | ||
| } | ||
|
|
||
| // TODO: radius increase? | ||
| arcane_mage_spell_t::execute(); | ||
|
|
||
| p()->trigger_arcane_charge( as<int>( data().effectN( 2 ).base_value() ) ); | ||
| // TODO: Remove check when 12.1 goes live. | ||
| if ( p()->dbc->wowv() < wowv_t{ 12, 1, 0 } ) | ||
| { | ||
| p()->trigger_arcane_charge( as<int>( data().effectN( 2 ).base_value() ) ); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better to generate the AC here with |
||
| } | ||
| else | ||
| { | ||
| // 12.1: Arcane Pulse generates 1 arcane charge per enemy hit. | ||
| int charges_per_hit = 1; | ||
|
|
||
| // Bug: with Impetus talented, the Reverberate echo generates double the arcane charges of the main cast | ||
| if ( background && p()->bugs && p()->talents.impetus.ok() ) | ||
| charges_per_hit = 2; | ||
|
|
||
| p()->trigger_arcane_charge( num_targets_hit * charges_per_hit ); | ||
| } | ||
|
|
||
| // In-game, Arcane Pulse internally sets a target it hits as a "Background Target", | ||
| // resulting in all of Pulse's background effects to be directed towards them. | ||
|
|
@@ -3020,6 +3144,7 @@ struct arcane_pulse_t final : public arcane_mage_spell_t | |
| p()->trigger_arcane_salvo( salvo_source, as<int>( p()->talents.expanded_mind->effectN( 1 ).base_value() ) ); | ||
| effect_target = rng().range( target_list() ); | ||
| p()->trigger_splinter( effect_target ); | ||
| p()->buffs.cumulative_power->expire(); // does not affect the reverb | ||
| } | ||
|
|
||
| if ( arcane_pulse_echo && rng().roll( p()->talents.reverberate->effectN( 1 ).percent() ) ) | ||
|
|
@@ -3030,7 +3155,19 @@ struct arcane_pulse_t final : public arcane_mage_spell_t | |
| { | ||
| double am = arcane_mage_spell_t::action_multiplier(); | ||
|
|
||
| am *= arcane_charge_multiplier(); | ||
| // TODO: Remove check when 12.1 goes live | ||
| if ( p()->dbc->wowv() < wowv_t{ 12, 1, 0 } ) | ||
| { | ||
| am *= arcane_charge_multiplier(); | ||
| } | ||
| // On 12.1, the main cast no longer benefits from Impetus's arcane charge multiplier, | ||
| // but the Reverberate echo still does. This is likely a bug. | ||
| else if ( background && p()->bugs && p()->talents.impetus.ok() ) | ||
| { | ||
| am *= arcane_charge_multiplier(); | ||
| } | ||
|
|
||
| am *= 1.0 + p()->buffs.cumulative_power->check_stack_value(); | ||
|
|
||
| return am; | ||
| } | ||
|
|
@@ -3146,6 +3283,8 @@ struct arcane_missiles_tick_t final : public custom_state_spell_t<arcane_mage_sp | |
| { | ||
| custom_state_spell_t::execute(); | ||
|
|
||
| p()->buffs.cumulative_power->trigger(); | ||
|
|
||
| p()->trigger_arcane_salvo( salvo_source ); | ||
| p()->trigger_arcane_salvo( crystal_source, as<int>( p()->talents.focusing_crystal->effectN( 2 ).base_value() ), | ||
| p()->talents.focusing_crystal->effectN( 1 ).percent() ); | ||
|
|
@@ -5653,6 +5792,7 @@ action_t* mage_t::create_action( std::string_view name, std::string_view options | |
| if ( name == "arcane_surge" ) return new arcane_surge_t( name, this, options_str ); | ||
| if ( name == "evocation" ) return new evocation_t( name, this, options_str ); | ||
| if ( name == "presence_of_mind" ) return new presence_of_mind_t( name, this, options_str ); | ||
| if ( name == "prismatic_bolt" ) return new prismatic_bolt_t( name, this, options_str ); | ||
| if ( name == "touch_of_the_magi" ) return new touch_of_the_magi_t( name, this, options_str ); | ||
|
|
||
| // Fire | ||
|
|
@@ -6020,18 +6160,21 @@ void mage_t::init_spells() | |
| talents.impetus = find_talent_spell( talent_tree::SPECIALIZATION, "Impetus" ); | ||
| // Row 8 | ||
| talents.touch_of_the_archmage_1 = find_talent_spell( talent_tree::SPECIALIZATION, 1257942 ); | ||
| talents.prismatic_bolt_1 = find_talent_spell( talent_tree::SPECIALIZATION, 1295923 ); | ||
| talents.evocation = find_talent_spell( talent_tree::SPECIALIZATION, "Evocation" ); | ||
| talents.mana_adept = find_talent_spell( talent_tree::SPECIALIZATION, "Mana Adept" ); | ||
| talents.enlightened = find_talent_spell( talent_tree::SPECIALIZATION, "Enlightened" ); | ||
| talents.focusing_crystal = find_talent_spell( talent_tree::SPECIALIZATION, "Focusing Crystal" ); | ||
| talents.illuminated_thoughts = find_talent_spell( talent_tree::SPECIALIZATION, "Illuminated Thoughts" ); | ||
| // Row 9 | ||
| talents.touch_of_the_archmage_2 = find_talent_spell( talent_tree::SPECIALIZATION, 1257947 ); | ||
| talents.prismatic_bolt_2 = find_talent_spell( talent_tree::SPECIALIZATION, 1295944 ); | ||
| talents.prodigious_savant = find_talent_spell( talent_tree::SPECIALIZATION, "Prodigious Savant" ); | ||
| talents.eureka = find_talent_spell( talent_tree::SPECIALIZATION, "Eureka" ); | ||
| talents.arcane_singularity = find_talent_spell( talent_tree::SPECIALIZATION, "Arcane Singularity" ); | ||
| // Row 10 | ||
| talents.touch_of_the_archmage_3 = find_talent_spell( talent_tree::SPECIALIZATION, 1257950 ); | ||
| talents.prismatic_bolt_3 = find_talent_spell( talent_tree::SPECIALIZATION, 1295946 ); | ||
| talents.charged_missiles = find_talent_spell( talent_tree::SPECIALIZATION, "Charged Missiles" ); | ||
| talents.high_voltage = find_talent_spell( talent_tree::SPECIALIZATION, "High Voltage" ); | ||
| talents.overflowing_insight = find_talent_spell( talent_tree::SPECIALIZATION, "Overflowing Insight" ); | ||
|
|
@@ -6316,6 +6459,9 @@ void mage_t::create_buffs() | |
| buffs.clearcasting = make_buff( this, "clearcasting", find_spell( 263725 ) ) | ||
| ->set_default_value_from_effect( 1 ) | ||
| ->set_chance( spec.clearcasting->ok() ) ; | ||
| buffs.cumulative_power = make_buff( this, "cumulative_power", find_spell( 1296930 ) ) | ||
| ->set_default_value_from_effect( 1 ) | ||
| ->set_chance( sets->has_set_bonus( MAGE_ARCANE, MID2, B4 ) ); | ||
| buffs.enlightened = make_buff( this, "enlightened", find_spell( 1217242 ) ) | ||
| ->set_schools_from_effect( 4 ) | ||
| ->add_invalidate( CACHE_PLAYER_DAMAGE_MULTIPLIER ) | ||
|
|
@@ -6338,6 +6484,8 @@ void mage_t::create_buffs() | |
| ->set_cooldown( 0_ms ) | ||
| ->set_stack_change_callback( [ this ] ( buff_t*, int, int cur ) | ||
| { if ( cur == 0 ) cooldowns.presence_of_mind->start( cooldowns.presence_of_mind->action ); } ); | ||
| buffs.prismatic_bolt = make_buff( this, "prismatic_bolt", find_spell( 1295942 ) ) | ||
| ->set_chance( talents.prismatic_bolt_1.ok() ); | ||
|
|
||
|
|
||
| // Fire | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a TODO somewhere on TotA so that we don't forget to remove it in 12.1.