From 0f9b44e44b9e5aa65070ca867d5c3fba9b82a271 Mon Sep 17 00:00:00 2001 From: Hondacrx Date: Mon, 18 Aug 2025 20:45:05 -0400 Subject: [PATCH] Core/Commands: Waypoint command fixes Port From (https://github.com/TrinityCore/TrinityCore/commit/e284dc0a8025c5e4da65271914c88d9afac95667) --- .../Database/Databases/WorldDatabase.cs | 10 +-- Source/Game/Chat/Commands/WPCommands.cs | 71 +++++++++---------- Source/Game/Movement/WaypointManager.cs | 59 ++++++++------- 3 files changed, 73 insertions(+), 67 deletions(-) diff --git a/Source/Framework/Database/Databases/WorldDatabase.cs b/Source/Framework/Database/Databases/WorldDatabase.cs index 0c67b1640..5926c6df9 100644 --- a/Source/Framework/Database/Databases/WorldDatabase.cs +++ b/Source/Framework/Database/Databases/WorldDatabase.cs @@ -28,14 +28,15 @@ namespace Framework.Database PrepareStatement(WorldStatements.UPD_CREATURE_WANDER_DISTANCE, "UPDATE creature SET wander_distance = ?, MovementType = ? WHERE guid = ?"); PrepareStatement(WorldStatements.UPD_CREATURE_SPAWN_TIME_SECS, "UPDATE creature SET spawntimesecs = ? WHERE guid = ?"); PrepareStatement(WorldStatements.INS_CREATURE_FORMATION, "INSERT INTO creature_formations (leaderGUID, memberGUID, dist, angle, groupAI) VALUES (?, ?, ?, ?, ?)"); - PrepareStatement(WorldStatements.SEL_WAYPOINT_PATH_BY_PATHID, "SELECT PathId, MoveType, Flags FROM waypoint_path WHERE PathId = ?"); + PrepareStatement(WorldStatements.SEL_WAYPOINT_PATH, "SELECT PathId, MoveType, Flags, Velocity FROM waypoint_path WHERE PathId = ? OR 1 = ?"); + PrepareStatement(WorldStatements.INS_WAYPOINT_PATH, "INSERT INTO waypoint_path (PathId, MoveType, Flags, Velocity, Comment) VALUES (?, ?, ?, ?, ?)"); PrepareStatement(WorldStatements.INS_WAYPOINT_PATH_NODE, "INSERT INTO waypoint_path_node (PathId, NodeId, PositionX, PositionY, PositionZ, Orientation) VALUES (?, ?, ?, ?, ?, ?)"); + PrepareStatement(WorldStatements.SEL_WAYPOINT_PATH_NODE, "SELECT PathId, NodeId, PositionX, PositionY, PositionZ, Orientation, Delay FROM waypoint_path_node WHERE PathId = ? OR 1 = ? ORDER BY NodeId"); PrepareStatement(WorldStatements.DEL_WAYPOINT_PATH_NODE, "DELETE FROM waypoint_path_node WHERE PathId = ? AND NodeId = ?"); PrepareStatement(WorldStatements.UPD_WAYPOINT_PATH_NODE, "UPDATE waypoint_path_node SET NodeId = NodeId - 1 WHERE PathId = ? AND NodeId > ?"); PrepareStatement(WorldStatements.UPD_WAYPOINT_PATH_NODE_POSITION, "UPDATE waypoint_path_node SET PositionX = ?, PositionY = ?, PositionZ = ?, Orientation = ? WHERE PathId = ? AND NodeId = ?"); PrepareStatement(WorldStatements.SEL_WAYPOINT_PATH_NODE_MAX_PATHID, "SELECT MAX(PathId) FROM waypoint_path_node"); PrepareStatement(WorldStatements.SEL_WAYPOINT_PATH_NODE_MAX_NODEID, "SELECT MAX(NodeId) FROM waypoint_path_node WHERE PathId = ?"); - PrepareStatement(WorldStatements.SEL_WAYPOINT_PATH_NODE_BY_PATHID, "SELECT PathId, NodeId, PositionX, PositionY, PositionZ, Orientation, Delay FROM waypoint_path_node WHERE PathId = ? ORDER BY NodeId"); PrepareStatement(WorldStatements.SEL_WAYPOINT_PATH_NODE_POS_BY_PATHID, "SELECT NodeId, PositionX, PositionY, PositionZ, Orientation FROM waypoint_path_node WHERE PathId = ?"); PrepareStatement(WorldStatements.SEL_WAYPOINT_PATH_NODE_POS_FIRST_BY_PATHID, "SELECT PositionX, PositionY, PositionZ, Orientation FROM waypoint_path_node WHERE NodeId = 1 AND PathId = ?"); PrepareStatement(WorldStatements.SEL_WAYPOINT_PATH_NODE_POS_LAST_BY_PATHID, "SELECT PositionX, PositionY, PositionZ, Orientation FROM waypoint_path_node WHERE PathId = ? ORDER BY NodeId DESC LIMIT 1"); @@ -89,13 +90,14 @@ namespace Framework.Database UPD_CREATURE_WANDER_DISTANCE, UPD_CREATURE_SPAWN_TIME_SECS, INS_CREATURE_FORMATION, - SEL_WAYPOINT_PATH_BY_PATHID, + SEL_WAYPOINT_PATH, + INS_WAYPOINT_PATH, + SEL_WAYPOINT_PATH_NODE, INS_WAYPOINT_PATH_NODE, DEL_WAYPOINT_PATH_NODE, UPD_WAYPOINT_PATH_NODE, UPD_WAYPOINT_PATH_NODE_POSITION, SEL_WAYPOINT_PATH_NODE_MAX_PATHID, - SEL_WAYPOINT_PATH_NODE_BY_PATHID, SEL_WAYPOINT_PATH_NODE_POS_BY_PATHID, SEL_WAYPOINT_PATH_NODE_POS_FIRST_BY_PATHID, SEL_WAYPOINT_PATH_NODE_POS_LAST_BY_PATHID, diff --git a/Source/Game/Chat/Commands/WPCommands.cs b/Source/Game/Chat/Commands/WPCommands.cs index c7605007b..1f034b827 100644 --- a/Source/Game/Chat/Commands/WPCommands.cs +++ b/Source/Game/Chat/Commands/WPCommands.cs @@ -16,14 +16,13 @@ namespace Game.Chat.Commands class WPCommands { [Command("add", RBACPermissions.CommandWpAdd)] - static bool HandleWpAddCommand(CommandHandler handler, uint? optionalpathId) + static bool HandleWpAddCommand(CommandHandler handler, uint? pathId) { Creature target = handler.GetSelectedCreature(); PreparedStatement stmt; - uint pathId; - if (!optionalpathId.HasValue) + if (!pathId.HasValue) { if (target != null) pathId = target.GetWaypointPathId(); @@ -35,22 +34,28 @@ namespace Game.Chat.Commands uint maxpathId = result1.Read(0); pathId = maxpathId + 1; handler.SendSysMessage("|cff00ff00New path started.|r"); + + stmt = WorldDatabase.GetPreparedStatement(WorldStatements.INS_WAYPOINT_PATH); + stmt.AddValue(0, pathId.Value); // PathId + stmt.AddValue(1, (byte)WaypointMoveType.Walk); // MoveType + stmt.AddValue(2, (byte)WaypointPathFlags.None); // Flags + stmt.AddNull(3); // Velocity + stmt.AddValue(4, "Created by .wp add"); // Comment + DB.World.Execute(stmt); } } - else - pathId = optionalpathId.Value; // pathId . ID of the Path // point . number of the waypoint (if not 0) - if (pathId == 0) + if (!pathId.HasValue || pathId.Value == 0) { handler.SendSysMessage("|cffff33ffCurrent creature haven't loaded path.|r"); return true; } stmt = WorldDatabase.GetPreparedStatement(WorldStatements.SEL_WAYPOINT_PATH_NODE_MAX_NODEID); - stmt.AddValue(0, pathId); + stmt.AddValue(0, pathId.Value); SQLResult result = DB.World.Query(stmt); uint nodeId = 0; @@ -60,7 +65,7 @@ namespace Game.Chat.Commands Player player = handler.GetPlayer(); stmt = WorldDatabase.GetPreparedStatement(WorldStatements.INS_WAYPOINT_PATH_NODE); - stmt.AddValue(0, pathId); + stmt.AddValue(0, pathId.Value); stmt.AddValue(1, nodeId); stmt.AddValue(2, player.GetPositionX()); stmt.AddValue(3, player.GetPositionY()); @@ -72,30 +77,23 @@ namespace Game.Chat.Commands { uint displayId = target.GetDisplayId(); - WaypointPath path = Global.WaypointMgr.GetPath(pathId); + WaypointPath path = Global.WaypointMgr.GetPath(pathId.Value); if (path == null) return true; Global.WaypointMgr.DevisualizePath(player, path); - Global.WaypointMgr.ReloadPath(pathId); + Global.WaypointMgr.ReloadPath(pathId.Value); Global.WaypointMgr.VisualizePath(player, path, displayId); } - handler.SendSysMessage("|cff00ff00pathId: |r|cff00ffff{pathId}|r|cff00ff00: Waypoint |r|cff00ffff{nodeId}|r|cff00ff00 created. "); + handler.SendSysMessage($"|cff00ff00pathId: |r|cff00ffff{pathId.Value}|r|cff00ff00: Waypoint |r|cff00ffff{nodeId}|r|cff00ff00 created. "); return true; } [Command("load", RBACPermissions.CommandWpLoad)] - static bool HandleWpLoadCommand(CommandHandler handler, uint? optionalpathId) + static bool HandleWpLoadCommand(CommandHandler handler, uint? pathId) { Creature target = handler.GetSelectedCreature(); - - // Did player provide a pathId? - if (!optionalpathId.HasValue) - return false; - - uint pathId = optionalpathId.Value; - if (target == null) { handler.SendSysMessage(CypherStrings.SelectCreature); @@ -123,14 +121,14 @@ namespace Game.Chat.Commands if (!result.IsEmpty()) { stmt = WorldDatabase.GetPreparedStatement(WorldStatements.UPD_CREATURE_ADDON_PATH); - stmt.AddValue(0, pathId); + stmt.AddValue(0, pathId.Value); stmt.AddValue(1, guidLow); } else { stmt = WorldDatabase.GetPreparedStatement(WorldStatements.INS_CREATURE_ADDON); stmt.AddValue(0, guidLow); - stmt.AddValue(1, pathId); + stmt.AddValue(1, pathId.Value); } DB.World.Execute(stmt); @@ -141,7 +139,7 @@ namespace Game.Chat.Commands DB.World.Execute(stmt); - target.LoadPath(pathId); + target.LoadPath(pathId.Value); target.SetDefaultMovementType(MovementGeneratorType.Waypoint); target.GetMotionMaster().Initialize(); target.Say("Path loaded.", Language.Universal); @@ -150,7 +148,7 @@ namespace Game.Chat.Commands } [Command("modify", RBACPermissions.CommandWpModify)] - static bool HandleWpModifyCommand(CommandHandler handler, string subCommand, [OptionalArg] string arg) + static bool HandleWpModifyCommand(CommandHandler handler, string subCommand) { // first arg: add del text emote spell waittime move if (subCommand.IsEmpty()) @@ -198,7 +196,7 @@ namespace Game.Chat.Commands } else if (subCommand == "move") { - handler.SendSysMessage("|cff00ff00DEBUG: .wp move, pathId: |r|cff00ffff%u|r, NodeId: |r|cff00ffff%u|r", path.Id, node.Id); + handler.SendSysMessage("|cff00ff00DEBUG: .wp modify move, pathId: |r|cff00ffff%u|r, NodeId: |r|cff00ffff%u|r", path.Id, node.Id); uint displayId = target.GetDisplayId(); @@ -215,28 +213,27 @@ namespace Game.Chat.Commands } [Command("reload", RBACPermissions.CommandWpReload)] - static bool HandleWpReloadCommand(CommandHandler handler, uint pathId) + static bool HandleWpReloadCommand(CommandHandler handler, uint id) { - if (pathId == 0) + if (id == 0) return false; - handler.SendSysMessage("|cff00ff00Loading Path: |r|cff00ffff{0}|r", pathId); - Global.WaypointMgr.ReloadPath(pathId); + handler.SendSysMessage($"|cff00ff00Loading Path: |r|cff00ffff{id}|r"); + Global.WaypointMgr.ReloadPath(id); return true; } [Command("show", RBACPermissions.CommandWpShow)] - static bool HandleWpShowCommand(CommandHandler handler, string subCommand, uint? optionalpathId) + static bool HandleWpShowCommand(CommandHandler handler, string subCommand, uint? pathId) { // first arg: on, off, first, last if (subCommand.IsEmpty()) return false; - uint pathId; Creature target = handler.GetSelectedCreature(); // Did player provide a pathId? - if (!optionalpathId.HasValue) + if (!pathId.HasValue) { // No pathId provided // . Player must have selected a creature @@ -256,8 +253,6 @@ namespace Game.Chat.Commands // . Creature selection is ignored <- if (target != null) handler.SendSysMessage(CypherStrings.WaypointCreatselected); - - pathId = optionalpathId.Value; } // Show info for the selected waypoint @@ -297,16 +292,16 @@ namespace Game.Chat.Commands } else if (subCommand == "on") { - WaypointPath path = Global.WaypointMgr.GetPath(pathId); + WaypointPath path = Global.WaypointMgr.GetPath(pathId.Value); if (path == null) { - handler.SendSysMessage($"|cff00ff00Path does not exist: id {pathId}|r"); + handler.SendSysMessage($"|cff00ff00Path does not exist: id {pathId.Value}|r"); return true; } if (path.Nodes.Empty()) { - handler.SendSysMessage($"|cff00ff00Path does not have any nodes: id {pathId}|r"); + handler.SendSysMessage($"|cff00ff00Path does not have any nodes: id {pathId.Value}|r"); return true; } @@ -328,10 +323,10 @@ namespace Game.Chat.Commands } else if (subCommand == "off") { - WaypointPath path = Global.WaypointMgr.GetPath(pathId); + WaypointPath path = Global.WaypointMgr.GetPath(pathId.Value); if (path == null) { - handler.SendSysMessage($"|cff00ff00Path does not exist: id {pathId}|r"); + handler.SendSysMessage($"|cff00ff00Path does not exist: id {pathId.Value}|r"); return true; } diff --git a/Source/Game/Movement/WaypointManager.cs b/Source/Game/Movement/WaypointManager.cs index a3f849166..a6f0f3284 100644 --- a/Source/Game/Movement/WaypointManager.cs +++ b/Source/Game/Movement/WaypointManager.cs @@ -27,8 +27,11 @@ namespace Game var oldMSTime = Time.GetMSTime(); - // 0 1 2 3 - SQLResult result = DB.World.Query("SELECT PathId, MoveType, Flags, Velocity FROM waypoint_path"); + PreparedStatement stmt = WorldDatabase.GetPreparedStatement(WorldStatements.SEL_WAYPOINT_PATH); + stmt.AddValue(0, 0); + stmt.AddValue(1, 1); + + SQLResult result = DB.World.Query(stmt); if (result.IsEmpty()) { Log.outInfo(LogFilter.ServerLoading, "Loaded 0 waypoint paths. DB table `waypoint_path` is empty!"); @@ -39,7 +42,7 @@ namespace Game do { - LoadPathFromDB(result.GetFields()); + LoadPathFromDB(result); ++count; } while (result.NextRow()); @@ -50,8 +53,11 @@ namespace Game { uint oldMSTime = Time.GetMSTime(); - // 0 1 2 3 4 5 6 - SQLResult result = DB.World.Query("SELECT PathId, NodeId, PositionX, PositionY, PositionZ, Orientation, Delay FROM waypoint_path_node ORDER BY PathId, NodeId"); + PreparedStatement stmt = WorldDatabase.GetPreparedStatement(WorldStatements.SEL_WAYPOINT_PATH_NODE); + stmt.AddValue(0, 0); + stmt.AddValue(1, 1); + + SQLResult result = DB.World.Query(stmt); if (result.IsEmpty()) { Log.outInfo(LogFilter.ServerLoading, "Loaded 0 waypoint path nodes. DB table `waypoint_path_node` is empty!"); @@ -62,7 +68,7 @@ namespace Game do { - LoadPathNodesFromDB(result.GetFields()); + LoadPathNodesFromDB(result); ++count; } while (result.NextRow()); @@ -70,12 +76,12 @@ namespace Game Log.outInfo(LogFilter.ServerLoading, $"Loaded {count} waypoint path nodes in {Time.GetMSTimeDiffToNow(oldMSTime)} ms"); } - void LoadPathFromDB(SQLFields fields) + void LoadPathFromDB(SQLResult result) { - uint pathId = fields.Read(0); + uint pathId = result.Read(0); WaypointPath path = new(); - path.MoveType = (WaypointMoveType)fields.Read(1); + path.MoveType = (WaypointMoveType)result.Read(1); if (path.MoveType >= WaypointMoveType.Max) { @@ -84,11 +90,11 @@ namespace Game } path.Id = pathId; - path.Flags = (WaypointPathFlags)fields.Read(2); + path.Flags = (WaypointPathFlags)result.Read(2); - if (!fields.IsNull(3)) + if (!result.IsNull(3)) { - float velocity = fields.Read(3); + float velocity = result.Read(3); if (velocity > 0.0f) path.Velocity = velocity; else @@ -100,9 +106,9 @@ namespace Game _pathStorage.Add(pathId, path); } - void LoadPathNodesFromDB(SQLFields fields) + void LoadPathNodesFromDB(SQLResult result) { - uint pathId = fields.Read(0); + uint pathId = result.Read(0); if (!_pathStorage.ContainsKey(pathId)) { @@ -110,22 +116,22 @@ namespace Game return; } - float x = fields.Read(2); - float y = fields.Read(3); - float z = fields.Read(4); + float x = result.Read(2); + float y = result.Read(3); + float z = result.Read(4); float? o = null; - if (!fields.IsNull(5)) - o = fields.Read(5); + if (!result.IsNull(5)) + o = result.Read(5); TimeSpan delay = default; - uint delayMs = fields.Read(6); + uint delayMs = result.Read(6); if (delayMs != 0) delay = TimeSpan.FromMilliseconds(delayMs); GridDefines.NormalizeMapCoord(ref x); GridDefines.NormalizeMapCoord(ref y); - WaypointNode waypoint = new(fields.Read(1), x, y, z, o, delay); + WaypointNode waypoint = new(result.Read(1), x, y, z, o, delay); _pathStorage[pathId].Nodes.Add(waypoint); } @@ -146,8 +152,10 @@ namespace Game public void ReloadPath(uint pathId) { // waypoint_path - PreparedStatement stmt = WorldDatabase.GetPreparedStatement(WorldStatements.SEL_WAYPOINT_PATH_BY_PATHID); + PreparedStatement stmt = WorldDatabase.GetPreparedStatement(WorldStatements.SEL_WAYPOINT_PATH); stmt.AddValue(0, pathId); + stmt.AddValue(1, 0); + SQLResult result = DB.World.Query(stmt); if (result.IsEmpty()) { @@ -157,12 +165,13 @@ namespace Game do { - LoadPathFromDB(result.GetFields()); + LoadPathFromDB(result); } while (result.NextRow()); // waypoint_path_data - stmt = WorldDatabase.GetPreparedStatement(WorldStatements.SEL_WAYPOINT_PATH_NODE_BY_PATHID); + stmt = WorldDatabase.GetPreparedStatement(WorldStatements.SEL_WAYPOINT_PATH_NODE); stmt.AddValue(0, pathId); + stmt.AddValue(1, 0); result = DB.World.Query(stmt); if (result.IsEmpty()) @@ -173,7 +182,7 @@ namespace Game do { - LoadPathNodesFromDB(result.GetFields()); + LoadPathNodesFromDB(result); } while (result.NextRow()); WaypointPath path = _pathStorage.LookupByKey(pathId);