Last active
June 21, 2018 17:12
-
-
Save cgdangelo/e7e0572312ebddd14df56617c5337893 to your computer and use it in GitHub Desktop.
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
commit e51691d169ae55d909d2854be29b4188a5523378 | |
Author: Charles D'Angelo <[email protected]> | |
Date: Thu Jun 21 11:54:40 2018 -0400 | |
[Mage] Add Time Anomaly in place of Temporal Flux | |
diff --git a/engine/class_modules/sc_mage.cpp b/engine/class_modules/sc_mage.cpp | |
index 3ade63c9bf..2db785156e 100755 | |
--- a/engine/class_modules/sc_mage.cpp | |
+++ b/engine/class_modules/sc_mage.cpp | |
@@ -302,6 +302,43 @@ struct proc_source_t : private noncopyable | |
struct mage_t : public player_t | |
{ | |
+ void trigger_arcane_charge( int stacks = 1 ) | |
+ { | |
+ buff_t* ac = buffs.arcane_charge; | |
+ | |
+ int before = ac -> check(); | |
+ | |
+ if ( bugs ) | |
+ { | |
+ // The damage bonus given by mastery seems to be snapshot at the moment | |
+ // Arcane Charge is gained. As long as the stack number remains the same, | |
+ // any future changes to mastery will have no effect. | |
+ // As of build 25881, 2018-01-22. | |
+ if ( ac -> check() < ac -> max_stack() ) | |
+ { | |
+ ac -> trigger( stacks, savant_damage_bonus() ); | |
+ } | |
+ } | |
+ else | |
+ { | |
+ ac -> trigger( stacks ); | |
+ } | |
+ | |
+ int after = ac -> check(); | |
+ | |
+ if ( talents.rule_of_threes -> ok() && before < 3 && after >= 3 ) | |
+ { | |
+ buffs.rule_of_threes -> trigger(); | |
+ } | |
+ } | |
+ | |
+ double savant_damage_bonus() const | |
+ { | |
+ // TODO: Arcane Charge effect 2 and Savant effect 3 have the relevant into for Arcane Barrage, | |
+ // but the mastery snapshot bug makes it awkward to use (we can only store one in buff's value). | |
+ return spec.arcane_charge -> effectN( 1 ).percent() + cache.mastery() * spec.savant -> effectN( 2 ).mastery_value(); | |
+ } | |
+ | |
public: | |
// Icicles | |
std::vector<icicle_tuple_t> icicles; | |
@@ -318,8 +355,8 @@ public: | |
action_t* ignite; | |
event_t* ignite_spread_event; | |
- // Evocation | |
- event_t* temporal_flux_event; | |
+ // Time Anomaly | |
+ event_t* time_anomaly_event; | |
// Active | |
player_t* last_bomb_target; | |
@@ -606,7 +643,7 @@ public: | |
// Tier 100 | |
const spell_data_t* overpowered; | |
- const spell_data_t* temporal_flux; | |
+ const spell_data_t* time_anomaly; | |
const spell_data_t* arcane_orb; | |
const spell_data_t* kindling; | |
const spell_data_t* pyroclasm; | |
@@ -1579,47 +1616,9 @@ struct arcane_mage_spell_t : public mage_spell_t | |
} | |
} | |
- double savant_damage_bonus() const | |
- { | |
- // TODO: Arcane Charge effect 2 and Savant effect 3 have the relevant into for Arcane Barrage, | |
- // but the mastery snapshot bug makes it awkward to use (we can only store one in buff's value). | |
- return p() -> spec.arcane_charge -> effectN( 1 ).percent() + | |
- p() -> cache.mastery() * p() -> spec.savant -> effectN( 2 ).mastery_value(); | |
- } | |
- | |
- void trigger_arcane_charge( int stacks = 1 ) | |
- { | |
- buff_t* ac = p() -> buffs.arcane_charge; | |
- | |
- int before = ac -> check(); | |
- | |
- if ( p() -> bugs ) | |
- { | |
- // The damage bonus given by mastery seems to be snapshot at the moment | |
- // Arcane Charge is gained. As long as the stack number remains the same, | |
- // any future changes to mastery will have no effect. | |
- // As of build 25881, 2018-01-22. | |
- if ( ac -> check() < ac -> max_stack() ) | |
- { | |
- ac -> trigger( stacks, savant_damage_bonus() ); | |
- } | |
- } | |
- else | |
- { | |
- ac -> trigger( stacks ); | |
- } | |
- | |
- int after = ac -> check(); | |
- | |
- if ( p() -> talents.rule_of_threes -> ok() && before < 3 && after >= 3 ) | |
- { | |
- p() -> buffs.rule_of_threes -> trigger(); | |
- } | |
- } | |
- | |
double arcane_charge_damage_bonus( bool arcane_barrage = false ) const | |
{ | |
- double per_ac_bonus = p() -> bugs ? p() -> buffs.arcane_charge -> check_value() : savant_damage_bonus(); | |
+ double per_ac_bonus = p() -> bugs ? p() -> buffs.arcane_charge -> check_value() : p() -> savant_damage_bonus(); | |
if ( arcane_barrage ) | |
{ | |
@@ -2128,7 +2127,7 @@ struct presence_of_mind_t : public arcane_mage_spell_t | |
if ( p() -> sets -> has_set_bonus( MAGE_ARCANE, T20, B2 ) ) | |
{ | |
- trigger_arcane_charge( 4 ); | |
+ p() -> trigger_arcane_charge( 4 ); | |
p() -> buffs.crackling_energy -> trigger(); | |
} | |
} | |
@@ -2314,7 +2313,7 @@ struct arcane_blast_t : public arcane_mage_spell_t | |
if ( hit_any_target ) | |
{ | |
- trigger_arcane_charge(); | |
+ p() -> trigger_arcane_charge(); | |
} | |
if ( p() -> buffs.presence_of_mind -> up() ) | |
@@ -2395,7 +2394,7 @@ struct arcane_explosion_t : public arcane_mage_spell_t | |
if ( hit_any_target ) | |
{ | |
- trigger_arcane_charge(); | |
+ p() -> trigger_arcane_charge(); | |
} | |
p() -> buffs.quick_thinker -> trigger(); | |
@@ -2624,7 +2623,7 @@ struct arcane_orb_bolt_t : public arcane_mage_spell_t | |
if ( result_is_hit( s -> result ) ) | |
{ | |
- trigger_arcane_charge(); | |
+ p() -> trigger_arcane_charge(); | |
p() -> buffs.quick_thinker -> trigger(); | |
} | |
} | |
@@ -2657,7 +2656,7 @@ struct arcane_orb_t : public arcane_mage_spell_t | |
virtual void execute() override | |
{ | |
arcane_mage_spell_t::execute(); | |
- trigger_arcane_charge(); | |
+ p() -> trigger_arcane_charge(); | |
} | |
virtual timespan_t travel_time() const override | |
@@ -2845,7 +2844,7 @@ struct charged_up_t : public arcane_mage_spell_t | |
{ | |
arcane_mage_spell_t::execute(); | |
- trigger_arcane_charge( 4 ); | |
+ p() -> trigger_arcane_charge( 4 ); | |
for ( int i = 0; i < 4; i++ ) | |
if ( p() -> buffs.quick_thinker -> trigger() ) | |
@@ -3086,26 +3085,6 @@ struct evocation_t : public arcane_mage_spell_t | |
mage -> buffs.evocation -> trigger( 1, mana_regen_multiplier, -1.0, duration ); | |
} | |
- struct temporal_flux_event_t : public event_t | |
- { | |
- mage_t* mage; | |
- | |
- temporal_flux_event_t( mage_t* m, timespan_t delay ) | |
- : event_t( *m, delay ), mage( m ) | |
- { } | |
- | |
- virtual const char* name() const override | |
- { | |
- return "temporal_flux_event"; | |
- } | |
- | |
- virtual void execute() override | |
- { | |
- mage -> temporal_flux_event = nullptr; | |
- trigger_evocation_buff( mage ); | |
- } | |
- }; | |
- | |
virtual void execute() override | |
{ | |
arcane_mage_spell_t::execute(); | |
@@ -3118,12 +3097,6 @@ struct evocation_t : public arcane_mage_spell_t | |
arcane_mage_spell_t::last_tick( d ); | |
p() -> buffs.evocation -> expire(); | |
- | |
- if ( p() -> talents.temporal_flux -> ok() ) | |
- { | |
- timespan_t delay = 1000 * p() -> talents.temporal_flux -> effectN( 1 ).time_value(); | |
- p() -> temporal_flux_event = make_event<temporal_flux_event_t>( *sim, p(), delay ); | |
- } | |
} | |
virtual bool usable_moving() const override | |
@@ -4961,7 +4934,6 @@ struct summon_arcane_familiar_t : public arcane_mage_spell_t | |
} | |
}; | |
- | |
// Time Warp Spell ============================================================ | |
struct time_warp_t : public mage_spell_t | |
@@ -5449,6 +5421,58 @@ struct ignite_spread_event_t : public event_t | |
sim(), *mage, timespan_t::from_seconds( 2.0 ) ); | |
} | |
}; | |
+ | |
+struct time_anomaly_event_t : public event_t | |
+{ | |
+ const char* name() const override | |
+ { | |
+ return "time_anomaly_event"; | |
+ } | |
+ | |
+ time_anomaly_event_t( mage_t& m, const timespan_t delta_time ) : | |
+ event_t( m, delta_time ), | |
+ mage( &m ) | |
+ { } | |
+ | |
+ enum time_anomaly_procs_e | |
+ { | |
+ TIME_ANOMALY_ARCANE_CHARGES = 0, | |
+ TIME_ANOMALY_ARCANE_POWER, | |
+ TIME_ANOMALY_EVOCATION | |
+ }; | |
+ | |
+ void execute() override | |
+ { | |
+ auto current_roll = static_cast<unsigned>( rng().range( 0, as<double>( 3.0 ) ) ); | |
+ | |
+ switch ( current_roll ) | |
+ { | |
+ case TIME_ANOMALY_ARCANE_CHARGES: | |
+ if ( mage -> buffs.arcane_charge -> check() < 3 ) | |
+ { | |
+ mage -> trigger_arcane_charge( as<unsigned>( mage -> talents.time_anomaly -> effectN( 3 ).base_value() ) ); | |
+ } | |
+ break; | |
+ | |
+ case TIME_ANOMALY_ARCANE_POWER: | |
+ mage -> buffs.arcane_power -> trigger( 1, buff_t::DEFAULT_VALUE(), 1.0, timespan_t::from_seconds( mage -> talents.time_anomaly -> effectN( 1 ).base_value() ) ); | |
+ break; | |
+ | |
+ case TIME_ANOMALY_EVOCATION: | |
+ mage -> buffs.evocation -> trigger( 1, buff_t::DEFAULT_VALUE(), 1.0, timespan_t::from_seconds( mage -> talents.time_anomaly -> effectN( 2 ).base_value() ) ); | |
+ break; | |
+ | |
+ default: | |
+ break; | |
+ } | |
+ | |
+ mage -> time_anomaly_event = make_event<time_anomaly_event_t>( sim(), *mage, mage -> talents.time_anomaly -> effectN( 1 ).period() ); | |
+ } | |
+ | |
+private: | |
+ mage_t* mage; | |
+}; | |
+ | |
} // namespace events | |
// ========================================================================== | |
@@ -5477,7 +5501,7 @@ mage_t::mage_t( sim_t* sim, const std::string& name, race_e r ) : | |
icicle( icicles_t() ), | |
ignite( nullptr ), | |
ignite_spread_event( nullptr ), | |
- temporal_flux_event( nullptr ), | |
+ time_anomaly_event( nullptr ), | |
last_bomb_target( nullptr ), | |
distance_from_rune( 0.0 ), | |
firestarter_time( timespan_t::zero() ), | |
@@ -5517,7 +5541,7 @@ mage_t::mage_t( sim_t* sim, const std::string& name, race_e r ) : | |
switch ( specialization() ) | |
{ | |
case MAGE_ARCANE: | |
- return spell -> id() == 234302; // Temporal Flux | |
+ return spell -> id() == 210805; // Time Anomaly | |
case MAGE_FIRE: | |
return spell -> id() == 205029; // Flame On | |
case MAGE_FROST: | |
@@ -5935,7 +5959,7 @@ void mage_t::init_spells() | |
talents.comet_storm = find_talent_spell( "Comet Storm" ); | |
// Tier 100 | |
talents.overpowered = find_talent_spell( "Overpowered" ); | |
- talents.temporal_flux = find_talent_spell( "Temporal Flux" ); | |
+ talents.time_anomaly = find_talent_spell( "Time Anomaly" ); | |
talents.arcane_orb = find_talent_spell( "Arcane Orb" ); | |
talents.kindling = find_talent_spell( "Kindling" ); | |
talents.pyroclasm = find_talent_spell( "Pyroclasm" ); | |
@@ -6938,7 +6962,7 @@ void mage_t::reset() | |
icicles.clear(); | |
event_t::cancel( icicle_event ); | |
event_t::cancel( ignite_spread_event ); | |
- event_t::cancel( temporal_flux_event ); | |
+ event_t::cancel( time_anomaly_event ); | |
if ( spec.savant -> ok() ) | |
{ | |
@@ -7019,6 +7043,11 @@ void mage_t::arise() | |
if ( talents.incanters_flow -> ok() ) | |
buffs.incanters_flow -> trigger(); | |
+ if ( talents.time_anomaly -> ok() ) | |
+ { | |
+ time_anomaly_event = make_event<events::time_anomaly_event_t>( *sim, *this, talents.time_anomaly -> effectN( 1 ).period() ); | |
+ } | |
+ | |
if ( blessing_of_wisdom_count > 0 ) | |
{ | |
buffs.greater_blessing_of_widsom -> trigger(); | |
@@ -7257,51 +7286,6 @@ expr_t* mage_t::create_expression( const std::string& name_str ) | |
std::vector<std::string> splits = util::string_split( name_str, "." ); | |
- // Temporal Flux expressions ================================================ | |
- if ( splits.size() == 2 && util::str_compare_ci( splits[ 0 ], "temporal_flux_delay" ) ) | |
- { | |
- enum temporal_flux_expr_type_e | |
- { | |
- DELAY_ACTIVE, | |
- DELAY_REMAINS | |
- }; | |
- | |
- struct temporal_flux_expr_t : public mage_expr_t | |
- { | |
- temporal_flux_expr_type_e type; | |
- | |
- temporal_flux_expr_t( mage_t& m, const std::string& name, temporal_flux_expr_type_e type ) : | |
- mage_expr_t( name, m ), type( type ) | |
- { } | |
- | |
- virtual double evaluate() override | |
- { | |
- switch ( type ) | |
- { | |
- case DELAY_ACTIVE: | |
- return mage.temporal_flux_event ? 1.0 : 0.0; | |
- case DELAY_REMAINS: | |
- return mage.temporal_flux_event ? mage.temporal_flux_event -> remains().total_seconds() : 0.0; | |
- default: | |
- return 0.0; | |
- } | |
- } | |
- }; | |
- | |
- if ( util::str_compare_ci( splits[ 1 ], "active" ) ) | |
- { | |
- return new temporal_flux_expr_t( *this, name_str, DELAY_ACTIVE ); | |
- } | |
- else if ( util::str_compare_ci( splits[ 1 ], "remains" ) ) | |
- { | |
- return new temporal_flux_expr_t( *this, name_str, DELAY_REMAINS ); | |
- } | |
- else | |
- { | |
- sim -> errorf( "Player %s temporal_flux_delay expression: unknown operation '%s'", name(), splits[ 1 ].c_str() ); | |
- } | |
- } | |
- | |
// Ground AoE expressions =================================================== | |
if ( splits.size() == 3 && util::str_compare_ci( splits[ 0 ], "ground_aoe" ) ) | |
{ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment