Skip to content

Commit 92942cd

Browse files
authored
[Death Knight] Update BoS for 2025/07/03 PTR build (#10388)
1 parent f37146a commit 92942cd

File tree

1 file changed

+15
-85
lines changed

1 file changed

+15
-85
lines changed

engine/class_modules/sc_death_knight.cpp

Lines changed: 15 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,7 +1423,6 @@ struct death_knight_t : public parse_player_effects_t
14231423
const spell_data_t* frostbane_buff;
14241424
const spell_data_t* frostbane_driver;
14251425
const spell_data_t* frostbane_damage;
1426-
const spell_data_t* breath_of_sindragosa_buff;
14271426
const spell_data_t* breath_of_sindragosa_erw_refund;
14281427
const spell_data_t* killing_streak_buff;
14291428
// Tier Sets
@@ -5631,63 +5630,23 @@ struct breath_of_sindragosa_buff_t : public death_knight_buff_t
56315630
{
56325631
breath_of_sindragosa_buff_t( death_knight_t* p, std::string_view name, const spell_data_t* s )
56335632
: death_knight_buff_t( p, name, s ),
5634-
ticking_cost( 0.0 ),
56355633
tick_period( p->talent.frost.breath_of_sindragosa->effectN( 1 ).period() ),
56365634
rune_gen( as<int>( p->spell.breath_of_sindragosa_rune_gen->effectN( 1 ).base_value() ) )
56375635
{
56385636
cooldown->duration = 0_ms; // Handled by the action
56395637
set_tick_on_application( false );
56405638
set_tick_zero( false );
56415639

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-
56525640
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-
56685641
// Default player target to begin with, if theres a valid last target, switch to that.
56695642
player_t* bos_target = p->target;
56705643
if ( !p->last_target->is_sleeping() && p->last_target != nullptr && p->last_target != source )
56715644
bos_target = p->last_target;
56725645

5673-
// If there's enough resources for another tick, deal damage
56745646
p->background_actions.breath_of_sindragosa_tick->execute_on_target( bos_target );
56755647
} );
56765648
}
56775649

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-
56915650
void expire_override( int expiration_stacks, timespan_t remaining_duration ) override
56925651
{
56935652
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
57005659
}
57015660

57025661
private:
5703-
double ticking_cost;
57045662
const timespan_t tick_period;
57055663
int rune_gen;
57065664
};
@@ -7875,16 +7833,6 @@ struct breath_of_sindragosa_tick_t final : public death_knight_spell_t
78757833
background = true;
78767834
reduced_aoe_targets = 1.0;
78777835
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-
}
78887836
ap_type = attack_power_type::WEAPON_BOTH;
78897837

78907838
if ( p->main_hand_weapon.group() == WEAPON_2H )
@@ -7906,14 +7854,6 @@ struct breath_of_sindragosa_tick_t final : public death_knight_spell_t
79067854
return 0;
79077855
}
79087856

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-
79177857
void impact( action_state_t* state ) override
79187858
{
79197859
death_knight_spell_t::impact( state );
@@ -7934,21 +7874,11 @@ struct breath_of_sindragosa_t final : public death_knight_spell_t
79347874
{
79357875
breath_of_sindragosa_t( death_knight_t* p, std::string_view options_str )
79367876
: death_knight_spell_t( "breath_of_sindragosa", p, p->talent.frost.breath_of_sindragosa ),
7937-
ticking_cost( 0.0 ),
79387877
rune_gen( 0 )
79397878
{
79407879
may_miss = may_dodge = may_parry = false;
79417880
parse_options( options_str );
79427881

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-
79527882
if ( p->talent.frost.breath_of_sindragosa.ok() )
79537883
{
79547884
add_child( p->background_actions.breath_of_sindragosa_tick );
@@ -7961,25 +7891,13 @@ struct breath_of_sindragosa_t final : public death_knight_spell_t
79617891
{
79627892
death_knight_spell_t::execute();
79637893
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() ) );
79657896

79667897
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();
79797898
}
79807899

79817900
private:
7982-
double ticking_cost;
79837901
int rune_gen;
79847902
};
79857903

@@ -10227,6 +10145,13 @@ struct howling_blast_t final : public death_knight_spell_t
1022710145
as<int>( p()->talent.deathbringer.dark_talons->effectN( 2 ).base_value() ) );
1022810146
}
1022910147

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+
1023010155
p()->buffs.rime->decrement();
1023110156

1023210157
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
1239412319
if ( talent.frost.killing_streak.ok() )
1239512320
buffs.killing_streak->trigger( decrement_count );
1239612321

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+
1239712328
for ( int i = decrement_count; i > 0; --i )
1239812329
{
1239912330
if ( talent.frost.bonegrinder.ok() && !buffs.bonegrinder_frost->up() )
@@ -14242,7 +14173,6 @@ void death_knight_t::spell_lookups()
1424214173
spell.frostbane_driver = conditional_spell_lookup( talent.frost.frostbane.ok(), 1228433 );
1424314174
spell.frostbane_damage = conditional_spell_lookup( talent.frost.frostbane.ok(), 1228443 );
1424414175
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 );
1424614176
spell.breath_of_sindragosa_erw_refund = conditional_spell_lookup( talent.frost.breath_of_sindragosa.ok(), 303753 );
1424714177
// Tier Sets
1424814178
spell.icy_vigor = conditional_spell_lookup( sets->has_set_bonus( DEATH_KNIGHT_FROST, TWW1, B4 ), 457189 );

0 commit comments

Comments
 (0)