aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2023-05-28 16:07:34 +0200
committerShauren <shauren.trinity@gmail.com>2024-10-05 17:34:06 +0200
commit36bd2df79210e44735d0364776ce0c28249acaa0 (patch)
treede697f3f9f6170632da2121df98d6c0b372af1a8
parentb10823fe31313fd93a08b2cde249823ed16f8534 (diff)
Core/Objects: Unify WorldObjectSearcher classes into one common implementation
(cherry picked from commit 261eb201bf107cef441d9b075e8f23bf0edfbaf0)
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiers.h137
-rw-r--r--src/server/game/Grids/Notifiers/GridNotifiersImpl.h246
-rw-r--r--src/server/game/Spells/Spell.cpp7
3 files changed, 99 insertions, 291 deletions
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h
index dc15625261c..faf245e578b 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -32,6 +32,15 @@
namespace Trinity
{
+ template<typename ObjectType>
+ struct GridMapTypeMaskForType : std::integral_constant<GridMapTypeMask, GridMapTypeMask(0)> { };
+
+ template<> struct GridMapTypeMaskForType<Corpse> : std::integral_constant<GridMapTypeMask, GRID_MAP_TYPE_MASK_CORPSE> { };
+ template<> struct GridMapTypeMaskForType<Creature> : std::integral_constant<GridMapTypeMask, GRID_MAP_TYPE_MASK_CREATURE> { };
+ template<> struct GridMapTypeMaskForType<DynamicObject> : std::integral_constant<GridMapTypeMask, GRID_MAP_TYPE_MASK_DYNAMICOBJECT> { };
+ template<> struct GridMapTypeMaskForType<GameObject> : std::integral_constant<GridMapTypeMask, GRID_MAP_TYPE_MASK_GAMEOBJECT> { };
+ template<> struct GridMapTypeMaskForType<Player> : std::integral_constant<GridMapTypeMask, GRID_MAP_TYPE_MASK_PLAYER> { };
+
struct TC_GAME_API VisibleNotifier
{
Player &i_player;
@@ -191,10 +200,53 @@ namespace Trinity
// SEARCHERS & LIST SEARCHERS & WORKERS
// WorldObject searchers & workers
+ enum class WorldObjectSearcherContinuation
+ {
+ Continue,
+ Return
+ };
+
+ template<typename Type>
+ class SearcherFirstObjectResult
+ {
+ Type& result;
+
+ protected:
+ explicit SearcherFirstObjectResult(Type& ref_) : result(ref_) { }
+
+ WorldObjectSearcherContinuation ShouldContinue() const
+ {
+ return result ? WorldObjectSearcherContinuation::Return : WorldObjectSearcherContinuation::Continue;
+ }
+
+ void Insert(Type object)
+ {
+ result = object;
+ }
+ };
+
+ template<typename Type>
+ class SearcherLastObjectResult
+ {
+ Type& result;
+
+ protected:
+ explicit SearcherLastObjectResult(Type& ref_) : result(ref_) { }
+
+ WorldObjectSearcherContinuation ShouldContinue() const
+ {
+ return WorldObjectSearcherContinuation::Continue;
+ }
+
+ void Insert(Type object)
+ {
+ result = object;
+ }
+ };
// Generic base class to insert elements into arbitrary containers using push_back
template<typename Type>
- class ContainerInserter
+ class SearcherContainerResult
{
using InserterType = void(*)(void*, Type&&);
@@ -203,7 +255,7 @@ namespace Trinity
protected:
template<typename T>
- ContainerInserter(T& ref_) : ref(&ref_)
+ explicit SearcherContainerResult(T& ref_) : ref(&ref_)
{
inserter = [](void* containerRaw, Type&& object)
{
@@ -212,71 +264,52 @@ namespace Trinity
};
}
+ WorldObjectSearcherContinuation ShouldContinue() const
+ {
+ return WorldObjectSearcherContinuation::Continue;
+ }
+
void Insert(Type object)
{
inserter(ref, std::move(object));
}
};
- template<class Check>
- struct WorldObjectSearcher
+ template<class Check, class Result>
+ struct WorldObjectSearcherBase : Result
{
uint32 i_mapTypeMask;
uint32 i_phaseMask;
- WorldObject* &i_object;
Check &i_check;
- WorldObjectSearcher(WorldObject const* searcher, WorldObject* & result, Check& check, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL)
- : i_mapTypeMask(mapTypeMask), i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) { }
-
- void Visit(GameObjectMapType &m);
- void Visit(PlayerMapType &m);
- void Visit(CreatureMapType &m);
- void Visit(CorpseMapType &m);
- void Visit(DynamicObjectMapType &m);
+ template<typename Container>
+ WorldObjectSearcherBase(WorldObject const* searcher, Container& result, Check& check, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL)
+ : Result(result), i_mapTypeMask(mapTypeMask), i_phaseMask(searcher->GetPhaseMask()), i_check(check) { }
- template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) { }
+ template<class T>
+ void Visit(GridRefManager<T>&);
};
template<class Check>
- struct WorldObjectLastSearcher
+ struct WorldObjectSearcher : WorldObjectSearcherBase<Check, SearcherFirstObjectResult<WorldObject*>>
{
- uint32 i_mapTypeMask;
- uint32 i_phaseMask;
- WorldObject* &i_object;
- Check &i_check;
+ WorldObjectSearcher(WorldObject const* searcher, WorldObject*& result, Check& check, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL)
+ : WorldObjectSearcherBase<Check, SearcherFirstObjectResult<WorldObject*>>(searcher, result, check, mapTypeMask) { }
+ };
+ template<class Check>
+ struct WorldObjectLastSearcher : WorldObjectSearcherBase<Check, SearcherLastObjectResult<WorldObject*>>
+ {
WorldObjectLastSearcher(WorldObject const* searcher, WorldObject* & result, Check& check, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL)
- : i_mapTypeMask(mapTypeMask), i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) { }
-
- void Visit(GameObjectMapType &m);
- void Visit(PlayerMapType &m);
- void Visit(CreatureMapType &m);
- void Visit(CorpseMapType &m);
- void Visit(DynamicObjectMapType &m);
-
- template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) { }
+ : WorldObjectSearcherBase<Check, SearcherLastObjectResult<WorldObject*>>(searcher, result, check, mapTypeMask) { }
};
template<class Check>
- struct WorldObjectListSearcher : ContainerInserter<WorldObject*>
+ struct WorldObjectListSearcher : WorldObjectSearcherBase<Check, SearcherContainerResult<WorldObject*>>
{
- uint32 i_mapTypeMask;
- uint32 i_phaseMask;
- Check& i_check;
-
template<typename Container>
WorldObjectListSearcher(WorldObject const* searcher, Container& container, Check & check, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL)
- : ContainerInserter<WorldObject*>(container),
- i_mapTypeMask(mapTypeMask), i_phaseMask(searcher->GetPhaseMask()), i_check(check) { }
-
- void Visit(PlayerMapType &m);
- void Visit(CreatureMapType &m);
- void Visit(CorpseMapType &m);
- void Visit(GameObjectMapType &m);
- void Visit(DynamicObjectMapType &m);
-
- template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) { }
+ : WorldObjectSearcherBase<Check, SearcherContainerResult<WorldObject*>>(searcher, container, check, mapTypeMask) { }
};
template<class Do>
@@ -370,14 +403,14 @@ namespace Trinity
};
template<class Check>
- struct GameObjectListSearcher : ContainerInserter<GameObject*>
+ struct GameObjectListSearcher : SearcherContainerResult<GameObject*>
{
uint32 i_phaseMask;
Check& i_check;
template<typename Container>
GameObjectListSearcher(WorldObject const* searcher, Container& container, Check & check)
- : ContainerInserter<GameObject*>(container),
+ : SearcherContainerResult<GameObject*>(container),
i_phaseMask(searcher->GetPhaseMask()), i_check(check) { }
void Visit(GameObjectMapType &m);
@@ -443,14 +476,14 @@ namespace Trinity
// All accepted by Check units if any
template<class Check>
- struct UnitListSearcher : ContainerInserter<Unit*>
+ struct UnitListSearcher : SearcherContainerResult<Unit*>
{
uint32 i_phaseMask;
Check& i_check;
template<typename Container>
UnitListSearcher(WorldObject const* searcher, Container& container, Check& check)
- : ContainerInserter<Unit*>(container),
+ : SearcherContainerResult<Unit*>(container),
i_phaseMask(searcher->GetPhaseMask()), i_check(check) { }
void Visit(PlayerMapType &m);
@@ -493,14 +526,14 @@ namespace Trinity
};
template<class Check>
- struct CreatureListSearcher : ContainerInserter<Creature*>
+ struct CreatureListSearcher : SearcherContainerResult<Creature*>
{
uint32 i_phaseMask;
Check& i_check;
template<typename Container>
CreatureListSearcher(WorldObject const* searcher, Container& container, Check & check)
- : ContainerInserter<Creature*>(container),
+ : SearcherContainerResult<Creature*>(container),
i_phaseMask(searcher->GetPhaseMask()), i_check(check) { }
void Visit(CreatureMapType &m);
@@ -545,19 +578,19 @@ namespace Trinity
};
template<class Check>
- struct PlayerListSearcher : ContainerInserter<Player*>
+ struct PlayerListSearcher : SearcherContainerResult<Player*>
{
uint32 i_phaseMask;
Check& i_check;
template<typename Container>
PlayerListSearcher(WorldObject const* searcher, Container& container, Check & check)
- : ContainerInserter<Player*>(container),
+ : SearcherContainerResult<Player*>(container),
i_phaseMask(searcher->GetPhaseMask()), i_check(check) { }
template<typename Container>
PlayerListSearcher(uint32 phaseMask, Container& container, Check & check)
- : ContainerInserter<Player*>(container),
+ : SearcherContainerResult<Player*>(container),
i_phaseMask(phaseMask), i_check(check) { }
void Visit(PlayerMapType &m);
diff --git a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h
index 5c2d958ed2c..bb417726403 100644
--- a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h
@@ -41,256 +41,28 @@ inline void Trinity::VisibleNotifier::Visit(GridRefManager<T> &m)
// WorldObject searchers & workers
-template<class Check>
-void Trinity::WorldObjectSearcher<Check>::Visit(GameObjectMapType &m)
-{
- if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_GAMEOBJECT))
- return;
-
- // already found
- if (i_object)
- return;
-
- for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- {
- if (!itr->GetSource()->InSamePhase(i_phaseMask))
- continue;
-
- if (i_check(itr->GetSource()))
- {
- i_object = itr->GetSource();
- return;
- }
- }
-}
-
-template<class Check>
-void Trinity::WorldObjectSearcher<Check>::Visit(PlayerMapType &m)
-{
- if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_PLAYER))
- return;
-
- // already found
- if (i_object)
- return;
-
- for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- {
- if (!itr->GetSource()->InSamePhase(i_phaseMask))
- continue;
-
- if (i_check(itr->GetSource()))
- {
- i_object = itr->GetSource();
- return;
- }
- }
-}
-
-template<class Check>
-void Trinity::WorldObjectSearcher<Check>::Visit(CreatureMapType &m)
-{
- if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CREATURE))
- return;
-
- // already found
- if (i_object)
- return;
-
- for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- {
- if (!itr->GetSource()->InSamePhase(i_phaseMask))
- continue;
-
- if (i_check(itr->GetSource()))
- {
- i_object = itr->GetSource();
- return;
- }
- }
-}
-
-template<class Check>
-void Trinity::WorldObjectSearcher<Check>::Visit(CorpseMapType &m)
+template <class Check, class Result>
+template <class T>
+void Trinity::WorldObjectSearcherBase<Check, Result>::Visit(GridRefManager<T>& m)
{
- if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CORPSE))
+ if (!(i_mapTypeMask & GridMapTypeMaskForType<T>::value))
return;
- // already found
- if (i_object)
+ if (this->ShouldContinue() == WorldObjectSearcherContinuation::Return)
return;
- for (CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
+ for (auto itr = m.begin(); itr != m.end(); ++itr)
{
- if (!itr->GetSource()->InSamePhase(i_phaseMask))
- continue;
-
if (i_check(itr->GetSource()))
{
- i_object = itr->GetSource();
- return;
- }
- }
-}
+ this->Insert(itr->GetSource());
-template<class Check>
-void Trinity::WorldObjectSearcher<Check>::Visit(DynamicObjectMapType &m)
-{
- if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_DYNAMICOBJECT))
- return;
-
- // already found
- if (i_object)
- return;
-
- for (DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- {
- if (!itr->GetSource()->InSamePhase(i_phaseMask))
- continue;
-
- if (i_check(itr->GetSource()))
- {
- i_object = itr->GetSource();
- return;
+ if (this->ShouldContinue() == WorldObjectSearcherContinuation::Return)
+ return;
}
}
}
-template<class Check>
-void Trinity::WorldObjectLastSearcher<Check>::Visit(GameObjectMapType &m)
-{
- if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_GAMEOBJECT))
- return;
-
- for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- {
- if (!itr->GetSource()->InSamePhase(i_phaseMask))
- continue;
-
- if (i_check(itr->GetSource()))
- i_object = itr->GetSource();
- }
-}
-
-template<class Check>
-void Trinity::WorldObjectLastSearcher<Check>::Visit(PlayerMapType &m)
-{
- if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_PLAYER))
- return;
-
- for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- {
- if (!itr->GetSource()->InSamePhase(i_phaseMask))
- continue;
-
- if (i_check(itr->GetSource()))
- i_object = itr->GetSource();
- }
-}
-
-template<class Check>
-void Trinity::WorldObjectLastSearcher<Check>::Visit(CreatureMapType &m)
-{
- if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CREATURE))
- return;
-
- for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- {
- if (!itr->GetSource()->InSamePhase(i_phaseMask))
- continue;
-
- if (i_check(itr->GetSource()))
- i_object = itr->GetSource();
- }
-}
-
-template<class Check>
-void Trinity::WorldObjectLastSearcher<Check>::Visit(CorpseMapType &m)
-{
- if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CORPSE))
- return;
-
- for (CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- {
- if (!itr->GetSource()->InSamePhase(i_phaseMask))
- continue;
-
- if (i_check(itr->GetSource()))
- i_object = itr->GetSource();
- }
-}
-
-template<class Check>
-void Trinity::WorldObjectLastSearcher<Check>::Visit(DynamicObjectMapType &m)
-{
- if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_DYNAMICOBJECT))
- return;
-
- for (DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- {
- if (!itr->GetSource()->InSamePhase(i_phaseMask))
- continue;
-
- if (i_check(itr->GetSource()))
- i_object = itr->GetSource();
- }
-}
-
-template<class Check>
-void Trinity::WorldObjectListSearcher<Check>::Visit(PlayerMapType &m)
-{
- if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_PLAYER))
- return;
-
- for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if (i_check(itr->GetSource()))
- Insert(itr->GetSource());
-}
-
-template<class Check>
-void Trinity::WorldObjectListSearcher<Check>::Visit(CreatureMapType &m)
-{
- if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CREATURE))
- return;
-
- for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if (i_check(itr->GetSource()))
- Insert(itr->GetSource());
-}
-
-template<class Check>
-void Trinity::WorldObjectListSearcher<Check>::Visit(CorpseMapType &m)
-{
- if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CORPSE))
- return;
-
- for (CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if (i_check(itr->GetSource()))
- Insert(itr->GetSource());
-}
-
-template<class Check>
-void Trinity::WorldObjectListSearcher<Check>::Visit(GameObjectMapType &m)
-{
- if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_GAMEOBJECT))
- return;
-
- for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if (i_check(itr->GetSource()))
- Insert(itr->GetSource());
-}
-
-template<class Check>
-void Trinity::WorldObjectListSearcher<Check>::Visit(DynamicObjectMapType &m)
-{
- if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_DYNAMICOBJECT))
- return;
-
- for (DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- if (i_check(itr->GetSource()))
- Insert(itr->GetSource());
-}
-
// Gameobject searchers
template<class Check>
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index e4a923f51f3..c5fe2d9dfd2 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -1891,9 +1891,11 @@ WorldObject* Spell::SearchNearbyTarget(float range, SpellTargetObjectTypes objec
uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
if (!containerTypeMask)
return nullptr;
+
Trinity::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
Trinity::WorldObjectLastSearcher<Trinity::WorldObjectSpellNearbyTargetCheck> searcher(m_caster, target, check, containerTypeMask);
- SearchTargets<Trinity::WorldObjectLastSearcher<Trinity::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
+ searcher.i_phaseMask = PHASEMASK_ANYWHERE;
+ SearchTargets<Trinity::WorldObjectLastSearcher<Trinity::WorldObjectSpellNearbyTargetCheck>>(searcher, containerTypeMask, m_caster, m_caster, range);
return target;
}
@@ -1906,7 +1908,8 @@ void Spell::SearchAreaTargets(std::list<WorldObject*>& targets, float range, Pos
float extraSearchRadius = range > 0.0f ? EXTRA_CELL_SEARCH_RADIUS : 0.0f;
Trinity::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList);
Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
- SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range + extraSearchRadius);
+ searcher.i_phaseMask = PHASEMASK_ANYWHERE;
+ SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellAreaTargetCheck>>(searcher, containerTypeMask, m_caster, position, range + extraSearchRadius);
}
void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTargets, WorldObject* target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, ConditionContainer* condList, bool isChainHeal)