From 36bd2df79210e44735d0364776ce0c28249acaa0 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 28 May 2023 16:07:34 +0200 Subject: Core/Objects: Unify WorldObjectSearcher classes into one common implementation (cherry picked from commit 261eb201bf107cef441d9b075e8f23bf0edfbaf0) --- src/server/game/Grids/Notifiers/GridNotifiers.h | 137 +++++++----- .../game/Grids/Notifiers/GridNotifiersImpl.h | 246 +-------------------- src/server/game/Spells/Spell.cpp | 7 +- 3 files changed, 99 insertions(+), 291 deletions(-) (limited to 'src/server/game') 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 + struct GridMapTypeMaskForType : std::integral_constant { }; + + template<> struct GridMapTypeMaskForType : std::integral_constant { }; + template<> struct GridMapTypeMaskForType : std::integral_constant { }; + template<> struct GridMapTypeMaskForType : std::integral_constant { }; + template<> struct GridMapTypeMaskForType : std::integral_constant { }; + template<> struct GridMapTypeMaskForType : std::integral_constant { }; + 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 + 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 + 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 - class ContainerInserter + class SearcherContainerResult { using InserterType = void(*)(void*, Type&&); @@ -203,7 +255,7 @@ namespace Trinity protected: template - 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 - struct WorldObjectSearcher + template + 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 + 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 void Visit(GridRefManager &) { } + template + void Visit(GridRefManager&); }; template - struct WorldObjectLastSearcher + struct WorldObjectSearcher : WorldObjectSearcherBase> { - 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>(searcher, result, check, mapTypeMask) { } + }; + template + struct WorldObjectLastSearcher : WorldObjectSearcherBase> + { 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 void Visit(GridRefManager &) { } + : WorldObjectSearcherBase>(searcher, result, check, mapTypeMask) { } }; template - struct WorldObjectListSearcher : ContainerInserter + struct WorldObjectListSearcher : WorldObjectSearcherBase> { - uint32 i_mapTypeMask; - uint32 i_phaseMask; - Check& i_check; - template WorldObjectListSearcher(WorldObject const* searcher, Container& container, Check & check, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL) - : ContainerInserter(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 void Visit(GridRefManager &) { } + : WorldObjectSearcherBase>(searcher, container, check, mapTypeMask) { } }; template @@ -370,14 +403,14 @@ namespace Trinity }; template - struct GameObjectListSearcher : ContainerInserter + struct GameObjectListSearcher : SearcherContainerResult { uint32 i_phaseMask; Check& i_check; template GameObjectListSearcher(WorldObject const* searcher, Container& container, Check & check) - : ContainerInserter(container), + : SearcherContainerResult(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 - struct UnitListSearcher : ContainerInserter + struct UnitListSearcher : SearcherContainerResult { uint32 i_phaseMask; Check& i_check; template UnitListSearcher(WorldObject const* searcher, Container& container, Check& check) - : ContainerInserter(container), + : SearcherContainerResult(container), i_phaseMask(searcher->GetPhaseMask()), i_check(check) { } void Visit(PlayerMapType &m); @@ -493,14 +526,14 @@ namespace Trinity }; template - struct CreatureListSearcher : ContainerInserter + struct CreatureListSearcher : SearcherContainerResult { uint32 i_phaseMask; Check& i_check; template CreatureListSearcher(WorldObject const* searcher, Container& container, Check & check) - : ContainerInserter(container), + : SearcherContainerResult(container), i_phaseMask(searcher->GetPhaseMask()), i_check(check) { } void Visit(CreatureMapType &m); @@ -545,19 +578,19 @@ namespace Trinity }; template - struct PlayerListSearcher : ContainerInserter + struct PlayerListSearcher : SearcherContainerResult { uint32 i_phaseMask; Check& i_check; template PlayerListSearcher(WorldObject const* searcher, Container& container, Check & check) - : ContainerInserter(container), + : SearcherContainerResult(container), i_phaseMask(searcher->GetPhaseMask()), i_check(check) { } template PlayerListSearcher(uint32 phaseMask, Container& container, Check & check) - : ContainerInserter(container), + : SearcherContainerResult(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 &m) // WorldObject searchers & workers -template -void Trinity::WorldObjectSearcher::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 -void Trinity::WorldObjectSearcher::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 -void Trinity::WorldObjectSearcher::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 -void Trinity::WorldObjectSearcher::Visit(CorpseMapType &m) +template +template +void Trinity::WorldObjectSearcherBase::Visit(GridRefManager& m) { - if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CORPSE)) + if (!(i_mapTypeMask & GridMapTypeMaskForType::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 -void Trinity::WorldObjectSearcher::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 -void Trinity::WorldObjectLastSearcher::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 -void Trinity::WorldObjectLastSearcher::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 -void Trinity::WorldObjectLastSearcher::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 -void Trinity::WorldObjectLastSearcher::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 -void Trinity::WorldObjectLastSearcher::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 -void Trinity::WorldObjectListSearcher::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 -void Trinity::WorldObjectListSearcher::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 -void Trinity::WorldObjectListSearcher::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 -void Trinity::WorldObjectListSearcher::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 -void Trinity::WorldObjectListSearcher::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 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 searcher(m_caster, target, check, containerTypeMask); - SearchTargets > (searcher, containerTypeMask, m_caster, m_caster, range); + searcher.i_phaseMask = PHASEMASK_ANYWHERE; + SearchTargets>(searcher, containerTypeMask, m_caster, m_caster, range); return target; } @@ -1906,7 +1908,8 @@ void Spell::SearchAreaTargets(std::list& 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 searcher(m_caster, targets, check, containerTypeMask); - SearchTargets > (searcher, containerTypeMask, m_caster, position, range + extraSearchRadius); + searcher.i_phaseMask = PHASEMASK_ANYWHERE; + SearchTargets>(searcher, containerTypeMask, m_caster, position, range + extraSearchRadius); } void Spell::SearchChainTargets(std::list& targets, uint32 chainTargets, WorldObject* target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, ConditionContainer* condList, bool isChainHeal) -- cgit v1.2.3