-
Notifications
You must be signed in to change notification settings - Fork 729
[Mage] Clearcasting BLP + Arcane TWW2 Tier Effect #10303
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
base: thewarwithin
Are you sure you want to change the base?
Changes from 6 commits
3a67df7
6063818
f0a38ae
ebeebd1
36a1802
721e967
be793ce
f3c5a49
0ff821c
cb84889
ac72b6e
90da679
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -472,6 +472,8 @@ struct mage_t final : public player_t | |
unsigned initial_spellfire_spheres = 5; | ||
arcane_phoenix_rotation arcane_phoenix_rotation_override = arcane_phoenix_rotation::DEFAULT; | ||
bool ice_nova_consumes_winters_chill = true; | ||
double clearcasting_chance = 0.0068; | ||
double illuminated_thoughts_clearcasting_chance = 0.0938; | ||
} options; | ||
|
||
// Pets | ||
|
@@ -575,6 +577,7 @@ struct mage_t final : public player_t | |
int embedded_splinters; | ||
int magis_spark_spells; | ||
int intuition_blp_count; | ||
int clearcasting_blp_count; | ||
} state; | ||
|
||
struct expression_support_t | ||
|
@@ -1029,7 +1032,7 @@ struct mage_t final : public player_t | |
void trigger_arcane_charge( int stacks = 1 ); | ||
bool trigger_brain_freeze( double chance, proc_t* source, timespan_t delay = 0.15_s ); | ||
bool trigger_crowd_control( const action_state_t* s, spell_mechanic type, timespan_t adjust = 0_ms ); | ||
bool trigger_clearcasting( double chance, timespan_t delay = 0.15_s ); | ||
bool trigger_clearcasting( double chance, timespan_t delay = 0.15_s, bool predictable = true, bool guaranteed_jackpot = false ); | ||
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. I don't know if it's better to handle jackpots/tier effects inside of Clearcasting or ToTM; ToTM grants a guaranteed jackpot, either I deal with it within totm's execute, or here. My reasoning was that since jackpots are directly linked with regular Clearcasting procs, I might as well pair them up, but I'm not sure if this is the right call. 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. Given the need to set up the RPPM for this as I mentioned in another comment, I don't think it makes sense to have the guaranteed triggers in here. I think it's better to just trigger it directly from TotM so that the trigger in here can always roll the RPPM. This way it's also a bit more consistent with how the other specs are handled. While this could cause a double trigger of the jackpot buffs in some cases, as far as I can tell that wouldn't matter, so we don't even need to test if it can happen in game. Is there any case other than the Time Anomaly trigger where a true 100% chance proc would not be predictable here? It might be better to make it |
||
bool trigger_fof( double chance, proc_t* source, int stacks = 1 ); | ||
void trigger_icicle( player_t* icicle_target, bool chain = false ); | ||
void trigger_icicle_gain( player_t* icicle_target, action_t* icicle_action, double chance = 1.0, timespan_t duration = timespan_t::min() ); | ||
|
@@ -2262,15 +2265,32 @@ struct mage_spell_t : public spell_t | |
// This will prevent for example Arcane Missiles consuming its own Clearcasting proc. | ||
consume_cost_reductions(); | ||
|
||
if ( p()->spec.clearcasting->ok() && triggers.clearcasting ) | ||
if ( triggers.clearcasting && p()->spec.clearcasting->ok() ) | ||
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. I don't know why I changed this. I suppose it just looked neater to me at the time? Sorry. |
||
{ | ||
// TODO: implement the hidden BLP | ||
double chance = p()->spec.clearcasting->effectN( 2 ).percent(); | ||
chance += p()->talents.illuminated_thoughts->effectN( 1 ).percent(); | ||
// Arcane Blast gets an additional 5% chance. Not mentioned in the spell data (or even the description). | ||
constexpr int cc_blp_threshold = 13; | ||
// The tooltip chance present on Clearcasting/Illuminated Thoughts is the total expected outcome of Clearcasting applications, not it's random proc chance. | ||
// Whenever combining both the proc chance and its bad luck protection, the final application rate is equal to its tooltip chance. | ||
double proc_chance = p()->options.clearcasting_chance; | ||
if ( p()->talents.illuminated_thoughts.ok() ) | ||
proc_chance = p()->options.illuminated_thoughts_clearcasting_chance; | ||
// Arcane Blast has an unmentioned 5% increase in total expected Clearcasting applications -- same BLP threshold, but higher proc chance. | ||
if ( id == 30451 ) | ||
chance += 0.05; | ||
p()->trigger_clearcasting( chance ); | ||
{ | ||
proc_chance = 0.0938; | ||
if ( p()->talents.illuminated_thoughts.ok() ) | ||
proc_chance = 0.1618; | ||
} | ||
|
||
// Likely a bug: Arcane Orb procs from Orb Barrage uniquely decrements the BLP, effectively nullifying the incoming increment from Barrage. | ||
if ( name_str == "orb_barrage_arcane_orb" ) | ||
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. I don't know if I should include the use of 'bugs' here. I have no idea if this is intentional by blizz -- if it is, I think it's kinda silly, though. 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. You should check whether the arcane_orb_t's |
||
p()->state.clearcasting_blp_count -= 1; | ||
else | ||
p()->state.clearcasting_blp_count += 1; | ||
if ( !background && rng().roll( proc_chance ) || ( p()->state.clearcasting_blp_count >= cc_blp_threshold ) ) | ||
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. I think something like this would be cleaner here, especially when combined with the change I mentioned above to replace that if ( p()->state.clearcasting_blp_count >= cc_blp_threshold )
proc_chance = 1.0;
if ( p()->trigger_clearcasting( proc_chance ) )
p()->state.clearcasting_blp_count = 0; 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. If we allow predicting the BLP (I'd assume for both this and intuition), might it be a good idea to make the bad luck protection visible as an actual buff, something like with AA's counter? I'd also assume it'd be nice to have it visible + tangible within the input. |
||
{ | ||
p()->trigger_clearcasting( 1.0, 100_ms, false ); | ||
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. Why 100_ms and not the default 0.15_s? I don't know which is more accurate, but I think it should be consistent in both places. 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. 100ms delay for CC gained via the BLP/random proc rate is what I consistently saw in logs. Occasionally, I'd see a bit of a delay greater than 100ms, but I believe it's mostly due to my autoclicker being unsynchronized with spell casts and its following GCD, so it'd desync every now and then. For stuff like TA/Splinterstorm/Soul/ToTM jackpot, it was 0ms, though. Yeah, I'll go ahead and change it. edit: I'll re-verify the delay closer, it's confusing me. Just a bit of time. |
||
p()->state.clearcasting_blp_count = 0; | ||
} | ||
} | ||
|
||
if ( !background && affected_by.ice_floes && time_to_execute > 0_ms ) | ||
|
@@ -3430,7 +3450,7 @@ struct arcane_orb_t final : public arcane_mage_spell_t | |
may_miss = false; | ||
aoe = -1; | ||
cooldown->charges += as<int>( p->talents.charged_orb->effectN( 1 ).base_value() ); | ||
triggers.clearcasting = type == ao_type::NORMAL; | ||
triggers.clearcasting = true; | ||
triggers.intuition = true; | ||
|
||
std::string_view bolt_name; | ||
|
@@ -6772,7 +6792,8 @@ struct touch_of_the_magi_t final : public arcane_mage_spell_t | |
|
||
p()->trigger_arcane_charge( as<int>( data().effectN( 2 ).base_value() ) ); | ||
p()->buffs.leydrinker->trigger(); | ||
p()->trigger_jackpot( true ); | ||
// Clearcastings generated by TWW2's tier effect is independent, allowing ToTM to sometimes apply two applications with one cast. | ||
p()->trigger_clearcasting( p()->sets->has_set_bonus( MAGE_ARCANE, TWW2, B2 ), 0_ms, true, true ); | ||
} | ||
|
||
void impact( action_state_t* s ) override | ||
|
@@ -7499,7 +7520,7 @@ struct time_anomaly_tick_event_t final : public mage_event_t | |
mage->buffs.arcane_surge->trigger( 1000 * mage->talents.time_anomaly->effectN( 1 ).time_value() ); | ||
break; | ||
case TA_CLEARCASTING: | ||
mage->trigger_clearcasting( 1.0, 0_ms ); | ||
mage->trigger_clearcasting( 1.0, 0_ms, false ); | ||
break; | ||
case TA_COMBUSTION: | ||
mage->buffs.combustion->trigger( 1000 * mage->talents.time_anomaly->effectN( 4 ).time_value() ); | ||
|
@@ -7584,7 +7605,7 @@ struct splinterstorm_event_t final : public mage_event_t | |
else | ||
// Doesn't seem to be affected by Illuminated Thoughts. | ||
// TODO: get more data and double check | ||
mage->trigger_clearcasting( mage->talents.splinterstorm->effectN( 4 ).percent(), 0_ms ); | ||
mage->trigger_clearcasting( mage->talents.splinterstorm->effectN( 4 ).percent(), 0_ms, false ); | ||
} | ||
|
||
mage->events.splinterstorm = make_event<splinterstorm_event_t>( | ||
|
@@ -7920,6 +7941,8 @@ void mage_t::create_options() | |
return true; | ||
} ) ); | ||
add_option( opt_bool( "mage.ice_nova_consumes_winters_chill", options.ice_nova_consumes_winters_chill ) ); | ||
add_option( opt_float( "mage.clearcasting_chance", options.clearcasting_chance)); | ||
add_option( opt_float( "mage.illuminated_thoughts_clearcasting_chance", options.illuminated_thoughts_clearcasting_chance)); | ||
|
||
player_t::create_options(); | ||
} | ||
|
@@ -8370,7 +8393,7 @@ void mage_t::init_spells() | |
void mage_t::init_special_effects() | ||
{ | ||
auto spell = sets->set( specialization(), TWW2, B2 ); | ||
if ( spell->ok() ) | ||
if ( spell->ok() && ( specialization() != MAGE_ARCANE ) ) | ||
{ | ||
auto effect = new special_effect_t( this ); | ||
effect->name_str = "mage_jackpot_proc"; | ||
|
@@ -9526,11 +9549,20 @@ void mage_t::trigger_jackpot( bool guaranteed ) | |
bool has_4pc = sets->has_set_bonus( specialization(), TWW2, B4 ); | ||
switch ( specialization() ) | ||
{ | ||
// TWW2's tier effect for Arcane doesn't randomly generate Clearcasting (has a misleading tooltip). Instead, it solely grants Clarity/AA whenever any source of CC is applied at a 13% chance. | ||
case MAGE_ARCANE: | ||
buffs.clarity->trigger(); | ||
trigger_clearcasting( 1.0, 0_ms ); | ||
if ( has_4pc ) | ||
buffs.aether_attunement->trigger(); | ||
if ( guaranteed || rng().roll( 0.13 ) ) | ||
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. I'm confused as to where it originally (before this) returned Jackpot's original proc rate -- I'm certain it's a 13% chance, but I can't find a mention of it. 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. The jackpot effects are normally triggered through the driver aura that gets set up in To roll the RPPM after triggering Clearcasting, we're probably going to need to (1) not create that special effect for Arcane and (2) manually set up the RPPM object for Arcane (see |
||
{ | ||
buffs.clarity->trigger(); | ||
if ( guaranteed ) | ||
buffs.clarity->predict(); | ||
if ( has_4pc ) | ||
{ | ||
buffs.aether_attunement->trigger(); | ||
if ( guaranteed ) | ||
buffs.aether_attunement->predict(); | ||
} | ||
} | ||
break; | ||
case MAGE_FIRE: | ||
{ | ||
|
@@ -9732,7 +9764,7 @@ void mage_t::trigger_splinter( player_t* target, int count ) | |
} | ||
} | ||
|
||
bool mage_t::trigger_clearcasting( double chance, timespan_t delay ) | ||
bool mage_t::trigger_clearcasting( double chance, timespan_t delay, bool predictable, bool guaranteed_jackpot ) | ||
{ | ||
if ( specialization() != MAGE_ARCANE ) | ||
return false; | ||
|
@@ -9744,10 +9776,11 @@ bool mage_t::trigger_clearcasting( double chance, timespan_t delay ) | |
make_event( *sim, delay, [ this ] { buffs.clearcasting->trigger(); } ); | ||
else | ||
buffs.clearcasting->trigger(); | ||
|
||
if ( chance >= 1.0 ) | ||
if ( predictable ) | ||
buffs.clearcasting->predict(); | ||
buffs.big_brained->trigger(); | ||
|
||
trigger_jackpot( guaranteed_jackpot ); | ||
} | ||
|
||
return success; | ||
|
Uh oh!
There was an error while loading. Please reload this page.