Skip to content

Commit

Permalink
[Deathknight] Blood 11.0.0.55288 (#8948)
Browse files Browse the repository at this point in the history
  • Loading branch information
Armadk committed Jun 26, 2024
1 parent 96dcf5b commit 3e61377
Showing 1 changed file with 139 additions and 37 deletions.
176 changes: 139 additions & 37 deletions engine/class_modules/sc_death_knight.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,7 @@ struct death_knight_t : public parse_player_effects_t
propagate_const<buff_t*> heartrend;
propagate_const<buff_t*> hemostasis;
propagate_const<buff_t*> ossuary;
buff_t* ossified_vitriol;
propagate_const<buff_t*> perseverance_of_the_ebon_blade;
propagate_const<buff_t*> rune_tap;
propagate_const<buff_t*> sanguine_ground;
Expand Down Expand Up @@ -1322,6 +1323,7 @@ struct death_knight_t : public parse_player_effects_t
const spell_data_t* bone_shield;
const spell_data_t* sanguine_ground;
const spell_data_t* ossuary_buff;
const spell_data_t* ossified_vitriol_buff;
const spell_data_t* crimson_scourge_buff;
const spell_data_t* heartbreaker_rp_gain;
const spell_data_t* heartrend_buff;
Expand Down Expand Up @@ -3376,6 +3378,29 @@ struct dancing_rune_weapon_pet_t : public death_knight_pet_t
}
};

struct vampiric_strike_t : public drw_action_t<melee_attack_t>
{
vampiric_strike_t( util::string_view n, dancing_rune_weapon_pet_t* p )
: drw_action_t<melee_attack_t>( p, n, p->dk()->spell.vampiric_strike )
{
attack_power_mod.direct = data().effectN( 5 ).ap_coeff();
}

double composite_crit_chance() const override
{
double cc = drw_action_t::composite_crit_chance();

// Sanguine Scent currently makes Vampiric Strike always crit when in execute range... for some reason
if ( dk()->bugs && dk()->talent.sanlayn.sanguine_scent.ok() &&
dk()->target->health_percentage() <= dk()->talent.sanlayn.sanguine_scent->effectN( 1 ).base_value() )
{
cc = 1.0;
}

return cc;
}
};

struct marrowrend_t : public drw_action_t<melee_attack_t>
{
int stack_gain;
Expand Down Expand Up @@ -3440,6 +3465,7 @@ struct dancing_rune_weapon_pet_t : public death_knight_pet_t
action_t* marrowrend;
action_t* soul_reaper;
action_t* consumption;
action_t* vampiric_strike;
} ability;

dancing_rune_weapon_pet_t( death_knight_t* owner, util::string_view drw_name = "dancing_rune_weapon" )
Expand Down Expand Up @@ -3487,6 +3513,10 @@ struct dancing_rune_weapon_pet_t : public death_knight_pet_t
{
ability.consumption = get_action<consumption_t>( "consumption", this );
}
if ( dk()->talent.sanlayn.vampiric_strike.ok() )
{
ability.vampiric_strike = get_action<vampiric_strike_t>( "vampiric_strike", this );
}
}

void arise() override
Expand Down Expand Up @@ -7082,6 +7112,8 @@ struct bonestorm_t final : public death_knight_spell_t
// or in Spelldata.
int charges = std::max( p()->buffs.bone_shield->check(), 10 );
p()->buffs.bone_shield->decrement( charges );
if( p() -> talent.blood.ossified_vitriol -> ok() )
p()->buffs.ossified_vitriol->trigger( charges );
return base_tick_time * charges / 10;
}

Expand Down Expand Up @@ -8864,23 +8896,6 @@ struct leeching_strike_t final : public death_knight_heal_t
}
};

