From 83f630c07271f646ad7b4772c4e7ed29247af217 Mon Sep 17 00:00:00 2001 From: nyterage Date: Thu, 23 Jan 2025 16:53:12 -0800 Subject: [PATCH] [Pet] Add option to disable guardian scaling modifiers for guardian type pets --- engine/action/action.cpp | 6 +- engine/action/parse_effects.cpp | 24 ++-- engine/action/parse_effects.hpp | 4 +- engine/class_modules/priest/sc_priest.cpp | 28 +++-- engine/class_modules/priest/sc_priest.hpp | 2 +- engine/class_modules/sc_hunter.cpp | 25 ++-- engine/class_modules/sc_hunter_live.inc | 25 ++-- engine/class_modules/sc_mage.cpp | 22 ++-- engine/class_modules/sc_mage_live.inc | 21 ++-- engine/class_modules/sc_rogue.cpp | 18 +-- engine/class_modules/sc_shaman.cpp | 11 +- engine/class_modules/warlock/sc_warlock.cpp | 133 +++++++++++--------- engine/class_modules/warlock/sc_warlock.hpp | 4 +- engine/player/pet.cpp | 9 +- engine/player/pet.hpp | 1 + engine/player/player.cpp | 4 +- engine/player/player.hpp | 4 +- engine/player/unique_gear_thewarwithin.cpp | 4 + 18 files changed, 191 insertions(+), 154 deletions(-) diff --git a/engine/action/action.cpp b/engine/action/action.cpp index 73ca571b740..7583dbc6f14 100644 --- a/engine/action/action.cpp +++ b/engine/action/action.cpp @@ -4158,8 +4158,8 @@ void action_t::snapshot_internal( action_state_t* state, unsigned flags, result_ if ( flags & STATE_MUL_PET ) { - state->pet_multiplier = - player->cast_pet()->owner->composite_player_pet_damage_multiplier( state, player->type == PLAYER_GUARDIAN ); + state->pet_multiplier = player->cast_pet()->owner->composite_player_pet_damage_multiplier( + state, player->type == PLAYER_GUARDIAN, player->cast_pet()->player_effect_scaling_guardian ); } if ( flags & STATE_TGT_MUL_DA ) @@ -4171,7 +4171,7 @@ void action_t::snapshot_internal( action_state_t* state, unsigned flags, result_ if ( flags & STATE_TGT_MUL_PET ) { state->target_pet_multiplier = player->cast_pet()->owner->composite_player_target_pet_damage_multiplier( - state->target, player->type == PLAYER_GUARDIAN ); + state->target, player->type == PLAYER_GUARDIAN, player->cast_pet()->player_effect_scaling_guardian ); } if ( flags & STATE_TGT_CRIT ) diff --git a/engine/action/parse_effects.cpp b/engine/action/parse_effects.cpp index 5c64cb1b00f..5afd74805cd 100644 --- a/engine/action/parse_effects.cpp +++ b/engine/action/parse_effects.cpp @@ -812,13 +812,15 @@ double parse_player_effects_t::composite_player_multiplier( school_e school ) co return m; } -double parse_player_effects_t::composite_player_pet_damage_multiplier( const action_state_t* s, bool guardian ) const +double parse_player_effects_t::composite_player_pet_damage_multiplier( const action_state_t* s, bool guardian, + bool scaling_guardian ) const { - auto dm = player_t::composite_player_pet_damage_multiplier( s, guardian ); + auto dm = player_t::composite_player_pet_damage_multiplier( s, guardian, scaling_guardian ); - for ( const auto& i : pet_multiplier_effects ) - if ( static_cast( i.opt_enum ) == guardian ) - dm *= 1.0 + get_effect_value( i, true ); + if ( scaling_guardian || !guardian ) + for ( const auto& i : pet_multiplier_effects ) + if ( static_cast( i.opt_enum ) == guardian ) + dm *= 1.0 + get_effect_value( i, true ); return dm; } @@ -988,14 +990,16 @@ double parse_player_effects_t::composite_player_target_multiplier( player_t* t, return tm; } -double parse_player_effects_t::composite_player_target_pet_damage_multiplier( player_t* t, bool guardian ) const +double parse_player_effects_t::composite_player_target_pet_damage_multiplier( player_t* t, bool guardian, + bool scaling_guardian ) const { - auto tm = player_t::composite_player_target_pet_damage_multiplier( t, guardian ); + auto tm = player_t::composite_player_target_pet_damage_multiplier( t, guardian, scaling_guardian ); auto td = get_target_data( t ); - for ( const auto& i : target_pet_multiplier_effects ) - if ( static_cast( i.opt_enum ) == guardian ) - tm *= 1.0 + get_effect_value( i, td ); + if ( scaling_guardian || !guardian ) + for ( const auto& i : target_pet_multiplier_effects ) + if ( static_cast( i.opt_enum ) == guardian ) + tm *= 1.0 + get_effect_value( i, td ); return tm; } diff --git a/engine/action/parse_effects.hpp b/engine/action/parse_effects.hpp index 88f4506e83f..26bb6576c3f 100644 --- a/engine/action/parse_effects.hpp +++ b/engine/action/parse_effects.hpp @@ -743,7 +743,7 @@ struct parse_player_effects_t : public player_t, public parse_effects_t double composite_heal_versatility() const override; double composite_mitigation_versatility() const override; double composite_player_multiplier( school_e ) const override; - double composite_player_pet_damage_multiplier( const action_state_t*, bool ) const override; + double composite_player_pet_damage_multiplier( const action_state_t*, bool, bool ) const override; double composite_attack_power_multiplier() const override; double composite_melee_crit_chance() const override; double composite_spell_crit_chance() const override; @@ -760,7 +760,7 @@ struct parse_player_effects_t : public player_t, public parse_effects_t double composite_dodge() const override; double matching_gear_multiplier( attribute_e ) const override; double composite_player_target_multiplier( player_t*, school_e ) const override; - double composite_player_target_pet_damage_multiplier( player_t*, bool ) const override; + double composite_player_target_pet_damage_multiplier( player_t*, bool, bool ) const override; void invalidate_cache( cache_e c ) override; diff --git a/engine/class_modules/priest/sc_priest.cpp b/engine/class_modules/priest/sc_priest.cpp index 68e91a03262..8016b76cfb2 100644 --- a/engine/class_modules/priest/sc_priest.cpp +++ b/engine/class_modules/priest/sc_priest.cpp @@ -3256,33 +3256,37 @@ double priest_t::composite_spell_crit_chance() const return sc; } -double priest_t::composite_player_pet_damage_multiplier( const action_state_t* s, bool guardian ) const +double priest_t::composite_player_pet_damage_multiplier( const action_state_t* s, bool guardian, + bool scaling_guardian ) const { - double m = player_t::composite_player_pet_damage_multiplier( s, guardian ); + double m = player_t::composite_player_pet_damage_multiplier( s, guardian, scaling_guardian ); // Certain modifiers are only for Guardians, otherwise just give the Pet Modifier - if ( guardian ) + if ( guardian && scaling_guardian ) { m *= ( 1.0 + specs.shadow_priest->effectN( 4 ).percent() ); m *= ( 1.0 + specs.discipline_priest->effectN( 15 ).percent() ); } - else + else if ( !guardian ) { m *= ( 1.0 + specs.shadow_priest->effectN( 3 ).percent() ); m *= ( 1.0 + specs.discipline_priest->effectN( 3 ).percent() ); } - // TWW1 Set Bonus for pet spells, this double dips with pet spells - if ( buffs.devouring_chorus->check() ) + if ( scaling_guardian || !guardian ) { - m *= ( 1.0 + buffs.devouring_chorus->check_stack_value() ); - } + // TWW1 Set Bonus for pet spells, this double dips with pet spells + if ( buffs.devouring_chorus->check() ) + { + m *= ( 1.0 + buffs.devouring_chorus->check_stack_value() ); + } - // Auto parsing does not cover melee attacks, and other attacks double dip with this - if ( buffs.devoured_pride->check() ) - { - m *= ( 1.0 + talents.shadow.devoured_pride->effectN( 2 ).percent() ); + // Auto parsing does not cover melee attacks, and other attacks double dip with this + if ( buffs.devoured_pride->check() ) + { + m *= ( 1.0 + talents.shadow.devoured_pride->effectN( 2 ).percent() ); + } } return m; } diff --git a/engine/class_modules/priest/sc_priest.hpp b/engine/class_modules/priest/sc_priest.hpp index a1bc380f760..2fb1e54caf8 100644 --- a/engine/class_modules/priest/sc_priest.hpp +++ b/engine/class_modules/priest/sc_priest.hpp @@ -896,7 +896,7 @@ struct priest_t final : public player_t double composite_melee_haste() const override; double composite_spell_haste() const override; double composite_spell_crit_chance() const override; - double composite_player_pet_damage_multiplier( const action_state_t*, bool ) const override; + double composite_player_pet_damage_multiplier( const action_state_t*, bool, bool ) const override; double composite_player_absorb_multiplier( const action_state_t* s ) const override; double composite_player_heal_multiplier( const action_state_t* s ) const override; double composite_player_multiplier( school_e school ) const override; diff --git a/engine/class_modules/sc_hunter.cpp b/engine/class_modules/sc_hunter.cpp index 6a331ccddac..70c7ca7689e 100644 --- a/engine/class_modules/sc_hunter.cpp +++ b/engine/class_modules/sc_hunter.cpp @@ -1019,8 +1019,8 @@ struct hunter_t final : public player_t double composite_player_critical_damage_multiplier( const action_state_t* ) const override; double composite_player_multiplier( school_e school ) const override; double composite_player_target_multiplier( player_t* target, school_e school ) const override; - double composite_player_pet_damage_multiplier( const action_state_t*, bool ) const override; - double composite_player_target_pet_damage_multiplier( player_t* target, bool guardian ) const override; + double composite_player_pet_damage_multiplier( const action_state_t*, bool, bool ) const override; + double composite_player_target_pet_damage_multiplier( player_t* target, bool guardian, bool scaling_guardian ) const override; double composite_leech() const override; double matching_gear_multiplier( attribute_e attr ) const override; double stacking_movement_modifier() const override; @@ -8839,16 +8839,19 @@ double hunter_t::composite_player_target_multiplier( player_t* target, school_e return d; } -double hunter_t::composite_player_pet_damage_multiplier( const action_state_t* s, bool guardian ) const +double hunter_t::composite_player_pet_damage_multiplier( const action_state_t* s, bool guardian, bool scaling_guardian ) const { - double m = player_t::composite_player_pet_damage_multiplier( s, guardian ); + double m = player_t::composite_player_pet_damage_multiplier( s, guardian, scaling_guardian ); - if ( mastery.master_of_beasts->ok() ) - m *= 1.0 + cache.mastery_value(); + if ( !guardian || scaling_guardian ) + { + if ( mastery.master_of_beasts->ok() ) + m *= 1.0 + cache.mastery_value(); - m *= 1 + specs.beast_mastery_hunter -> effectN( 3 ).percent(); - m *= 1 + specs.survival_hunter -> effectN( 3 ).percent(); - m *= 1 + specs.marksmanship_hunter -> effectN( 3 ).percent(); + m *= 1 + specs.beast_mastery_hunter->effectN( 3 ).percent(); + m *= 1 + specs.survival_hunter->effectN( 3 ).percent(); + m *= 1 + specs.marksmanship_hunter->effectN( 3 ).percent(); + } if ( !guardian ) { @@ -8863,9 +8866,9 @@ double hunter_t::composite_player_pet_damage_multiplier( const action_state_t* s return m; } -double hunter_t::composite_player_target_pet_damage_multiplier( player_t* target, bool guardian ) const +double hunter_t::composite_player_target_pet_damage_multiplier( player_t* target, bool guardian, bool scaling_guardian ) const { - double m = player_t::composite_player_target_pet_damage_multiplier( target, guardian ); + double m = player_t::composite_player_target_pet_damage_multiplier( target, guardian, scaling_guardian ); if ( !guardian ) { diff --git a/engine/class_modules/sc_hunter_live.inc b/engine/class_modules/sc_hunter_live.inc index b76913f1d07..c482d1ac3ef 100644 --- a/engine/class_modules/sc_hunter_live.inc +++ b/engine/class_modules/sc_hunter_live.inc @@ -989,8 +989,8 @@ public: double composite_player_critical_damage_multiplier( const action_state_t* ) const override; double composite_player_multiplier( school_e school ) const override; double composite_player_target_multiplier( player_t* target, school_e school ) const override; - double composite_player_pet_damage_multiplier( const action_state_t*, bool ) const override; - double composite_player_target_pet_damage_multiplier( player_t* target, bool guardian ) const override; + double composite_player_pet_damage_multiplier( const action_state_t*, bool, bool ) const override; + double composite_player_target_pet_damage_multiplier( player_t* target, bool guardian, bool scaling_guardian ) const override; double composite_leech() const override; double matching_gear_multiplier( attribute_e attr ) const override; double stacking_movement_modifier() const override; @@ -8913,16 +8913,19 @@ double hunter_t::composite_player_target_multiplier( player_t* target, school_e return d; } -double hunter_t::composite_player_pet_damage_multiplier( const action_state_t* s, bool guardian ) const +double hunter_t::composite_player_pet_damage_multiplier( const action_state_t* s, bool guardian, bool scaling_guardian ) const { - double m = player_t::composite_player_pet_damage_multiplier( s, guardian ); + double m = player_t::composite_player_pet_damage_multiplier( s, guardian, scaling_guardian ); - if ( mastery.master_of_beasts->ok() ) - m *= 1.0 + cache.mastery_value(); + if( !guardian || scaling_guardian ) + { + if ( mastery.master_of_beasts->ok() ) + m *= 1.0 + cache.mastery_value(); - m *= 1 + specs.beast_mastery_hunter -> effectN( 3 ).percent(); - m *= 1 + specs.survival_hunter -> effectN( 3 ).percent(); - m *= 1 + specs.marksmanship_hunter -> effectN( 3 ).percent(); + m *= 1 + specs.beast_mastery_hunter -> effectN( 3 ).percent(); + m *= 1 + specs.survival_hunter -> effectN( 3 ).percent(); + m *= 1 + specs.marksmanship_hunter -> effectN( 3 ).percent(); + } if ( !guardian ) { @@ -8937,9 +8940,9 @@ double hunter_t::composite_player_pet_damage_multiplier( const action_state_t* s return m; } -double hunter_t::composite_player_target_pet_damage_multiplier( player_t* target, bool guardian ) const +double hunter_t::composite_player_target_pet_damage_multiplier( player_t* target, bool guardian, bool scaling_guardian ) const { - double m = player_t::composite_player_target_pet_damage_multiplier( target, guardian ); + double m = player_t::composite_player_target_pet_damage_multiplier( target, guardian, scaling_guardian ); if ( !guardian ) { diff --git a/engine/class_modules/sc_mage.cpp b/engine/class_modules/sc_mage.cpp index 4a068738a9f..38f392354b3 100644 --- a/engine/class_modules/sc_mage.cpp +++ b/engine/class_modules/sc_mage.cpp @@ -974,8 +974,8 @@ struct mage_t final : public player_t double stacking_movement_modifier() const override; double composite_player_critical_damage_multiplier( const action_state_t* ) const override; double composite_player_multiplier( school_e ) const override; - double composite_player_pet_damage_multiplier( const action_state_t*, bool ) const override; - double composite_player_target_pet_damage_multiplier( player_t*, bool ) const override; + double composite_player_pet_damage_multiplier( const action_state_t*, bool, bool ) const override; + double composite_player_target_pet_damage_multiplier( player_t*, bool, bool ) const override; double composite_melee_crit_chance() const override; double composite_spell_crit_chance() const override; double composite_melee_haste() const override; @@ -8867,13 +8867,17 @@ double mage_t::composite_player_multiplier( school_e school ) const return m; } -double mage_t::composite_player_pet_damage_multiplier( const action_state_t* s, bool guardian ) const +double mage_t::composite_player_pet_damage_multiplier( const action_state_t* s, bool guardian, + bool scaling_guardian ) const { - double m = player_t::composite_player_pet_damage_multiplier( s, guardian ); + double m = player_t::composite_player_pet_damage_multiplier( s, guardian, scaling_guardian ); - m *= 1.0 + spec.arcane_mage->effectN( 3 ).percent(); - m *= 1.0 + spec.fire_mage->effectN( 3 ).percent(); - m *= 1.0 + spec.frost_mage->effectN( 3 ).percent(); + if ( !guardian || scaling_guardian ) + { + m *= 1.0 + spec.arcane_mage->effectN( 3 ).percent(); + m *= 1.0 + spec.fire_mage->effectN( 3 ).percent(); + m *= 1.0 + spec.frost_mage->effectN( 3 ).percent(); + } if ( !guardian ) { @@ -8884,9 +8888,9 @@ double mage_t::composite_player_pet_damage_multiplier( const action_state_t* s, return m; } -double mage_t::composite_player_target_pet_damage_multiplier( player_t* target, bool guardian ) const +double mage_t::composite_player_target_pet_damage_multiplier( player_t* target, bool guardian, bool scaling_guardian ) const { - double m = player_t::composite_player_target_pet_damage_multiplier( target, guardian ); + double m = player_t::composite_player_target_pet_damage_multiplier( target, guardian, scaling_guardian ); if ( auto td = find_target_data( target ) ) { diff --git a/engine/class_modules/sc_mage_live.inc b/engine/class_modules/sc_mage_live.inc index 3a540c50b27..5b34b6a8b3c 100644 --- a/engine/class_modules/sc_mage_live.inc +++ b/engine/class_modules/sc_mage_live.inc @@ -960,8 +960,8 @@ public: double stacking_movement_modifier() const override; double composite_player_critical_damage_multiplier( const action_state_t* ) const override; double composite_player_multiplier( school_e ) const override; - double composite_player_pet_damage_multiplier( const action_state_t*, bool ) const override; - double composite_player_target_pet_damage_multiplier( player_t*, bool ) const override; + double composite_player_pet_damage_multiplier( const action_state_t*, bool, bool ) const override; + double composite_player_target_pet_damage_multiplier( player_t*, bool, bool ) const override; double composite_melee_crit_chance() const override; double composite_spell_crit_chance() const override; double composite_melee_haste() const override; @@ -8795,13 +8795,16 @@ double mage_t::composite_player_multiplier( school_e school ) const return m; } -double mage_t::composite_player_pet_damage_multiplier( const action_state_t* s, bool guardian ) const +double mage_t::composite_player_pet_damage_multiplier( const action_state_t* s, bool guardian, bool scaling_guardian ) const { - double m = player_t::composite_player_pet_damage_multiplier( s, guardian ); + double m = player_t::composite_player_pet_damage_multiplier( s, guardian, scaling_guardian ); - m *= 1.0 + spec.arcane_mage->effectN( 3 ).percent(); - m *= 1.0 + spec.fire_mage->effectN( 3 ).percent(); - m *= 1.0 + spec.frost_mage->effectN( 3 ).percent(); + if( !guardian || scaling_guardian ) + { + m *= 1.0 + spec.arcane_mage->effectN( 3 ).percent(); + m *= 1.0 + spec.fire_mage->effectN( 3 ).percent(); + m *= 1.0 + spec.frost_mage->effectN( 3 ).percent(); + } if ( !guardian ) { @@ -8812,9 +8815,9 @@ double mage_t::composite_player_pet_damage_multiplier( const action_state_t* s, return m; } -double mage_t::composite_player_target_pet_damage_multiplier( player_t* target, bool guardian ) const +double mage_t::composite_player_target_pet_damage_multiplier( player_t* target, bool guardian, bool scaling_guardian ) const { - double m = player_t::composite_player_target_pet_damage_multiplier( target, guardian ); + double m = player_t::composite_player_target_pet_damage_multiplier( target, guardian, scaling_guardian ); if ( auto td = find_target_data( target ) ) { diff --git a/engine/class_modules/sc_rogue.cpp b/engine/class_modules/sc_rogue.cpp index d095da12f85..50b590819bb 100644 --- a/engine/class_modules/sc_rogue.cpp +++ b/engine/class_modules/sc_rogue.cpp @@ -1291,7 +1291,7 @@ class rogue_t : public player_t double composite_leech() const override; double matching_gear_multiplier( attribute_e attr ) const override; double composite_player_multiplier( school_e school ) const override; - double composite_player_pet_damage_multiplier( const action_state_t*, bool ) const override; + double composite_player_pet_damage_multiplier( const action_state_t*, bool guardian, bool scaling_guardian ) const override; double composite_player_target_multiplier( player_t* target, school_e school ) const override; double composite_player_target_crit_chance( player_t* target ) const override; double composite_player_target_armor( player_t* target ) const override; @@ -5552,7 +5552,7 @@ struct secret_technique_t : public rogue_attack_t if ( secondary_trigger_type == secondary_trigger::SECRET_TECHNIQUE_CLONE ) { // Secret Technique clones count as pets and benefit from pet modifiers - m *= p()->composite_player_pet_damage_multiplier( state, true ); + m *= p()->composite_player_pet_damage_multiplier( state, true, true ); } return m; @@ -9749,13 +9749,17 @@ double rogue_t::composite_player_multiplier( school_e school ) const // rogue_t::composite_player_pet_damage_multiplier ========================== -double rogue_t::composite_player_pet_damage_multiplier( const action_state_t* s, bool guardian ) const +double rogue_t::composite_player_pet_damage_multiplier( const action_state_t* s, bool guardian, + bool scaling_guardian ) const { - double m = player_t::composite_player_pet_damage_multiplier( s, guardian ); + double m = player_t::composite_player_pet_damage_multiplier( s, guardian, scaling_guardian ); - m *= 1.0 + spec.assassination_rogue->effectN( 6 ).percent(); - m *= 1.0 + spec.outlaw_rogue->effectN( 3 ).percent(); - m *= 1.0 + spec.subtlety_rogue->effectN( 8 ).percent(); + if ( !guardian || scaling_guardian ) + { + m *= 1.0 + spec.assassination_rogue->effectN( 6 ).percent(); + m *= 1.0 + spec.outlaw_rogue->effectN( 3 ).percent(); + m *= 1.0 + spec.subtlety_rogue->effectN( 8 ).percent(); + } return m; } diff --git a/engine/class_modules/sc_shaman.cpp b/engine/class_modules/sc_shaman.cpp index 6358866852a..15af4cf4b25 100644 --- a/engine/class_modules/sc_shaman.cpp +++ b/engine/class_modules/sc_shaman.cpp @@ -1379,7 +1379,7 @@ struct shaman_t : public player_t double composite_spell_haste() const override; double composite_player_multiplier( school_e school ) const override; double composite_player_target_multiplier( player_t* target, school_e school ) const override; - double composite_player_pet_damage_multiplier( const action_state_t* state, bool guardian ) const override; + double composite_player_pet_damage_multiplier( const action_state_t* state, bool guardian, bool scaling_guardian ) const override; double composite_maelstrom_gain_coefficient( const action_state_t* /* state */ = nullptr ) const { return 1.0; } double matching_gear_multiplier( attribute_e attr ) const override; @@ -14536,9 +14536,10 @@ double shaman_t::composite_player_target_multiplier( player_t* target, school_e // shaman_t::composite_player_pet_damage_multiplier ========================= -double shaman_t::composite_player_pet_damage_multiplier( const action_state_t* s, bool guardian ) const +double shaman_t::composite_player_pet_damage_multiplier( const action_state_t* s, bool guardian, + bool scaling_guardian ) const { - double m = player_t::composite_player_pet_damage_multiplier( s, guardian ); + double m = player_t::composite_player_pet_damage_multiplier( s, guardian, scaling_guardian ); if ( !guardian ) { @@ -14547,9 +14548,9 @@ double shaman_t::composite_player_pet_damage_multiplier( const action_state_t* s m *= 1.0 + spec.enhancement_shaman->effectN( 3 ).percent(); m *= 1.0 + mastery.elemental_overload->effectN( 5 ).mastery_value() * cache.mastery(); - //m *= 1.0 + buff.elemental_equilibrium->value(); TODO: check what this was doing here + // m *= 1.0 + buff.elemental_equilibrium->value(); TODO: check what this was doing here } - else + else if ( scaling_guardian ) { m *= 1.0 + spec.elemental_shaman->effectN( 4 ).percent(); diff --git a/engine/class_modules/warlock/sc_warlock.cpp b/engine/class_modules/warlock/sc_warlock.cpp index a6d6e4fe544..4b6c7621505 100644 --- a/engine/class_modules/warlock/sc_warlock.cpp +++ b/engine/class_modules/warlock/sc_warlock.cpp @@ -324,93 +324,102 @@ double warlock_t::composite_player_multiplier( school_e school ) const return m; } -double warlock_t::composite_player_pet_damage_multiplier( const action_state_t* s, bool guardian ) const +double warlock_t::composite_player_pet_damage_multiplier( const action_state_t* s, bool guardian, + bool scaling_guardian ) const { - double m = player_t::composite_player_pet_damage_multiplier( s, guardian ); + double m = player_t::composite_player_pet_damage_multiplier( s, guardian, scaling_guardian ); - if ( specialization() == WARLOCK_DESTRUCTION ) + if ( !guardian || scaling_guardian ) { - m *= 1.0 + warlock_base.destruction_warlock->effectN( guardian ? 4 : 3 ).percent(); + if ( specialization() == WARLOCK_DESTRUCTION ) + { + m *= 1.0 + warlock_base.destruction_warlock->effectN( guardian ? 4 : 3 ).percent(); - // 2022-11-27 Rolling Havoc is missing the aura for guardians - if ( talents.rolling_havoc.ok() && !guardian ) - m *= 1.0 + buffs.rolling_havoc->check_stack_value(); - } + // 2022-11-27 Rolling Havoc is missing the aura for guardians + if ( talents.rolling_havoc.ok() && !guardian ) + m *= 1.0 + buffs.rolling_havoc->check_stack_value(); + } - if ( specialization() == WARLOCK_DEMONOLOGY ) - { - m *= 1.0 + warlock_base.demonology_warlock->effectN( guardian ? 5 : 3 ).percent(); - - // Renormalize to use the guardian effect when appropriate, in case the values are ever different - if ( !guardian ) - m *= 1.0 + cache.mastery_value(); - else - m *= 1.0 + ( cache.mastery_value() ) * ( warlock_base.master_demonologist->effectN( 3 ).sp_coeff() / warlock_base.master_demonologist->effectN( 1 ).sp_coeff() ); + if ( specialization() == WARLOCK_DEMONOLOGY ) + { + m *= 1.0 + warlock_base.demonology_warlock->effectN( guardian ? 5 : 3 ).percent(); - if ( !guardian && talents.rune_of_shadows.ok() ) - m *= 1.0 + talents.rune_of_shadows->effectN( 1 ).percent(); + // Renormalize to use the guardian effect when appropriate, in case the values are ever different + if ( !guardian ) + m *= 1.0 + cache.mastery_value(); + else + m *= 1.0 + ( cache.mastery_value() ) * ( warlock_base.master_demonologist->effectN( 3 ).sp_coeff() / + warlock_base.master_demonologist->effectN( 1 ).sp_coeff() ); - if ( !guardian && sets->has_set_bonus( WARLOCK_DEMONOLOGY, TWW1, B2 ) ) - m *= 1.0 + tier.hexflame_demo_2pc->effectN( 1 ).percent(); - } + if ( !guardian && talents.rune_of_shadows.ok() ) + m *= 1.0 + talents.rune_of_shadows->effectN( 1 ).percent(); - if ( specialization() == WARLOCK_AFFLICTION ) - { - m *= 1.0 + warlock_base.affliction_warlock->effectN( guardian ? 7 : 3 ).percent(); + if ( !guardian && sets->has_set_bonus( WARLOCK_DEMONOLOGY, TWW1, B2 ) ) + m *= 1.0 + tier.hexflame_demo_2pc->effectN( 1 ).percent(); + } - // 2024-07-06 Summoner's Embrace only affects main pet - if ( !guardian && talents.summoners_embrace.ok() ) - m *= 1.0 + talents.summoners_embrace->effectN( 2 ).percent(); - } + if ( specialization() == WARLOCK_AFFLICTION ) + { + m *= 1.0 + warlock_base.affliction_warlock->effectN( guardian ? 7 : 3 ).percent(); - if ( hero.flames_of_xoroth.ok() ) - m *= 1.0 + hero.flames_of_xoroth->effectN( guardian ? 3 : 4 ).percent(); + // 2024-07-06 Summoner's Embrace only affects main pet + if ( !guardian && talents.summoners_embrace.ok() ) + m *= 1.0 + talents.summoners_embrace->effectN( 2 ).percent(); + } - if ( hero.abyssal_dominion.ok() && buffs.abyssal_dominion->check() ) - m *= 1.0 + hero.abyssal_dominion_buff->effectN( guardian ? 1 : 2 ).percent(); + if ( hero.flames_of_xoroth.ok() ) + m *= 1.0 + hero.flames_of_xoroth->effectN( guardian ? 3 : 4 ).percent(); - if ( hero.xalans_ferocity.ok() ) - m *= 1.0 + hero.xalans_ferocity->effectN( guardian ? 7 : 3 ).percent(); + if ( hero.abyssal_dominion.ok() && buffs.abyssal_dominion->check() ) + m *= 1.0 + hero.abyssal_dominion_buff->effectN( guardian ? 1 : 2 ).percent(); - if ( hero.xalans_cruelty.ok() ) - m *= 1.0 + hero.xalans_cruelty->effectN( guardian ? 6 : 5 ).percent(); + if ( hero.xalans_ferocity.ok() ) + m *= 1.0 + hero.xalans_ferocity->effectN( guardian ? 7 : 3 ).percent(); + if ( hero.xalans_cruelty.ok() ) + m *= 1.0 + hero.xalans_cruelty->effectN( guardian ? 6 : 5 ).percent(); + } return m; } -double warlock_t::composite_player_target_pet_damage_multiplier( player_t* target, bool guardian ) const +double warlock_t::composite_player_target_pet_damage_multiplier( player_t* target, bool guardian, + bool scaling_guardian ) const { - double m = player_t::composite_player_target_pet_damage_multiplier( target, guardian ); - - const warlock_td_t* td = get_target_data( target ); + double m = player_t::composite_player_target_pet_damage_multiplier( target, guardian, scaling_guardian ); - if ( specialization() == WARLOCK_AFFLICTION ) + if ( !guardian || scaling_guardian ) { - if ( talents.haunt.ok() && td->debuffs_haunt->check() ) - m *= 1.0 + td->debuffs_haunt->data().effectN( guardian ? 4 : 3 ).percent(); + const warlock_td_t* td = get_target_data( target ); - if ( talents.shadow_embrace.ok() ) - m *= 1.0 + td->debuffs_shadow_embrace->check_stack_value(); + if ( specialization() == WARLOCK_AFFLICTION ) + { + if ( talents.haunt.ok() && td->debuffs_haunt->check() ) + m *= 1.0 + td->debuffs_haunt->data().effectN( guardian ? 4 : 3 ).percent(); - if ( talents.infirmity.ok() && !guardian ) - m *= 1.0 + td->debuffs_infirmity->check_stack_value(); // Guardian effect is missing from spell data. Last checked 2024-07-07 - } + if ( talents.shadow_embrace.ok() ) + m *= 1.0 + td->debuffs_shadow_embrace->check_stack_value(); - if ( specialization() == WARLOCK_DESTRUCTION ) - { - if ( talents.eradication.ok() ) - m *= 1.0 + td->debuffs_eradication->check_value(); - } + if ( talents.infirmity.ok() && !guardian ) + m *= 1.0 + td->debuffs_infirmity + ->check_stack_value(); // Guardian effect is missing from spell data. Last checked 2024-07-07 + } - if ( specialization() == WARLOCK_DEMONOLOGY ) - { - // Fel Sunder lacks guardian effect, so only main pet is benefitting. Last checked 2024-07-14 - if ( talents.fel_sunder.ok() && ( !guardian || !bugs ) ) - m *= 1.0 + td->debuffs_fel_sunder->check_stack_value(); - } + if ( specialization() == WARLOCK_DESTRUCTION ) + { + if ( talents.eradication.ok() ) + m *= 1.0 + td->debuffs_eradication->check_value(); + } - if ( hero.cloven_souls.ok() && td->debuffs_cloven_soul->check() ) - m *= 1.0 + hero.cloven_soul_debuff->effectN( guardian ? 3 : 2 ).percent(); + if ( specialization() == WARLOCK_DEMONOLOGY ) + { + // Fel Sunder lacks guardian effect, so only main pet is benefitting. Last checked 2024-07-14 + if ( talents.fel_sunder.ok() && ( !guardian || !bugs ) ) + m *= 1.0 + td->debuffs_fel_sunder->check_stack_value(); + } + + if ( hero.cloven_souls.ok() && td->debuffs_cloven_soul->check() ) + m *= 1.0 + hero.cloven_soul_debuff->effectN( guardian ? 3 : 2 ).percent(); + } return m; } diff --git a/engine/class_modules/warlock/sc_warlock.hpp b/engine/class_modules/warlock/sc_warlock.hpp index 3a21710af41..797473ade03 100644 --- a/engine/class_modules/warlock/sc_warlock.hpp +++ b/engine/class_modules/warlock/sc_warlock.hpp @@ -836,8 +836,8 @@ struct warlock_t : public player_t double matching_gear_multiplier( attribute_e attr ) const override; double composite_player_multiplier( school_e school ) const override; double composite_player_target_multiplier( player_t* target, school_e school ) const override; - double composite_player_pet_damage_multiplier( const action_state_t*, bool ) const override; - double composite_player_target_pet_damage_multiplier( player_t* target, bool guardian ) const override; + double composite_player_pet_damage_multiplier( const action_state_t*, bool, bool ) const override; + double composite_player_target_pet_damage_multiplier( player_t* target, bool guardian, bool ) const override; void invalidate_cache( cache_e ) override; double composite_spell_crit_chance() const override; double composite_melee_crit_chance() const override; diff --git a/engine/player/pet.cpp b/engine/player/pet.cpp index ae5bf17b765..3d9d39f7760 100644 --- a/engine/player/pet.cpp +++ b/engine/player/pet.cpp @@ -39,12 +39,8 @@ struct expiration_t : public event_t }; } -pet_t::pet_t( sim_t* sim, - player_t* owner, - util::string_view name, - bool guardian, - bool dynamic ) : - pet_t( sim, owner, name, PET_NONE, guardian, dynamic ) +pet_t::pet_t( sim_t* sim, player_t* owner, util::string_view name, bool guardian, bool dynamic ) + : pet_t( sim, owner, name, PET_NONE, guardian, dynamic ) { } @@ -57,6 +53,7 @@ pet_t::pet_t( sim_t* sim, player_t* owner, util::string_view name, pet_e pet_typ summoned( false ), dynamic( dynamic ), can_dismiss( !guardian ), + player_effect_scaling_guardian( guardian ), affects_wod_legendary_ring( true ), pet_type( pet_type ), expiration( nullptr ), diff --git a/engine/player/pet.hpp b/engine/player/pet.hpp index 79768db844f..5e1a5f83e10 100644 --- a/engine/player/pet.hpp +++ b/engine/player/pet.hpp @@ -22,6 +22,7 @@ struct pet_t : public player_t bool summoned; bool dynamic; bool can_dismiss; + bool player_effect_scaling_guardian; bool affects_wod_legendary_ring; pet_e pet_type; event_t* expiration; diff --git a/engine/player/player.cpp b/engine/player/player.cpp index bbaa28bf702..5e4e42fd630 100644 --- a/engine/player/player.cpp +++ b/engine/player/player.cpp @@ -4949,7 +4949,7 @@ double player_t::composite_total_corruption() const return cache.corruption() - cache.corruption_resistance(); } -double player_t::composite_player_pet_damage_multiplier( const action_state_t*, bool guardian ) const +double player_t::composite_player_pet_damage_multiplier( const action_state_t*, bool guardian, bool scaling_guardian ) const { double m = 1.0; @@ -4968,7 +4968,7 @@ double player_t::composite_player_pet_damage_multiplier( const action_state_t*, return m; } -double player_t::composite_player_target_pet_damage_multiplier( player_t*, bool ) const +double player_t::composite_player_target_pet_damage_multiplier( player_t*, bool, bool ) const { return 1.0; } diff --git a/engine/player/player.hpp b/engine/player/player.hpp index 091d558a784..8d138419054 100644 --- a/engine/player/player.hpp +++ b/engine/player/player.hpp @@ -1204,8 +1204,8 @@ struct player_t : public actor_t virtual double composite_player_dh_multiplier( school_e ) const { return 1.0; } virtual double composite_player_th_multiplier( school_e ) const; virtual double composite_player_absorb_multiplier( const action_state_t* s ) const; - virtual double composite_player_pet_damage_multiplier( const action_state_t*, bool guardian ) const; - virtual double composite_player_target_pet_damage_multiplier( player_t*, bool guardian ) const; + virtual double composite_player_pet_damage_multiplier( const action_state_t*, bool guardian, bool scaling_guardian ) const; + virtual double composite_player_target_pet_damage_multiplier( player_t*, bool guardian, bool scaling_guardian ) const; virtual double composite_player_target_crit_chance( player_t* ) const; virtual double composite_player_critical_damage_multiplier( const action_state_t* s ) const; virtual double composite_player_critical_healing_multiplier() const; diff --git a/engine/player/unique_gear_thewarwithin.cpp b/engine/player/unique_gear_thewarwithin.cpp index 24b4ddce651..a4f078d49af 100644 --- a/engine/player/unique_gear_thewarwithin.cpp +++ b/engine/player/unique_gear_thewarwithin.cpp @@ -2080,6 +2080,7 @@ void sigil_of_algari_concordance( special_effect_t& e ) aoe_action( nullptr ) { npc_id = summon_spell->effectN( 1 ).misc_value1(); + player_effect_scaling_guardian = false; } resource_e primary_resource() const override @@ -4164,6 +4165,7 @@ void candle_confidant( special_effect_t& effect ) { npc_id = summon_spell->effectN( 1 ).misc_value1(); use_auto_attack = false; + player_effect_scaling_guardian = false; } resource_e primary_resource() const override @@ -6140,6 +6142,7 @@ void noggenfogger_ultimate_deluxe( special_effect_t& effect ) : pet_t( e.player->sim, e.player, name, true, true ), effect( e ), parent_action( nullptr ) { npc_id = summon_spell->effectN( 1 ).misc_value1(); + player_effect_scaling_guardian = false; } resource_e primary_resource() const override @@ -6645,6 +6648,7 @@ void zees_thug_hotline( special_effect_t& effect ) { npc_id = summon_spell->effectN( 1 ).misc_value1(); use_auto_attack = false; + player_effect_scaling_guardian = false; } resource_e primary_resource() const override