diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index f9296b908b7..8ef47641635 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -621,6 +621,46 @@ namespace Trinity template void Visit(GridRefManager &) { } }; + // AreaTrigger searchers + template + struct AreaTriggerSearcherBase : Result + { + PhaseShift const* i_phaseShift; + Check& i_check; + + template + AreaTriggerSearcherBase(PhaseShift const* phaseShift, Container& result, Check& check) + : Result(result), i_phaseShift(phaseShift), i_check(check) { + } + + void Visit(AreaTriggerMapType& m); + + template void Visit(GridRefManager&) {} + }; + + template + struct AreaTriggerSearcher : AreaTriggerSearcherBase> + { + AreaTriggerSearcher(WorldObject const* searcher, AreaTrigger*& result, Check& check) + : AreaTriggerSearcherBase>(&searcher->GetPhaseShift(), result, check) {} + }; + + // Last accepted by Check GO if any (Check can change requirements at each call) + template + struct AreaTriggerLastSearcher : AreaTriggerSearcherBase> + { + AreaTriggerLastSearcher(WorldObject const* searcher, AreaTrigger*& result, Check& check) + : AreaTriggerSearcherBase>(&searcher->GetPhaseShift(), result, check) {} + }; + + template + struct AreaTriggerListSearcher : AreaTriggerSearcherBase> + { + template + AreaTriggerListSearcher(WorldObject const* searcher, Container& container, Check& check) + : AreaTriggerSearcherBase>(&searcher->GetPhaseShift(), container, check) {} + }; + // CHECKS && DO classes // CHECK modifiers @@ -1796,6 +1836,31 @@ namespace Trinity uint32 _entry; }; + class NearestAreaTriggerEntryInObjectRangeCheck + { + public: + NearestAreaTriggerEntryInObjectRangeCheck(WorldObject const& obj, uint32 entry, float range, bool spawnedOnly = false) : i_obj(obj), i_entry(entry), i_range(range), i_spawnedOnly(spawnedOnly) { } + + bool operator()(AreaTrigger const* at) + { + if ((!i_spawnedOnly || at->IsStaticSpawn()) && at->GetEntry() == i_entry && at->GetGUID() != i_obj.GetGUID() && i_obj.IsWithinDist(at, i_range)) + { + i_range = i_obj.GetDistance(at); + return true; + } + return false; + } + + private: + WorldObject const& i_obj; + uint32 i_entry; + float i_range; + bool i_spawnedOnly; + + // prevent clone this object + NearestAreaTriggerEntryInObjectRangeCheck(NearestGameObjectEntryInObjectRangeCheck const&) = delete; + }; + // Player checks and do // Prepare using Builder localized packets with caching and send to player diff --git a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h index e3da1f69e82..536777d7647 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h +++ b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h @@ -295,6 +295,29 @@ void Trinity::PlayerSearcherBase::Visit(PlayerMapType& m) } } +// AreaTrigger searchers + +template +void Trinity::AreaTriggerSearcherBase::Visit(AreaTriggerMapType& m) +{ + if (this->ShouldContinue() == WorldObjectSearcherContinuation::Return) + return; + + for (GridReference const& ref : m) + { + if (!ref.GetSource()->InSamePhase(*i_phaseShift)) + continue; + + if (i_check(ref.GetSource())) + { + this->Insert(ref.GetSource()); + + if (this->ShouldContinue() == WorldObjectSearcherContinuation::Return) + return; + } + } +} + template void Trinity::LocalizedDo::operator()(Player const* p) {