[11913] Add commands for MMaps

Added commands are:
.mmap [on|off] to show state of mmaps, or to enable/disable mmaps globally
.mmap stats to show information about current state of mmaps
.mmap loadedtiles to show which tiles are currently loaded
.mmap path to calculate and show a path to current select unit
.mmap loc to print on which tile one is
.mmap testarea to calculate paths for all nearby npcs to player

Authorship goes to qsa in addition
This commit is contained in:
faramir118 2012-01-29 23:47:02 +01:00 committed by Schmoozerd
parent 2f0ed05566
commit d83c7d8c8c
5 changed files with 283 additions and 2 deletions

View file

@ -396,6 +396,17 @@ ChatCommand * ChatHandler::getCommandTable()
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand mmapCommandTable[] =
{
{ "path", SEC_GAMEMASTER, false, &ChatHandler::HandleMmapPathCommand, "", NULL },
{ "loc", SEC_GAMEMASTER, false, &ChatHandler::HandleMmapLocCommand, "", NULL },
{ "loadedtiles", SEC_GAMEMASTER, false, &ChatHandler::HandleMmapLoadedTilesCommand, "", NULL },
{ "stats", SEC_GAMEMASTER, false, &ChatHandler::HandleMmapStatsCommand, "", NULL },
{ "testarea", SEC_GAMEMASTER, false, &ChatHandler::HandleMmapTestArea, "", NULL },
{ "", SEC_ADMINISTRATOR, false, &ChatHandler::HandleMmap, "", NULL },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand modifyCommandTable[] =
{
{ "hp", SEC_MODERATOR, false, &ChatHandler::HandleModifyHPCommand, "", NULL },
@ -813,6 +824,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "waterwalk", SEC_GAMEMASTER, false, &ChatHandler::HandleWaterwalkCommand, "", NULL },
{ "quit", SEC_CONSOLE, true, &ChatHandler::HandleQuitCommand, "", NULL },
{ "gearscore", SEC_ADMINISTRATOR, false, &ChatHandler::HandleShowGearScoreCommand, "", NULL },
{ "mmap", SEC_GAMEMASTER, false, NULL, "", mmapCommandTable },
{ NULL, 0, false, NULL, "", NULL }
};

View file

@ -598,6 +598,13 @@ class MANGOS_DLL_SPEC ChatHandler
bool HandleQuitCommand(char* args);
bool HandleShowGearScoreCommand(char* args);
bool HandleMmapPathCommand(char* args);
bool HandleMmapLocCommand(char* args);
bool HandleMmapLoadedTilesCommand(char* args);
bool HandleMmapStatsCommand(char* args);
bool HandleMmap(char* args);
bool HandleMmapTestArea(char* args);
//! Development Commands
bool HandleSaveAllCommand(char* args);

View file

