aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Spells/Spell.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game/Spells/Spell.cpp')
-rw-r--r--src/server/game/Spells/Spell.cpp51
1 files changed, 40 insertions, 11 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 6f3e829f799..9ab610412df 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -1418,15 +1418,18 @@ void Spell::SelectImplicitAreaTargets(SpellEffectInfo const& spellEffectInfo, Sp
if (!m_caster->IsUnit() || !m_caster->ToUnit()->IsInRaidWith(targetedUnit))
targets.push_back(m_targets.GetUnitTarget());
else
- SearchAreaTargets(targets, spellEffectInfo, radius, targetedUnit, referer, targetType.GetObjectType(), targetType.GetCheckType(), spellEffectInfo.ImplicitTargetConditions.get());
+ SearchAreaTargets(targets, spellEffectInfo, radius, targetedUnit, referer, targetType.GetObjectType(), targetType.GetCheckType(),
+ spellEffectInfo.ImplicitTargetConditions.get(), Trinity::WorldObjectSpellAreaTargetSearchReason::Area);
}
break;
case TARGET_UNIT_CASTER_AND_SUMMONS:
targets.push_back(m_caster);
- SearchAreaTargets(targets, spellEffectInfo, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), spellEffectInfo.ImplicitTargetConditions.get());
+ SearchAreaTargets(targets, spellEffectInfo, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(),
+ spellEffectInfo.ImplicitTargetConditions.get(), Trinity::WorldObjectSpellAreaTargetSearchReason::Area);
break;
default:
- SearchAreaTargets(targets, spellEffectInfo, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), spellEffectInfo.ImplicitTargetConditions.get());
+ SearchAreaTargets(targets, spellEffectInfo, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(),
+ spellEffectInfo.ImplicitTargetConditions.get(), Trinity::WorldObjectSpellAreaTargetSearchReason::Area);
break;
}
@@ -2186,20 +2189,23 @@ WorldObject* Spell::SearchNearbyTarget(SpellEffectInfo const& spellEffectInfo, f
return target;
}
-void Spell::SearchAreaTargets(std::list<WorldObject*>& targets, SpellEffectInfo const& spellEffectInfo, float range, Position const* position, WorldObject* referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionContainer const* condList)
+void Spell::SearchAreaTargets(std::list<WorldObject*>& targets, SpellEffectInfo const& spellEffectInfo, float range, Position const* position, WorldObject* referer,
+ SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionContainer const* condList,
+ Trinity::WorldObjectSpellAreaTargetSearchReason searchReason)
{
uint32 containerTypeMask = GetSearcherTypeMask(m_spellInfo, spellEffectInfo, objectType, condList);
if (!containerTypeMask)
return;
float extraSearchRadius = range > 0.0f ? EXTRA_CELL_SEARCH_RADIUS : 0.0f;
- Trinity::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList, objectType);
+ Trinity::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList, objectType, searchReason);
Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
searcher.i_phaseShift = &PhasingHandler::GetAlwaysVisiblePhaseShift();
SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellAreaTargetCheck>>(searcher, containerTypeMask, m_caster, position, range + extraSearchRadius);
}
-void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTargets, WorldObject* target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellEffectInfo const& spellEffectInfo, bool isChainHeal)
+void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTargets, WorldObject* target, SpellTargetObjectTypes objectType,
+ SpellTargetCheckTypes selectType, SpellEffectInfo const& spellEffectInfo, bool isChainHeal)
{
// max dist for jump target selection
float jumpRadius = 0.0f;
@@ -2241,7 +2247,8 @@ void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTar
WorldObject* chainSource = m_spellInfo->HasAttribute(SPELL_ATTR2_CHAIN_FROM_CASTER) ? m_caster : target;
std::list<WorldObject*> tempTargets;
- SearchAreaTargets(tempTargets, spellEffectInfo, searchRadius, chainSource, m_caster, objectType, selectType, spellEffectInfo.ImplicitTargetConditions.get());
+ SearchAreaTargets(tempTargets, spellEffectInfo, searchRadius, chainSource, m_caster, objectType, selectType, spellEffectInfo.ImplicitTargetConditions.get(),
+ Trinity::WorldObjectSpellAreaTargetSearchReason::Chain);
tempTargets.remove(target);
// remove targets which are always invalid for chain spells
@@ -9189,15 +9196,16 @@ bool WorldObjectSpellNearbyTargetCheck::operator()(WorldObject* target)
}
WorldObjectSpellAreaTargetCheck::WorldObjectSpellAreaTargetCheck(float range, Position const* position, WorldObject* caster,
- WorldObject* referer, SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer const* condList, SpellTargetObjectTypes objectType)
- : WorldObjectSpellTargetCheck(caster, referer, spellInfo, selectionType, condList, objectType), _range(range), _position(position) { }
+ WorldObject* referer, SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer const* condList, SpellTargetObjectTypes objectType,
+ WorldObjectSpellAreaTargetSearchReason searchReason /*= Area*/)
+ : WorldObjectSpellTargetCheck(caster, referer, spellInfo, selectionType, condList, objectType), _range(range), _position(position), _searchReason(searchReason) { }
bool WorldObjectSpellAreaTargetCheck::operator()(WorldObject* target) const
{
- if (target->ToGameObject())
+ if (GameObject* gameObjectTarget = target->ToGameObject())
{
// isInRange including the dimension of the GO
- bool isInRange = target->ToGameObject()->IsInRange(_position->GetPositionX(), _position->GetPositionY(), _position->GetPositionZ(), _range);
+ bool isInRange = gameObjectTarget->IsInRange(_position->GetPositionX(), _position->GetPositionY(), _position->GetPositionZ(), _range);
if (!isInRange)
return false;
}
@@ -9206,6 +9214,27 @@ bool WorldObjectSpellAreaTargetCheck::operator()(WorldObject* target) const
bool isInsideCylinder = target->IsWithinDist2d(_position, _range) && std::abs(target->GetPositionZ() - _position->GetPositionZ()) <= _range;
if (!isInsideCylinder)
return false;
+
+ if (Creature* creatureTarget = target->ToCreature())
+ {
+ if (CreatureImmunities const* immunities = SpellMgr::GetCreatureImmunities(creatureTarget->GetCreatureTemplate()->CreatureImmunitiesId))
+ {
+ switch (_searchReason)
+ {
+ case WorldObjectSpellAreaTargetSearchReason::Area:
+ if (immunities->ImmuneAoE)
+ return false;
+ break;
+ case WorldObjectSpellAreaTargetSearchReason::Chain:
+ if (immunities->ImmuneChain)
+ return false;
+ break;
+ default:
+ break;
+ }
+
+ }
+ }
}
return WorldObjectSpellTargetCheck::operator ()(target);