fix(Core/Spells): Hunter traps should not be activated by targets not… (#11971)
fix(Core/Spells): Hunter traps should not be activated by targets not in LoS. Fixes #11432
This commit is contained in:
@@ -701,8 +701,8 @@ void GameObject::Update(uint32 diff)
|
|||||||
// search unfriendly creature
|
// search unfriendly creature
|
||||||
if (owner && goInfo->trap.autoCloseTime != -1) // hunter trap
|
if (owner && goInfo->trap.autoCloseTime != -1) // hunter trap
|
||||||
{
|
{
|
||||||
Acore::AnyUnfriendlyNoTotemUnitInObjectRangeCheck checker(this, owner, radius);
|
Acore::NearestAttackableNoTotemUnitInObjectRangeCheck checker(this, owner, radius);
|
||||||
Acore::UnitSearcher<Acore::AnyUnfriendlyNoTotemUnitInObjectRangeCheck> searcher(this, target, checker);
|
Acore::UnitSearcher<Acore::NearestAttackableNoTotemUnitInObjectRangeCheck> searcher(this, target, checker);
|
||||||
Cell::VisitAllObjects(this, searcher, radius);
|
Cell::VisitAllObjects(this, searcher, radius);
|
||||||
}
|
}
|
||||||
else // environmental trap
|
else // environmental trap
|
||||||
|
|||||||
@@ -898,6 +898,47 @@ namespace Acore
|
|||||||
float i_range;
|
float i_range;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class NearestAttackableNoTotemUnitInObjectRangeCheck
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NearestAttackableNoTotemUnitInObjectRangeCheck(WorldObject const* obj, Unit const* owner, float range) : i_obj(obj), i_owner(owner), i_range(range) {}
|
||||||
|
|
||||||
|
bool operator()(Unit* u)
|
||||||
|
{
|
||||||
|
if (!u->IsAlive())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u->GetCreatureType() == CREATURE_TYPE_NON_COMBAT_PET)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (u->GetTypeId() == TYPEID_UNIT && u->ToCreature()->IsTotem())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!u->isTargetableForAttack(false, i_owner))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!i_obj->IsWithinDistInMap(u, i_range) || !i_owner->IsValidAttackTarget(u) || !i_obj->IsWithinLOSInMap(u))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
WorldObject const* i_obj;
|
||||||
|
Unit const* i_owner;
|
||||||
|
float i_range;
|
||||||
|
};
|
||||||
|
|
||||||
class AnyUnfriendlyAttackableVisibleUnitInObjectRangeCheck
|
class AnyUnfriendlyAttackableVisibleUnitInObjectRangeCheck
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -5892,31 +5892,27 @@ SpellCastResult Spell::CheckCast(bool strict)
|
|||||||
if ((!m_caster->IsTotem() || !m_spellInfo->IsPositive()) && !m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) &&
|
if ((!m_caster->IsTotem() || !m_spellInfo->IsPositive()) && !m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) &&
|
||||||
!m_spellInfo->HasAttribute(SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT))
|
!m_spellInfo->HasAttribute(SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT))
|
||||||
{
|
{
|
||||||
WorldObject* losCenter = nullptr;
|
bool castedByGameobject = false;
|
||||||
uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
|
uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
|
||||||
if (m_originalCasterGUID.IsGameObject())
|
if (m_originalCasterGUID.IsGameObject())
|
||||||
{
|
{
|
||||||
losCenter = m_caster->GetMap()->GetGameObject(m_originalCasterGUID);
|
castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
|
||||||
}
|
}
|
||||||
else if (m_caster->GetEntry() == WORLD_TRIGGER)
|
else if (m_caster->GetEntry() == WORLD_TRIGGER)
|
||||||
{
|
{
|
||||||
if (TempSummon* tempSummon = m_caster->ToTempSummon())
|
if (TempSummon* tempSummon = m_caster->ToTempSummon())
|
||||||
{
|
{
|
||||||
losCenter = tempSummon->GetSummonerGameObject();
|
castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (losCenter)
|
if (castedByGameobject)
|
||||||
{
|
{
|
||||||
// If spell casted by gameobject then ignore M2 models
|
// If spell casted by gameobject then ignore M2 models
|
||||||
losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
|
losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
losCenter = m_caster;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!losCenter->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks((losChecks))))
|
if (!m_caster->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks((losChecks))))
|
||||||
{
|
{
|
||||||
return SPELL_FAILED_LINE_OF_SIGHT;
|
return SPELL_FAILED_LINE_OF_SIGHT;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user