Core/GameObjects: Fixed traps not being able to trigger for friendly targets

This commit is contained in:
Shauren authored and Ovahlord committed 2023-07-11 17:24:33 +02:00
1 parent b802fbbbdc
commit 62389bc267
2 files changed
+52 -4

No files matched your search

@@ -748,6 +748,37 @@ bool GameObject::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, P
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))
{
// 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 (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
SpellEffectInfo const& spellEffectInfo = trapSpell->Effects[i];
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);
@@ -999,10 +1030,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.spell))
{
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 = (worldObjectTarget && worldObjectTarget->IsUnit()) ? worldObjectTarget->ToUnit() : nullptr;
}
else
{
Trinity::NearestAttackableNoTotemUnitInObjectRangeCheck checker(this, radius);
Trinity::UnitLastSearcher<Trinity::NearestAttackableNoTotemUnitInObjectRangeCheck> searcher(this, target, checker);
Cell::VisitAllObjects(this, searcher, radius);
}
}
else
{