diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/GameObject/GameObject.cpp | 48 | ||||
-rw-r--r-- | src/server/game/Entities/GameObject/GameObject.h | 6 |
2 files changed, 50 insertions, 4 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index be46c3394f2..27b3afc81e7 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -374,6 +374,35 @@ bool GameObject::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, u m_invisibility.AddFlag(INVISIBILITY_TRAP); m_invisibility.AddValue(INVISIBILITY_TRAP, 300); } + + m_goValue.Trap.TargetSearcherCheckType = TARGET_CHECK_ENEMY; + if (SpellInfo const* trapSpell = sSpellMgr->GetSpellInfo(goinfo->trap.spellId)) + { + // positive spells may require enemy targets + if (trapSpell->IsPositive()) + { + bool targetsAlly = false; + bool targetsEnemy = false; + auto isAllyTarget = [](SpellImplicitTargetInfo const& targetInfo) + { + return targetInfo.GetObjectType() == TARGET_OBJECT_TYPE_UNIT && targetInfo.GetCheckType() == TARGET_CHECK_ALLY; + }; + auto isEnemyTarget = [](SpellImplicitTargetInfo const& targetInfo) + { + return targetInfo.GetObjectType() == TARGET_OBJECT_TYPE_UNIT && targetInfo.GetCheckType() == TARGET_CHECK_ENEMY; + }; + for (SpellEffectInfo const& spellEffectInfo : trapSpell->GetEffects()) + { + if (!spellEffectInfo.IsEffect()) + continue; + + targetsAlly = targetsAlly || isAllyTarget(spellEffectInfo.TargetA) || isAllyTarget(spellEffectInfo.TargetB); + targetsEnemy = targetsEnemy || isEnemyTarget(spellEffectInfo.TargetA) || isEnemyTarget(spellEffectInfo.TargetB); + } + if (targetsAlly) + m_goValue.Trap.TargetSearcherCheckType = targetsEnemy ? TARGET_CHECK_DEFAULT : TARGET_CHECK_ALLY; + } + } break; default: SetGoAnimProgress(animprogress); @@ -651,10 +680,21 @@ void GameObject::Update(uint32 diff) /// @todo this hack with search required until GO casting not implemented if (GetOwner()) { - // Hunter trap: Search units which are unfriendly to the trap's owner - Trinity::NearestAttackableNoTotemUnitInObjectRangeCheck checker(this, radius); - Trinity::UnitLastSearcher<Trinity::NearestAttackableNoTotemUnitInObjectRangeCheck> searcher(this, target, checker); - Cell::VisitAllObjects(this, searcher, radius); + // summoned traps: Search targets fit to trap spell data + if (SpellInfo const* trapSpell = sSpellMgr->GetSpellInfo(goInfo->trap.spellId)) + { + WorldObject* worldObjectTarget = nullptr; + Trinity::WorldObjectSpellNearbyTargetCheck checker(radius, this, trapSpell, m_goValue.Trap.TargetSearcherCheckType, nullptr); + Trinity::WorldObjectLastSearcher searcher(this, worldObjectTarget, checker, GRID_MAP_TYPE_MASK_CREATURE | GRID_MAP_TYPE_MASK_PLAYER); + Cell::VisitAllObjects(this, searcher, radius); + target = Object::ToUnit(worldObjectTarget); + } + else + { + Trinity::NearestAttackableNoTotemUnitInObjectRangeCheck checker(this, radius); + Trinity::UnitLastSearcher<Trinity::NearestAttackableNoTotemUnitInObjectRangeCheck> searcher(this, target, checker); + Cell::VisitAllObjects(this, searcher, radius); + } } else { diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index cd983c6a303..f45682405b2 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -32,10 +32,16 @@ class OPvPCapturePoint; class Transport; class Unit; struct TransportAnimation; +enum SpellTargetCheckTypes : uint8; enum TriggerCastFlags : uint32; union GameObjectValue { + //6 GAMEOBJECT_TYPE_TRAP + struct + { + SpellTargetCheckTypes TargetSearcherCheckType; + } Trap; //11 GAMEOBJECT_TYPE_TRANSPORT struct { |