aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp48
-rw-r--r--src/server/game/Entities/GameObject/GameObject.h6
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
{