struct heart_strike_bloodied_blade_t : public death_knight_melee_attack_t
{
heart_strike_bloodied_blade_t( util::string_view n, death_knight_t* p )
: death_knight_melee_attack_t( n, p, p->spell.heart_strike_bloodied_blade )
{
background = true;
aoe = 2;
weapon = &( p->main_hand_weapon );
}

int n_targets() const override
{
return p()->in_death_and_decay() ? aoe + as<int>( p()->talent.cleaving_strikes->effectN( 3 ).base_value() )
: aoe;
}
};

struct heart_strike_base_t : public death_knight_melee_attack_t
{
heart_strike_base_t( util::string_view n, death_knight_t* p, const spell_data_t* s )
Expand All @@ -8906,19 +8921,6 @@ struct heart_strike_base_t : public death_knight_melee_attack_t
p()->buffs.heartrend->trigger();
}

if ( p()->pets.dancing_rune_weapon_pet.active_pet() != nullptr )
{
p()->pets.dancing_rune_weapon_pet.active_pet()->ability.heart_strike->execute_on_target( target );
}

if ( p()->talent.blood.everlasting_bond.ok() )
{
if ( p()->pets.everlasting_bond_pet.active_pet() != nullptr )
{
p()->pets.everlasting_bond_pet.active_pet()->ability.heart_strike->execute_on_target( target );
}
}

if ( p()->talent.deathbringer.dark_talons.ok() && p()->buffs.icy_talons->check() &&
rng().roll( p()->talent.deathbringer.dark_talons->effectN( 1 ).percent() ) )
{
Expand Down Expand Up @@ -8954,18 +8956,29 @@ struct heart_strike_base_t : public death_knight_melee_attack_t

struct vampiric_strike_blood_t : public heart_strike_base_t
{
vampiric_strike_blood_t( util::string_view n, death_knight_t* p )
vampiric_strike_blood_t( util::string_view n, death_knight_t* p, bool bloodied_blade_triggered )
: heart_strike_base_t( n, p, p->spell.vampiric_strike )
{
attack_power_mod.direct = data().effectN( 5 ).ap_coeff();
energize_amount = std::fabs( data().powerN( 2 ).cost() );
if ( p->talent.sanlayn.infliction_of_sorrow.ok() )

if ( bloodied_blade_triggered )
{
add_child( p->active_spells.infliction_of_sorrow );
background = true;
}
if ( p->talent.sanlayn.the_blood_is_life.ok() )
else
{
p->pets.blood_beast.set_creation_event_callback( pets::parent_pet_action_fn( this ) );
if ( p->talent.sanlayn.infliction_of_sorrow.ok() )
{
// We only can have this be a child of a single thing, so parent it to the main vampiric strike
add_child( p->active_spells.infliction_of_sorrow );
}
// In game bloodied blade vamp strikes will proc this. But I have no desire to re-write this all right now, and
// expect this to change due to how buggy it is.
if ( p->talent.sanlayn.the_blood_is_life.ok() )
{
p->pets.blood_beast.set_creation_event_callback( pets::parent_pet_action_fn( this ) );
}
}
}

Expand All @@ -8986,6 +8999,19 @@ struct vampiric_strike_blood_t : public heart_strike_base_t
void execute() override
{
heart_strike_base_t::execute();

if ( p()->pets.dancing_rune_weapon_pet.active_pet() != nullptr )
{
p()->pets.dancing_rune_weapon_pet.active_pet()->ability.vampiric_strike->execute_on_target( target );
}

if ( p()->talent.blood.everlasting_bond.ok() )
{
if ( p()->pets.everlasting_bond_pet.active_pet() != nullptr )
{
p()->pets.everlasting_bond_pet.active_pet()->ability.vampiric_strike->execute_on_target( target );
}
}
p()->trigger_sanlayn_execute_talents( true );
}

Expand All @@ -9008,7 +9034,7 @@ struct heart_strike_t : public heart_strike_base_t
parse_options( options_str );
if ( p->talent.sanlayn.vampiric_strike.ok() )
{
vampiric_strike = new vampiric_strike_blood_t( "vampiric_strike", p );
vampiric_strike = new vampiric_strike_blood_t( "vampiric_strike", p, false );
vampiric_strike_cost = p->spell.vampiric_strike->cost( POWER_RUNE );
add_child( vampiric_strike );
}
Expand All @@ -9035,6 +9061,20 @@ struct heart_strike_t : public heart_strike_base_t
return;
}
heart_strike_base_t::execute();

if ( p()->pets.dancing_rune_weapon_pet.active_pet() != nullptr )
{
p()->pets.dancing_rune_weapon_pet.active_pet()->ability.heart_strike->execute_on_target( target );
}

if ( p()->talent.blood.everlasting_bond.ok() )
{
if ( p()->pets.everlasting_bond_pet.active_pet() != nullptr )
{
p()->pets.everlasting_bond_pet.active_pet()->ability.heart_strike->execute_on_target( target );
}
}

p()->trigger_sanlayn_execute_talents( false );
}

