TrinityCore
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#include "WorldSession.h"
39
40#if TRINITY_COMPILER == TRINITY_COMPILER_GNU
41#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
42#endif
43
45{
46public:
47 wp_commandscript() : CommandScript("wp_commandscript") { }
48
49 std::vector<ChatCommand> GetCommands() const override
50 {
51 static std::vector<ChatCommand> wpCommandTable =
52 {
59 };
60 static std::vector<ChatCommand> commandTable =
61 {
62 { "wp", rbac::RBAC_PERM_COMMAND_WP, false, nullptr, "", wpCommandTable },
63 };
64 return commandTable;
65 }
87 static bool HandleWpAddCommand(ChatHandler* handler, char const* args)
88 {
89 // optional
90 char* path_number = nullptr;
91 uint32 pathid = 0;
92
93 if (*args)
94 path_number = strtok((char*)args, " ");
95
96 Creature* target = handler->getSelectedCreature();
97
98 if (!path_number)
99 {
100 if (target)
101 pathid = target->GetWaypointPathId();
102 else
103 {
105
106 PreparedQueryResult result = WorldDatabase.Query(stmt);
107
108 uint32 maxpathid = result->Fetch()->GetInt32();
109 pathid = maxpathid+1;
110 handler->PSendSysMessage("%s%s|r", "|cff00ff00", "New path started.");
111 }
112 }
113 else
114 pathid = atoi(path_number);
115
116 // PathId -> ID of the Path
117 // point -> number of the waypoint (if not 0)
118
119 if (!pathid)
120 {
121 handler->PSendSysMessage("%s%s|r", "|cffff33ff", "Current creature haven't loaded path.");
122 return true;
123 }
124
126 stmt->setUInt32(0, pathid);
127 PreparedQueryResult result = WorldDatabase.Query(stmt);
128
129 uint32 nodeId = 0;
130 if (result)
131 nodeId = (*result)[0].GetUInt32() + 1;
132
133 Player* player = handler->GetPlayer();
134 //Map* map = player->GetMap();
135
136 stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_WAYPOINT_PATH_NODE);
137 stmt->setUInt32(0, pathid);
138 stmt->setUInt32(1, nodeId);
139 stmt->setFloat(2, player->GetPositionX());
140 stmt->setFloat(3, player->GetPositionY());
141 stmt->setFloat(4, player->GetPositionZ());
142 stmt->setFloat(5, player->GetOrientation());
143 WorldDatabase.Execute(stmt);
144
145 if (target)
146 {
147 uint32 displayId = target->GetDisplayId();
148
149 WaypointPath const* path = sWaypointMgr->GetPath(pathid);
150 if (!path)
151 return true;
152
153 sWaypointMgr->DevisualizePath(handler->GetPlayer(), path);
154 sWaypointMgr->ReloadPath(pathid);
155 sWaypointMgr->VisualizePath(handler->GetPlayer(), path, displayId);
156 }
157
158 handler->PSendSysMessage("%s%s%u%s%u%s|r", "|cff00ff00", "PathID: |r|cff00ffff", pathid, "|r|cff00ff00: Waypoint |r|cff00ffff", nodeId, "|r|cff00ff00 created. ");
159 return true;
160 } // HandleWpAddCommand
161
162 static bool HandleWpLoadCommand(ChatHandler* handler, char const* args)
163 {
164 if (!*args)
165 return false;
166
167 // optional
168 char* path_number = nullptr;
169
170 if (*args)
171 path_number = strtok((char*)args, " ");
172
173 uint32 pathid = 0;
174 ObjectGuid::LowType guidLow = UI64LIT(0);
175 Creature* target = handler->getSelectedCreature();
176
177 // Did player provide a PathId?
178 if (!path_number)
179 return false;
180
181 if (!target)
182 {
184 handler->SetSentErrorMessage(true);
185 return false;
186 }
187
188 if (target->GetEntry() == 1)
189 {
190 handler->PSendSysMessage("%s%s|r", "|cffff33ff", "You want to load path to a waypoint? Aren't you?");
191 handler->SetSentErrorMessage(true);
192 return false;
193 }
194
195 pathid = atoi(path_number);
196
197 if (!pathid)
198 {
199 handler->PSendSysMessage("%s%s|r", "|cffff33ff", "No valid path number provided.");
200 return true;
201 }
202
203 guidLow = target->GetSpawnId();
204
206
207 stmt->setUInt64(0, guidLow);
208
209 PreparedQueryResult result = WorldDatabase.Query(stmt);
210
211 if (result)
212 {
213 stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_ADDON_PATH);
214
215 stmt->setUInt32(0, pathid);
216 stmt->setUInt64(1, guidLow);
217 }
218 else
219 {
220 stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_CREATURE_ADDON);
221
222 stmt->setUInt64(0, guidLow);
223 stmt->setUInt32(1, pathid);
224 }
225
226 WorldDatabase.Execute(stmt);
227
228 stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_MOVEMENT_TYPE);
230 stmt->setUInt64(1, guidLow);
231 WorldDatabase.Execute(stmt);
232
233 target->LoadPath(pathid);
235 target->GetMotionMaster()->Initialize();
236 target->Say("Path loaded.", LANG_UNIVERSAL);
237
238 return true;
239 }
240
241 static bool HandleWpReloadCommand(ChatHandler* handler, char const* args)
242 {
243 if (!*args)
244 return false;
245
246 uint32 id = atoi(args);
247
248 if (!id)
249 return false;
250
251 handler->PSendSysMessage("%s%s|r|cff00ffff%u|r", "|cff00ff00", "Loading Path: ", id);
252 sWaypointMgr->ReloadPath(id);
253 return true;
254 }
255
256 static bool HandleWpUnLoadCommand(ChatHandler* handler, char const* /*args*/)
257 {
258 Creature* target = handler->getSelectedCreature();
259 WorldDatabasePreparedStatement* stmt = nullptr;
260
261 if (!target)
262 {
263 handler->PSendSysMessage("%s%s|r", "|cff33ffff", "You must select a target.");
264 return true;
265 }
266
267 ObjectGuid::LowType guidLow = target->GetSpawnId();
268 if (!guidLow)
269 {
270 handler->PSendSysMessage("%s%s|r", "|cffff33ff", "Target is not saved to DB.");
271 return true;
272 }
273
274 CreatureAddon const* addon = sObjectMgr->GetCreatureAddon(guidLow);
275 if (!addon || addon->PathId == 0)
276 {
277 handler->PSendSysMessage("%s%s|r", "|cffff33ff", "Target does not have a loaded path.");
278 return true;
279 }
280
281 stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE_ADDON);
282 stmt->setUInt64(0, guidLow);
283 WorldDatabase.Execute(stmt);
284
285 target->UpdateCurrentWaypointInfo(0, 0);
286
287 stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_CREATURE_MOVEMENT_TYPE);
289 stmt->setUInt64(1, guidLow);
290 WorldDatabase.Execute(stmt);
291
292 target->LoadPath(0);
295 target->GetMotionMaster()->Initialize();
296 target->Say("Path unloaded.", LANG_UNIVERSAL);
297 return true;
298 }
299
300 static bool HandleWpModifyCommand(ChatHandler* handler, char const* args)
301 {
302 if (!*args)
303 return false;
304
305 // first arg: add del text emote spell waittime move
306 char* show_str = strtok((char*)args, " ");
307 if (!show_str)
308 {
309 return false;
310 }
311
312 std::string show = show_str;
313
314 // Did user provide a GUID
315 // or did the user select a creature?
316 // -> variable lowguid is filled with the GUID of the NPC
317 Creature* target = handler->getSelectedCreature();
318
319 // User did select a visual waypoint?
320 if (!target || target->GetEntry() != VISUAL_WAYPOINT)
321 {
322 handler->SendSysMessage("|cffff33ffERROR: You must select a waypoint.|r");
323 return false;
324 }
325
326 WaypointPath const* path = sWaypointMgr->GetPathByVisualGUID(target->GetGUID());
327 if (!path)
328 {
329 handler->PSendSysMessage("|cff00ff00Path does not exist or target has no path|r");
330 handler->SetSentErrorMessage(true);
331 return false;
332 }
333
334 WaypointNode const* node = sWaypointMgr->GetNodeByVisualGUID(target->GetGUID());
335 if (!node)
336 {
337 handler->PSendSysMessage("|cff00ff00Path does not exist or target has no path|r");
338 handler->SetSentErrorMessage(true);
339 return false;
340 }
341
342 if (show == "del")
343 {
344 handler->PSendSysMessage("|cff00ff00DEBUG: .wp modify del, PathId: |r|cff00ffff%u|r, NodeId: |r|cff00ffff%u|r", path->Id, node->Id);
345
346 uint32 displayId = target->GetDisplayId();
347
348 sWaypointMgr->DevisualizePath(handler->GetPlayer(), path);
349 sWaypointMgr->DeleteNode(path, node);
350 sWaypointMgr->ReloadPath(path->Id);
351 sWaypointMgr->VisualizePath(handler->GetPlayer(), path, displayId);
352
354 return true;
355 }
356 else if (show == "move")
357 {
358 handler->PSendSysMessage("|cff00ff00DEBUG: .wp move, PathId: |r|cff00ffff%u|r, NodeId: |r|cff00ffff%u|r", path->Id, node->Id);
359
360 uint32 displayId = target->GetDisplayId();
361
362 sWaypointMgr->DevisualizePath(handler->GetPlayer(), path);
363 sWaypointMgr->MoveNode(path, node, handler->GetPlayer()->GetPosition());
364 sWaypointMgr->ReloadPath(path->Id);
365 sWaypointMgr->VisualizePath(handler->GetPlayer(), path, displayId);
366
368 return true;
369 }
370 return false;
371 }
372
373 static bool HandleWpShowCommand(ChatHandler* handler, char const* args)
374 {
375 if (!*args)
376 return false;
377
378 // first arg: on, off, first, last
379 char* show_str = strtok((char*)args, " ");
380 if (!show_str)
381 return false;
382
383 // second arg: GUID (optional, if a creature is selected)
384 char* guid_str = strtok((char*)nullptr, " ");
385
386 uint32 pathid = 0;
387 Creature* target = handler->getSelectedCreature();
388
389 // Did player provide a PathID?
390 if (!guid_str)
391 {
392 // No PathID provided
393 // -> Player must have selected a creature
394
395 if (!target)
396 {
398 handler->SetSentErrorMessage(true);
399 return false;
400 }
401
402 pathid = target->GetWaypointPathId();
403 }
404 else
405 {
406 // PathID provided
407 // Warn if player also selected a creature
408 // -> Creature selection is ignored <-
409 if (target)
411
412 pathid = Trinity::StringTo<uint32>(guid_str).value_or(0);
413 }
414
415 std::string show = show_str;
416
417 //handler->PSendSysMessage("wpshow - show: %s", show);
418
419 // Show info for the selected waypoint
420 if (show == "info")
421 {
422 if (!target || target->GetEntry() != VISUAL_WAYPOINT)
423 {
425 handler->SetSentErrorMessage(true);
426 return false;
427 }
428
429 WaypointPath const* path = sWaypointMgr->GetPathByVisualGUID(target->GetGUID());
430 if (!path)
431 {
432 handler->PSendSysMessage("|cff00ff00Path does not exist or target has no path|r");
433 handler->SetSentErrorMessage(true);
434 return false;
435 }
436
437 WaypointNode const* node = sWaypointMgr->GetNodeByVisualGUID(target->GetGUID());
438 if (!node)
439 {
440 handler->PSendSysMessage("|cff00ff00Path does not exist or target has no path|r");
441 handler->SetSentErrorMessage(true);
442 return false;
443 }
444
445 handler->SendSysMessage("|cff00ffffDEBUG: .wp show info:|r");
446 handler->PSendSysMessage("|cff00ff00Show info: Path Id: |r|cff00ffff%u|r", path->Id);
447 handler->PSendSysMessage("|cff00ff00Show info: Path MoveType: |r|cff00ffff%u|r", AsUnderlyingType(path->MoveType));
448 handler->PSendSysMessage("|cff00ff00Show info: Path Flags: |r|cff00ffff%u|r", path->Flags.AsUnderlyingType());
449 handler->PSendSysMessage("|cff00ff00Show info: Node Id: |r|cff00ffff%u|r", node->Id);
450 handler->PSendSysMessage("|cff00ff00Show info: Node Delay: |r|cff00ffff%u|r", node->Id);
451
452 return true;
453 }
454 else if (show == "on")
455 {
456 WaypointPath const* path = sWaypointMgr->GetPath(pathid);
457 if (!path)
458 {
459 handler->PSendSysMessage("|cff00ff00Path does not exist: id %u|r", pathid);
460 return true;
461 }
462
463 if (path->Nodes.empty())
464 {
465 handler->PSendSysMessage("|cff00ff00Path does not have any nodes: id %u|r", pathid);
466 return true;
467 }
468
469 Optional<uint32> displayId;
470 if (target)
471 displayId = target->GetDisplayId();
472
473 sWaypointMgr->VisualizePath(handler->GetPlayer(), path, displayId);
474
475 ObjectGuid const& guid = sWaypointMgr->GetVisualGUIDByNode(path->Id, path->Nodes.front().Id);
476 if (!guid.IsEmpty())
477 {
478 handler->SendSysMessage("|cff00ff00Path with id %u is already showing.|r", pathid);
479 return true;
480 }
481
482 handler->SendSysMessage("|cff00ff00Showing path with id %u.|r", pathid);
483 return true;
484 }
485 else if (show == "off")
486 {
487 WaypointPath const* path = sWaypointMgr->GetPath(pathid);
488 if (!path)
489 {
490 handler->PSendSysMessage("|cff00ff00Path does not exist: id %u|r", pathid);
491 return true;
492 }
493
494 sWaypointMgr->DevisualizePath(handler->GetPlayer(), path);
495
497 return true;
498 }
499
500 handler->PSendSysMessage("|cffff33ffDEBUG: .wp show - no valid command found|r");
501 return true;
502 }
503};
504
506{
507 new wp_commandscript();
508}
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
Definition: DatabaseEnv.cpp:20
uint8_t uint8
Definition: Define.h:144
#define UI64LIT(N)
Definition: Define.h:127
uint32_t uint32
Definition: Define.h:142
@ LANG_WAYPOINT_REMOVED
Definition: Language.h:289
@ LANG_SELECT_CREATURE
Definition: Language.h:32
@ LANG_WAYPOINT_CHANGED
Definition: Language.h:284
@ LANG_WAYPOINT_CREATSELECTED
Definition: Language.h:272
@ LANG_WAYPOINT_VP_ALLREMOVED
Definition: Language.h:277
@ LANG_WAYPOINT_VP_SELECT
Definition: Language.h:274
@ IDLE_MOTION_TYPE
@ WAYPOINT_MOTION_TYPE
#define sObjectMgr
Definition: ObjectMgr.h:1946
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:491
#define sWaypointMgr
@ WORLD_INS_CREATURE_ADDON
Definition: WorldDatabase.h:65
@ WORLD_SEL_CREATURE_ADDON_BY_GUID
Definition: WorldDatabase.h:67
@ WORLD_INS_WAYPOINT_PATH_NODE
Definition: WorldDatabase.h:53
@ WORLD_UPD_CREATURE_MOVEMENT_TYPE
Definition: WorldDatabase.h:45
@ WORLD_UPD_CREATURE_ADDON_PATH
Definition: WorldDatabase.h:64
@ WORLD_DEL_CREATURE_ADDON
Definition: WorldDatabase.h:66
@ WORLD_SEL_WAYPOINT_PATH_NODE_MAX_NODEID
Definition: WorldDatabase.h:62
@ WORLD_SEL_WAYPOINT_PATH_NODE_MAX_PATHID
Definition: WorldDatabase.h:57
void PSendSysMessage(const char *fmt, Args &&... args)
Definition: Chat.h:57
Creature * getSelectedCreature()
Definition: Chat.cpp:236
void SetSentErrorMessage(bool val)
Definition: Chat.h:114
Player * GetPlayer() const
Definition: Chat.cpp:39
virtual void SendSysMessage(std::string_view str, bool escapeCharacters=false)
Definition: Chat.cpp:113
void UpdateCurrentWaypointInfo(uint32 nodeId, uint32 pathId)
Definition: Creature.h:386
uint32 GetWaypointPathId() const
Definition: Creature.h:381
ObjectGuid::LowType GetSpawnId() const
Definition: Creature.h:98
void SetDefaultMovementType(MovementGeneratorType mgt)
Definition: Creature.h:150
void LoadPath(uint32 pathid)
Definition: Creature.h:382
constexpr std::underlying_type_t< T > AsUnderlyingType() const
Definition: EnumFlag.h:122
void Initialize()
void MoveTargetedHome()
bool IsEmpty() const
Definition: ObjectGuid.h:319
uint64 LowType
Definition: ObjectGuid.h:278
uint32 GetEntry() const
Definition: Object.h:161
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
void setFloat(const uint8 index, const float value)
void setUInt8(const uint8 index, const uint8 value)
void setUInt32(const uint8 index, const uint32 value)
void setUInt64(const uint8 index, const uint64 value)
virtual void Say(std::string_view text, Language language, WorldObject const *target=nullptr)
Definition: Unit.cpp:13562
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
uint32 GetDisplayId() const
Definition: Unit.h:1567
static bool HandleWpShowCommand(ChatHandler *handler, char const *args)
Definition: cs_wp.cpp:373
static bool HandleWpAddCommand(ChatHandler *handler, char const *args)
Definition: cs_wp.cpp:87
static bool HandleWpUnLoadCommand(ChatHandler *handler, char const *)
Definition: cs_wp.cpp:256
static bool HandleWpLoadCommand(ChatHandler *handler, char const *args)
Definition: cs_wp.cpp:162
std::vector< ChatCommand > GetCommands() const override
Definition: cs_wp.cpp:49
static bool HandleWpModifyCommand(ChatHandler *handler, char const *args)
Definition: cs_wp.cpp:300
static bool HandleWpReloadCommand(ChatHandler *handler, char const *args)
Definition: cs_wp.cpp:241
void AddSC_wp_commandscript()
Definition: cs_wp.cpp:505
@ 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
Definition: RBAC.h:639
@ RBAC_PERM_COMMAND_WP_RELOAD
Definition: RBAC.h:645
constexpr float GetPositionX() const
Definition: Position.h:76
constexpr float GetPositionY() const
Definition: Position.h:77
constexpr void GetPosition(float &x, float &y) const
Definition: Position.h:81
constexpr float GetOrientation() const
Definition: Position.h:79
constexpr float GetPositionZ() const
Definition: Position.h:78
std::vector< WaypointNode > Nodes
EnumFlag< WaypointPathFlags > Flags
WaypointMoveType MoveType