Skip to content

Instantly share code, notes, and snippets.

@cgdangelo
Last active June 21, 2018 17:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cgdangelo/e7e0572312ebddd14df56617c5337893 to your computer and use it in GitHub Desktop.
Save cgdangelo/e7e0572312ebddd14df56617c5337893 to your computer and use it in GitHub Desktop.
commit e51691d169ae55d909d2854be29b4188a5523378
Author: Charles D'Angelo <c.g.dangelo@gmail.com>
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