diff options
Diffstat (limited to 'src/server/game/Spells/Spell.cpp')
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 51 |
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); |