Core/GameObjects: Fixed traps not being able to trigger for friendly targets
Closes #27210 Closes #28945 (cherry picked from commit 3993c45a040c01a6708850adfb014489b0e0ed8d)
This commit is contained in:
@@ -1130,6 +1130,35 @@ bool GameObject::Create(uint32 entry, Map* map, Position const& pos, QuaternionD
|
||||
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.spell, map->GetDifficultyID()))
|
||||
{
|
||||
// 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;
|
||||
case GAMEOBJECT_TYPE_CONTROL_ZONE:
|
||||
m_goTypeImpl = std::make_unique<GameObjectType::ControlZone>(*this);
|
||||
@@ -1472,10 +1501,21 @@ void GameObject::Update(uint32 diff)
|
||||
|
||||
if (GetOwner() || goInfo->trap.Checkallunits)
|
||||
{
|
||||
// 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.spell, GetMap()->GetDifficultyID()))
|
||||
{
|
||||
WorldObject* worldObjectTarget = nullptr;
|
||||
Trinity::WorldObjectSpellNearbyTargetCheck checker(radius, this, trapSpell, m_goValue.Trap.TargetSearcherCheckType, nullptr, TARGET_OBJECT_TYPE_UNIT);
|
||||
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
|
||||
{
|
||||
|
||||
@@ -33,6 +33,7 @@ class TransportBase;
|
||||
class Unit;
|
||||
struct Loot;
|
||||
struct TransportAnimation;
|
||||
enum SpellTargetCheckTypes : uint8;
|
||||
enum TriggerCastFlags : uint32;
|
||||
|
||||
namespace Vignettes
|
||||
@@ -122,6 +123,11 @@ private:
|
||||
|
||||
union GameObjectValue
|
||||
{
|
||||
//6 GAMEOBJECT_TYPE_TRAP
|
||||
struct
|
||||
{
|
||||
SpellTargetCheckTypes TargetSearcherCheckType;
|
||||
} Trap;
|
||||
//25 GAMEOBJECT_TYPE_FISHINGHOLE
|
||||
struct
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user