diff options
author | Shauren <shauren.trinity@gmail.com> | 2023-05-28 16:07:34 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2024-10-05 17:34:06 +0200 |
commit | 36bd2df79210e44735d0364776ce0c28249acaa0 (patch) | |
tree | de697f3f9f6170632da2121df98d6c0b372af1a8 | |
parent | b10823fe31313fd93a08b2cde249823ed16f8534 (diff) |
Core/Objects: Unify WorldObjectSearcher classes into one common implementation
(cherry picked from commit 261eb201bf107cef441d9b075e8f23bf0edfbaf0)
-rw-r--r-- | src/server/game/Grids/Notifiers/GridNotifiers.h | 137 | ||||
-rw-r--r-- | src/server/game/Grids/Notifiers/GridNotifiersImpl.h | 246 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 7 |
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) |