diff --git a/data/sql/updates/pending_db_world/rev_1724946417358596409.sql b/data/sql/updates/pending_db_world/rev_1724946417358596409.sql new file mode 100644 index 000000000..28cccba32 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1724946417358596409.sql @@ -0,0 +1,13 @@ +-- +UPDATE `spell_dbc` +SET `Attributes`=`Attributes`|64, `AttributesEx4`=34603008, `ProcChance`=101, `DurationIndex`=21, +`Effect_1`=6, `Effect_2`=6, `Effect_3`=6, `EffectBasePoints_1`=-1, `EffectBasePoints_2`=-1, `EffectBasePoints_3`=-1, +`ImplicitTargetA_1`=1, `ImplicitTargetA_2`=1, `ImplicitTargetA_3`=1, +`EffectAura_1`=55, `EffectAura_2`=240, `EffectAura_3`=123, +`EffectMultipleValue_1`=1.0, `EffectMultipleValue_2`=1.0, `EffectMultipleValue_3`=1.0, +`EffectMiscValue_3`=124 +WHERE `ID`=67561; +DELETE FROM `spell_script_names` WHERE `spell_id` IN (49040, 67561); +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(49040, 'spell_dk_army_of_the_dead_passive'), +(67561, 'spell_pet_spellhit_expertise_spellpen_scaling'); diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 5f4d3057a..58d7be70e 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -1362,11 +1362,11 @@ bool Guardian::InitStatsForLevel(uint8 petlevel) } case NPC_ARMY_OF_THE_DEAD: { - AddAura(SPELL_HUNTER_PET_SCALING_04, this); - AddAura(SPELL_DK_PET_SCALING_01, this); + AddAura(SPELL_DK_ARMY_OF_THE_DEAD_PASSIVE, this); AddAura(SPELL_DK_PET_SCALING_02, this); AddAura(SPELL_DK_PET_SCALING_03, this); - AddAura(SPELL_PET_AVOIDANCE, this); + AddAura(SPELL_DK_AVOIDANCE, this); + AddAura(SPELL_PET_SCALING_MASTER_06, this); SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4))); SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4))); diff --git a/src/server/game/Entities/Pet/PetDefines.h b/src/server/game/Entities/Pet/PetDefines.h index 65de91faa..b0bbe57ac 100644 --- a/src/server/game/Entities/Pet/PetDefines.h +++ b/src/server/game/Entities/Pet/PetDefines.h @@ -134,7 +134,9 @@ enum NPCEntries enum PetScalingSpells { SPELL_PET_AVOIDANCE = 32233, + SPELL_PET_SCALING_MASTER_06 = 67561, // Serverside - Pet Scaling - Master Spell 06 - Spell Hit, Expertise, Spell Penetration + // Hunter SPELL_HUNTER_PET_SCALING_01 = 34902, SPELL_HUNTER_PET_SCALING_02 = 34903, SPELL_HUNTER_PET_SCALING_03 = 34904, @@ -190,9 +192,11 @@ enum PetScalingSpells // Death Knight SPELL_ORC_RACIAL_COMMAND_DK = 65221, SPELL_NIGHT_OF_THE_DEAD_AVOIDANCE = 62137, - SPELL_DK_PET_SCALING_01 = 51996, - SPELL_DK_PET_SCALING_02 = 54566, - SPELL_DK_PET_SCALING_03 = 61697 + SPELL_DK_PET_SCALING_01 = 54566, + SPELL_DK_PET_SCALING_02 = 51996, + SPELL_DK_PET_SCALING_03 = 61697, + SPELL_DK_AVOIDANCE = 65220, + SPELL_DK_ARMY_OF_THE_DEAD_PASSIVE = 49040, }; #define PET_FOLLOW_DIST 1.0f diff --git a/src/server/scripts/Pet/pet_dk.cpp b/src/server/scripts/Pet/pet_dk.cpp index 959649e0f..a0a79b949 100644 --- a/src/server/scripts/Pet/pet_dk.cpp +++ b/src/server/scripts/Pet/pet_dk.cpp @@ -303,10 +303,6 @@ public: { CombatAI::InitializeAI(); ((Minion*)me)->SetFollowAngle(rand_norm() * 2 * M_PI); - - // Heroism / Bloodlust immunity - me->ApplySpellImmune(0, IMMUNITY_ID, 32182, true); - me->ApplySpellImmune(0, IMMUNITY_ID, 2825, true); } }; diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp index 408ffc314..3222df8df 100644 --- a/src/server/scripts/Spells/spell_dk.cpp +++ b/src/server/scripts/Spells/spell_dk.cpp @@ -751,8 +751,8 @@ class spell_dk_pet_scaling : public AuraScript // Check just if owner has Ravenous Dead since it's effect is not an aura if (AuraEffect const* rdEff = owner->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DEATHKNIGHT, 3010, 0)) { - SpellInfo const* spellInfo = rdEff->GetSpellInfo(); // Then get the SpellProto and add the dummy effect value - AddPct(modifier, spellInfo->Effects[EFFECT_1].CalcValue()); // Ravenous Dead edits the original scale + SpellInfo const* spellInfo = rdEff->GetSpellInfo(); // Then get the SpellProto and add the dummy effect value + AddPct(modifier, spellInfo->Effects[EFFECT_1].CalcValue()); // Ravenous Dead edits the original scale } // xinef: Glyph of the Ghoul @@ -2203,6 +2203,72 @@ class spell_dk_will_of_the_necropolis : public AuraScript } }; +// 49040 - Army of the Dead Passive +class spell_dk_army_of_the_dead_passive : public AuraScript +{ + PrepareAuraScript(spell_dk_army_of_the_dead_passive); + + void CalculateAPAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + // army ghoul inherits 6.5% of AP + if (Unit* owner = GetUnitOwner()->GetOwner()) + amount = CalculatePct(std::max(0, owner->GetTotalAttackPowerValue(BASE_ATTACK)), 6.5f); + } + + void CalculateHealthAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + // army ghoul inherits 20% of health + if (Unit* owner = GetUnitOwner()->GetOwner()) + amount = owner->CountPctFromMaxHealth(20); + } + + void CalculateSPAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + // army ghoul inherits 6.5% of AP + if (Unit* owner = GetUnitOwner()->GetOwner()) + amount = CalculatePct(std::max(0, owner->GetTotalAttackPowerValue(BASE_ATTACK)), 6.5f); + } + + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + if (GetUnitOwner()->IsPet()) + return; + + GetUnitOwner()->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_STAT, true, SPELL_BLOCK_TYPE_POSITIVE); + GetUnitOwner()->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, true, SPELL_BLOCK_TYPE_POSITIVE); + GetUnitOwner()->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_ATTACK_POWER, true, SPELL_BLOCK_TYPE_POSITIVE); + GetUnitOwner()->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_ATTACK_POWER_PCT, true, SPELL_BLOCK_TYPE_POSITIVE); + // Heroism / Bloodlust immunity + GetUnitOwner()->ApplySpellImmune(0, IMMUNITY_ID, 32182, true); + GetUnitOwner()->ApplySpellImmune(0, IMMUNITY_ID, 2825, true); + } + + void CalcPeriodic(AuraEffect const* /*aurEff*/, bool& isPeriodic, int32& amplitude) + { + if (!GetUnitOwner()->IsPet()) + return; + + isPeriodic = true; + amplitude = 2 * IN_MILLISECONDS; + } + + void HandlePeriodic(AuraEffect const* aurEff) + { + PreventDefaultAction(); + GetEffect(aurEff->GetEffIndex())->RecalculateAmount(); + } + + void Register() override + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_army_of_the_dead_passive::CalculateAPAmount, EFFECT_0, SPELL_AURA_MOD_ATTACK_POWER); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_army_of_the_dead_passive::CalculateHealthAmount, EFFECT_1, SPELL_AURA_MOD_INCREASE_HEALTH); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_army_of_the_dead_passive::CalculateSPAmount, EFFECT_2, SPELL_AURA_MOD_DAMAGE_DONE); + OnEffectApply += AuraEffectApplyFn(spell_dk_army_of_the_dead_passive::HandleEffectApply, EFFECT_ALL, SPELL_AURA_ANY, AURA_EFFECT_HANDLE_REAL); + DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_dk_army_of_the_dead_passive::CalcPeriodic, EFFECT_ALL, SPELL_AURA_ANY); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_dk_army_of_the_dead_passive::HandlePeriodic, EFFECT_ALL, SPELL_AURA_ANY); + } +}; + void AddSC_deathknight_spell_scripts() { RegisterSpellScript(spell_dk_wandering_plague); @@ -2250,4 +2316,5 @@ void AddSC_deathknight_spell_scripts() RegisterSpellScript(spell_dk_vampiric_blood); RegisterSpellScript(spell_dk_will_of_the_necropolis); RegisterSpellScript(spell_dk_ghoul_thrash); + RegisterSpellScript(spell_dk_army_of_the_dead_passive); } diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index b29818522..f672ad8b6 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -5320,6 +5320,65 @@ class spell_gen_set_health : public SpellScript } }; +// 67561 - Serverside - Pet Scaling - Master Spell 06 - Spell Hit, Expertise, Spell Penetration +class spell_pet_spellhit_expertise_spellpen_scaling : public AuraScript +{ + PrepareAuraScript(spell_pet_spellhit_expertise_spellpen_scaling) + + int32 CalculatePercent(float hitChance, float cap, float maxChance) + { + return (hitChance / cap) * maxChance; + } + + void CalculateSpellHitAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + if (Player* modOwner = GetUnitOwner()->GetSpellModOwner()) + amount = CalculatePercent(modOwner->m_modMeleeHitChance, 8.0f, 17.0f); + } + + void CalculateExpertiseAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + if (Player* modOwner = GetUnitOwner()->GetSpellModOwner()) + amount = CalculatePercent(modOwner->m_modMeleeHitChance, 8.0f, 26.0f); + } + + void CalculateSpellPenAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/) + { + if (Player* modOwner = GetUnitOwner()->GetSpellModOwner()) + amount = modOwner->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, SPELL_SCHOOL_MASK_SPELL); + } + + void HandleEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + { + GetUnitOwner()->ApplySpellImmune(GetId(), IMMUNITY_STATE, aurEff->GetAuraType(), true, SPELL_BLOCK_TYPE_POSITIVE); + } + + void CalcPeriodic(AuraEffect const* /*aurEff*/, bool& isPeriodic, int32& amplitude) + { + if (!GetUnitOwner()->IsPet()) + return; + + isPeriodic = true; + amplitude = 3 * IN_MILLISECONDS; + } + + void HandlePeriodic(AuraEffect const* aurEff) + { + PreventDefaultAction(); + GetEffect(aurEff->GetEffIndex())->RecalculateAmount(); + } + + void Register() override + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pet_spellhit_expertise_spellpen_scaling::CalculateSpellHitAmount, EFFECT_0, SPELL_AURA_MOD_SPELL_HIT_CHANCE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pet_spellhit_expertise_spellpen_scaling::CalculateExpertiseAmount, EFFECT_1, SPELL_AURA_MOD_EXPERTISE); + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pet_spellhit_expertise_spellpen_scaling::CalculateSpellPenAmount, EFFECT_2, SPELL_AURA_MOD_TARGET_RESISTANCE); + OnEffectApply += AuraEffectApplyFn(spell_pet_spellhit_expertise_spellpen_scaling::HandleEffectApply, EFFECT_ALL, SPELL_AURA_ANY, AURA_EFFECT_HANDLE_REAL); + DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_pet_spellhit_expertise_spellpen_scaling::CalcPeriodic, EFFECT_ALL, SPELL_AURA_ANY); + OnEffectPeriodic += AuraEffectPeriodicFn(spell_pet_spellhit_expertise_spellpen_scaling::HandlePeriodic, EFFECT_ALL, SPELL_AURA_ANY); + } +}; + void AddSC_generic_spell_scripts() { RegisterSpellScript(spell_silithyst); @@ -5478,4 +5537,5 @@ void AddSC_generic_spell_scripts() RegisterSpellScript(spell_gen_sober_up); RegisterSpellScript(spell_gen_steal_weapon); RegisterSpellScript(spell_gen_set_health); + RegisterSpellScript(spell_pet_spellhit_expertise_spellpen_scaling); }