diff options
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 9 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.h | 47 | ||||
-rw-r--r-- | src/server/game/Grids/Notifiers/GridNotifiers.h | 68 | ||||
-rw-r--r-- | src/server/game/Phasing/PhasingHandler.cpp | 11 | ||||
-rw-r--r-- | src/server/game/Phasing/PhasingHandler.h | 1 |
5 files changed, 109 insertions, 27 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 608cef987cd..cea03921ed6 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2115,11 +2115,14 @@ Creature* WorldObject::FindNearestCreature(uint32 entry, float range, bool alive return creature; } -Creature* WorldObject::FindNearestCreatureWithAura(uint32 entry, uint32 spellId, float range, bool alive) const +Creature* WorldObject::FindNearestCreatureWithOptions(float range, FindCreatureOptions const& options) const { Creature* creature = nullptr; - Trinity::NearestCreatureEntryWithLiveStateAndAuraInObjectRangeCheck checker(*this, entry, spellId, alive, range); - Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithLiveStateAndAuraInObjectRangeCheck> searcher(this, creature, checker); + Trinity::NearestCreatureEntryWithOptionsInObjectRangeCheck checker(*this, range, options); + Trinity::CreatureLastSearcher<Trinity::NearestCreatureEntryWithOptionsInObjectRangeCheck> searcher(this, creature, checker); + if (options.IgnorePhases) + searcher.i_phaseShift = &PhasingHandler::GetAlwaysVisiblePhaseShift(); + Cell::VisitAllObjects(this, searcher, range); return creature; } diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 17ded06619f..2f185cea7c2 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -432,6 +432,51 @@ class FlaggedValuesArray32 T_FLAGS m_flags; }; +struct FindCreatureOptions +{ + FindCreatureOptions() = default; + + FindCreatureOptions& SetCreatureId(uint32 creatureId) { CreatureId = creatureId; return *this; } + + FindCreatureOptions& SetIsAlive(bool isAlive) { IsAlive = isAlive; return *this; } + FindCreatureOptions& SetIsInCombat(bool isInCombat) { IsInCombat = isInCombat; return *this; } + FindCreatureOptions& SetIsSummon(bool isSummon) { IsSummon = isSummon; return *this; } + + FindCreatureOptions& SetIgnorePhases(bool ignorePhases) { IgnorePhases = ignorePhases; return *this; } + FindCreatureOptions& SetIgnoreNotOwnedPrivateObjects(bool ignoreNotOwnedPrivateObjects) { IgnoreNotOwnedPrivateObjects = ignoreNotOwnedPrivateObjects; return *this; } + FindCreatureOptions& SetIgnorePrivateObjects(bool ignorePrivateObjects) { IgnorePrivateObjects = ignorePrivateObjects; return *this; } + + FindCreatureOptions& SetHasAura(uint32 spellId) { AuraSpellId = spellId; return *this; } + FindCreatureOptions& SetOwner(ObjectGuid ownerGuid) { OwnerGuid = ownerGuid; return *this; } + FindCreatureOptions& SetCharmer(ObjectGuid charmerGuid) { CharmerGuid = charmerGuid; return *this; } + FindCreatureOptions& SetCreator(ObjectGuid creatorGuid) { CreatorGuid = creatorGuid; return *this; } + FindCreatureOptions& SetDemonCreator(ObjectGuid demonCreatorGuid) { DemonCreatorGuid = demonCreatorGuid; return *this; } + FindCreatureOptions& SetPrivateObjectOwner(ObjectGuid privateObjectOwnerGuid) { PrivateObjectOwnerGuid = privateObjectOwnerGuid; return *this; } + + Optional<uint32> CreatureId; + + Optional<bool> IsAlive; + Optional<bool> IsInCombat; + Optional<bool> IsSummon; + + bool IgnorePhases; + bool IgnoreNotOwnedPrivateObjects; + bool IgnorePrivateObjects; + + Optional<uint32> AuraSpellId; + Optional<ObjectGuid> OwnerGuid; + Optional<ObjectGuid> CharmerGuid; + Optional<ObjectGuid> CreatorGuid; + Optional<ObjectGuid> DemonCreatorGuid; + Optional<ObjectGuid> PrivateObjectOwnerGuid; + + FindCreatureOptions(FindCreatureOptions const&) = delete; + FindCreatureOptions(FindCreatureOptions&&) = delete; + + FindCreatureOptions& operator=(FindCreatureOptions const&) = delete; + FindCreatureOptions& operator=(FindCreatureOptions&&) = delete; +}; + class TC_GAME_API WorldObject : public Object, public WorldLocation { protected: @@ -580,7 +625,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation void SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list = nullptr); Creature* FindNearestCreature(uint32 entry, float range, bool alive = true) const; - Creature* FindNearestCreatureWithAura(uint32 entry, uint32 spellId, float range, bool alive = true) const; + Creature* FindNearestCreatureWithOptions(float range, FindCreatureOptions const& options) const; GameObject* FindNearestGameObject(uint32 entry, float range, bool spawnedOnly = true) const; GameObject* FindNearestUnspawnedGameObject(uint32 entry, float range) const; GameObject* FindNearestGameObjectOfType(GameobjectTypes type, float range) const; diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index f673bb42857..71cc95fb679 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -1441,37 +1441,59 @@ namespace Trinity NearestCreatureEntryWithLiveStateInObjectRangeCheck(NearestCreatureEntryWithLiveStateInObjectRangeCheck const&) = delete; }; - class NearestCreatureEntryWithLiveStateAndAuraInObjectRangeCheck + class NearestCreatureEntryWithOptionsInObjectRangeCheck { public: - NearestCreatureEntryWithLiveStateAndAuraInObjectRangeCheck(WorldObject const& obj, uint32 entry, uint32 spellId, bool alive, float range) - : i_obj(obj), i_entry(entry), i_spellId(spellId), i_alive(alive), i_range(range) { } + NearestCreatureEntryWithOptionsInObjectRangeCheck(WorldObject const& obj, float range, FindCreatureOptions const& args) + : i_obj(obj), i_args(args), i_range(range) { } - bool operator()(Creature* u) - { - if (u->getDeathState() != DEAD - && u->GetEntry() == i_entry - && u->HasAura(i_spellId) - && u->IsAlive() == i_alive - && u->GetGUID() != i_obj.GetGUID() - && i_obj.IsWithinDistInMap(u, i_range) - && u->CheckPrivateObjectOwnerVisibility(&i_obj)) + bool operator()(Creature* u) { + if (u->getDeathState() == DEAD) // Despawned + return false; + + if (u->GetGUID() == i_obj.GetGUID()) + return false; + + if (!i_obj.IsWithinDistInMap(u, i_range)) + return false; + + if (i_args.CreatureId && u->GetEntry() != i_args.CreatureId) + return false; + + if (i_args.IsAlive.has_value() && u->IsAlive() != i_args.IsAlive) + return false; + + if (i_args.IsSummon.has_value() && u->IsSummon() != i_args.IsSummon) + return false; + + if (i_args.IsInCombat.has_value() && u->IsInCombat() != i_args.IsInCombat) + return false; + + if ((i_args.OwnerGuid && u->GetOwnerGUID() != i_args.OwnerGuid) + || (i_args.CharmerGuid && u->GetCharmerGUID() != i_args.CharmerGuid) + || (i_args.CreatorGuid && u->GetCreatorGUID() != i_args.CreatorGuid) + || (i_args.DemonCreatorGuid && u->GetDemonCreatorGUID() != i_args.DemonCreatorGuid) + || (i_args.PrivateObjectOwnerGuid && u->GetPrivateObjectOwner() != i_args.PrivateObjectOwnerGuid)) + return false; + + if (i_args.IgnorePrivateObjects && u->IsPrivateObject()) + return false; + + if (i_args.IgnoreNotOwnedPrivateObjects && !u->CheckPrivateObjectOwnerVisibility(&i_obj)) + return false; + + if (i_args.AuraSpellId && !u->HasAura(*i_args.AuraSpellId)) + return false; + i_range = i_obj.GetDistance(u); // use found unit range as new range limit for next check return true; } - return false; - } - private: - WorldObject const& i_obj; - uint32 i_entry; - uint32 i_spellId; - bool i_alive; - float i_range; - - // prevent clone this object - NearestCreatureEntryWithLiveStateAndAuraInObjectRangeCheck(NearestCreatureEntryWithLiveStateAndAuraInObjectRangeCheck const&) = delete; + private: + WorldObject const& i_obj; + FindCreatureOptions const& i_args; + float i_range; }; class AnyPlayerInObjectRangeCheck diff --git a/src/server/game/Phasing/PhasingHandler.cpp b/src/server/game/Phasing/PhasingHandler.cpp index b97efdc74e4..01f996a5a11 100644 --- a/src/server/game/Phasing/PhasingHandler.cpp +++ b/src/server/game/Phasing/PhasingHandler.cpp @@ -38,6 +38,12 @@ namespace { PhaseShift const Empty; +PhaseShift const AlwaysVisible = [] +{ + PhaseShift phaseShift; + PhasingHandler::InitDbPhaseShift(phaseShift, PHASE_USE_FLAGS_ALWAYS_VISIBLE, 0, 0); + return phaseShift; +}(); inline PhaseFlags GetPhaseFlags(uint32 phaseId) { @@ -514,6 +520,11 @@ PhaseShift const& PhasingHandler::GetEmptyPhaseShift() return Empty; } +PhaseShift const& PhasingHandler::GetAlwaysVisiblePhaseShift() +{ + return AlwaysVisible; +} + void PhasingHandler::InitDbPhaseShift(PhaseShift& phaseShift, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId) { phaseShift.ClearPhases(); diff --git a/src/server/game/Phasing/PhasingHandler.h b/src/server/game/Phasing/PhasingHandler.h index 25a89c829b4..779cae19821 100644 --- a/src/server/game/Phasing/PhasingHandler.h +++ b/src/server/game/Phasing/PhasingHandler.h @@ -59,6 +59,7 @@ public: static void FillPartyMemberPhase(WorldPackets::Party::PartyMemberPhaseStates* partyMemberPhases, PhaseShift const& phaseShift); static PhaseShift const& GetEmptyPhaseShift(); + static PhaseShift const& GetAlwaysVisiblePhaseShift(); static void InitDbPhaseShift(PhaseShift& phaseShift, uint8 phaseUseFlags, uint16 phaseId, uint32 phaseGroupId); static void InitDbPersonalOwnership(PhaseShift& phaseShift, ObjectGuid const& personalGuid); static void InitDbVisibleMapId(PhaseShift& phaseShift, int32 visibleMapId); |