@ -49,6 +49,8 @@
#include <typeinfo>
#include "TargetedMovementGenerator.h" // for HandleNpcUnFollowCommand
#include "MoveMap.h" // for mmap manager
#include "PathFinder.h" // for mmap commands
static uint32 ReputationRankStrIndex[MAX_REPUTATION_RANK] =
{
@ -5287,3 +5289,193 @@ bool ChatHandler::HandleTitlesCurrentCommand(char* args)
return true;
}
bool ChatHandler::HandleMmapPathCommand(char* args)
{
if (!MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(m_session->GetPlayer()->GetMapId()))
{
PSendSysMessage("NavMesh not loaded for current map.");
return true;
}
PSendSysMessage("mmap path:");
// units
Player* player = m_session->GetPlayer();
Unit* target = getSelectedUnit();
if (!player || !target)
{
PSendSysMessage("Invalid target/source selection.");
return true;
}
char* para = strtok(args, " ");
bool useStraightPath = false;
if (para && strcmp(para, "true") == 0)
useStraightPath = true;
// unit locations
float x, y, z;
player->GetPosition(x, y, z);
// path
PathFinder path(target);
path.setUseStrightPath(useStraightPath);
path.calculate(x, y, z);
PointsArray pointPath = path.getPath();
PSendSysMessage("%s's path to %s:", target->GetName(), player->GetName());
PSendSysMessage("Building %s", useStraightPath ? "StraightPath" : "SmoothPath");
PSendSysMessage("length %i type %u", pointPath.size(), path.getPathType());
Vector3 start = path.getStartPosition();
Vector3 end = path.getEndPosition();
Vector3 actualEnd = path.getActualEndPosition();
PSendSysMessage("start (%.3f, %.3f, %.3f)", start.x, start.y, start.z);
PSendSysMessage("end (%.3f, %.3f, %.3f)", end.x, end.y, end.z);
PSendSysMessage("actual end (%.3f, %.3f, %.3f)", actualEnd.x, actualEnd.y, actualEnd.z);
if (!player->isGameMaster())
PSendSysMessage("Enable GM mode to see the path points.");
// this entry visible only to GM's with "gm on"
static const uint32 WAYPOINT_NPC_ENTRY = 1;
Creature* wp = NULL;
for (uint32 i = 0; i < pointPath.size(); ++i)
{
wp = player->SummonCreature(WAYPOINT_NPC_ENTRY, pointPath[i].x, pointPath[i].y, pointPath[i].z, 0, TEMPSUMMON_TIMED_DESPAWN, 9000);
// TODO: make creature not sink/fall
}
return true;
}
bool ChatHandler::HandleMmapLocCommand(char* /*args*/)
{
PSendSysMessage("mmap tileloc:");
// grid tile location
Player* player = m_session->GetPlayer();
int32 gx = 32 - player->GetPositionX() / SIZE_OF_GRIDS;
int32 gy = 32 - player->GetPositionY() / SIZE_OF_GRIDS;
PSendSysMessage("%03u%02i%02i.mmtile", player->GetMapId(), gy, gx);
PSendSysMessage("gridloc [%i,%i]", gx, gy);
// calculate navmesh tile location
const dtNavMesh* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(player->GetMapId());
const dtNavMeshQuery* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(player->GetMapId(), player->GetInstanceId());
if (!navmesh || !navmeshquery)
{
PSendSysMessage("NavMesh not loaded for current map.");
return true;
}
const float* min = navmesh->getParams()->orig;
float x, y, z;
player->GetPosition(x, y, z);
float location[VERTEX_SIZE] = {y, z, x};
float extents[VERTEX_SIZE] = {3.0f, 5.0f, 3.0f};
int32 tilex = int32((y - min[0]) / SIZE_OF_GRIDS);
int32 tiley = int32((x - min[2]) / SIZE_OF_GRIDS);
PSendSysMessage("Calc [%02i,%02i]", tilex, tiley);
// navmesh poly -> navmesh tile location
dtQueryFilter filter = dtQueryFilter();
dtPolyRef polyRef = INVALID_POLYREF;
navmeshquery->findNearestPoly(location, extents, &filter, &polyRef, NULL);
if (polyRef == INVALID_POLYREF)
PSendSysMessage("Dt [??,??] (invalid poly, probably no tile loaded)");
else
{
const dtMeshTile* tile;
const dtPoly* poly;
navmesh->getTileAndPolyByRef(polyRef, &tile, &poly);
if (tile)
PSendSysMessage("Dt [%02i,%02i]", tile->header->x, tile->header->y);
else
PSendSysMessage("Dt [??,??] (no tile loaded)");
}
return true;
}
bool ChatHandler::HandleMmapLoadedTilesCommand(char* /*args*/)
{
uint32 mapid = m_session->GetPlayer()->GetMapId();
const dtNavMesh* navmesh = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMesh(mapid);
const dtNavMeshQuery* navmeshquery = MMAP::MMapFactory::createOrGetMMapManager()->GetNavMeshQuery(mapid, m_session->GetPlayer()->GetInstanceId());
if (!navmesh || !navmeshquery)
{
PSendSysMessage("NavMesh not loaded for current map.");
return true;
}
PSendSysMessage("mmap loadedtiles:");
for (int32 i = 0; i < navmesh->getMaxTiles(); ++i)
{
const dtMeshTile* tile = navmesh->getTile(i);
if (!tile || !tile->header)
continue;
PSendSysMessage("[%02i,%02i]", tile->header->x, tile->header->y);
}
return true;
}
bool ChatHandler::HandleMmapStatsCommand(char* /*args*/)
{
PSendSysMessage("mmap stats:");
PSendSysMessage(" global mmap pathfinding is %sabled", sWorld.getConfig(CONFIG_BOOL_MMAP_ENABLED) ? "en" : "dis");
MMAP::MMapManager *manager = MMAP::MMapFactory::createOrGetMMapManager();
PSendSysMessage(" %u maps loaded with %u tiles overall", manager->getLoadedMapsCount(), manager->getLoadedTilesCount());
const dtNavMesh* navmesh = manager->GetNavMesh(m_session->GetPlayer()->GetMapId());
if (!navmesh)
{
PSendSysMessage("NavMesh not loaded for current map.");
return true;
}
uint32 tileCount = 0;
uint32 nodeCount = 0;
uint32 polyCount = 0;
uint32 vertCount = 0;
uint32 triCount = 0;
uint32 triVertCount = 0;
uint32 dataSize = 0;
for (int32 i = 0; i < navmesh->getMaxTiles(); ++i)
{
const dtMeshTile* tile = navmesh->getTile(i);
if (!tile || !tile->header)
continue;
tileCount ++;
nodeCount += tile->header->bvNodeCount;
polyCount += tile->header->polyCount;
vertCount += tile->header->vertCount;
triCount += tile->header->detailTriCount;
triVertCount += tile->header->detailVertCount;
dataSize += tile->dataSize;
}
PSendSysMessage("Navmesh stats on current map:");
PSendSysMessage(" %u tiles loaded", tileCount);
PSendSysMessage(" %u BVTree nodes", nodeCount);
PSendSysMessage(" %u polygons (%u vertices)", polyCount, vertCount);
PSendSysMessage(" %u triangles (%u vertices)", triCount, triVertCount);
PSendSysMessage(" %.2f MB of data (not including pointers)", ((float)dataSize / sizeof(unsigned char)) / 1048576);
return true;
}

