diff options
-rw-r--r-- | sql/updates/world/master/2023_07_30_00_world.sql | 3 | ||||
-rw-r--r-- | src/server/game/Entities/GameObject/GameObject.cpp | 24 | ||||
-rw-r--r-- | src/server/game/Entities/GameObject/GameObject.h | 8 | ||||
-rw-r--r-- | src/server/game/Entities/GameObject/GameObjectData.h | 1 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 31 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Object.h | 20 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 10 | ||||
-rw-r--r-- | src/server/game/Grids/Notifiers/GridNotifiers.h | 64 |
8 files changed, 151 insertions, 10 deletions
diff --git a/sql/updates/world/master/2023_07_30_00_world.sql b/sql/updates/world/master/2023_07_30_00_world.sql new file mode 100644 index 00000000000..0b4686a7e7d --- /dev/null +++ b/sql/updates/world/master/2023_07_30_00_world.sql @@ -0,0 +1,3 @@ +ALTER TABLE `gameobject` ADD `StringId` varchar(64) AFTER `ScriptName`; + +ALTER TABLE `gameobject_template` ADD `StringId` varchar(64) AFTER `ScriptName`; diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 4d46568c92b..df5c39ecffa 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -880,6 +880,9 @@ bool GameObject::Create(uint32 entry, Map* map, Position const& pos, QuaternionD } LastUsedScriptID = GetGOInfo()->ScriptId; + + m_stringIds[0] = goInfo->StringId; + AIM_Initialize(); if (spawnid) @@ -1712,6 +1715,8 @@ bool GameObject::LoadFromDB(ObjectGuid::LowType spawnId, Map* map, bool addToMap m_goData = data; + m_stringIds[1] = data->StringId; + if (addToMap && !GetMap()->AddToMap(this)) return false; @@ -3198,6 +3203,25 @@ uint32 GameObject::GetScriptId() const return GetGOInfo()->ScriptId; } +bool GameObject::HasStringId(std::string_view id) const +{ + return std::find(m_stringIds.begin(), m_stringIds.end(), id) != m_stringIds.end(); +} + +void GameObject::SetScriptStringId(std::string id) +{ + if (!id.empty()) + { + m_scriptStringId.emplace(std::move(id)); + m_stringIds[2] = *m_scriptStringId; + } + else + { + m_scriptStringId.reset(); + m_stringIds[2] = {}; + } +} + // overwrite WorldObject function for proper name localization std::string GameObject::GetNameForLocaleIdx(LocaleConstant locale) const { diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 8c08ef627b5..82868a33f52 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -354,10 +354,14 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> void SetRespawnCompatibilityMode(bool mode = true) { m_respawnCompatibilityMode = mode; } bool GetRespawnCompatibilityMode() {return m_respawnCompatibilityMode; } + std::string const& GetAIName() const; uint32 GetScriptId() const; GameObjectAI* AI() const { return m_AI; } - std::string const& GetAIName() const; + bool HasStringId(std::string_view id) const; + void SetScriptStringId(std::string id); + std::array<std::string_view, 3> const& GetStringIds() const { return m_stringIds; } + void SetDisplayId(uint32 displayid); uint32 GetDisplayId() const { return m_gameObjectData->DisplayID; } uint8 GetNameSetId() const; @@ -450,6 +454,8 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> GameObjectData const* m_goData; std::unique_ptr<GameObjectTypeBase> m_goTypeImpl; GameObjectValue m_goValue; // TODO: replace with m_goTypeImpl + std::array<std::string_view, 3> m_stringIds; + Optional<std::string> m_scriptStringId; int64 m_packedRotation; QuaternionData m_localRotation; diff --git a/src/server/game/Entities/GameObject/GameObjectData.h b/src/server/game/Entities/GameObject/GameObjectData.h index 88a76ef7d7d..0021f82ba9f 100644 --- a/src/server/game/Entities/GameObject/GameObjectData.h +++ b/src/server/game/Entities/GameObject/GameObjectData.h @@ -836,6 +836,7 @@ struct GameObjectTemplate std::string AIName; uint32 ScriptId; + std::string StringId; WorldPacket QueryData[TOTAL_LOCALES]; // helpers diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 461b372cdcb..9a0a941a98a 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2163,6 +2163,19 @@ GameObject* WorldObject::FindNearestGameObject(uint32 entry, float range, bool s return go; } +GameObject* WorldObject::FindNearestGameObjectWithOptions(float range, FindGameObjectOptions const& options) const +{ + GameObject* go = nullptr; + Trinity::NearestCheckCustomizer checkCustomizer(*this, range); + Trinity::GameObjectWithOptionsInObjectRangeCheck checker(*this, checkCustomizer, options); + Trinity::GameObjectLastSearcher searcher(this, go, checker); + if (options.IgnorePhases) + searcher.i_phaseShift = &PhasingHandler::GetAlwaysVisiblePhaseShift(); + + Cell::VisitGridObjects(this, searcher, range); + return go; +} + GameObject* WorldObject::FindNearestUnspawnedGameObject(uint32 entry, float range) const { GameObject* go = nullptr; @@ -3245,6 +3258,18 @@ void WorldObject::GetGameObjectListWithEntryInGrid(Container& gameObjectContaine } template <typename Container> +void WorldObject::GetGameObjectListWithOptionsInGrid(Container& gameObjectContainer, float maxSearchRange, FindGameObjectOptions const& options) const +{ + Trinity::InRangeCheckCustomizer checkCustomizer(*this, maxSearchRange); + Trinity::GameObjectWithOptionsInObjectRangeCheck check(*this, checkCustomizer, options); + Trinity::GameObjectListSearcher searcher(this, gameObjectContainer, check); + if (options.IgnorePhases) + searcher.i_phaseShift = &PhasingHandler::GetAlwaysVisiblePhaseShift(); + + Cell::VisitGridObjects(this, searcher, maxSearchRange); +} + +template <typename Container> void WorldObject::GetCreatureListWithEntryInGrid(Container& creatureContainer, uint32 entry, float maxSearchRange /*= 250.0f*/) const { Trinity::AllCreaturesOfEntryInRange check(this, entry, maxSearchRange); @@ -3255,7 +3280,7 @@ void WorldObject::GetCreatureListWithEntryInGrid(Container& creatureContainer, u template <typename Container> void WorldObject::GetCreatureListWithOptionsInGrid(Container& creatureContainer, float maxSearchRange, FindCreatureOptions const& options) const { - Trinity::NoopCheckCustomizer checkCustomizer; + Trinity::InRangeCheckCustomizer checkCustomizer(*this, maxSearchRange); Trinity::CreatureWithOptionsInObjectRangeCheck check(*this, checkCustomizer, options); Trinity::CreatureListSearcher searcher(this, creatureContainer, check); if (options.IgnorePhases) @@ -3700,6 +3725,10 @@ template TC_GAME_API void WorldObject::GetGameObjectListWithEntryInGrid(std::lis template TC_GAME_API void WorldObject::GetGameObjectListWithEntryInGrid(std::deque<GameObject*>&, uint32, float) const; template TC_GAME_API void WorldObject::GetGameObjectListWithEntryInGrid(std::vector<GameObject*>&, uint32, float) const; +template TC_GAME_API void WorldObject::GetGameObjectListWithOptionsInGrid(std::list<GameObject*>&, float, FindGameObjectOptions const&) const; +template TC_GAME_API void WorldObject::GetGameObjectListWithOptionsInGrid(std::deque<GameObject*>&, float, FindGameObjectOptions const&) const; +template TC_GAME_API void WorldObject::GetGameObjectListWithOptionsInGrid(std::vector<GameObject*>&, float, FindGameObjectOptions const&) const; + template TC_GAME_API void WorldObject::GetCreatureListWithEntryInGrid(std::list<Creature*>&, uint32, float) const; template TC_GAME_API void WorldObject::GetCreatureListWithEntryInGrid(std::deque<Creature*>&, uint32, float) const; template TC_GAME_API void WorldObject::GetCreatureListWithEntryInGrid(std::vector<Creature*>&, uint32, float) const; diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index e6025514676..4bc8fc28896 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -453,6 +453,22 @@ struct FindCreatureOptions Optional<ObjectGuid> PrivateObjectOwnerGuid; }; +struct FindGameObjectOptions +{ + Optional<uint32> GameObjectId; + Optional<std::string_view> StringId; + + Optional<bool> IsSummon; + Optional<bool> IsSpawned; + + bool IgnorePhases = false; + bool IgnoreNotOwnedPrivateObjects = true; + bool IgnorePrivateObjects = false; + + Optional<ObjectGuid> OwnerGuid; + Optional<ObjectGuid> PrivateObjectOwnerGuid; +}; + class TC_GAME_API WorldObject : public Object, public WorldLocation { protected: @@ -603,6 +619,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation Creature* FindNearestCreature(uint32 entry, 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* FindNearestGameObjectWithOptions(float range, FindGameObjectOptions const& options) const; GameObject* FindNearestUnspawnedGameObject(uint32 entry, float range) const; GameObject* FindNearestGameObjectOfType(GameobjectTypes type, float range) const; Player* SelectNearestPlayer(float distance) const; @@ -666,6 +683,9 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation void GetGameObjectListWithEntryInGrid(Container& gameObjectContainer, uint32 entry, float maxSearchRange = 250.0f) const; template <typename Container> + void GetGameObjectListWithOptionsInGrid(Container& gameObjectContainer, float maxSearchRange, FindGameObjectOptions const& options) const; + + template <typename Container> void GetCreatureListWithEntryInGrid(Container& creatureContainer, uint32 entry, float maxSearchRange = 250.0f) const; template <typename Container> diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 1bbd97a85ef..91a931486ae 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -2430,8 +2430,8 @@ void ObjectMgr::LoadGameObjects() QueryResult result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, " // 7 8 9 10 11 12 13 14 15 16 "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnDifficulties, eventEntry, poolSpawnId, " - // 17 18 19 20 21 - "phaseUseFlags, phaseid, phasegroup, terrainSwapMap, ScriptName " + // 17 18 19 20 21 22 + "phaseUseFlags, phaseid, phasegroup, terrainSwapMap, ScriptName, StringId " "FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid " "LEFT OUTER JOIN pool_members ON pool_members.type = 1 AND gameobject.guid = pool_members.spawnId"); @@ -2607,6 +2607,7 @@ void ObjectMgr::LoadGameObjects() } data.scriptId = GetScriptId(fields[21].GetString()); + data.StringId = fields[22].GetString(); if (data.rotation.x < -1.0f || data.rotation.x > 1.0f) { @@ -7613,8 +7614,8 @@ void ObjectMgr::LoadGameObjectTemplate() "Data0, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10, Data11, Data12, " // 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 "Data13, Data14, Data15, Data16, Data17, Data18, Data19, Data20, Data21, Data22, Data23, Data24, Data25, Data26, Data27, Data28, " - // 37 38 39 40 41 42 43 44 45 - "Data29, Data30, Data31, Data32, Data33, Data34, ContentTuningId, AIName, ScriptName " + // 37 38 39 40 41 42 43 44 45 46 + "Data29, Data30, Data31, Data32, Data33, Data34, ContentTuningId, AIName, ScriptName, StringId " "FROM gameobject_template"); if (!result) @@ -7646,6 +7647,7 @@ void ObjectMgr::LoadGameObjectTemplate() got.ContentTuningId = fields[43].GetInt32(); got.AIName = fields[44].GetString(); got.ScriptId = GetScriptId(fields[45].GetString()); + got.StringId = fields[46].GetString(); // Checks if (!got.AIName.empty() && !sGameObjectAIRegistry->HasItem(got.AIName)) diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index ae156bca5de..28ed5f71a46 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -615,12 +615,21 @@ namespace Trinity // CHECKS && DO classes // CHECK modifiers - class NoopCheckCustomizer + class InRangeCheckCustomizer { public: - bool Test(WorldObject const* /*o*/) const { return true; } + explicit InRangeCheckCustomizer(WorldObject const& obj, float range) : i_obj(obj), i_range(range) { } + + bool Test(WorldObject const* o) const + { + return i_obj.IsWithinDist(o, i_range); + } void Update(WorldObject const* /*o*/) { } + + private: + WorldObject const& i_obj; + float i_range; }; class NearestCheckCustomizer @@ -1398,14 +1407,14 @@ namespace Trinity NearestCreatureEntryWithLiveStateInObjectRangeCheck(NearestCreatureEntryWithLiveStateInObjectRangeCheck const&) = delete; }; - template <typename Customizer = NoopCheckCustomizer> + template <typename Customizer = InRangeCheckCustomizer> class CreatureWithOptionsInObjectRangeCheck { public: CreatureWithOptionsInObjectRangeCheck(WorldObject const& obj, Customizer& customizer, FindCreatureOptions const& args) : i_obj(obj), i_args(args), i_customizer(customizer) { } - bool operator()(Creature* u) const + bool operator()(Creature const* u) const { if (u->getDeathState() == DEAD) // Despawned return false; @@ -1457,6 +1466,53 @@ namespace Trinity Customizer& i_customizer; }; + template <typename Customizer = InRangeCheckCustomizer> + class GameObjectWithOptionsInObjectRangeCheck + { + public: + GameObjectWithOptionsInObjectRangeCheck(WorldObject const& obj, Customizer& customizer, FindGameObjectOptions const& args) + : i_obj(obj), i_args(args), i_customizer(customizer) { } + + bool operator()(GameObject const* go) const + { + if (i_args.IsSpawned.has_value() && i_args.IsSpawned != go->isSpawned()) // Despawned + return false; + + if (go->GetGUID() == i_obj.GetGUID()) + return false; + + if (!i_customizer.Test(go)) + return false; + + if (i_args.GameObjectId && go->GetEntry() != i_args.GameObjectId) + return false; + + if (i_args.StringId && !go->HasStringId(*i_args.StringId)) + return false; + + if (i_args.IsSummon.has_value() && (go->GetSpawnId() == 0) != i_args.IsSummon) + return false; + + if ((i_args.OwnerGuid && go->GetOwnerGUID() != i_args.OwnerGuid) + || (i_args.PrivateObjectOwnerGuid && go->GetPrivateObjectOwner() != i_args.PrivateObjectOwnerGuid)) + return false; + + if (i_args.IgnorePrivateObjects && go->IsPrivateObject()) + return false; + + if (i_args.IgnoreNotOwnedPrivateObjects && !go->CheckPrivateObjectOwnerVisibility(&i_obj)) + return false; + + i_customizer.Update(go); + return true; + } + + private: + WorldObject const& i_obj; + FindGameObjectOptions const& i_args; + Customizer& i_customizer; + }; + class AnyPlayerInObjectRangeCheck { public: |