TrinityCore
Loading...
Searching...
No Matches
cs_mmaps.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
26#include "ScriptMgr.h"
27#include "CellImpl.h"
28#include "Chat.h"
29#include "ChatCommand.h"
30#include "DisableMgr.h"
31#include "GridNotifiersImpl.h"
32#include "MMapManager.h"
33#include "PathGenerator.h"
34#include "PhasingHandler.h"
35#include "Player.h"
37#include "RBAC.h"
38#include "WorldSession.h"
39
40#if TRINITY_COMPILER == TRINITY_COMPILER_GNU
41#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
42#endif
43
44using namespace Trinity::ChatCommands;
45
47{
48public:
49 mmaps_commandscript() : CommandScript("mmaps_commandscript") { }
50
51 std::span<ChatCommandBuilder const> GetCommands() const override
52 {
53 static ChatCommandTable mmapCommandTable =
54 {
60 };
61
62 static ChatCommandTable commandTable =
63 {
64 { "mmap", rbac::RBAC_PERM_COMMAND_MMAP, true, nullptr, "", mmapCommandTable },
65 };
66 return commandTable;
67 }
68
69 static bool HandleMmapPathCommand(ChatHandler* handler, char const* args)
70 {
71 Player* player = handler->GetSession()->GetPlayer();
72 if (!MMAP::MMapManager::instance()->GetNavMesh(player->GetMapId(), player->GetInstanceId()))
73 {
74 handler->PSendSysMessage("NavMesh not loaded for current map.");
75 return true;
76 }
77
78 handler->PSendSysMessage("mmap path:");
79
80 // units
81 Unit* target = handler->getSelectedUnit();
82 if (!player || !target)
83 {
84 handler->PSendSysMessage("Invalid target/source selection.");
85 return true;
86 }
87
88 char* para = strtok((char*)args, " ");
89
90 bool useStraightPath = false;
91 if (para && strcmp(para, "true") == 0)
92 useStraightPath = true;
93
94 bool useRaycast = false;
95 if (para && (strcmp(para, "line") == 0 || strcmp(para, "ray") == 0 || strcmp(para, "raycast") == 0))
96 useRaycast = true;
97
98 // unit locations
99 float x, y, z;
100 player->GetPosition(x, y, z);
101
102 // path
103 PathGenerator path(target);
104 path.SetUseStraightPath(useStraightPath);
105 path.SetUseRaycast(useRaycast);
106 bool result = path.CalculatePath(x, y, z, false);
107
108 Movement::PointsArray const& pointPath = path.GetPath();
109 handler->PSendSysMessage("%s's path to %s:", target->GetName().c_str(), player->GetName().c_str());
110 handler->PSendSysMessage("Building: %s", useStraightPath ? "StraightPath" : useRaycast ? "Raycast" : "SmoothPath");
111 handler->PSendSysMessage("Result: %s - Length: %zu - Type: %u", (result ? "true" : "false"), pointPath.size(), path.GetPathType());
112
113 G3D::Vector3 const& start = path.GetStartPosition();
114 G3D::Vector3 const& end = path.GetEndPosition();
115 G3D::Vector3 const& actualEnd = path.GetActualEndPosition();
116
117 handler->PSendSysMessage("StartPosition (%.3f, %.3f, %.3f)", start.x, start.y, start.z);
118 handler->PSendSysMessage("EndPosition (%.3f, %.3f, %.3f)", end.x, end.y, end.z);
119 handler->PSendSysMessage("ActualEndPosition (%.3f, %.3f, %.3f)", actualEnd.x, actualEnd.y, actualEnd.z);
120
121 if (!player->IsGameMaster())
122 handler->PSendSysMessage("Enable GM mode to see the path points.");
123
124 for (uint32 i = 0; i < pointPath.size(); ++i)
125 player->SummonCreature(VISUAL_WAYPOINT, pointPath[i].x, pointPath[i].y, pointPath[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 9s);
126
127 return true;
128 }
129
130 static bool HandleMmapLocCommand(ChatHandler* handler, char const* /*args*/)
131 {
132 handler->PSendSysMessage("mmap tileloc:");
133
134 // grid tile location
135 Player* player = handler->GetSession()->GetPlayer();
136
137 int32 gx = 32 - player->GetPositionX() / SIZE_OF_GRIDS;
138 int32 gy = 32 - player->GetPositionY() / SIZE_OF_GRIDS;
139
140 float x, y, z;
141 player->GetPosition(x, y, z);
142
143 // calculate navmesh tile location
144 uint32 terrainMapId = PhasingHandler::GetTerrainMapId(player->GetPhaseShift(), player->GetMapId(), player->GetMap()->GetTerrain(), x, y);
145
146 handler->PSendSysMessage("%04u_%02i_%02i.mmtile", terrainMapId, gx, gy);
147 handler->PSendSysMessage("tileloc [%i, %i]", gy, gx);
148
149 dtNavMesh const* navmesh = MMAP::MMapManager::instance()->GetNavMesh(terrainMapId, player->GetInstanceId());
150 dtNavMeshQuery const* navmeshquery = MMAP::MMapManager::instance()->GetNavMeshQuery(terrainMapId, player->GetMapId(), player->GetInstanceId());
151 if (!navmesh || !navmeshquery)
152 {
153 handler->PSendSysMessage("NavMesh not loaded for current map.");
154 return true;
155 }
156
157 float const* min = navmesh->getParams()->orig;
158 float location[VERTEX_SIZE] = { y, z, x };
159 float extents[VERTEX_SIZE] = { 3.0f, 5.0f, 3.0f };
160
161 int32 tilex = int32((y - min[0]) / SIZE_OF_GRIDS);
162 int32 tiley = int32((x - min[2]) / SIZE_OF_GRIDS);
163
164 handler->PSendSysMessage("Calc [%02i, %02i]", tilex, tiley);
165
166 // navmesh poly -> navmesh tile location
167 dtQueryFilter filter = dtQueryFilter();
168 dtPolyRef polyRef = INVALID_POLYREF;
169 if (dtStatusFailed(navmeshquery->findNearestPoly(location, extents, &filter, &polyRef, nullptr)))
170 {
171 handler->PSendSysMessage("Dt [??,??] (invalid poly, probably no tile loaded)");
172 return true;
173 }
174
175 if (polyRef == INVALID_POLYREF)
176 handler->PSendSysMessage("Dt [??, ??] (invalid poly, probably no tile loaded)");
177 else
178 {
179 dtMeshTile const* tile;
180 dtPoly const* poly;
181 if (dtStatusSucceed(navmesh->getTileAndPolyByRef(polyRef, &tile, &poly)))
182 {
183 if (tile)
184 {
185 handler->PSendSysMessage("Dt [%02i,%02i]", tile->header->x, tile->header->y);
186 return true;
187 }
188 }
189
190 handler->PSendSysMessage("Dt [??,??] (no tile loaded)");
191 }
192
193 return true;
194 }
195
196 static bool HandleMmapLoadedTilesCommand(ChatHandler* handler, char const* /*args*/)
197 {
198 Player* player = handler->GetSession()->GetPlayer();
199 uint32 terrainMapId = PhasingHandler::GetTerrainMapId(player->GetPhaseShift(), player->GetMapId(), player->GetMap()->GetTerrain(), player->GetPositionX(), player->GetPositionY());
200 dtNavMesh const* navmesh = MMAP::MMapManager::instance()->GetNavMesh(terrainMapId, player->GetInstanceId());
201 dtNavMeshQuery const* navmeshquery = MMAP::MMapManager::instance()->GetNavMeshQuery(terrainMapId, player->GetMapId(), player->GetInstanceId());
202 if (!navmesh || !navmeshquery)
203 {
204 handler->PSendSysMessage("NavMesh not loaded for current map.");
205 return true;
206 }
207
208 handler->PSendSysMessage("mmap loadedtiles:");
209
210 for (int32 i = 0; i < navmesh->getMaxTiles(); ++i)
211 {
212 dtMeshTile const* tile = navmesh->getTile(i);
213 if (!tile || !tile->header)
214 continue;
215
216 handler->PSendSysMessage("[%02i, %02i]", tile->header->x, tile->header->y);
217 }
218
219 return true;
220 }
221
222 static bool HandleMmapStatsCommand(ChatHandler* handler, char const* /*args*/)
223 {
224 Player* player = handler->GetSession()->GetPlayer();
225 uint32 terrainMapId = PhasingHandler::GetTerrainMapId(player->GetPhaseShift(), player->GetMapId(), player->GetMap()->GetTerrain(), player->GetPositionX(), player->GetPositionY());
226 handler->PSendSysMessage("mmap stats:");
227 handler->PSendSysMessage(" global mmap pathfinding is %sabled", DisableMgr::IsPathfindingEnabled(player->GetMapId()) ? "en" : "dis");
228
230 handler->PSendSysMessage(" %u maps loaded with %u tiles overall", manager->getLoadedMapsCount(), manager->getLoadedTilesCount());
231
232 dtNavMesh const* navmesh = manager->GetNavMesh(terrainMapId, player->GetInstanceId());
233 if (!navmesh)
234 {
235 handler->PSendSysMessage("NavMesh not loaded for current map.");
236 return true;
237 }
238
239 uint32 tileCount = 0;
240 uint32 nodeCount = 0;
241 uint32 polyCount = 0;
242 uint32 vertCount = 0;
243 uint32 triCount = 0;
244 uint32 triVertCount = 0;
245 uint32 dataSize = 0;
246 for (int32 i = 0; i < navmesh->getMaxTiles(); ++i)
247 {
248 dtMeshTile const* tile = navmesh->getTile(i);
249 if (!tile || !tile->header)
250 continue;
251
252 tileCount++;
253 nodeCount += tile->header->bvNodeCount;
254 polyCount += tile->header->polyCount;
255 vertCount += tile->header->vertCount;
256 triCount += tile->header->detailTriCount;
257 triVertCount += tile->header->detailVertCount;
258 dataSize += tile->dataSize;
259 }
260
261 handler->PSendSysMessage("Navmesh stats:");
262 handler->PSendSysMessage(" %u tiles loaded", tileCount);
263 handler->PSendSysMessage(" %u BVTree nodes", nodeCount);
264 handler->PSendSysMessage(" %u polygons (%u vertices)", polyCount, vertCount);
265 handler->PSendSysMessage(" %u triangles (%u vertices)", triCount, triVertCount);
266 handler->PSendSysMessage(" %.2f MB of data (not including pointers)", ((float)dataSize / sizeof(unsigned char)) / 1048576);
267
268 return true;
269 }
270
271 static bool HandleMmapTestArea(ChatHandler* handler, char const* /*args*/)
272 {
273 float radius = 40.0f;
274 WorldObject* object = handler->GetSession()->GetPlayer();
275
276 // Get Creatures
277 std::list<Creature*> creatureList;
278 Trinity::AnyUnitInObjectRangeCheck go_check(object, radius);
279 Trinity::CreatureListSearcher<Trinity::AnyUnitInObjectRangeCheck> go_search(object, creatureList, go_check);
280 Cell::VisitGridObjects(object, go_search, radius);
281
282 if (!creatureList.empty())
283 {
284 handler->PSendSysMessage("Found %zu Creatures.", creatureList.size());
285
286 uint32 paths = 0;
287 uint32 uStartTime = getMSTime();
288
289 float gx, gy, gz;
290 object->GetPosition(gx, gy, gz);
291 for (std::list<Creature*>::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr)
292 {
293 PathGenerator path(*itr);
294 path.CalculatePath(gx, gy, gz);
295 ++paths;
296 }
297
298 uint32 uPathLoadTime = getMSTimeDiff(uStartTime, getMSTime());
299 handler->PSendSysMessage("Generated %i paths in %i ms", paths, uPathLoadTime);
300 }
301 else
302 handler->PSendSysMessage("No creatures in %f yard range.", radius);
303
304 return true;
305 }
306};
307
int32_t int32
Definition Define.h:150
uint32_t uint32
Definition Define.h:154
#define SIZE_OF_GRIDS
Definition GridDefines.h:40
@ TEMPSUMMON_TIMED_DESPAWN
#define VERTEX_SIZE
#define INVALID_POLYREF
Role Based Access Control related classes definition.
uint32 getMSTime()
Definition Timer.h:33
uint32 getMSTimeDiff(uint32 oldMSTime, uint32 newMSTime)
Definition Timer.h:40
#define VISUAL_WAYPOINT
Definition Unit.h:35
Unit * getSelectedUnit()
Definition Chat.cpp:216
WorldSession * GetSession()
Definition Chat.h:42
void PSendSysMessage(char const *fmt, Args &&... args)
Definition Chat.h:62
uint32 getLoadedMapsCount() const
Definition MMapManager.h:73
static MMapManager * instance()
dtNavMesh * GetNavMesh(uint32 mapId, uint32 instanceId)
dtNavMeshQuery const * GetNavMeshQuery(uint32 meshMapId, uint32 instanceMapId, uint32 instanceId)
uint32 getLoadedTilesCount() const
Definition MMapManager.h:72
TerrainInfo * GetTerrain() const
Definition Map.h:299
void SetUseRaycast(bool useRaycast)
Movement::PointsArray const & GetPath() const
G3D::Vector3 const & GetStartPosition() const
PathType GetPathType() const
G3D::Vector3 const & GetEndPosition() const
bool CalculatePath(float srcX, float srcY, float srcZ, float destX, float destY, float destZ, bool forceDest=false)
void SetUseStraightPath(bool useStraightPath)
G3D::Vector3 const & GetActualEndPosition() const
static uint32 GetTerrainMapId(PhaseShift const &phaseShift, uint32 mapId, TerrainInfo const *terrain, float x, float y)
bool IsGameMaster() const
Definition Player.h:1309
Definition Unit.h:635
constexpr uint32 GetMapId() const
Definition Position.h:216
Map * GetMap() const
Definition Object.h:411
TempSummon * SummonCreature(uint32 entry, Position const &pos, TempSummonType despawnType=TEMPSUMMON_MANUAL_DESPAWN, Milliseconds despawnTime=0s, uint32 vehId=0, uint32 spellId=0, ObjectGuid privateObjectOwner=ObjectGuid::Empty)
Definition Object.cpp:1398
PhaseShift & GetPhaseShift()
Definition Object.h:310
uint32 GetInstanceId() const
Definition Object.h:308
std::string const & GetName() const
Definition Object.h:342
Player * GetPlayer() const
std::span< ChatCommandBuilder const > GetCommands() const override
Definition cs_mmaps.cpp:51
static bool HandleMmapTestArea(ChatHandler *handler, char const *)
Definition cs_mmaps.cpp:271
static bool HandleMmapLocCommand(ChatHandler *handler, char const *)
Definition cs_mmaps.cpp:130
static bool HandleMmapPathCommand(ChatHandler *handler, char const *args)
Definition cs_mmaps.cpp:69
static bool HandleMmapStatsCommand(ChatHandler *handler, char const *)
Definition cs_mmaps.cpp:222
static bool HandleMmapLoadedTilesCommand(ChatHandler *handler, char const *)
Definition cs_mmaps.cpp:196
void AddSC_mmaps_commandscript()
Definition cs_mmaps.cpp:308
bool IsPathfindingEnabled(uint32 mapId)
std::vector< Vector3 > PointsArray
ChatCommandBuilder const [] ChatCommandTable
Definition ChatCommand.h:49
@ RBAC_PERM_COMMAND_MMAP_LOC
Definition RBAC.h:410
@ RBAC_PERM_COMMAND_MMAP
Definition RBAC.h:408
@ RBAC_PERM_COMMAND_MMAP_TESTAREA
Definition RBAC.h:413
@ RBAC_PERM_COMMAND_MMAP_STATS
Definition RBAC.h:412
@ RBAC_PERM_COMMAND_MMAP_LOADEDTILES
Definition RBAC.h:409
@ RBAC_PERM_COMMAND_MMAP_PATH
Definition RBAC.h:411
static void VisitGridObjects(WorldObject const *obj, T &visitor, float radius, bool dont_load=true)
Definition CellImpl.h:179
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