aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Spells/Spell.cpp99
-rw-r--r--src/server/game/Spells/Spell.h2
2 files changed, 54 insertions, 47 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index e83c236ad69..f59e27da9c1 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -753,10 +753,53 @@ void Spell::SelectSpellTargets()
if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM))
m_targets.SetTargetFlag(TARGET_FLAG_GAMEOBJECT);
- uint32 currentlyProcessedEffectMask = processedEffectsMaskForSpell;
- SelectEffectImplicitTargets(spellEffectInfo, spellEffectInfo.TargetA, processedEffectsMaskForSpell);
- SelectEffectImplicitTargets(spellEffectInfo, spellEffectInfo.TargetB, processedEffectsMaskForSpell);
- currentlyProcessedEffectMask = processedEffectsMaskForSpell & ~currentlyProcessedEffectMask;
+ uint32 implicitTargetEffectMaskToSelect = [&]
+ {
+ uint32 effectMask = 1u << spellEffectInfo.EffectIndex;
+ // set the same target list for all effects
+ // some spells appear to need this, however this requires more research
+ std::array<SpellEffectInfo, MAX_SPELL_EFFECTS> const& effects = GetSpellInfo()->GetEffects();
+ // choose which targets we can select at once
+ for (uint32 j = spellEffectInfo.EffectIndex + 1; j < effects.size(); ++j)
+ {
+ if (effects[j].IsEffect() &&
+ spellEffectInfo.TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
+ spellEffectInfo.TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
+ spellEffectInfo.ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
+ CheckScriptEffectImplicitTargets(spellEffectInfo.EffectIndex, j))
+ {
+ auto shouldCheckRadius = [](SpellImplicitTargetInfo const& targetInfo)
+ {
+ switch (targetInfo.GetSelectionCategory())
+ {
+ case TARGET_SELECT_CATEGORY_NEARBY:
+ case TARGET_SELECT_CATEGORY_CONE:
+ case TARGET_SELECT_CATEGORY_AREA:
+ return true;
+ default:
+ break;
+ }
+ return false;
+ };
+
+ if (shouldCheckRadius(spellEffectInfo.TargetA) || shouldCheckRadius(spellEffectInfo.TargetB))
+ if (spellEffectInfo.CalcRadius(m_caster) != effects[j].CalcRadius(m_caster))
+ continue;
+
+ effectMask |= 1 << j;
+ }
+ }
+
+ return effectMask;
+ }();
+
+ implicitTargetEffectMaskToSelect &= ~processedEffectsMaskForSpell;
+ if (implicitTargetEffectMaskToSelect)
+ {
+ SelectEffectImplicitTargets(spellEffectInfo, spellEffectInfo.TargetA, implicitTargetEffectMaskToSelect);
+ SelectEffectImplicitTargets(spellEffectInfo, spellEffectInfo.TargetB, implicitTargetEffectMaskToSelect);
+ processedEffectsMaskForSpell |= implicitTargetEffectMaskToSelect;
+ }
// Select targets of effect based on effect type
// those are used when no valid target could be added for spell effect based on spell target type
@@ -768,7 +811,7 @@ void Spell::SelectSpellTargets()
if (m_targets.HasDst())
AddDestTarget(*m_targets.GetDst(), spellEffectInfo.EffectIndex);
- if (currentlyProcessedEffectMask
+ if (implicitTargetEffectMaskToSelect
&& (spellEffectInfo.TargetA.GetObjectType() == TARGET_OBJECT_TYPE_UNIT
|| spellEffectInfo.TargetA.GetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST
|| spellEffectInfo.TargetB.GetObjectType() == TARGET_OBJECT_TYPE_UNIT
@@ -776,9 +819,9 @@ void Spell::SelectSpellTargets()
{
if (m_spellInfo->HasAttribute(SPELL_ATTR1_REQUIRE_ALL_TARGETS))
{
- bool noTargetFound = std::ranges::none_of(m_UniqueTargetInfo, [currentlyProcessedEffectMask](TargetInfo const& target)
+ bool noTargetFound = std::ranges::none_of(m_UniqueTargetInfo, [implicitTargetEffectMaskToSelect](TargetInfo const& target)
{
- return target.EffectMask & currentlyProcessedEffectMask;
+ return target.EffectMask & implicitTargetEffectMaskToSelect;
});
if (noTargetFound)
@@ -790,9 +833,9 @@ void Spell::SelectSpellTargets()
}
if (m_spellInfo->HasAttribute(SPELL_ATTR2_FAIL_ON_ALL_TARGETS_IMMUNE))
{
- bool anyNonImmuneTargetFound = std::ranges::any_of(m_UniqueTargetInfo, [currentlyProcessedEffectMask](TargetInfo const& target)
+ bool anyNonImmuneTargetFound = std::ranges::any_of(m_UniqueTargetInfo, [implicitTargetEffectMaskToSelect](TargetInfo const& target)
{
- return target.EffectMask & currentlyProcessedEffectMask && target.MissCondition != SPELL_MISS_IMMUNE && target.MissCondition != SPELL_MISS_IMMUNE2;
+ return target.EffectMask & implicitTargetEffectMaskToSelect && target.MissCondition != SPELL_MISS_IMMUNE && target.MissCondition != SPELL_MISS_IMMUNE2;
});
if (!anyNonImmuneTargetFound)
@@ -879,47 +922,11 @@ void Spell::RecalculateDelayMomentForDst()
m_caster->m_Events.ModifyEventTime(_spellEvent, Milliseconds(GetDelayStart() + m_delayMoment));
}
-void Spell::SelectEffectImplicitTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32& processedEffectMask)
+void Spell::SelectEffectImplicitTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effectMask)
{
if (!targetType.GetTarget())
return;
- uint32 effectMask = 1 << spellEffectInfo.EffectIndex;
-
- // targets for effect already selected
- if (effectMask & processedEffectMask)
- return;
-
- // set the same target list for all effects
- // some spells appear to need this, however this requires more research
- std::array<SpellEffectInfo, MAX_SPELL_EFFECTS> const& effects = GetSpellInfo()->GetEffects();
- // choose which targets we can select at once
- for (uint32 j = spellEffectInfo.EffectIndex + 1; j < effects.size(); ++j)
- {
- if (effects[j].IsEffect() &&
- spellEffectInfo.TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
- spellEffectInfo.TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
- spellEffectInfo.ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
- CheckScriptEffectImplicitTargets(spellEffectInfo.EffectIndex, j))
- {
- switch (targetType.GetSelectionCategory())
- {
- case TARGET_SELECT_CATEGORY_NEARBY:
- case TARGET_SELECT_CATEGORY_CONE:
- case TARGET_SELECT_CATEGORY_AREA:
- if (spellEffectInfo.CalcRadius(m_caster) != effects[j].CalcRadius(m_caster))
- continue;
- break;
- default:
- break;
- }
-
- effectMask |= 1 << j;
- }
- }
-
- processedEffectMask |= effectMask;
-
switch (targetType.GetSelectionCategory())
{
case TARGET_SELECT_CATEGORY_CHANNEL:
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 5f36ea02b85..496dd23e698 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -287,7 +287,7 @@ class TC_GAME_API Spell
void SelectExplicitTargets();
void SelectSpellTargets();
- void SelectEffectImplicitTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32& processedEffectMask);
+ void SelectEffectImplicitTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effectMask);
void SelectImplicitChannelTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effMask);
void SelectImplicitNearbyTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effMask);
void SelectImplicitConeTargets(SpellEffectInfo const& spellEffectInfo, SpellImplicitTargetInfo const& targetType, uint32 effMask);