diff --git a/sql/updates/world/4.3.4/2021_02_27_00_world.sql b/sql/updates/world/4.3.4/2021_02_27_00_world.sql new file mode 100644 index 0000000000..bc7dff6dc2 --- /dev/null +++ b/sql/updates/world/4.3.4/2021_02_27_00_world.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_script_names` WHERE `ScriptName`= 'spell_dru_nourish'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(50464, 'spell_dru_nourish'); diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index 492558a41c..d2be07bac4 100644 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -152,10 +152,24 @@ bool Player::UpdateStats(Stats stat) void Player::ApplySpellPowerBonus(int32 amount, bool apply) { + if (HasAuraType(SPELL_AURA_OVERRIDE_SPELL_POWER_BY_AP_PCT)) + return; + apply = _ModifyUInt32(apply, m_baseSpellPower, amount); // For speed just update for client ApplyModUInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS, amount, apply); + for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) + ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + i, amount, apply); +} + +void Player::UpdateSpellDamageAndHealingBonus() +{ + // Magic damage modifiers implemented in Unit::SpellDamageBonusDone + // This information for client side use only + // Get healing bonus for all schools + SetStatInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS, SpellBaseHealingBonusDone(SPELL_SCHOOL_MASK_ALL)); + // Get damage bonus for all schools Unit::AuraEffectList const& modDamageAuras = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE); for (uint16 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) { @@ -169,36 +183,6 @@ void Player::ApplySpellPowerBonus(int32 amount, bool apply) } } -void Player::UpdateSpellDamageAndHealingBonus() -{ - // Handle overrides first - AuraEffectList const& overrideSpellPowerAuras = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_SPELL_POWER_BY_AP_PCT); - if (!overrideSpellPowerAuras.empty()) - { - for (auto itr : overrideSpellPowerAuras) - SetFloatValue(PLAYER_FIELD_OVERRIDE_SPELL_POWER_BY_AP_PCT, float(itr->GetAmount())); - } - else - { - // Magic damage modifiers implemented in Unit::SpellDamageBonusDone - // This information for client side use only - // Get healing bonus for all schools - SetStatInt32Value(PLAYER_FIELD_MOD_HEALING_DONE_POS, SpellBaseHealingBonusDone(SPELL_SCHOOL_MASK_ALL)); - // Get damage bonus for all schools - Unit::AuraEffectList const& modDamageAuras = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE); - for (uint16 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) - { - SetInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + i, std::accumulate(modDamageAuras.begin(), modDamageAuras.end(), 0, [i](int32 negativeMod, AuraEffect const* aurEff) - { - if (aurEff->GetAmount() < 0 && aurEff->GetMiscValue() & (1 << i)) - negativeMod += aurEff->GetAmount(); - return negativeMod; - })); - SetStatInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + i, SpellBaseDamageBonusDone(SpellSchoolMask(1 << i)) - GetInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + i)); - } - } -} - bool Player::UpdateAllStats() { for (int8 i = STAT_STRENGTH; i < MAX_STATS; ++i) @@ -385,7 +369,8 @@ void Player::UpdateAttackPowerAndDamage(bool ranged) UpdateDamagePhysical(BASE_ATTACK); if (CanDualWield() && haveOffhandWeapon()) //allow update offhand damage only if player knows DualWield Spec and has equipped offhand weapon UpdateDamagePhysical(OFF_ATTACK); - if (getClass() == CLASS_SHAMAN || getClass() == CLASS_PALADIN) // mental quickness + + if (HasAuraType(SPELL_AURA_OVERRIDE_SPELL_POWER_BY_AP_PCT)) UpdateSpellDamageAndHealingBonus(); } } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 2fdf79b6fb..10ea76b9c8 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -6525,7 +6525,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin DoneTotal += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS, victim->GetCreatureTypeMask()); // Done fixed damage bonus auras - int32 DoneAdvertisedBenefit = SpellBaseDamageBonusDone(spellProto->GetSchoolMask()); + int32 DoneAdvertisedBenefit = SpellBaseDamageBonusDone(spellProto->GetSchoolMask(), true); // Custom scripted damage switch (spellProto->SpellFamilyName) @@ -6542,12 +6542,12 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin case SPELLFAMILY_WARLOCK: // Warlock Minions inherit 50% of their owner's spell power if (IsMinion() && GetOwner()) - DoneAdvertisedBenefit = owner->SpellBaseDamageBonusDone(spellProto->GetSchoolMask()) * 0.5f; + DoneAdvertisedBenefit = owner->SpellBaseDamageBonusDone(spellProto->GetSchoolMask(), true) * 0.5f; break; case SPELLFAMILY_MAGE: // Mage Water Elementals inherit 40% of their owner's spell power if (IsMinion() && GetOwner()) - DoneAdvertisedBenefit = owner->SpellBaseDamageBonusDone(spellProto->GetSchoolMask()) * 0.4f; + DoneAdvertisedBenefit = owner->SpellBaseDamageBonusDone(spellProto->GetSchoolMask(), true) * 0.4f; break; default: break; @@ -6866,24 +6866,30 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui return uint32(std::max(tmpDamage, 0.0f)); } -int32 Unit::SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const +int32 Unit::SpellBaseDamageBonusDone(SpellSchoolMask schoolMask, bool withSpellPowerPctMod /*= false*/) const { - // Overriden spell power values block any other spellpower benefit - AuraEffectList const& overrideSpellPowerAuras = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_SPELL_POWER_BY_AP_PCT); - for (auto itr : overrideSpellPowerAuras) - return CalculatePct(GetTotalAttackPowerValue(BASE_ATTACK), itr->GetAmount()); + if (IsPlayer()) + { + float overrideSP = GetFloatValue(PLAYER_FIELD_OVERRIDE_SPELL_POWER_BY_AP_PCT); + if (overrideSP > 0.0f) + return int32(CalculatePct(GetTotalAttackPowerValue(BASE_ATTACK), overrideSP) + 0.5f); + } int32 DoneAdvertisedBenefit = GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_DAMAGE_DONE, schoolMask); - if (GetTypeId() == TYPEID_PLAYER) + if (Player const* player = ToPlayer()) { // Base value - DoneAdvertisedBenefit += ToPlayer()->GetBaseSpellPowerBonus(); + DoneAdvertisedBenefit += player->GetBaseSpellPowerBonus(); // Check if we are ever using mana - PaperDollFrame.lua if (GetPowerIndex(POWER_MANA) != MAX_POWERS) DoneAdvertisedBenefit += std::max(0, int32(GetStat(STAT_INTELLECT)) - 10); // spellpower from intellect + // Spell Power bonus from SPELL_AURA_MOD_SPELL_POWER_PCT + if (withSpellPowerPctMod) + DoneAdvertisedBenefit *= player->GetFloatValue(PLAYER_FIELD_MOD_SPELL_POWER_PCT); + // Damage bonus from stats AuraEffectList const& mDamageDoneOfStatPercent = GetAuraEffectsByType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT); for (AuraEffect const* aurEff : mDamageDoneOfStatPercent) @@ -6896,8 +6902,6 @@ int32 Unit::SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const } } - // Spell power from SPELL_AURA_MOD_SPELL_POWER_PCT - AddPct(DoneAdvertisedBenefit, GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_POWER_PCT)); // ... and attack power DoneAdvertisedBenefit += static_cast(CalculatePct(GetTotalAttackPowerValue(BASE_ATTACK), GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER, schoolMask))); } @@ -7242,65 +7246,24 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui // done scripted mod (take it from owner) Unit const* owner = GetOwner() ? GetOwner() : this; - AuraEffectList const& mOverrideClassScript= owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); - for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i) + for (AuraEffect const* overrideClassScripts : owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS)) { - if (!(*i)->IsAffectingSpell(spellProto)) + if (!overrideClassScripts->IsAffectingSpell(spellProto)) continue; - switch ((*i)->GetMiscValue()) + + switch (overrideClassScripts->GetMiscValue()) { case 4415: // Increased Rejuvenation Healing case 4953: - case 3736: // Hateful Totem of the Third Wind / Increased Lesser Healing Wave / LK Arena (4/5/6) Totem of the Third Wind / Savage Totem of the Third Wind - DoneTotal += (*i)->GetAmount(); + DoneTotal += overrideClassScripts->GetAmount(); break; - case 47558: // Test of Faith - case 47559: - case 47560: - if (victim->HealthBelowPct(50)) - AddPct(DoneTotal, (*i)->GetAmount()); - break; - case 8477: // Nourish Heal Boost - { - int32 stepPercent = (*i)->GetAmount(); - int32 modPercent = 0; - AuraApplicationMap const& victimAuras = victim->GetAppliedAuras(); - for (AuraApplicationMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr) - { - Aura const* aura = itr->second->GetBase(); - if (aura->GetCasterGUID() != GetGUID()) - continue; - SpellInfo const* m_spell = aura->GetSpellInfo(); - if (m_spell->SpellFamilyName != SPELLFAMILY_DRUID || - !(m_spell->SpellFamilyFlags[1] & 0x00000010 || m_spell->SpellFamilyFlags[0] & 0x50)) - continue; - modPercent += stepPercent * aura->GetStackAmount(); - } - AddPct(DoneTotal, modPercent); - break; - } default: break; } } - // Custom scripted damage - switch (spellProto->SpellFamilyName) - { - case SPELLFAMILY_SHAMAN: - { - // Nature's Blessing - if (AuraEffect const* blessing = GetDummyAuraEffect(SPELLFAMILY_SHAMAN, 2012, EFFECT_0)) - if (blessing->IsAffectingSpell(spellProto) && victim->HasAura(974, GetGUID())) - AddPct(DoneTotalMod, blessing->GetAmount()); - break; - } - default: - break; - } - // Done fixed damage bonus auras - int32 DoneAdvertisedBenefit = SpellBaseHealingBonusDone(spellProto->GetSchoolMask()); + int32 DoneAdvertisedBenefit = SpellBaseHealingBonusDone(spellProto->GetSchoolMask(), true); // Check for table values float coeff = spellProto->Effects[effIndex].BonusMultiplier; @@ -7380,62 +7343,66 @@ float Unit::SpellHealingPctDone(Unit* victim, SpellInfo const* spellProto) const float DoneTotalMod = 1.0f; // Healing done percent - AuraEffectList const& mHealingDonePct = GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT); - for (AuraEffectList::const_iterator i = mHealingDonePct.begin(); i != mHealingDonePct.end(); ++i) - AddPct(DoneTotalMod, (*i)->GetAmount()); + DoneTotalMod *= GetTotalAuraMultiplier(SPELL_AURA_MOD_HEALING_DONE_PERCENT); // done scripted mod (take it from owner) Unit const* owner = GetOwner() ? GetOwner() : this; - AuraEffectList const& mOverrideClassScript= owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); - for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i) + for (AuraEffect const* overrideClassScripts : owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS)) { - if (!(*i)->IsAffectingSpell(spellProto)) + if (!overrideClassScripts->IsAffectingSpell(spellProto)) continue; - switch ((*i)->GetMiscValue()) + switch (overrideClassScripts->GetMiscValue()) { case 21: // Test of Faith case 6935: case 6918: if (victim->HealthBelowPct(50)) - AddPct(DoneTotalMod, (*i)->GetAmount()); + AddPct(DoneTotalMod, overrideClassScripts->GetAmount()); break; case 7798: // Glyph of Regrowth { if (victim->GetAuraEffect(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_DRUID, 0x40, 0, 0)) - AddPct(DoneTotalMod, (*i)->GetAmount()); + AddPct(DoneTotalMod, overrideClassScripts->GetAmount()); break; } case 8477: // Nourish Heal Boost { - int32 stepPercent = (*i)->GetAmount(); int32 modPercent = 0; AuraApplicationMap const& victimAuras = victim->GetAppliedAuras(); - for (AuraApplicationMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr) + + for (auto aurAppPair : victim->GetAppliedAuras()) { - Aura const* aura = itr->second->GetBase(); + Aura const* aura = aurAppPair.second->GetBase(); if (aura->GetCasterGUID() != GetGUID()) continue; - SpellInfo const* m_spell = aura->GetSpellInfo(); - if (m_spell->SpellFamilyName != SPELLFAMILY_DRUID || - !(m_spell->SpellFamilyFlags[1] & 0x00000010 || m_spell->SpellFamilyFlags[0] & 0x50)) - continue; - modPercent += stepPercent * aura->GetStackAmount(); + + if (aura->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID && aura->GetSpellInfo()->SpellFamilyFlags.HasFlag(0x10 | 0x40, 0x10 | 0x4000000, 0)) + modPercent += overrideClassScripts->GetAmount() * aura->GetStackAmount(); } AddPct(DoneTotalMod, modPercent); break; } - case 7871: // Glyph of Lesser Healing Wave - { - if (victim->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, 0, 0x00000400, 0, GetGUID())) - AddPct(DoneTotalMod, (*i)->GetAmount()); - break; - } default: break; } } + // Custom scripted damage + switch (spellProto->SpellFamilyName) + { + case SPELLFAMILY_SHAMAN: + { + // Nature's Blessing + if (AuraEffect const* blessing = GetDummyAuraEffect(SPELLFAMILY_SHAMAN, 2012, EFFECT_0)) + if (blessing->IsAffectingSpell(spellProto) && victim->HasAura(974, GetGUID())) + AddPct(DoneTotalMod, blessing->GetAmount()); + break; + } + default: + break; + } + float healthPctDiff = 100.f - victim->GetHealthPct(); for (AuraEffect const* healingDonePctVsTargetHealth : owner->GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_DONE_PCT_VERSUS_TARGET_HEALTH)) { @@ -7534,30 +7501,36 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u return uint32(std::max(heal, 0.0f)); } -int32 Unit::SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) const +int32 Unit::SpellBaseHealingBonusDone(SpellSchoolMask schoolMask, bool withSpellPowerPctMod /*= false*/) const { - // Overriden spell power values block any other spellpower benefit - AuraEffectList const& overrideSpellPowerAuras = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_SPELL_POWER_BY_AP_PCT); - for (auto itr : overrideSpellPowerAuras) - return CalculatePct(GetTotalAttackPowerValue(BASE_ATTACK), itr->GetAmount()); + if (IsPlayer()) + { + float overrideSP = GetFloatValue(PLAYER_FIELD_OVERRIDE_SPELL_POWER_BY_AP_PCT); + if (overrideSP > 0.0f) + return int32(CalculatePct(GetTotalAttackPowerValue(BASE_ATTACK), overrideSP) + 0.5f); + } - int32 advertisedBenefit = 0; - - AuraEffectList const& mHealingDone = GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_DONE); - for (AuraEffectList::const_iterator i = mHealingDone.begin(); i != mHealingDone.end(); ++i) - if (!(*i)->GetMiscValue() || ((*i)->GetMiscValue() & schoolMask) != 0) - advertisedBenefit += (*i)->GetAmount(); + int32 advertisedBenefit = GetTotalAuraModifier(SPELL_AURA_MOD_HEALING_DONE, [schoolMask](AuraEffect const* aurEff) -> bool + { + if (!aurEff->GetMiscValue() || (aurEff->GetMiscValue() & schoolMask) != 0) + return true; + return false; + }); // Healing bonus of spirit, intellect and strength - if (GetTypeId() == TYPEID_PLAYER) + if (Player const* player = ToPlayer()) { // Base value - advertisedBenefit += ToPlayer()->GetBaseSpellPowerBonus(); + advertisedBenefit += player->GetBaseSpellPowerBonus(); // Check if we are ever using mana - PaperDollFrame.lua if (GetPowerIndex(POWER_MANA) != MAX_POWERS) advertisedBenefit += std::max(0, int32(GetStat(STAT_INTELLECT)) - 10); // spellpower from intellect + // Spell Power bonus from SPELL_AURA_MOD_SPELL_POWER_PCT + if (withSpellPowerPctMod) + advertisedBenefit *= player->GetFloatValue(PLAYER_FIELD_MOD_SPELL_POWER_PCT); + // Healing bonus from stats AuraEffectList const& mHealingDoneOfStatPercent = GetAuraEffectsByType(SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT); for (AuraEffectList::const_iterator i = mHealingDoneOfStatPercent.begin(); i != mHealingDoneOfStatPercent.end(); ++i) @@ -7567,25 +7540,8 @@ int32 Unit::SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) const advertisedBenefit += int32(CalculatePct(GetStat(usedStat), (*i)->GetAmount())); } - // Spell power from SPELL_AURA_MOD_SPELL_POWER_PCT - AuraEffectList const& mSpellPowerPct = GetAuraEffectsByType(SPELL_AURA_MOD_SPELL_POWER_PCT); - for (AuraEffect const* aurEff : mSpellPowerPct) - { - int32 spellGroupVal = GetHighestExclusiveSameEffectSpellGroupValue(aurEff, SPELL_AURA_MOD_SPELL_POWER_PCT); - if (abs(spellGroupVal) >= abs(aurEff->GetAmount())) - { - AddPct(advertisedBenefit, spellGroupVal); - break; - } - else if (!spellGroupVal) - AddPct(advertisedBenefit, aurEff->GetAmount()); - } - // ... and attack power - AuraEffectList const& mHealingDonebyAP = GetAuraEffectsByType(SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER); - for (AuraEffectList::const_iterator i = mHealingDonebyAP.begin(); i != mHealingDonebyAP.end(); ++i) - if ((*i)->GetMiscValue() & schoolMask) - advertisedBenefit += int32(CalculatePct(GetTotalAttackPowerValue(BASE_ATTACK), (*i)->GetAmount())); + advertisedBenefit += CalculatePct(GetTotalAttackPowerValue(BASE_ATTACK), GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER, schoolMask)); } return advertisedBenefit; } diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index bb062efb91..4ea4640b50 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1520,12 +1520,12 @@ class TC_GAME_API Unit : public WorldObject Unit* GetMagicHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo); Unit* GetMeleeHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo = nullptr); - int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const; + int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask, bool withSpellPowerPctMod = false) const; int32 SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) const; uint32 SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, uint32 stack = 1) const; float SpellDamagePctDone(Unit* victim, SpellInfo const* spellProto, DamageEffectType damagetype) const; uint32 SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 pdamage, DamageEffectType damagetype) const; - int32 SpellBaseHealingBonusDone(SpellSchoolMask schoolMask) const; + int32 SpellBaseHealingBonusDone(SpellSchoolMask schoolMask, bool withSpellPowerPctMod = false) const; int32 SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask) const; uint32 SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, uint32 stack = 1) const; float SpellHealingPctDone(Unit* victim, SpellInfo const* spellProto) const; diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h index 8386f7c3f6..cc945e4bad 100644 --- a/src/server/game/Spells/Auras/SpellAuraDefines.h +++ b/src/server/game/Spells/Auras/SpellAuraDefines.h @@ -441,7 +441,7 @@ enum AuraType : uint32 SPELL_AURA_MOD_NEXT_SPELL = 363, // Used by 101601 Throw Totem - causes the client to initialize spell cast with specified spell SPELL_AURA_364 = 364, // Not used in 4.3.4 SPELL_AURA_MAX_FAR_CLIP_PLANE = 365, // Overrides client's View Distance setting to max("Fair", current_setting) and turns off terrain display - SPELL_AURA_OVERRIDE_SPELL_POWER_BY_AP_PCT = 366, // NYI - Sets spellpower equal to % of attack power, discarding all other bonuses (from gear and buffs) + SPELL_AURA_OVERRIDE_SPELL_POWER_BY_AP_PCT = 366, // Sets spellpower equal to % of attack power, discarding all other bonuses (from gear and buffs) SPELL_AURA_OVERRIDE_AUTOATTACK_WITH_RANGED_SPELL = 367, // NYI SPELL_AURA_368 = 368, // Not used in 4.3.4 SPELL_AURA_ENABLE_POWER_BAR_TIMER = 369, diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 2000f6d3db..593a992967 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -431,7 +431,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]= &AuraEffect::HandleNULL, //363 SPELL_AURA_MOD_NEXT_SPELL &AuraEffect::HandleUnused, //364 unused (4.3.4) &AuraEffect::HandleNULL, //365 SPELL_AURA_MAX_FAR_CLIP_PLANE - &AuraEffect::HandleOverrideSpellPowerByApPct, //366 SPELL_AURA_OVERRIDE_SPELL_POWER_BY_AP_PCT + &AuraEffect::HandleOverrideSpellPowerByAttackPower, //366 SPELL_AURA_OVERRIDE_SPELL_POWER_BY_AP_PCT &AuraEffect::HandleNULL, //367 SPELL_AURA_OVERRIDE_AUTOATTACK_WITH_RANGED_SPELL &AuraEffect::HandleUnused, //368 unused (4.3.4) &AuraEffect::HandleNULL, //369 SPELL_AURA_ENABLE_POWER_BAR_TIMER @@ -4245,16 +4245,17 @@ void AuraEffect::HandleAuraModAttackPowerOfArmor(AuraApplication const* aurApp, target->ToPlayer()->UpdateAttackPowerAndDamage(false); } -void AuraEffect::HandleOverrideSpellPowerByApPct(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const +void AuraEffect::HandleOverrideSpellPowerByAttackPower(AuraApplication const* aurApp, uint8 mode, bool apply) const { - if (!(mode & (AURA_EFFECT_HANDLE_REAL))) + if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT))) return; - Unit* target = aurApp->GetTarget(); + Player* target = aurApp->GetTarget()->ToPlayer(); + if (!target) + return; - // Recalculate bonus - if (target->GetTypeId() == TYPEID_PLAYER) - target->ToPlayer()->UpdateSpellDamageAndHealingBonus(); + target->ApplyModSignedFloatValue(PLAYER_FIELD_OVERRIDE_SPELL_POWER_BY_AP_PCT, float(m_amount), apply); + target->UpdateSpellDamageAndHealingBonus(); } /********************************/ @@ -5178,15 +5179,17 @@ void AuraEffect::HandlePreventResurrection(AuraApplication const* aurApp, uint8 aurApp->GetTarget()->SetByteFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_FLAGS, PLAYER_FIELD_BYTE_RELEASE_TIMER); } -void AuraEffect::HandleAuraModSpellPowerPct(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const +void AuraEffect::HandleAuraModSpellPowerPct(AuraApplication const* aurApp, uint8 mode, bool apply) const { if (!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT))) return; - Unit* target = aurApp->GetTarget(); + Player* target = aurApp->GetTarget()->ToPlayer(); + if (!target) + return; - if (Player* player = target->ToPlayer()) - player->UpdateSpellDamageAndHealingBonus(); + // Calculations done in Unit::SpellBaseHealingBonusDone and Unit::SpellBaseDamageBonusDone + target->SetFloatValue(PLAYER_FIELD_MOD_SPELL_POWER_PCT, target->GetTotalAuraMultiplier(SPELL_AURA_MOD_SPELL_POWER_PCT)); } void AuraEffect::HandleMastery(AuraApplication const* aurApp, uint8 mode, bool /*apply*/) const diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h index 906f9aa9df..4b877895c2 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.h +++ b/src/server/game/Spells/Auras/SpellAuraEffects.h @@ -266,7 +266,7 @@ class TC_GAME_API AuraEffect void HandleAuraModAttackPowerPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const; void HandleAuraModRangedAttackPowerPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const; void HandleAuraModAttackPowerOfArmor(AuraApplication const* aurApp, uint8 mode, bool apply) const; - void HandleOverrideSpellPowerByApPct(AuraApplication const* aurApp, uint8 mode, bool apply) const; + void HandleOverrideSpellPowerByAttackPower(AuraApplication const* aurApp, uint8 mode, bool apply) const; // damage bonus void HandleModDamageDone(AuraApplication const* aurApp, uint8 mode, bool apply) const; void HandleModDamagePercentDone(AuraApplication const* aurApp, uint8 mode, bool apply) const; diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp index 6a5251c6ef..a3684ef233 100644 --- a/src/server/scripts/Spells/spell_druid.cpp +++ b/src/server/scripts/Spells/spell_druid.cpp @@ -1940,6 +1940,32 @@ class spell_dru_skull_bash : public SpellScript } }; +// 50464 - Nourish +class spell_dru_nourish : public SpellScript +{ + // Nourish heals for an additional 20% if Rejuvenation, Regrowth, Wild Growth or Lifebloom is on the target + void HandleHealBonus(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + if (!caster) + return; + + auto periodicHealEffects = GetHitUnit()->GetAuraEffectsByType(SPELL_AURA_PERIODIC_HEAL); + if (std::any_of(periodicHealEffects.begin(), periodicHealEffects.end(), [caster](AuraEffect const* aurEff) + { + return (aurEff->GetCasterGUID() == caster->GetGUID() + && aurEff->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID + && !aurEff->GetSpellInfo()->SpellFamilyFlags.HasFlag(0x10 | 0x40, 0x10 | 0x4000000, 0)); + })) + SetHitHeal(GetHitHeal() * 1.2f); + } + + void Register() override + { + OnEffectHitTarget.Register(&spell_dru_nourish::HandleHealBonus, EFFECT_0, SPELL_EFFECT_HEAL); + } +}; + void AddSC_druid_spell_scripts() { RegisterSpellScript(spell_dru_astral_alignment); @@ -1969,6 +1995,7 @@ void AddSC_druid_spell_scripts() RegisterSpellScript(spell_dru_living_seed); RegisterSpellScript(spell_dru_living_seed_proc); RegisterSpellScript(spell_dru_moonfire); + RegisterSpellScript(spell_dru_nourish); RegisterSpellScript(spell_dru_pulverize); RegisterSpellScript(spell_dru_rejuvenation); RegisterSpellScript(spell_dru_rip);