diff options
| author | ModoX <moardox@gmail.com> | 2024-01-05 17:56:19 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-01-05 17:56:19 +0100 |
| commit | 12186ef8573f60abeff4747da58767ee71092600 (patch) | |
| tree | 7d9a1da93e86fa3ccd84c02658bface3ef536721 /src/server/game/Movement/Waypoints | |
| parent | 390f0be9fb22766638006f43e4d0887108ba49e8 (diff) | |
Core/Waypoints: Refactor to split data into path and node related info in db (#29506)
Diffstat (limited to 'src/server/game/Movement/Waypoints')
| -rw-r--r-- | src/server/game/Movement/Waypoints/WaypointDefines.h | 69 | ||||
| -rw-r--r-- | src/server/game/Movement/Waypoints/WaypointManager.cpp | 326 | ||||
| -rw-r--r-- | src/server/game/Movement/Waypoints/WaypointManager.h | 36 |
3 files changed, 327 insertions, 104 deletions
diff --git a/src/server/game/Movement/Waypoints/WaypointDefines.h b/src/server/game/Movement/Waypoints/WaypointDefines.h index 119219dd3d4..d801531b316 100644 --- a/src/server/game/Movement/Waypoints/WaypointDefines.h +++ b/src/server/game/Movement/Waypoints/WaypointDefines.h @@ -19,51 +19,68 @@ #define TRINITY_WAYPOINTDEFINES_H #include "Define.h" +#include "EnumFlag.h" #include "Optional.h" #include <vector> -enum WaypointMoveType +#define WAYPOINT_PATH_FLAG_FOLLOW_PATH_BACKWARDS_MINIMUM_NODES 2 + +enum class WaypointMoveType : uint8 { - WAYPOINT_MOVE_TYPE_WALK, - WAYPOINT_MOVE_TYPE_RUN, - WAYPOINT_MOVE_TYPE_LAND, - WAYPOINT_MOVE_TYPE_TAKEOFF, + Walk = 0, + Run = 1, + Land = 2, + TakeOff = 3, - WAYPOINT_MOVE_TYPE_MAX + Max }; +enum class WaypointPathFlags : uint8 +{ + None = 0x00, + FollowPathBackwardsFromEndToStart = 0x01, +}; + +DEFINE_ENUM_FLAG(WaypointPathFlags); + struct WaypointNode { - WaypointNode() : id(0), x(0.f), y(0.f), z(0.f), delay(0), moveType(WAYPOINT_MOVE_TYPE_RUN) { } - WaypointNode(uint32 _id, float _x, float _y, float _z, Optional<float> _orientation = { }, uint32 _delay = 0) + WaypointNode() : Id(0), X(0.f), Y(0.f), Z(0.f), Delay(0), MoveType(WaypointMoveType::Walk) { } + WaypointNode(uint32 id, float x, float y, float z, Optional<float> orientation = { }, uint32 delay = 0) { - id = _id; - x = _x; - y = _y; - z = _z; - orientation = _orientation; - delay = _delay; - moveType = WAYPOINT_MOVE_TYPE_WALK; + Id = id; + X = x; + Y = y; + Z = z; + Orientation = orientation; + Delay = delay; + MoveType = WaypointMoveType::Walk; } - uint32 id; - float x, y, z; - Optional<float> orientation; - uint32 delay; - uint32 moveType; + uint32 Id; + float X; + float Y; + float Z; + Optional<float> Orientation; + uint32 Delay; + WaypointMoveType MoveType; }; struct WaypointPath { - WaypointPath() : id(0) { } - WaypointPath(uint32 _id, std::vector<WaypointNode>&& _nodes) + WaypointPath() : Id(0), MoveType(WaypointMoveType::Walk), Flags(WaypointPathFlags::None) { } + WaypointPath(uint32 id, std::vector<WaypointNode>&& nodes, WaypointMoveType moveType = WaypointMoveType::Walk, WaypointPathFlags flags = WaypointPathFlags::None) { - id = _id; - nodes = _nodes; + Id = id; + Nodes = nodes; + Flags = flags; + MoveType = moveType; } - std::vector<WaypointNode> nodes; - uint32 id; + std::vector<WaypointNode> Nodes; + uint32 Id; + WaypointMoveType MoveType; + EnumFlag<WaypointPathFlags> Flags = WaypointPathFlags::None; }; #endif diff --git a/src/server/game/Movement/Waypoints/WaypointManager.cpp b/src/server/game/Movement/Waypoints/WaypointManager.cpp index ab018e66233..cb282e6ec30 100644 --- a/src/server/game/Movement/Waypoints/WaypointManager.cpp +++ b/src/server/game/Movement/Waypoints/WaypointManager.cpp @@ -19,17 +19,31 @@ #include "DatabaseEnv.h" #include "GridDefines.h" #include "Log.h" +#include "MapUtils.h" +#include "ObjectAccessor.h" +#include "Optional.h" +#include "TemporarySummon.h" +#include "Unit.h" -void WaypointMgr::Load() +void WaypointMgr::LoadPaths() +{ + _LoadPaths(); + _LoadPathNodes(); + DoPostLoadingChecks(); +} + +void WaypointMgr::_LoadPaths() { uint32 oldMSTime = getMSTime(); - // 0 1 2 3 4 5 6 7 - QueryResult result = WorldDatabase.Query("SELECT id, point, position_x, position_y, position_z, orientation, move_type, delay FROM waypoint_data ORDER BY id, point"); + _pathStore.clear(); + + // 0 1 2 + QueryResult result = WorldDatabase.Query("SELECT PathId, MoveType, Flags FROM waypoint_path"); if (!result) { - TC_LOG_INFO("server.loading", ">> Loaded 0 waypoints. DB table `waypoint_data` is empty!"); + TC_LOG_INFO("server.loading", ">> Loaded 0 waypoint paths. DB table `waypoint_path` is empty!"); return; } @@ -37,42 +51,92 @@ void WaypointMgr::Load() do { - Field* fields = result->Fetch(); - uint32 pathId = fields[0].GetUInt32(); - float x = fields[2].GetFloat(); - float y = fields[3].GetFloat(); - float z = fields[4].GetFloat(); - Optional<float> o; - if (!fields[5].IsNull()) - o = fields[5].GetFloat(); - - Trinity::NormalizeMapCoord(x); - Trinity::NormalizeMapCoord(y); - - WaypointNode waypoint; - waypoint.id = fields[1].GetUInt32(); - waypoint.x = x; - waypoint.y = y; - waypoint.z = z; - waypoint.orientation = o; - waypoint.moveType = fields[6].GetUInt32(); - - if (waypoint.moveType >= WAYPOINT_MOVE_TYPE_MAX) - { - TC_LOG_ERROR("sql.sql", "Waypoint {} in waypoint_data has invalid move_type, ignoring", waypoint.id); - continue; - } + LoadPathFromDB(result->Fetch()); + ++count; + } while (result->NextRow()); + + TC_LOG_INFO("server.loading", ">> Loaded {} waypoint paths in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); +} + +void WaypointMgr::_LoadPathNodes() +{ + uint32 oldMSTime = getMSTime(); + // 0 1 2 3 4 5 6 + QueryResult result = WorldDatabase.Query("SELECT PathId, NodeId, PositionX, PositionY, PositionZ, Orientation, Delay FROM waypoint_path_node ORDER BY PathId, NodeId"); + + if (!result) + { + TC_LOG_INFO("server.loading", ">> Loaded 0 waypoint path nodes. DB table `waypoint_path_node` is empty!"); + return; + } - waypoint.delay = fields[7].GetUInt32(); + uint32 count = 0; - WaypointPath& path = _waypointStore[pathId]; - path.id = pathId; - path.nodes.push_back(std::move(waypoint)); + do + { + LoadPathNodesFromDB(result->Fetch()); ++count; } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded {} waypoints in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded {} waypoint path nodes in {} ms", count, GetMSTimeDiffToNow(oldMSTime)); + DoPostLoadingChecks(); +} + +void WaypointMgr::LoadPathFromDB(Field* fields) +{ + uint32 pathId = fields[0].GetUInt32(); + + WaypointPath& path = _pathStore[pathId]; + path.Id = pathId; + path.MoveType = (WaypointMoveType)fields[1].GetUInt8(); + + if (path.MoveType >= WaypointMoveType::Max) + { + TC_LOG_ERROR("sql.sql", "PathId {} in `waypoint_path` has invalid MoveType {}, ignoring", pathId, AsUnderlyingType(path.MoveType)); + return; + } + path.Flags = (WaypointPathFlags)fields[2].GetUInt8(); + path.Nodes.clear(); +} + +void WaypointMgr::LoadPathNodesFromDB(Field* fields) +{ + uint32 pathId = fields[0].GetUInt32(); + + if (_pathStore.find(pathId) == _pathStore.end()) + { + TC_LOG_ERROR("sql.sql", "PathId {} in `waypoint_path_node` does not exist in `waypoint_path`, ignoring", pathId); + return; + } + + float x = fields[2].GetFloat(); + float y = fields[3].GetFloat(); + float z = fields[4].GetFloat(); + Optional<float> o; + if (!fields[5].IsNull()) + o = fields[5].GetFloat(); + + Trinity::NormalizeMapCoord(x); + Trinity::NormalizeMapCoord(y); + + WaypointNode waypoint(fields[1].GetUInt32(), x, y, z, o, fields[6].GetUInt32()); + + WaypointPath& path = _pathStore[pathId]; + path.Nodes.push_back(std::move(waypoint)); +} + +void WaypointMgr::DoPostLoadingChecks() +{ + for (auto const& path : _pathStore) + { + WaypointPath pathInfo = path.second; + if (pathInfo.Nodes.empty()) + TC_LOG_ERROR("sql.sql", "PathId {} in `waypoint_path` has no assigned nodes in `waypoint_path_node`", pathInfo.Id); + + if (pathInfo.Flags.HasFlag(WaypointPathFlags::FollowPathBackwardsFromEndToStart) && pathInfo.Nodes.size() < WAYPOINT_PATH_FLAG_FOLLOW_PATH_BACKWARDS_MINIMUM_NODES) + TC_LOG_ERROR("sql.sql", "PathId {} in `waypoint_path` has FollowPathBackwardsFromEndToStart set, but only {} nodes, requires {}", pathInfo.Id, pathInfo.Nodes.size(), WAYPOINT_PATH_FLAG_FOLLOW_PATH_BACKWARDS_MINIMUM_NODES); + } } WaypointMgr* WaypointMgr::instance() @@ -81,61 +145,177 @@ WaypointMgr* WaypointMgr::instance() return &instance; } -void WaypointMgr::ReloadPath(uint32 id) +void WaypointMgr::ReloadPath(uint32 pathId) { - WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_DATA_BY_ID); + // waypoint_path + { + WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_PATH_BY_PATHID); + stmt->setUInt32(0, pathId); - stmt->setUInt32(0, id); + PreparedQueryResult result = WorldDatabase.Query(stmt); - PreparedQueryResult result = WorldDatabase.Query(stmt); + if (!result) + { + TC_LOG_ERROR("sql.sql", "PathId {} in `waypoint_path` not found, ignoring", pathId); + return; + } - if (!result) - return; + do + { + LoadPathFromDB(result->Fetch()); + } while (result->NextRow()); + } - std::vector<WaypointNode> values; - do + // waypoint_path_data { - Field* fields = result->Fetch(); - float x = fields[1].GetFloat(); - float y = fields[2].GetFloat(); - float z = fields[3].GetFloat(); - Optional<float> o; - if (!fields[4].IsNull()) - o = fields[4].GetFloat(); - - Trinity::NormalizeMapCoord(x); - Trinity::NormalizeMapCoord(y); - - WaypointNode waypoint; - waypoint.id = fields[0].GetUInt32(); - waypoint.x = x; - waypoint.y = y; - waypoint.z = z; - waypoint.orientation = o; - waypoint.moveType = fields[5].GetUInt32(); - - if (waypoint.moveType >= WAYPOINT_MOVE_TYPE_MAX) + WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_WAYPOINT_PATH_NODE_BY_PATHID); + stmt->setUInt32(0, pathId); + + PreparedQueryResult result = WorldDatabase.Query(stmt); + + if (!result) { - TC_LOG_ERROR("sql.sql", "Waypoint {} in waypoint_data has invalid move_type, ignoring", waypoint.id); + TC_LOG_ERROR("sql.sql", "PathId {} in `waypoint_path_node` not found, ignoring", pathId); + return; + } + + do + { + LoadPathNodesFromDB(result->Fetch()); + } while (result->NextRow()); + } +} + +void WaypointMgr::VisualizePath(Unit* owner, WaypointPath const* path, Optional<uint32> displayId) +{ + for (WaypointNode const& node : path->Nodes) + { + std::pair<uint32, uint32> pathNodePair(path->Id, node.Id); + + auto itr = _nodeToVisualWaypointGUIDsMap.find(pathNodePair); + if (itr != _nodeToVisualWaypointGUIDsMap.end()) + continue; + + TempSummon* summon = owner->SummonCreature(VISUAL_WAYPOINT, node.X, node.Y, node.Z, node.Orientation ? *node.Orientation : 0.0f); + if (!summon) continue; + + if (displayId) + { + summon->SetDisplayId(*displayId, true); + summon->SetObjectScale(0.5f); } - waypoint.delay = fields[6].GetUInt32(); + _nodeToVisualWaypointGUIDsMap[pathNodePair] = summon->GetGUID(); + _visualWaypointGUIDToNodeMap[summon->GetGUID()] = std::pair<WaypointPath const*, WaypointNode const*>(path, &node); + } +} + +void WaypointMgr::DevisualizePath(Unit* owner, WaypointPath const* path) +{ + for (WaypointNode const& node : path->Nodes) + { + std::pair<uint32, uint32> pathNodePair(path->Id, node.Id); + auto itr = _nodeToVisualWaypointGUIDsMap.find(pathNodePair); + if (itr == _nodeToVisualWaypointGUIDsMap.end()) + continue; + + Creature* creature = ObjectAccessor::GetCreature(*owner, itr->second); + if (!creature) + continue; + + _visualWaypointGUIDToNodeMap.erase(itr->second); + _nodeToVisualWaypointGUIDsMap.erase(pathNodePair); - values.push_back(std::move(waypoint)); + creature->DespawnOrUnsummon(); } - while (result->NextRow()); +} + +void WaypointMgr::MoveNode(WaypointPath const* path, WaypointNode const* node, Position const& pos) +{ + WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_PATH_NODE_POSITION); + stmt->setFloat(0, pos.GetPositionX()); + stmt->setFloat(1, pos.GetPositionY()); + stmt->setFloat(2, pos.GetPositionZ()); + stmt->setFloat(3, pos.GetOrientation()); + stmt->setUInt32(4, path->Id); + stmt->setUInt32(5, node->Id); + WorldDatabase.Execute(stmt); +} + +void WaypointMgr::DeleteNode(WaypointPath const* path, WaypointNode const* node) +{ + WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_WAYPOINT_PATH_NODE); + stmt->setUInt32(0, path->Id); + stmt->setUInt32(1, node->Id); + WorldDatabase.Execute(stmt); + + stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_PATH_NODE); + stmt->setUInt32(0, path->Id); + stmt->setUInt32(1, node->Id); + WorldDatabase.Execute(stmt); +} + +void WaypointMgr::DeleteNode(uint32 pathId, uint32 nodeId) +{ + WaypointPath const* path = GetPath(pathId); + if (!path) + return; + + WaypointNode const* node = GetNode(path, nodeId); + if (!node) + return; - WaypointPath& path = _waypointStore[id]; - path.id = id; - path.nodes = std::move(values); + DeleteNode(path, node); } -WaypointPath const* WaypointMgr::GetPath(uint32 id) const +WaypointPath const* WaypointMgr::GetPath(uint32 pathId) const { - auto itr = _waypointStore.find(id); - if (itr != _waypointStore.end()) - return &itr->second; + return Trinity::Containers::MapGetValuePtr(_pathStore, pathId); +} +WaypointNode const* WaypointMgr::GetNode(WaypointPath const* path, uint32 nodeId) const +{ + for (WaypointNode const& node : path->Nodes) + { + if (node.Id == nodeId) + return &node; + } return nullptr; } + +WaypointNode const* WaypointMgr::GetNode(uint32 pathId, uint32 nodeId) const +{ + WaypointPath const* path = GetPath(pathId); + if (!path) + return nullptr; + + return GetNode(path->Id, nodeId); +} + +WaypointPath const* WaypointMgr::GetPathByVisualGUID(ObjectGuid guid) const +{ + auto itr = _visualWaypointGUIDToNodeMap.find(guid); + if (itr == _visualWaypointGUIDToNodeMap.end()) + return nullptr; + + return itr->second.first; +} + +WaypointNode const* WaypointMgr::GetNodeByVisualGUID(ObjectGuid guid) const +{ + auto itr = _visualWaypointGUIDToNodeMap.find(guid); + if (itr == _visualWaypointGUIDToNodeMap.end()) + return nullptr; + + return itr->second.second; +} + +ObjectGuid const& WaypointMgr::GetVisualGUIDByNode(uint32 pathId, uint32 nodeId) const +{ + auto itr = _nodeToVisualWaypointGUIDsMap.find(std::make_pair(pathId, nodeId)); + if (itr == _nodeToVisualWaypointGUIDsMap.end()) + return ObjectGuid::Empty; + + return itr->second; +} diff --git a/src/server/game/Movement/Waypoints/WaypointManager.h b/src/server/game/Movement/Waypoints/WaypointManager.h index 906c6981e28..721f79d76a6 100644 --- a/src/server/game/Movement/Waypoints/WaypointManager.h +++ b/src/server/game/Movement/Waypoints/WaypointManager.h @@ -19,27 +19,53 @@ #define TRINITY_WAYPOINTMANAGER_H #include "Define.h" +#include "Field.h" +#include "Hash.h" +#include "ObjectGuid.h" +#include "Position.h" #include "WaypointDefines.h" #include <unordered_map> +class Unit; + class TC_GAME_API WaypointMgr { public: static WaypointMgr* instance(); // Attempts to reload a single path from database - void ReloadPath(uint32 id); + void ReloadPath(uint32 pathId); // Loads all paths from database, should only run on startup - void Load(); + void LoadPaths(); + void LoadPathFromDB(Field* fields); + void LoadPathNodesFromDB(Field* fields); + void DoPostLoadingChecks(); + + void VisualizePath(Unit* owner, WaypointPath const* path, Optional<uint32> displayId); + void DevisualizePath(Unit* owner, WaypointPath const* path); + + void MoveNode(WaypointPath const* path, WaypointNode const* node, Position const& pos); + void DeleteNode(WaypointPath const* path, WaypointNode const* node); + void DeleteNode(uint32 pathId, uint32 nodeId); - // Returns the path from a given id - WaypointPath const* GetPath(uint32 id) const; + WaypointPath const* GetPath(uint32 pathId) const; + WaypointNode const* GetNode(WaypointPath const* path, uint32 nodeId) const; + WaypointNode const* GetNode(uint32 pathId, uint32 nodeId) const; + WaypointPath const* GetPathByVisualGUID(ObjectGuid guid) const; + WaypointNode const* GetNodeByVisualGUID(ObjectGuid guid) const; + ObjectGuid const& GetVisualGUIDByNode(uint32 pathId, uint32 nodeId) const; private: WaypointMgr() { } - std::unordered_map<uint32, WaypointPath> _waypointStore; + void _LoadPaths(); + void _LoadPathNodes(); + + std::unordered_map<uint32 /*pathId*/, WaypointPath> _pathStore; + + std::unordered_map<std::pair<uint32 /*pathId*/, uint32 /*nodeId*/>, ObjectGuid> _nodeToVisualWaypointGUIDsMap; + std::unordered_map<ObjectGuid, std::pair<WaypointPath const*, WaypointNode const*>> _visualWaypointGUIDToNodeMap; }; #define sWaypointMgr WaypointMgr::instance() |
