@@ -1423,7 +1423,6 @@ struct death_knight_t : public parse_player_effects_t
1423
1423
const spell_data_t* frostbane_buff;
1424
1424
const spell_data_t* frostbane_driver;
1425
1425
const spell_data_t* frostbane_damage;
1426
- const spell_data_t* breath_of_sindragosa_buff;
1427
1426
const spell_data_t* breath_of_sindragosa_erw_refund;
1428
1427
const spell_data_t* killing_streak_buff;
1429
1428
// Tier Sets
@@ -5631,63 +5630,23 @@ struct breath_of_sindragosa_buff_t : public death_knight_buff_t
5631
5630
{
5632
5631
breath_of_sindragosa_buff_t( death_knight_t* p, std::string_view name, const spell_data_t* s )
5633
5632
: death_knight_buff_t( p, name, s ),
5634
- ticking_cost( 0.0 ),
5635
5633
tick_period( p->talent.frost.breath_of_sindragosa->effectN( 1 ).period() ),
5636
5634
rune_gen( as<int>( p->spell.breath_of_sindragosa_rune_gen->effectN( 1 ).base_value() ) )
5637
5635
{
5638
5636
cooldown->duration = 0_ms; // Handled by the action
5639
5637
set_tick_on_application( false );
5640
5638
set_tick_zero( false );
5641
5639
5642
- // Extract the cost per tick from spelldata
5643
- for ( size_t idx = 1; idx <= data().power_count(); idx++ )
5644
- {
5645
- const spellpower_data_t& power = data().powerN( idx );
5646
- if ( power.aura_id() == 0 || player->dbc->spec_by_spell( power.aura_id() ) == player->specialization() )
5647
- {
5648
- ticking_cost = power.cost_per_tick();
5649
- }
5650
- }
5651
-
5652
5640
set_tick_callback( [ &, p ]( buff_t* /* buff */, int /* total_ticks */, timespan_t /* tick_time */ ) {
5653
- // If the player doesn't have enough RP to fuel this tick, BoS is cancelled and no RP is consumed
5654
- // This can happen if the player uses another RP spender between two ticks and is left with < 15 RP
5655
- if ( !check_resource( "for this tick" ) )
5656
- return;
5657
-
5658
- // Else, consume the resource and update the damage tick's resource stats
5659
- p->resource_loss( RESOURCE_RUNIC_POWER, ticking_cost, nullptr, p->background_actions.breath_of_sindragosa_tick );
5660
- p->background_actions.breath_of_sindragosa_tick->stats->consume_resource( RESOURCE_RUNIC_POWER, ticking_cost );
5661
-
5662
- // If the player doesn't have enough RP to fuel the next tick, BoS is cancelled
5663
- // after the RP consumption and before the damage event
5664
- // This is the normal BoS expiration scenario
5665
- if ( !check_resource( "for the next tick" ) )
5666
- return;
5667
-
5668
5641
// Default player target to begin with, if theres a valid last target, switch to that.
5669
5642
player_t* bos_target = p->target;
5670
5643
if ( !p->last_target->is_sleeping() && p->last_target != nullptr && p->last_target != source )
5671
5644
bos_target = p->last_target;
5672
5645
5673
- // If there's enough resources for another tick, deal damage
5674
5646
p->background_actions.breath_of_sindragosa_tick->execute_on_target( bos_target );
5675
5647
} );
5676
5648
}
5677
5649
5678
- bool check_resource( std::string_view s )
5679
- {
5680
- if ( p()->resource_available( RESOURCE_RUNIC_POWER, ticking_cost ) )
5681
- return true;
5682
-
5683
- sim->print_log( "Player {} doesn't have the {} Runic Power required {}. Breath of Sindragosa was cancelled.",
5684
- p()->name_str, ticking_cost, s );
5685
-
5686
- // Separate the expiration event to happen immediately after tick processing
5687
- make_event( *sim, 0_ms, [ & ]() { expire(); } );
5688
- return false;
5689
- }
5690
-
5691
5650
void expire_override( int expiration_stacks, timespan_t remaining_duration ) override
5692
5651
{
5693
5652
death_knight_buff_t::expire_override( expiration_stacks, remaining_duration );
@@ -5700,7 +5659,6 @@ struct breath_of_sindragosa_buff_t : public death_knight_buff_t
5700
5659
}
5701
5660
5702
5661
private:
5703
- double ticking_cost;
5704
5662
const timespan_t tick_period;
5705
5663
int rune_gen;
5706
5664
};
@@ -7875,16 +7833,6 @@ struct breath_of_sindragosa_tick_t final : public death_knight_spell_t
7875
7833
background = true;
7876
7834
reduced_aoe_targets = 1.0;
7877
7835
full_amount_targets = 1;
7878
- // Extract the cost per tick from spelldata
7879
- for ( size_t idx = 1; idx <= p->buffs.breath_of_sindragosa->data().power_count(); idx++ )
7880
- {
7881
- const spellpower_data_t& power = p->buffs.breath_of_sindragosa->data().powerN( idx );
7882
- if ( power.aura_id() == 0 || player->dbc->spec_by_spell( power.aura_id() ) == player->specialization() )
7883
- {
7884
- // Make sure to set base_casts for runic power spending procs.
7885
- base_costs[ RESOURCE_RUNIC_POWER ] = power.cost_per_tick();
7886
- }
7887
- }
7888
7836
ap_type = attack_power_type::WEAPON_BOTH;
7889
7837
7890
7838
if ( p->main_hand_weapon.group() == WEAPON_2H )
@@ -7906,14 +7854,6 @@ struct breath_of_sindragosa_tick_t final : public death_knight_spell_t
7906
7854
return 0;
7907
7855
}
7908
7856
7909
- void execute() override
7910
- {
7911
- death_knight_spell_t::execute();
7912
- p()->buffs.rime->trigger(
7913
- 1, buff_t::DEFAULT_VALUE(),
7914
- p()->spec.rime->effectN( 1 ).percent() + p()->talent.frost.rage_of_the_frozen_champion->effectN( 2 ).percent() );
7915
- }
7916
-
7917
7857
void impact( action_state_t* state ) override
7918
7858
{
7919
7859
death_knight_spell_t::impact( state );
@@ -7934,21 +7874,11 @@ struct breath_of_sindragosa_t final : public death_knight_spell_t
7934
7874
{
7935
7875
breath_of_sindragosa_t( death_knight_t* p, std::string_view options_str )
7936
7876
: death_knight_spell_t( "breath_of_sindragosa", p, p->talent.frost.breath_of_sindragosa ),
7937
- ticking_cost( 0.0 ),
7938
7877
rune_gen( 0 )
7939
7878
{
7940
7879
may_miss = may_dodge = may_parry = false;
7941
7880
parse_options( options_str );
7942
7881
7943
- for ( size_t idx = 1; idx <= data().power_count(); idx++ )
7944
- {
7945
- const spellpower_data_t& power = data().powerN( idx );
7946
- if ( power.aura_id() == 0 || player->dbc->spec_by_spell( power.aura_id() ) == player->specialization() )
7947
- {
7948
- ticking_cost = power.cost_per_tick();
7949
- }
7950
- }
7951
-
7952
7882
if ( p->talent.frost.breath_of_sindragosa.ok() )
7953
7883
{
7954
7884
add_child( p->background_actions.breath_of_sindragosa_tick );
@@ -7961,25 +7891,13 @@ struct breath_of_sindragosa_t final : public death_knight_spell_t
7961
7891
{
7962
7892
death_knight_spell_t::execute();
7963
7893
p()->buffs.breath_of_sindragosa->trigger();
7964
- p()->replenish_rune( rune_gen, p()->gains.breath_of_sindragosa );
7894
+ p()->cooldown.empower_rune_weapon->reset(
7895
+ false, as<int>( p()->spell.breath_of_sindragosa_erw_refund->effectN( 1 ).base_value() ) );
7965
7896
7966
7897
p()->background_actions.breath_of_sindragosa_tick->execute_on_target( target );
7967
-
7968
- if ( p()->talent.icy_talons.ok() )
7969
- p()->buffs.icy_talons->trigger();
7970
- }
7971
-
7972
- // Breath of Sindragosa can not be used if there isn't enough resources available for one tick
7973
- bool ready() override
7974
- {
7975
- if ( !p()->resource_available( RESOURCE_RUNIC_POWER, ticking_cost ) )
7976
- return false;
7977
-
7978
- return death_knight_spell_t::ready();
7979
7898
}
7980
7899
7981
7900
private:
7982
- double ticking_cost;
7983
7901
int rune_gen;
7984
7902
};
7985
7903
@@ -10227,6 +10145,13 @@ struct howling_blast_t final : public death_knight_spell_t
10227
10145
as<int>( p()->talent.deathbringer.dark_talons->effectN( 2 ).base_value() ) );
10228
10146
}
10229
10147
10148
+ if ( p()->talent.frost.breath_of_sindragosa.ok() && p()->buffs.breath_of_sindragosa->check() && p()->buffs.rime->check() )
10149
+ {
10150
+ timespan_t base_extension = p()->talent.frost.breath_of_sindragosa->effectN( 3 ).time_value();
10151
+ p()->buffs.breath_of_sindragosa->extend_duration(p(), base_extension);
10152
+ }
10153
+
10154
+
10230
10155
p()->buffs.rime->decrement();
10231
10156
10232
10157
if ( p()->talent.frost.howling_blades->ok() )
@@ -12394,6 +12319,12 @@ void death_knight_t::consume_killing_machine( proc_t* proc, timespan_t total_del
12394
12319
if ( talent.frost.killing_streak.ok() )
12395
12320
buffs.killing_streak->trigger( decrement_count );
12396
12321
12322
+ if ( talent.frost.breath_of_sindragosa.ok() && buffs.breath_of_sindragosa->check() )
12323
+ {
12324
+ timespan_t base_extension = talent.frost.breath_of_sindragosa->effectN( 3 ).time_value();
12325
+ buffs.breath_of_sindragosa->extend_duration(this, base_extension * decrement_count);
12326
+ }
12327
+
12397
12328
for ( int i = decrement_count; i > 0; --i )
12398
12329
{
12399
12330
if ( talent.frost.bonegrinder.ok() && !buffs.bonegrinder_frost->up() )
@@ -14242,7 +14173,6 @@ void death_knight_t::spell_lookups()
14242
14173
spell.frostbane_driver = conditional_spell_lookup( talent.frost.frostbane.ok(), 1228433 );
14243
14174
spell.frostbane_damage = conditional_spell_lookup( talent.frost.frostbane.ok(), 1228443 );
14244
14175
spell.killing_streak_buff = conditional_spell_lookup( talent.frost.killing_streak.ok(), 1230916 );
14245
- spell.breath_of_sindragosa_buff = conditional_spell_lookup( talent.frost.breath_of_sindragosa.ok(), 152279 );
14246
14176
spell.breath_of_sindragosa_erw_refund = conditional_spell_lookup( talent.frost.breath_of_sindragosa.ok(), 303753 );
14247
14177
// Tier Sets
14248
14178
spell.icy_vigor = conditional_spell_lookup( sets->has_set_bonus( DEATH_KNIGHT_FROST, TWW1, B4 ), 457189 );
0 commit comments