View file

@ -41,6 +41,7 @@
#include "CellImpl.h"
#include "Weather.h"
#include "PointMovementGenerator.h"
#include "PathFinder.h"
#include "TargetedMovementGenerator.h"
#include "SkillDiscovery.h"
#include "SkillExtraItems.h"
@ -7091,4 +7092,73 @@ bool ChatHandler::HandleShowGearScoreCommand(char *args)
PSendSysMessage(LANG_GEARSCORE, GetNameLink(player).c_str(), gearScore);
return true;
}
}
bool ChatHandler::HandleMmap(char* args)
{
bool on;
if (ExtractOnOff(&args, on))
{
if (on)
{
sWorld.setConfig(CONFIG_BOOL_MMAP_ENABLED, true);
SendSysMessage("WORLD: mmaps are now ENABLED (individual map settings still in effect)");
}
else
{
sWorld.setConfig(CONFIG_BOOL_MMAP_ENABLED, false);
SendSysMessage("WORLD: mmaps are now DISABLED");
}
return true;
}
on = sWorld.getConfig(CONFIG_BOOL_MMAP_ENABLED);
PSendSysMessage("mmaps are %sabled", on ? "en" : "dis");
return true;
}
bool ChatHandler::HandleMmapTestArea(char* args)
{
float radius = 40.0f;
ExtractFloat(&args, radius);
CellPair pair(MaNGOS::ComputeCellPair( m_session->GetPlayer()->GetPositionX(), m_session->GetPlayer()->GetPositionY()) );
Cell cell(pair);
cell.SetNoCreate();
std::list<Creature*> creatureList;
MaNGOS::AnyUnitInObjectRangeCheck go_check(m_session->GetPlayer(), radius);
MaNGOS::CreatureListSearcher<MaNGOS::AnyUnitInObjectRangeCheck> go_search(creatureList, go_check);
TypeContainerVisitor<MaNGOS::CreatureListSearcher<MaNGOS::AnyUnitInObjectRangeCheck>, GridTypeMapContainer> go_visit(go_search);
// Get Creatures
cell.Visit(pair, go_visit, *(m_session->GetPlayer()->GetMap()), *(m_session->GetPlayer()), radius);
if (!creatureList.empty())
{
PSendSysMessage("Found %i Creatures.", creatureList.size());
uint32 paths = 0;
uint32 uStartTime = WorldTimer::getMSTime();
float gx,gy,gz;
m_session->GetPlayer()->GetPosition(gx,gy,gz);
for (std::list<Creature*>::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr)
{
PathFinder path(*itr);
path.calculate(gx, gy, gz);
++paths;
}
uint32 uPathLoadTime = WorldTimer::getMSTimeDiff(uStartTime, WorldTimer::getMSTime());
PSendSysMessage("Generated %i paths in %i ms", paths, uPathLoadTime);
}
else
{
PSendSysMessage("No creatures in %f yard range.", radius);
}
return true;
}

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "11912"
#define REVISION_NR "11913"
#endif // __REVISION_NR_H__