TrinityCore
Loading...
Searching...
No Matches
cs_wp.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/* ScriptData
19Name: wp_commandscript
20%Complete: 100
21Comment: All wp related commands
22Category: commandscripts
23EndScriptData */
24
25#include "ScriptMgr.h"
26#include "Chat.h"
27#include "ChatCommand.h"
28#include "Creature.h"
29#include "DatabaseEnv.h"
30#include "Language.h"
31#include "Map.h"
32#include "MotionMaster.h"
33#include "ObjectMgr.h"
34#include "PhasingHandler.h"
35#include "Player.h"
36#include "RBAC.h"
37#include "WaypointManager.h"
38
39using namespace Trinity::ChatCommands;
40
42{
43public:
44 wp_commandscript() : CommandScript("wp_commandscript") { }
45
46 std::span<ChatCommandBuilder const> GetCommands() const override
47 {
48 static ChatCommandTable wpCommandTable =
49 {
56 };
57 static ChatCommandTable commandTable =
58 {
59 { "wp", wpCommandTable },
60 };
61 return commandTable;
62 }
84 static bool HandleWpAddCommand(ChatHandler* handler, Optional<uint32> pathid)
85 {
86 Creature* target = handler->getSelectedCreature();
87
88 if (!pathid)
89 {
90 if (target)
91 pathid = target->GetWaypointPathId();
92 else
93 {
95
96 PreparedQueryResult result = WorldDatabase.Query(stmt);
97
98 uint32 maxpathid = result->Fetch()->GetInt32();
99 pathid = maxpathid+1;
100 handler->PSendSysMessage("%s%s|r", "|cff00ff00", "New path started.");
101
102 stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_WAYPOINT_PATH);
103 stmt->setUInt32(0, *pathid); // PathId
104 stmt->setUInt8(1, AsUnderlyingType(WaypointMoveType::Walk)); // MoveType
106 stmt->setNull(3); // Velocity
107 stmt->setString(4, "Created by .wp add"sv); // Comment
108 WorldDatabase.Execute(stmt);
109 }
110 }
111
112 // PathId -> ID of the Path
113 // point -> number of the waypoint (if not 0)
114 if (!pathid || pathid == 0u)
115 {
116 handler->PSendSysMessage("%s%s|r", "|cffff33ff", "Current creature haven't loaded path.");
117 return true;
118 }
119
121 stmt->setUInt32(0, *pathid);
122 PreparedQueryResult result = WorldDatabase.Query(stmt);
123
124 uint32 nodeId = 0;
125 if (result)
126 nodeId = (*result)[0].GetUInt32() + 1;
127
128 Player* player = handler->GetPlayer();
129
130 stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_WAYPOINT_PATH_NODE);
131 stmt->setUInt32(0, *pathid);
132 stmt->setUInt32(1, nodeId);
133 stmt->setFloat(2, player->GetPositionX());
134 stmt->setFloat(3, player->GetPositionY());
135 stmt->setFloat(4, player->GetPositionZ());
136 stmt->setFloat(5, player->GetOrientation());
137 WorldDatabase.Execute(stmt);
138
139 if (target)
140 {
141 uint32 displayId = target->GetDisplayId();
142
143 WaypointPath const* path = sWaypointMgr->GetPath(*pathid);
144 if (!path)
145 return true;
146
147 sWaypointMgr->DevisualizePath(handler->GetPlayer(), path);
148 sWaypointMgr->ReloadPath(*pathid);
149 sWaypointMgr->VisualizePath(handler->GetPlayer(), path, displayId);
150 }
151
152 handler->PSendSysMessage("%s%s%u%s%u%s|r", "|cff00ff00", "PathID: |r|cff00ffff", *pathid, "|r|cff00ff00: Waypoint |r|cff00ffff", nodeId, "|r|cff00ff00 created. ");
153 return true;
154 } // HandleWpAddCommand
155
156 static bool HandleWpLoadCommand(ChatHandler* handler, uint32 pathid)
157 {
158 Creature* target = handler->getSelectedCreature();
159
160 if (!target)
161 {
163 handler->SetSentErrorMessage(true);
164 return false;
165 }
166
167 if (target->GetEntry() == 1)
168 {
169 handler->PSendSysMessage("%s%s|r", "|cffff33ff", "You want to load path to a waypoint? Aren't you?");
170 handler->SetSentErrorMessage(true);
171 return false;
172 }
173
174 if (!pathid || !sWaypointMgr->GetPath(pathid))
175 {
176 handler->PSendSysMessage("%s%s|r", "|cffff33ff", "No valid path number provided.");
177 return true;
178 }
179
180 ObjectGuid::LowType guidLow = target->GetSpawnId();
181
183
184 stmt->setUInt64(0, guidLow);
185
186 PreparedQueryResult result = WorldDatabase.Query(stmt);
187
188 if (result)
189 {
190 stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_ADDON_PATH);
191
192 stmt->setUInt32(0, pathid);
193 stmt->setUInt64(1, guidLow);
194 }
195 else
196 {
197 stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_CREATURE_ADDON);
198
199 stmt->setUInt64(0, guidLow);
200 stmt->setUInt32(1, pathid);
201 }
202
203 WorldDatabase.Execute(stmt);
204
205 stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_MOVEMENT_TYPE);
207 stmt->setUInt64(1, guidLow);
208 WorldDatabase.Execute(stmt);
209
210 target->LoadPath(pathid);
212 target->GetMotionMaster()->Initialize();
213 target->Say("Path loaded.", LANG_UNIVERSAL);
214
215 return true;
216 }
217
218 static bool HandleWpReloadCommand(ChatHandler* handler, uint32 id)
219 {
220 if (!id)
221 return false;
222
223 handler->PSendSysMessage("%s%s|r|cff00ffff%u|r", "|cff00ff00", "Loading Path: ", id);
224 sWaypointMgr->ReloadPath(id);
225 return true;
226 }
227
228 static bool HandleWpUnLoadCommand(ChatHandler* handler)
229 {
230 Creature* target = handler->getSelectedCreature();
231 WorldDatabasePreparedStatement* stmt = nullptr;
232
233 if (!target)
234 {
235 handler->PSendSysMessage("%s%s|r", "|cff33ffff", "You must select a target.");
236 return true;
237 }
238
239 ObjectGuid::LowType guidLow = target->GetSpawnId();
240 if (!guidLow)
241 {
242 handler->PSendSysMessage("%s%s|r", "|cffff33ff", "Target is not saved to DB.");
243 return true;
244 }
245
246 CreatureAddon const* addon = sObjectMgr->GetCreatureAddon(guidLow);
247 if (!addon || addon->PathId == 0)
248 {
249 handler->PSendSysMessage("%s%s|r", "|cffff33ff", "Target does not have a loaded path.");
250 return true;
251 }
252
253 stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE_ADDON);
254 stmt->setUInt64(0, guidLow);
255 WorldDatabase.Execute(stmt);
256
257 target->UpdateCurrentWaypointInfo(0, 0);
258
259 stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_MOVEMENT_TYPE);
261 stmt->setUInt64(1, guidLow);
262 WorldDatabase.Execute(stmt);
263
264 target->LoadPath(0);
267 target->GetMotionMaster()->Initialize();
268 target->Say("Path unloaded.", LANG_UNIVERSAL);
269 return true;
270 }
271
272 static bool HandleWpModifyCommand(ChatHandler* handler, Variant<EXACT_SEQUENCE("del"), EXACT_SEQUENCE("move")> show)
273 {
274 // Did user provide a GUID
275 // or did the user select a creature?
276 // -> variable lowguid is filled with the GUID of the NPC
277 Creature* target = handler->getSelectedCreature();
278
279 // User did select a visual waypoint?
280 if (!target || target->GetEntry() != VISUAL_WAYPOINT)
281 {
282 handler->SendSysMessage("|cffff33ffERROR: You must select a waypoint.|r");
283 return false;
284 }
285
286 WaypointPath const* path = sWaypointMgr->GetPathByVisualGUID(target->GetGUID());
287 if (!path)
288 {
289 handler->PSendSysMessage("|cff00ff00Path does not exist or target has no path|r");
290 handler->SetSentErrorMessage(true);
291 return false;
292 }
293
294 WaypointNode const* node = sWaypointMgr->GetNodeByVisualGUID(target->GetGUID());
295 if (!node)
296 {
297 handler->PSendSysMessage("|cff00ff00Path does not exist or target has no path|r");
298 handler->SetSentErrorMessage(true);
299 return false;
300 }
301
302 if (show.holds_alternative<EXACT_SEQUENCE("del")>())
303 {
304 handler->PSendSysMessage("|cff00ff00DEBUG: .wp modify del, PathId: |r|cff00ffff%u|r, NodeId: |r|cff00ffff%u|r", path->Id, node->Id);
305
306 uint32 displayId = target->GetDisplayId();
307
308 sWaypointMgr->DevisualizePath(handler->GetPlayer(), path);
309 sWaypointMgr->DeleteNode(path, node);
310 sWaypointMgr->ReloadPath(path->Id);
311 sWaypointMgr->VisualizePath(handler->GetPlayer(), path, displayId);
312
314 return true;
315 }
316 else if (show.holds_alternative<EXACT_SEQUENCE("move")>())
317 {
318 handler->PSendSysMessage("|cff00ff00DEBUG: .wp modify move, PathId: |r|cff00ffff%u|r, NodeId: |r|cff00ffff%u|r", path->Id, node->Id);
319
320 uint32 displayId = target->GetDisplayId();
321
322 sWaypointMgr->DevisualizePath(handler->GetPlayer(), path);
323 sWaypointMgr->MoveNode(path, node, handler->GetPlayer()->GetPosition());
324 sWaypointMgr->ReloadPath(path->Id);
325 sWaypointMgr->VisualizePath(handler->GetPlayer(), path, displayId);
326
328 return true;
329 }
330 return false;
331 }
332
333 static bool HandleWpShowCommand(ChatHandler* handler, Variant<EXACT_SEQUENCE("off"), EXACT_SEQUENCE("on"), EXACT_SEQUENCE("info")> show, Optional<uint32> pathid)
334 {
335 Creature* target = handler->getSelectedCreature();
336
337 // Did player provide a PathID?
338 if (!pathid)
339 {
340 // No PathID provided
341 // -> Player must have selected a creature
342
343 if (!target)
344 {
346 handler->SetSentErrorMessage(true);
347 return false;
348 }
349
350 pathid = target->GetWaypointPathId();
351 }
352 else
353 {
354 // PathID provided
355 // Warn if player also selected a creature
356 // -> Creature selection is ignored <-
357 if (target)
359 }
360
361 // Show info for the selected waypoint
362 if (show.holds_alternative<EXACT_SEQUENCE("info")>())
363 {
364 if (!target || target->GetEntry() != VISUAL_WAYPOINT)
365 {
367 handler->SetSentErrorMessage(true);
368 return false;
369 }
370
371 WaypointPath const* path = sWaypointMgr->GetPathByVisualGUID(target->GetGUID());
372 if (!path)
373 {
374 handler->PSendSysMessage("|cff00ff00Path does not exist or target has no path|r");
375 handler->SetSentErrorMessage(true);
376 return false;
377 }
378
379 WaypointNode const* node = sWaypointMgr->GetNodeByVisualGUID(target->GetGUID());
380 if (!node)
381 {
382 handler->PSendSysMessage("|cff00ff00Path does not exist or target has no path|r");
383 handler->SetSentErrorMessage(true);
384 return false;
385 }
386
387 handler->SendSysMessage("|cff00ffffDEBUG: .wp show info:|r");
388 handler->PSendSysMessage("|cff00ff00Show info: Path Id: |r|cff00ffff%u|r", path->Id);
389 handler->PSendSysMessage("|cff00ff00Show info: Path MoveType: |r|cff00ffff%u|r", AsUnderlyingType(path->MoveType));
390 handler->PSendSysMessage("|cff00ff00Show info: Path Flags: |r|cff00ffff%u|r", path->Flags.AsUnderlyingType());
391 handler->PSendSysMessage("|cff00ff00Show info: Node Id: |r|cff00ffff%u|r", node->Id);
392 handler->PSendSysMessage("|cff00ff00Show info: Node Delay: |r|cff00ffff%u|r", node->Id);
393
394 return true;
395 }
396 else if (show.holds_alternative<EXACT_SEQUENCE("on")>())
397 {
398 WaypointPath const* path = sWaypointMgr->GetPath(*pathid);
399 if (!path)
400 {
401 handler->PSendSysMessage("|cff00ff00Path does not exist: id %u|r", *pathid);
402 return true;
403 }
404
405 if (path->Nodes.empty())
406 {
407 handler->PSendSysMessage("|cff00ff00Path does not have any nodes: id %u|r", *pathid);
408 return true;
409 }
410
411 Optional<uint32> displayId;
412 if (target)
413 displayId = target->GetDisplayId();
414
415 sWaypointMgr->VisualizePath(handler->GetPlayer(), path, displayId);
416
417 ObjectGuid const& guid = sWaypointMgr->GetVisualGUIDByNode(path->Id, path->Nodes.front().Id);
418 if (!guid.IsEmpty())
419 {
420 handler->PSendSysMessage("|cff00ff00Path with id %u is already showing.|r", *pathid);
421 return true;
422 }
423
424 handler->PSendSysMessage("|cff00ff00Showing path with id %u.|r", *pathid);
425 return true;
426 }
427 else if (show.holds_alternative<EXACT_SEQUENCE("off")>())
428 {
429 WaypointPath const* path = sWaypointMgr->GetPath(*pathid);
430 if (!path)
431 {
432 handler->PSendSysMessage("|cff00ff00Path does not exist: id %u|r", *pathid);
433 return true;
434 }
435
436 sWaypointMgr->DevisualizePath(handler->GetPlayer(), path);
437
439 return true;
440 }
441
442 handler->PSendSysMessage("|cffff33ffDEBUG: .wp show - no valid command found|r");
443 return true;
444 }
445};
446
448{
449 new wp_commandscript();
450}
#define EXACT_SEQUENCE(str)
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
uint8_t uint8
Definition Define.h:156
uint32_t uint32
Definition Define.h:154
@ LANG_WAYPOINT_REMOVED
Definition Language.h:288
@ LANG_SELECT_CREATURE
Definition Language.h:32
@ LANG_WAYPOINT_CHANGED
Definition Language.h:283
@ LANG_WAYPOINT_CREATSELECTED
Definition Language.h:271
@ LANG_WAYPOINT_VP_ALLREMOVED
Definition Language.h:276
@ LANG_WAYPOINT_VP_SELECT
Definition Language.h:273
@ IDLE_MOTION_TYPE
@ WAYPOINT_MOTION_TYPE
#define sObjectMgr
Definition ObjectMgr.h:1885
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:25
Role Based Access Control related classes definition.
@ LANG_UNIVERSAL
#define VISUAL_WAYPOINT
Definition Unit.h:35
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
Definition Util.h:565
#define sWaypointMgr
@ WORLD_INS_CREATURE_ADDON
@ WORLD_SEL_CREATURE_ADDON_BY_GUID
@ WORLD_INS_WAYPOINT_PATH_NODE
@ WORLD_INS_WAYPOINT_PATH
@ WORLD_UPD_CREATURE_MOVEMENT_TYPE
@ WORLD_UPD_CREATURE_ADDON_PATH
@ WORLD_DEL_CREATURE_ADDON
@ WORLD_SEL_WAYPOINT_PATH_NODE_MAX_NODEID
@ WORLD_SEL_WAYPOINT_PATH_NODE_MAX_PATHID
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
Creature * getSelectedCreature()
Definition Chat.cpp:240
void SetSentErrorMessage(bool val)
Definition Chat.h:127
Player * GetPlayer() const
Definition Chat.cpp:37
void PSendSysMessage(char const *fmt, Args &&... args)
Definition Chat.h:62
virtual void SendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition Chat.cpp:111
void UpdateCurrentWaypointInfo(uint32 nodeId, uint32 pathId)
Definition Creature.h:401
uint32 GetWaypointPathId() const
Definition Creature.h:396
ObjectGuid::LowType GetSpawnId() const
Definition Creature.h:110
void SetDefaultMovementType(MovementGeneratorType mgt)
Definition Creature.h:164
void LoadPath(uint32 pathid)
Definition Creature.h:397
constexpr std::underlying_type_t< T > AsUnderlyingType() const
Definition EnumFlag.h:122
void MoveTargetedHome()
bool IsEmpty() const
Definition ObjectGuid.h:362
uint64 LowType
Definition ObjectGuid.h:321
uint32 GetEntry() const
Definition Object.h:89
void setString(uint8 index, std::string &&value)
void setUInt32(uint8 index, uint32 value)
void setFloat(uint8 index, float value)
void setUInt64(uint8 index, uint64 value)
void setUInt8(uint8 index, uint8 value)
virtual void Say(std::string_view text, Language language, WorldObject const *target=nullptr)
Definition Unit.cpp:14332
MotionMaster * GetMotionMaster()
Definition Unit.h:1723
uint32 GetDisplayId() const
Definition Unit.h:1610
static bool HandleWpShowCommand(ChatHandler *handler, Variant< EXACT_SEQUENCE("off"), EXACT_SEQUENCE("on"), EXACT_SEQUENCE("info")> show, Optional< uint32 > pathid)
Definition cs_wp.cpp:333
std::span< ChatCommandBuilder const > GetCommands() const override
Definition cs_wp.cpp:46
static bool HandleWpModifyCommand(ChatHandler *handler, Variant< EXACT_SEQUENCE("del"), EXACT_SEQUENCE("move")> show)
Definition cs_wp.cpp:272
static bool HandleWpAddCommand(ChatHandler *handler, Optional< uint32 > pathid)
Definition cs_wp.cpp:84
static bool HandleWpUnLoadCommand(ChatHandler *handler)
Definition cs_wp.cpp:228
static bool HandleWpReloadCommand(ChatHandler *handler, uint32 id)
Definition cs_wp.cpp:218
static bool HandleWpLoadCommand(ChatHandler *handler, uint32 pathid)
Definition cs_wp.cpp:156
void AddSC_wp_commandscript()
Definition cs_wp.cpp:447
ChatCommandBuilder const [] ChatCommandTable
Definition ChatCommand.h:49
@ RBAC_PERM_COMMAND_WP_SHOW
Definition RBAC.h:646
@ RBAC_PERM_COMMAND_WP_MODIFY
Definition RBAC.h:643
@ RBAC_PERM_COMMAND_WP_UNLOAD
Definition RBAC.h:644
@ RBAC_PERM_COMMAND_WP_LOAD
Definition RBAC.h:642
@ RBAC_PERM_COMMAND_WP_ADD
Definition RBAC.h:640
@ RBAC_PERM_COMMAND_WP_RELOAD
Definition RBAC.h:645
constexpr float GetPositionX() const
Definition Position.h:87
constexpr float GetPositionY() const
Definition Position.h:88
constexpr void GetPosition(float &x, float &y) const
Definition Position.h:92
constexpr float GetOrientation() const
Definition Position.h:90
constexpr float GetPositionZ() const
Definition Position.h:89
std::vector< WaypointNode > Nodes
EnumFlag< WaypointPathFlags > Flags
WaypointMoveType MoveType