Expand All @@ -9052,6 +9092,56 @@ struct heart_strike_t : public heart_strike_base_t
double vampiric_strike_cost;
};

struct heart_strike_bloodied_blade_t : public death_knight_melee_attack_t
{
heart_strike_bloodied_blade_t( util::string_view n, death_knight_t* p )
: death_knight_melee_attack_t( n, p, p->spell.heart_strike_bloodied_blade )
{
background = true;
aoe = 2;
weapon = &( p->main_hand_weapon );

if ( p->talent.sanlayn.vampiric_strike.ok() )
{
vampiric_strike = new vampiric_strike_blood_t( "vampiric_strike_bloodied_blade", p, true );
vampiric_strike_cost = p->spell.vampiric_strike->cost( POWER_RUNE );
add_child( vampiric_strike );
}
}

int n_targets() const override
{
return p()->in_death_and_decay() ? aoe + as<int>( p()->talent.cleaving_strikes->effectN( 3 ).base_value() )
: aoe;
}

double cost() const override
{
if ( p()->talent.sanlayn.vampiric_strike.ok() && p()->buffs.vampiric_strike->check() )
{
return vampiric_strike_cost;
}
else
return 0;
}

void execute() override
{
if ( p()->talent.sanlayn.vampiric_strike.ok() && p()->buffs.vampiric_strike->check() )
{
vampiric_strike->execute();
stats->add_execute( 0_ms, target );
return;
}
death_knight_melee_attack_t::execute();
p()->trigger_sanlayn_execute_talents( false );
}

private:
vampiric_strike_blood_t* vampiric_strike;
double vampiric_strike_cost;
};

// Horn of Winter ===========================================================

struct horn_of_winter_t final : public death_knight_spell_t
Expand Down Expand Up @@ -9250,6 +9340,9 @@ struct marrowrend_t final : public death_knight_melee_attack_t
{
p()->buffs.painful_death->expire();
}

if ( p()->buffs.ossified_vitriol->up() )
p()->buffs.ossified_vitriol->expire();
}

void impact( action_state_t* s ) override
Expand Down Expand Up @@ -10342,6 +10435,8 @@ struct tombstone_t final : public death_knight_spell_t
p()->resource_gain( RESOURCE_RUNIC_POWER, power, p()->gains.tombstone, this );
p()->buffs.tombstone->trigger( 1, shield * p()->resources.max[ RESOURCE_HEALTH ] );
p()->buffs.bone_shield->decrement( charges );
if( p() -> talent.blood.ossified_vitriol -> ok() )
p()->buffs.ossified_vitriol->trigger( charges );
p()->cooldown.dancing_rune_weapon->adjust( p()->talent.blood.insatiable_blade->effectN( 1 ).time_value() *
charges );

