aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Spells/SpellInfo.cpp
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2025-03-28 23:42:39 +0100
committerOvahlord <dreadkiller@gmx.de>2025-04-06 19:39:51 +0200
commit1309508002b4c989d46200ffc452db4a8f5ffdc3 (patch)
tree5ac081b17400ab4bb4c8f6dc35f8ca9771e2bfac /src/server/game/Spells/SpellInfo.cpp
parent58e3cee2fa032d4a2e928599b86f53d5b9ba3490 (diff)
Core/Spells: Apply spell modifiers multiple times to each cast, based on number of matched SpellFamilyFlags bits
(cherry picked from commit dfcd41abefec371e6af9db7db92c1dd55aa701ff) # Conflicts: # src/server/game/Entities/Player/Player.cpp
Diffstat (limited to 'src/server/game/Spells/SpellInfo.cpp')
-rw-r--r--src/server/game/Spells/SpellInfo.cpp22
1 files changed, 14 insertions, 8 deletions
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index ec495532d4e..378c89eee45 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -37,6 +37,7 @@
#include "SpellMgr.h"
#include "Vehicle.h"
#include <G3D/g3dmath.h>
+#include <bit>
uint32 GetTargetFlagMask(SpellTargetObjectTypes objType)
{
@@ -1839,11 +1840,8 @@ bool SpellInfo::IsAffectedBySpellMods() const
return !HasAttribute(SPELL_ATTR3_IGNORE_CASTER_MODIFIERS);
}
-bool SpellInfo::IsAffectedBySpellMod(SpellModifier const* mod) const
+uint32 SpellInfo::IsAffectedBySpellMod(SpellModifier const* mod) const
{
- if (!IsAffectedBySpellMods())
- return false;
-
SpellInfo const* affectSpell = sSpellMgr->GetSpellInfo(mod->spellId, Difficulty);
if (!affectSpell)
return false;
@@ -1852,13 +1850,21 @@ bool SpellInfo::IsAffectedBySpellMod(SpellModifier const* mod) const
{
case SPELLMOD_FLAT:
case SPELLMOD_PCT:
+ {
// TEMP: dont use IsAffected - !familyName and !familyFlags are not valid options for spell mods
// TODO: investigate if the !familyName and !familyFlags conditions are even valid for all other (nonmod) uses of SpellInfo::IsAffected
- return affectSpell->SpellFamilyName == SpellFamilyName && static_cast<SpellModifierByClassMask const*>(mod)->mask & SpellFamilyFlags;
+ if (affectSpell->SpellFamilyName != SpellFamilyName)
+ return false;
+
+ // spell modifiers should apply as many times as number of matched SpellFamilyFlags bits (verified with spell 1218116 with modifier 384451 in patch 11.1.0 and client tooltip code since at least 3.3.5)
+ // unknown if this is a bug or strange design choice...
+ FlagsArray<uint32, 4> matched = static_cast<SpellModifierByClassMask const*>(mod)->mask & SpellFamilyFlags;
+ return std::popcount(matched[0]) + std::popcount(matched[1]) + std::popcount(matched[2]) + std::popcount(matched[3]);
+ }
case SPELLMOD_LABEL_FLAT:
- return HasLabel(static_cast<SpellFlatModifierByLabel const*>(mod)->value.LabelID);
+ return HasLabel(static_cast<SpellFlatModifierByLabel const*>(mod)->value.LabelID) ? 1 : 0;
case SPELLMOD_LABEL_PCT:
- return HasLabel(static_cast<SpellPctModifierByLabel const*>(mod)->value.LabelID);
+ return HasLabel(static_cast<SpellPctModifierByLabel const*>(mod)->value.LabelID) ? 1 : 0;
default:
break;
}
@@ -4975,5 +4981,5 @@ bool SpellInfo::MeetsFutureSpellPlayerCondition(Player const* player) const
bool SpellInfo::HasLabel(uint32 labelId) const
{
- return Labels.find(labelId) != Labels.end();
+ return Labels.contains(labelId);
}