mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-20 01:15:35 +01:00
Core/AreaTriggers: Optimize target searching
* Don't visit grid objects for serverside areatriggers (search world container only for player) * Move existing target list to "exitUnits" instead of copying it
This commit is contained in:
@@ -329,7 +329,7 @@ float AreaTrigger::GetProgress() const
|
||||
|
||||
void AreaTrigger::UpdateTargetList()
|
||||
{
|
||||
std::list<Unit*> targetList;
|
||||
std::vector<Unit*> targetList;
|
||||
|
||||
switch (GetTemplate()->Type)
|
||||
{
|
||||
@@ -352,7 +352,22 @@ void AreaTrigger::UpdateTargetList()
|
||||
HandleUnitEnterExit(targetList);
|
||||
}
|
||||
|
||||
void AreaTrigger::SearchUnitInSphere(std::list<Unit*>& targetList)
|
||||
void AreaTrigger::SearchUnits(std::vector<Unit*>& targetList, float radius, bool check3D)
|
||||
{
|
||||
Trinity::AnyUnitInObjectRangeCheck check(this, radius, check3D);
|
||||
if (IsServerSide())
|
||||
{
|
||||
Trinity::PlayerListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(this, targetList, check);
|
||||
Cell::VisitWorldObjects(this, searcher, GetTemplate()->MaxSearchRadius);
|
||||
}
|
||||
else
|
||||
{
|
||||
Trinity::UnitListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(this, targetList, check);
|
||||
Cell::VisitAllObjects(this, searcher, GetTemplate()->MaxSearchRadius);
|
||||
}
|
||||
}
|
||||
|
||||
void AreaTrigger::SearchUnitInSphere(std::vector<Unit*>& targetList)
|
||||
{
|
||||
float radius = GetTemplate()->SphereDatas.Radius;
|
||||
if (GetTemplate()->HasFlag(AREATRIGGER_FLAG_HAS_DYNAMIC_SHAPE))
|
||||
@@ -365,20 +380,16 @@ void AreaTrigger::SearchUnitInSphere(std::list<Unit*>& targetList)
|
||||
}
|
||||
}
|
||||
|
||||
Trinity::AnyUnitInObjectRangeCheck check(this, radius);
|
||||
Trinity::UnitListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(this, targetList, check);
|
||||
Cell::VisitAllObjects(this, searcher, GetTemplate()->MaxSearchRadius);
|
||||
SearchUnits(targetList, radius, true);
|
||||
}
|
||||
|
||||
void AreaTrigger::SearchUnitInBox(std::list<Unit*>& targetList)
|
||||
void AreaTrigger::SearchUnitInBox(std::vector<Unit*>& targetList)
|
||||
{
|
||||
float extentsX = GetTemplate()->BoxDatas.Extents[0];
|
||||
float extentsY = GetTemplate()->BoxDatas.Extents[1];
|
||||
float extentsZ = GetTemplate()->BoxDatas.Extents[2];
|
||||
|
||||
Trinity::AnyUnitInObjectRangeCheck check(this, GetTemplate()->MaxSearchRadius, false);
|
||||
Trinity::UnitListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(this, targetList, check);
|
||||
Cell::VisitAllObjects(this, searcher, GetTemplate()->MaxSearchRadius);
|
||||
SearchUnits(targetList, GetTemplate()->MaxSearchRadius, false);
|
||||
|
||||
float halfExtentsX = extentsX / 2.0f;
|
||||
float halfExtentsY = extentsY / 2.0f;
|
||||
@@ -395,51 +406,46 @@ void AreaTrigger::SearchUnitInBox(std::list<Unit*>& targetList)
|
||||
|
||||
G3D::AABox const box({ minX, minY, minZ }, { maxX, maxY, maxZ });
|
||||
|
||||
targetList.remove_if([&box](Unit* unit) -> bool
|
||||
targetList.erase(std::remove_if(targetList.begin(), targetList.end(), [&box](Unit* unit) -> bool
|
||||
{
|
||||
return !box.contains({ unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ() });
|
||||
});
|
||||
}), targetList.end());
|
||||
}
|
||||
|
||||
void AreaTrigger::SearchUnitInPolygon(std::list<Unit*>& targetList)
|
||||
void AreaTrigger::SearchUnitInPolygon(std::vector<Unit*>& targetList)
|
||||
{
|
||||
Trinity::AnyUnitInObjectRangeCheck check(this, GetTemplate()->MaxSearchRadius, false);
|
||||
Trinity::UnitListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(this, targetList, check);
|
||||
Cell::VisitAllObjects(this, searcher, GetTemplate()->MaxSearchRadius);
|
||||
SearchUnits(targetList, GetTemplate()->MaxSearchRadius, false);
|
||||
|
||||
float height = GetTemplate()->PolygonDatas.Height;
|
||||
float minZ = GetPositionZ() - height;
|
||||
float maxZ = GetPositionZ() + height;
|
||||
|
||||
targetList.remove_if([this, minZ, maxZ](Unit* unit) -> bool
|
||||
targetList.erase(std::remove_if(targetList.begin(), targetList.end(), [this, minZ, maxZ](Unit* unit) -> bool
|
||||
{
|
||||
return !CheckIsInPolygon2D(unit)
|
||||
|| unit->GetPositionZ() < minZ
|
||||
|| unit->GetPositionZ() > maxZ;
|
||||
});
|
||||
}), targetList.end());
|
||||
}
|
||||
|
||||
void AreaTrigger::SearchUnitInCylinder(std::list<Unit*>& targetList)
|
||||
void AreaTrigger::SearchUnitInCylinder(std::vector<Unit*>& targetList)
|
||||
{
|
||||
Trinity::AnyUnitInObjectRangeCheck check(this, GetTemplate()->MaxSearchRadius, false);
|
||||
Trinity::UnitListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(this, targetList, check);
|
||||
Cell::VisitAllObjects(this, searcher, GetTemplate()->MaxSearchRadius);
|
||||
SearchUnits(targetList, GetTemplate()->MaxSearchRadius, false);
|
||||
|
||||
float height = GetTemplate()->CylinderDatas.Height;
|
||||
float minZ = GetPositionZ() - height;
|
||||
float maxZ = GetPositionZ() + height;
|
||||
|
||||
targetList.remove_if([minZ, maxZ](Unit* unit) -> bool
|
||||
targetList.erase(std::remove_if(targetList.begin(), targetList.end(), [minZ, maxZ](Unit* unit) -> bool
|
||||
{
|
||||
return unit->GetPositionZ() < minZ
|
||||
|| unit->GetPositionZ() > maxZ;
|
||||
});
|
||||
}), targetList.end());
|
||||
}
|
||||
|
||||
void AreaTrigger::HandleUnitEnterExit(std::list<Unit*> const& newTargetList)
|
||||
void AreaTrigger::HandleUnitEnterExit(std::vector<Unit*> const& newTargetList)
|
||||
{
|
||||
GuidUnorderedSet exitUnits = _insideUnits;
|
||||
_insideUnits.clear();
|
||||
GuidUnorderedSet exitUnits(std::move(_insideUnits));
|
||||
|
||||
std::vector<Unit*> enteringUnits;
|
||||
|
||||
|
||||
@@ -118,12 +118,13 @@ class TC_GAME_API AreaTrigger : public WorldObject, public GridObject<AreaTrigge
|
||||
float GetProgress() const;
|
||||
|
||||
void UpdateTargetList();
|
||||
void SearchUnitInSphere(std::list<Unit*>& targetList);
|
||||
void SearchUnitInBox(std::list<Unit*>& targetList);
|
||||
void SearchUnitInPolygon(std::list<Unit*>& targetList);
|
||||
void SearchUnitInCylinder(std::list<Unit*>& targetList);
|
||||
void SearchUnits(std::vector<Unit*>& targetList, float radius, bool check3D);
|
||||
void SearchUnitInSphere(std::vector<Unit*>& targetList);
|
||||
void SearchUnitInBox(std::vector<Unit*>& targetList);
|
||||
void SearchUnitInPolygon(std::vector<Unit*>& targetList);
|
||||
void SearchUnitInCylinder(std::vector<Unit*>& targetList);
|
||||
bool CheckIsInPolygon2D(Position const* pos) const;
|
||||
void HandleUnitEnterExit(std::list<Unit*> const& targetList);
|
||||
void HandleUnitEnterExit(std::vector<Unit*> const& targetList);
|
||||
|
||||
void DoActions(Unit* unit);
|
||||
void UndoActions(Unit* unit);
|
||||
|
||||
Reference in New Issue
Block a user