diff options
| author | Shauren <shauren.trinity@gmail.com> | 2025-03-28 23:42:39 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2025-03-28 23:42:39 +0100 |
| commit | dfcd41abefec371e6af9db7db92c1dd55aa701ff (patch) | |
| tree | 732a3b27ad42c7c4ea68f742927ed1183eea6620 /src/server/game/Entities | |
| parent | ba2847e7b82409bd721b872f7d6bb0b8653c28f2 (diff) | |
Core/Spells: Apply spell modifiers multiple times to each cast, based on number of matched SpellFamilyFlags bits
Diffstat (limited to 'src/server/game/Entities')
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 45 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.h | 2 |
2 files changed, 27 insertions, 20 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index cf8d7b08a6c..a8fe32ceb74 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -22403,45 +22403,45 @@ void Player::SendRemoveControlBar() const SendDirectMessage(packet.Write()); } -bool Player::IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier const* mod, Spell* spell) +uint32 Player::IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier const* mod, Spell const* spell) { if (!mod || !spellInfo) - return false; + return 0; // First time this aura applies a mod to us and is out of charges - if (spell && mod->ownerAura->IsUsingCharges() && !mod->ownerAura->GetCharges() && !spell->m_appliedMods.count(mod->ownerAura)) - return false; + if (spell && mod->ownerAura->IsUsingCharges() && !mod->ownerAura->GetCharges() && !spell->m_appliedMods.contains(mod->ownerAura)) + return 0; switch (mod->op) { case SpellModOp::Duration: // +duration to infinite duration spells making them limited if (spellInfo->GetDuration() == -1) - return false; + return 0; break; case SpellModOp::CritChance: // mod crit to spells that can't crit if (!spellInfo->HasAttribute(SPELL_ATTR0_CU_CAN_CRIT)) - return false; + return 0; break; case SpellModOp::PointsIndex0: // check if spell has any effect at that index case SpellModOp::Points: if (spellInfo->GetEffects().size() <= EFFECT_0) - return false; + return 0; break; case SpellModOp::PointsIndex1: // check if spell has any effect at that index if (spellInfo->GetEffects().size() <= EFFECT_1) - return false; + return 0; break; case SpellModOp::PointsIndex2: // check if spell has any effect at that index if (spellInfo->GetEffects().size() <= EFFECT_2) - return false; + return 0; break; case SpellModOp::PointsIndex3: // check if spell has any effect at that index if (spellInfo->GetEffects().size() <= EFFECT_3) - return false; + return 0; break; case SpellModOp::PointsIndex4: // check if spell has any effect at that index if (spellInfo->GetEffects().size() <= EFFECT_4) - return false; + return 0; break; default: break; @@ -22458,6 +22458,9 @@ void Player::GetSpellModValues(SpellInfo const* spellInfo, SpellModOp op, Spell* *flat = 0; *pct = 1.0f; + if (!spellInfo->IsAffectedBySpellMods()) + return; + auto spellModOpBegin = std::ranges::lower_bound(m_spellMods, op, std::ranges::less(), &SpellModifier::op); if (spellModOpBegin == m_spellMods.end() || (*spellModOpBegin)->op != op) return; @@ -22587,33 +22590,36 @@ void Player::GetSpellModValues(SpellInfo const* spellInfo, SpellModOp op, Spell* for (SpellModifier* mod : spellModTypeRange(SPELLMOD_FLAT)) { - if (!IsAffectedBySpellmod(spellInfo, mod, spell)) + uint32 applyCount = IsAffectedBySpellmod(spellInfo, mod, spell); + if (!applyCount) continue; int32 value = static_cast<SpellModifierByClassMask*>(mod)->value; if (value == 0) continue; - *flat += value; + *flat += value * applyCount; Player::ApplyModToSpell(mod, spell); } for (SpellModifier* mod : spellModTypeRange(SPELLMOD_LABEL_FLAT)) { - if (!IsAffectedBySpellmod(spellInfo, mod, spell)) + uint32 applyCount = IsAffectedBySpellmod(spellInfo, mod, spell); + if (!applyCount) continue; int32 value = static_cast<SpellFlatModifierByLabel*>(mod)->value.ModifierValue; if (value == 0) continue; - *flat += value; + *flat += value * applyCount; Player::ApplyModToSpell(mod, spell); } for (SpellModifier* mod : spellModTypeRange(SPELLMOD_PCT)) { - if (!IsAffectedBySpellmod(spellInfo, mod, spell)) + uint32 applyCount = IsAffectedBySpellmod(spellInfo, mod, spell); + if (!applyCount) continue; // skip percent mods for null basevalue (most important for spell mods with charges) @@ -22631,13 +22637,14 @@ void Player::GetSpellModValues(SpellInfo const* spellInfo, SpellModOp op, Spell* continue; } - *pct *= 1.0f + CalculatePct(1.0f, value); + *pct *= std::pow(1.0f + CalculatePct(1.0f, value), applyCount); Player::ApplyModToSpell(mod, spell); } for (SpellModifier* mod : spellModTypeRange(SPELLMOD_LABEL_PCT)) { - if (!IsAffectedBySpellmod(spellInfo, mod, spell)) + uint32 applyCount = IsAffectedBySpellmod(spellInfo, mod, spell); + if (!applyCount) continue; // skip percent mods for null basevalue (most important for spell mods with charges) @@ -22655,7 +22662,7 @@ void Player::GetSpellModValues(SpellInfo const* spellInfo, SpellModOp op, Spell* continue; } - *pct *= value; + *pct *= std::pow(value, applyCount); Player::ApplyModToSpell(mod, spell); } } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 36bf7c764eb..ae955a9b683 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1993,7 +1993,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player> PlayerSpellMap & GetSpellMap() { return m_spells; } void AddSpellMod(SpellModifier* mod, bool apply); - static bool IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier const* mod, Spell* spell = nullptr); + static uint32 IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier const* mod, Spell const* spell = nullptr); template <class T> void GetSpellModValues(SpellInfo const* spellInfo, SpellModOp op, Spell* spell, T base, int32* flat, float* pct) const; template <class T> |