Expand Down Expand Up @@ -12489,7 +12584,7 @@ void death_knight_t::init_spells()
talent.blood.ossuary = find_talent_spell( talent_tree::SPECIALIZATION, "Ossuary" );
talent.blood.improved_vampiric_blood = find_talent_spell( talent_tree::SPECIALIZATION, "Improved Vampiric Blood" );
talent.blood.improved_heart_strike = find_talent_spell( talent_tree::SPECIALIZATION, "Improved Heart Strike" );
talent.blood.ossified_vitriol = find_talent_spell( talent_tree::SPECIALIZATION, "Ossified Virtiol" );
talent.blood.ossified_vitriol = find_talent_spell( talent_tree::SPECIALIZATION, "Ossified Vitriol" );

// Row 5
talent.blood.leeching_strike = find_talent_spell( talent_tree::SPECIALIZATION, "Leeching Strike" );
Expand Down Expand Up @@ -12740,6 +12835,7 @@ void death_knight_t::init_spells()
spell.bone_shield = conditional_spell_lookup( spec.blood_death_knight->ok(), 195181 );
spell.sanguine_ground = conditional_spell_lookup( talent.blood.sanguine_ground.ok(), 391459 );
spell.ossuary_buff = conditional_spell_lookup( talent.blood.ossuary.ok(), 219788 );
spell.ossified_vitriol_buff = conditional_spell_lookup( talent.blood.ossified_vitriol.ok(), 458745 );
spell.crimson_scourge_buff = conditional_spell_lookup( spec.crimson_scourge->ok(), 81141 );
spell.heartbreaker_rp_gain = conditional_spell_lookup( talent.blood.heartbreaker.ok(), 210738 );
spell.heartrend_buff = conditional_spell_lookup( talent.blood.heartrend.ok(), 377656 );
Expand Down Expand Up @@ -13395,6 +13491,8 @@ void death_knight_t::create_buffs()

buffs.ossuary = make_buff( this, "ossuary", spell.ossuary_buff )->set_default_value_from_effect( 1, 0.1 );

buffs.ossified_vitriol = make_buff( this, "ossified_vitriol", spell.ossified_vitriol_buff );

buffs.coagulopathy = make_buff( this, "coagulopathy", talent.blood.coagulopathy->effectN( 2 ).trigger() )
->set_trigger_spell( talent.blood.coagulopathy )
->set_default_value_from_effect( 1 );
Expand Down Expand Up @@ -13946,6 +14044,8 @@ void death_knight_t::bone_shield_handler( const action_state_t* state ) const
if ( specialization() == DEATH_KNIGHT_BLOOD )
{
buffs.bone_shield->decrement();
if( talent.blood.ossified_vitriol -> ok() )
buffs.ossified_vitriol->trigger();
if ( sets -> has_set_bonus( DEATH_KNIGHT_BLOOD, TWW1, B2 ) )
buffs.unbroken_tww1_2pc->trigger();
if ( sets -> has_set_bonus( DEATH_KNIGHT_BLOOD, TWW1, B4 ) )
Expand Down Expand Up @@ -14221,6 +14321,7 @@ void pets::pet_action_t<T_PET, Base>::apply_pet_action_effects()
parse_effects( dk()->buffs.hemostasis );
parse_effects( dk()->buffs.crimson_scourge );
parse_effects( dk()->buffs.ossuary );
parse_effects( dk()->buffs.ossified_vitriol );
// Don't auto parse coag, since there is some snapshot behavior when the weapon dies
// parse_effects( dk()->buffs.coagulopathy );

Expand Down Expand Up @@ -14277,6 +14378,7 @@ void death_knight_action_t<Base>::apply_action_effects()
parse_effects( p()->buffs.coagulopathy );
parse_effects( p()->buffs.consumption );
parse_effects( p()->buffs.crimson_scourge );
parse_effects( p()->buffs.ossified_vitriol );
parse_effects( p()->buffs.sanguine_ground );
parse_effects( p()->buffs.heartrend, p()->talent.blood.heartrend );
parse_effects( p()->buffs.hemostasis );
Expand Down

0 comments on commit 3e61377

Please sign in to comment.