diff options
| author | Seyden <saiifii@live.de> | 2023-08-22 00:02:37 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-08-22 00:02:37 +0200 |
| commit | 42a6e0eb1afa431fc1efe7d4c5a62758fed42684 (patch) | |
| tree | 236e4df00001eca190999eb4bd5d7419ee4a4b3a /src/server/game/Spells/Spell.cpp | |
| parent | e600cd392ba4eea17012663b08aeb429cb4fd774 (diff) | |
Core/Spells: Implement sqrt based aoe damage diminishing (#29192)
Co-authored-by: Shauren <shauren.trinity@gmail.com>
Diffstat (limited to 'src/server/game/Spells/Spell.cpp')
| -rw-r--r-- | src/server/game/Spells/Spell.cpp | 59 |
1 files changed, 55 insertions, 4 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 50483d7b714..ff2c0128e07 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -2620,6 +2620,23 @@ void Spell::AddDestTarget(SpellDestination const& dest, uint32 effIndex) m_destTargets[effIndex] = dest; } +int32 Spell::GetUnitTargetIndexForEffect(ObjectGuid const& target, SpellEffIndex effect) const +{ + int32 index = 0; + for (TargetInfo const& uniqueTargetInfo : m_UniqueTargetInfo) + { + if (uniqueTargetInfo.MissCondition == SPELL_MISS_NONE && uniqueTargetInfo.EffectMask & (1 << effect)) + { + if (uniqueTargetInfo.TargetGUID == target) + break; + + ++index; + } + } + + return index; +} + int64 Spell::GetUnitTargetCountForEffect(SpellEffIndex effect) const { return std::count_if(m_UniqueTargetInfo.begin(), m_UniqueTargetInfo.end(), [effect](TargetInfo const& targetInfo) @@ -8297,16 +8314,44 @@ void Spell::DoEffectOnLaunchTarget(TargetInfo& targetInfo, float multiplier, Spe if (m_originalCaster && m_damage > 0) { - if (spellEffectInfo.IsTargetingArea() || spellEffectInfo.IsAreaAuraEffect() || spellEffectInfo.IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA) || m_spellInfo->HasAttribute(SPELL_ATTR5_TREAT_AS_AREA_EFFECT)) + bool isAoeTarget = spellEffectInfo.IsTargetingArea() || spellEffectInfo.IsAreaAuraEffect() || spellEffectInfo.IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA); + if (isAoeTarget || m_spellInfo->HasAttribute(SPELL_ATTR5_TREAT_AS_AREA_EFFECT)) { m_damage = unit->CalculateAOEAvoidance(m_damage, m_spellInfo->SchoolMask, m_originalCaster->GetGUID()); if (m_originalCaster->GetTypeId() == TYPEID_PLAYER) { + int64 targetCount = !isAoeTarget && m_spellValue->ParentSpellTargetCount ? *m_spellValue->ParentSpellTargetCount : GetUnitTargetCountForEffect(spellEffectInfo.EffectIndex); + int32 targetIndex = !isAoeTarget && m_spellValue->ParentSpellTargetIndex ? *m_spellValue->ParentSpellTargetIndex : GetUnitTargetIndexForEffect(targetInfo.TargetGUID, spellEffectInfo.EffectIndex); + + // sqrt target cap damage calculation + if (m_spellInfo->SqrtDamageAndHealingDiminishing.MaxTargets + && targetCount > m_spellInfo->SqrtDamageAndHealingDiminishing.MaxTargets + && targetIndex >= m_spellInfo->SqrtDamageAndHealingDiminishing.NumNonDiminishedTargets) + m_damage = m_damage * std::sqrt(float(m_spellInfo->SqrtDamageAndHealingDiminishing.MaxTargets) / std::min(AOE_DAMAGE_TARGET_CAP, targetCount)); + // cap damage of player AOE - int64 targetAmount = GetUnitTargetCountForEffect(spellEffectInfo.EffectIndex); - if (targetAmount > 20) - m_damage = m_damage * 20 / targetAmount; + if (targetCount > AOE_DAMAGE_TARGET_CAP) + m_damage = m_damage * AOE_DAMAGE_TARGET_CAP / targetCount; + } + } + } + + if (m_originalCaster && m_healing > 0) + { + bool isAoeTarget = spellEffectInfo.IsTargetingArea() || spellEffectInfo.IsAreaAuraEffect() || spellEffectInfo.IsEffect(SPELL_EFFECT_PERSISTENT_AREA_AURA); + if (isAoeTarget || m_spellInfo->HasAttribute(SPELL_ATTR5_TREAT_AS_AREA_EFFECT)) + { + if (m_originalCaster->GetTypeId() == TYPEID_PLAYER) + { + int64 targetCount = !isAoeTarget && m_spellValue->ParentSpellTargetCount ? *m_spellValue->ParentSpellTargetCount : GetUnitTargetCountForEffect(spellEffectInfo.EffectIndex); + int32 targetIndex = !isAoeTarget && m_spellValue->ParentSpellTargetIndex ? *m_spellValue->ParentSpellTargetIndex : GetUnitTargetIndexForEffect(targetInfo.TargetGUID, spellEffectInfo.EffectIndex); + + // sqrt target cap healing calculation + if (m_spellInfo->SqrtDamageAndHealingDiminishing.MaxTargets + && targetCount > m_spellInfo->SqrtDamageAndHealingDiminishing.MaxTargets + && targetIndex >= m_spellInfo->SqrtDamageAndHealingDiminishing.NumNonDiminishedTargets) + m_healing = m_healing * std::sqrt(float(m_spellInfo->SqrtDamageAndHealingDiminishing.MaxTargets) / std::min(AOE_DAMAGE_TARGET_CAP, targetCount)); } } } @@ -8426,6 +8471,12 @@ void Spell::SetSpellValue(SpellValueMod mod, int32 value) case SPELLVALUE_DURATION: m_spellValue->Duration = value; break; + case SPELLVALUE_PARENT_SPELL_TARGET_COUNT: + m_spellValue->ParentSpellTargetCount = value; + break; + case SPELLVALUE_PARENT_SPELL_TARGET_INDEX: + m_spellValue->ParentSpellTargetIndex = value; + break; default: break; } |
