mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 13:37:05 +00:00
[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:
parent
2f0ed05566
commit
d83c7d8c8c
5 changed files with 283 additions and 2 deletions
|
|
@ -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 }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "11912"
|
||||
#define REVISION_NR "11913"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue