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