aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Spells/Spell.cpp
diff options
context:
space:
mode:
authorSeyden <saiifii@live.de>2023-08-22 00:02:37 +0200
committerGitHub <noreply@github.com>2023-08-22 00:02:37 +0200
commit42a6e0eb1afa431fc1efe7d4c5a62758fed42684 (patch)
tree236e4df00001eca190999eb4bd5d7419ee4a4b3a /src/server/game/Spells/Spell.cpp
parente600cd392ba4eea17012663b08aeb429cb4fd774 (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.cpp59
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;
}