mirror of
https://github.com/SWG-Source/src.git
synced 2026-09-13 00:45:03 -04:00
Added serverPathfinding library
This commit is contained in:
+1
-1
@@ -19,7 +19,7 @@ find_package(Perl REQUIRED)
|
|||||||
find_package(STLPort REQUIRED)
|
find_package(STLPort REQUIRED)
|
||||||
find_package(ZLib REQUIRED)
|
find_package(ZLib REQUIRED)
|
||||||
|
|
||||||
#include_directories(${STLPORT_INCLUDE_DIR})
|
include_directories(${STLPORT_INCLUDE_DIR})
|
||||||
|
|
||||||
add_subdirectory(external)
|
add_subdirectory(external)
|
||||||
add_subdirectory(engine)
|
add_subdirectory(engine)
|
||||||
|
|||||||
@@ -3,5 +3,6 @@ add_subdirectory(serverGame)
|
|||||||
add_subdirectory(serverKeyShare)
|
add_subdirectory(serverKeyShare)
|
||||||
add_subdirectory(serverMetrics)
|
add_subdirectory(serverMetrics)
|
||||||
add_subdirectory(serverNetworkMessages)
|
add_subdirectory(serverNetworkMessages)
|
||||||
|
add_subdirectory(serverPathfinding)
|
||||||
add_subdirectory(serverScript)
|
add_subdirectory(serverScript)
|
||||||
add_subdirectory(serverUtility)
|
add_subdirectory(serverUtility)
|
||||||
|
|||||||
@@ -714,32 +714,41 @@ endif()
|
|||||||
include_directories(
|
include_directories(
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/shared
|
${CMAKE_CURRENT_SOURCE_DIR}/shared
|
||||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedCollision/include/public
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedCollision/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedCommandParser/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFile/include/public
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFile/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundation/include/public
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundation/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundationTypes/include/public
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundationTypes/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFractal/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedGame/include/public
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedGame/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedLog/include/public
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedLog/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMath/include/public
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMath/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMathArchive/include/public
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMathArchive/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMessageDispatch/include/public
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMessageDispatch/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedNetwork/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedNetworkMessages/include/public
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedNetworkMessages/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedObject/include/public
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedObject/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedPathfinding/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedRandom/include/public
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedRandom/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedSkillSystem/include/public
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedSkillSystem/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedTerrain/include/public
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedTerrain/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedUtility/include/public
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedUtility/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/server/library/serverMetrics/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/server/library/serverNetworkMessages/include/public
|
${SWG_ENGINE_SOURCE_DIR}/server/library/serverNetworkMessages/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/server/library/serverPathfinding/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/server/library/serverScript/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/server/library/serverUtility/include/public
|
${SWG_ENGINE_SOURCE_DIR}/server/library/serverUtility/include/public
|
||||||
${SWG_GAME_SOURCE_DIR}/shared/library/swgSharedUtility/include/public
|
${SWG_GAME_SOURCE_DIR}/shared/library/swgSharedUtility/include/public
|
||||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/archive/include
|
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/archive/include
|
||||||
|
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/fileInterface/include/public
|
||||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/localization/include
|
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/localization/include
|
||||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/localizationArchive/include/public
|
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/localizationArchive/include/public
|
||||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/singleton/include
|
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/singleton/include
|
||||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicode/include
|
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicode/include
|
||||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicodeArchive/include/public
|
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicodeArchive/include/public
|
||||||
${Boost_INCLUDE_DIR}
|
${Boost_INCLUDE_DIR}
|
||||||
|
${JNI_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
|
||||||
|
project(serverPathfinding)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/public)
|
||||||
|
|
||||||
|
add_subdirectory(src)
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
#include "../../src/shared/CityPathGraph.h"
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
#include "../../src/shared/CityPathGraphManager.h"
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
#include "../../src/shared/CityPathNode.h"
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
#include "../../src/shared/FirstServerPathfinding.h"
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
#include "../../src/shared/PathAutoGenerator.h"
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
#include "../../src/shared/ServerPathBuildManager.h"
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
#include "../../src/shared/ServerPathBuilder.h"
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
#include "../../src/shared/ServerPathfinding.h"
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
#include "../../src/shared/ServerPathfindingConstants.h"
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
#include "../../src/shared/ServerPathfindingMessaging.h"
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
#include "../../src/shared/ServerPathfindingNotification.h"
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
#include "../../src/shared/SetupServerPathfinding.h"
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
|
||||||
|
set(SHARED_SOURCES
|
||||||
|
shared/CityPathGraph.cpp
|
||||||
|
shared/CityPathGraph.h
|
||||||
|
shared/CityPathGraphManager.cpp
|
||||||
|
shared/CityPathGraphManager.h
|
||||||
|
shared/CityPathNode.cpp
|
||||||
|
shared/CityPathNode.h
|
||||||
|
shared/FirstServerPathfinding.h
|
||||||
|
shared/PathAutoGenerator.cpp
|
||||||
|
shared/PathAutoGenerator.h
|
||||||
|
shared/ServerPathBuilder.cpp
|
||||||
|
shared/ServerPathBuilder.h
|
||||||
|
shared/ServerPathBuildManager.cpp
|
||||||
|
shared/ServerPathBuildManager.h
|
||||||
|
shared/ServerPathfindingConstants.cpp
|
||||||
|
shared/ServerPathfindingConstants.h
|
||||||
|
shared/ServerPathfinding.cpp
|
||||||
|
shared/ServerPathfinding.h
|
||||||
|
shared/ServerPathfindingMessaging.cpp
|
||||||
|
shared/ServerPathfindingMessaging.h
|
||||||
|
shared/ServerPathfindingNotification.cpp
|
||||||
|
shared/ServerPathfindingNotification.h
|
||||||
|
shared/SetupServerPathfinding.cpp
|
||||||
|
shared/SetupServerPathfinding.h
|
||||||
|
)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
set(PLATFORM_SOURCES
|
||||||
|
win32/FirstServerPathfinding.cpp
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
set(PLATFORM_SOURCES "")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/shared
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedCollision/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFile/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundation/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundationTypes/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedGame/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMath/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMathArchive/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMessageDispatch/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedNetworkMessages/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedObject/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedPathfinding/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedRandom/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedSkillSystem/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedTerrain/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedUtility/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/server/library/serverGame/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/server/library/serverNetworkMessages/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/server/library/serverScript/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/server/library/serverUtility/include/public
|
||||||
|
${SWG_GAME_SOURCE_DIR}/shared/library/swgSharedUtility/include/public
|
||||||
|
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/archive/include
|
||||||
|
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/localization/include
|
||||||
|
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/localizationArchive/include/public
|
||||||
|
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicode/include
|
||||||
|
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicodeArchive/include/public
|
||||||
|
${Boost_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(serverPathfinding STATIC
|
||||||
|
${SHARED_SOURCES}
|
||||||
|
${PLATFORM_SOURCES}
|
||||||
|
)
|
||||||
@@ -0,0 +1,740 @@
|
|||||||
|
// ======================================================================
|
||||||
|
//
|
||||||
|
// CityPathGraph.cpp
|
||||||
|
// copyright (c) 2001 Sony Online Entertainment
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include "serverPathfinding/FirstServerPathfinding.h"
|
||||||
|
#include "serverPathfinding/CityPathGraph.h"
|
||||||
|
|
||||||
|
#include "serverPathfinding/CityPathNode.h"
|
||||||
|
#include "serverPathfinding/ServerPathfindingConstants.h"
|
||||||
|
|
||||||
|
#include "sharedCollision/CollisionWorld.h"
|
||||||
|
#include "sharedCollision/Containment2d.h"
|
||||||
|
|
||||||
|
#include "sharedFoundation/DynamicVariableList.h"
|
||||||
|
|
||||||
|
#include "sharedMath/AxialBox.h"
|
||||||
|
#include "sharedMath/SphereTree.h"
|
||||||
|
|
||||||
|
#include "sharedObject/CellProperty.h"
|
||||||
|
|
||||||
|
#include "sharedPathfinding/ConfigSharedPathfinding.h"
|
||||||
|
|
||||||
|
#include "Unicode.h"
|
||||||
|
#include "UnicodeUtils.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class PathNodeSphereAccessor;
|
||||||
|
|
||||||
|
typedef SphereTree<PathNode *, PathNodeSphereAccessor> PathNodeTree;
|
||||||
|
|
||||||
|
float g_linkDistance = 40.0f;
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
class PathNodeSphereAccessor: public BaseSphereTreeAccessor<PathNode *, PathNodeSphereAccessor>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static Sphere const getExtent(PathNode const * const node)
|
||||||
|
{
|
||||||
|
return Sphere(node->getPosition_p(), 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char const *getDebugName(PathNode const * const node)
|
||||||
|
{
|
||||||
|
//@todo - make this return the path node name if there is one
|
||||||
|
|
||||||
|
UNREF(node);
|
||||||
|
|
||||||
|
return "pathNode";
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
CityPathGraph::CityPathGraph ( int cityToken )
|
||||||
|
: DynamicPathGraph(PGT_City),
|
||||||
|
m_nodeTree( new PathNodeTree ),
|
||||||
|
m_namedNodes( new std::map<Unicode::String, std::set<CityPathNode *> >),
|
||||||
|
m_token(cityToken),
|
||||||
|
m_dirtyBoxes( new BoxList() )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CityPathGraph::~CityPathGraph()
|
||||||
|
{
|
||||||
|
delete m_namedNodes;
|
||||||
|
m_namedNodes = NULL;
|
||||||
|
|
||||||
|
delete m_nodeTree;
|
||||||
|
m_nodeTree = NULL;
|
||||||
|
|
||||||
|
delete m_dirtyBoxes;
|
||||||
|
m_dirtyBoxes = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
int CityPathGraph::addNode ( DynamicPathNode * newNode )
|
||||||
|
{
|
||||||
|
CityPathNode * cityNode = dynamic_cast<CityPathNode *>(newNode);
|
||||||
|
|
||||||
|
NOT_NULL(cityNode);
|
||||||
|
|
||||||
|
int index = DynamicPathGraph::addNode(newNode);
|
||||||
|
|
||||||
|
SpatialHandle * handle = m_nodeTree->addObject( cityNode );
|
||||||
|
if (handle != NULL)
|
||||||
|
{
|
||||||
|
if (cityNode->getName() != Unicode::emptyString)
|
||||||
|
{
|
||||||
|
std::map<Unicode::String, std::set<CityPathNode *> >::iterator found = m_namedNodes->find(cityNode->getName());
|
||||||
|
if (found == m_namedNodes->end())
|
||||||
|
found = m_namedNodes->insert(std::make_pair(cityNode->getName(), std::set<CityPathNode *>())).first;
|
||||||
|
found->second.insert(cityNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cityNode->setSpatialHandle( handle );
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
bool dirty = ConfigSharedPathfinding::getEnableDirtyBoxes() && isDirty(cityNode->getPosition_p());
|
||||||
|
|
||||||
|
ServerObject const * source = cityNode->getSourceObject();
|
||||||
|
|
||||||
|
if(source && source->getObjVars().hasItem(OBJVAR_PATHFINDING_WAYPOINT_EDGES) && !dirty)
|
||||||
|
{
|
||||||
|
cityNode->loadEdgesFromObjvars();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
relinkNode(cityNode->getIndex());
|
||||||
|
|
||||||
|
cityNode->saveAllData();
|
||||||
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CityPathGraph::removeNode ( int nodeIndex )
|
||||||
|
{
|
||||||
|
CityPathNode * cityNode = _getNode(nodeIndex);
|
||||||
|
NOT_NULL(cityNode);
|
||||||
|
|
||||||
|
SpatialHandle * handle = cityNode->getSpatialHandle();
|
||||||
|
|
||||||
|
if (m_namedNodes != NULL)
|
||||||
|
{
|
||||||
|
std::map<Unicode::String, std::set<CityPathNode *> >::iterator found = m_namedNodes->find(cityNode->getName());
|
||||||
|
if (found != m_namedNodes->end())
|
||||||
|
{
|
||||||
|
found->second.erase(cityNode);
|
||||||
|
if (found->second.empty())
|
||||||
|
m_namedNodes->erase(found);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_nodeTree->removeObject( handle );
|
||||||
|
|
||||||
|
cityNode->setSpatialHandle(NULL);
|
||||||
|
|
||||||
|
DynamicPathGraph::removeNode(nodeIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// When a waypoint is permanently destroyed from a city graph, we need to
|
||||||
|
// make sure that all neighboring nodes are relinked and thatthe edge
|
||||||
|
// lists on the objvars are updated as well.
|
||||||
|
|
||||||
|
void CityPathGraph::destroyNode ( int nodeIndex )
|
||||||
|
{
|
||||||
|
CityPathNode * cityNode = _getNode(nodeIndex);
|
||||||
|
|
||||||
|
if(cityNode == NULL) return;
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Remember which nodes were adjacent to the node we're removing
|
||||||
|
|
||||||
|
std::vector<int> neighborList;
|
||||||
|
|
||||||
|
int edgeCount = cityNode->getEdgeCount();
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < edgeCount; i++)
|
||||||
|
{
|
||||||
|
int neighborIndex = cityNode->getNeighbor(i);
|
||||||
|
|
||||||
|
neighborList.push_back( neighborIndex );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Update the sphere tree
|
||||||
|
|
||||||
|
SpatialHandle * handle = cityNode->getSpatialHandle();
|
||||||
|
|
||||||
|
m_nodeTree->removeObject( handle );
|
||||||
|
|
||||||
|
cityNode->setSpatialHandle(NULL);
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Remove the node
|
||||||
|
|
||||||
|
removeNode( nodeIndex );
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Relink the neighbors and store their new edge lists back into
|
||||||
|
// the objvars. Do this in two passes to ensure that the edges
|
||||||
|
// aren't corrupted (relinking a node can change the edge lists
|
||||||
|
// of other nodes)
|
||||||
|
|
||||||
|
for(i = 0; i < edgeCount; i++)
|
||||||
|
{
|
||||||
|
relinkNode(neighborList[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < edgeCount; i++)
|
||||||
|
{
|
||||||
|
CityPathNode * neighborNode = _getNode(neighborList[i]);
|
||||||
|
|
||||||
|
if(neighborNode) neighborNode->saveEdgesToObjvars();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CityPathGraph::moveNode ( int nodeIndex, Vector const & newPosition )
|
||||||
|
{
|
||||||
|
CityPathNode * cityNode = _getNode(nodeIndex);
|
||||||
|
|
||||||
|
if(cityNode == NULL) return;
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Remember which nodes were adjacent to the node we're removing
|
||||||
|
|
||||||
|
std::vector<int> oldNeighborList;
|
||||||
|
|
||||||
|
int oldEdgeCount = cityNode->getEdgeCount();
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < oldEdgeCount; i++)
|
||||||
|
{
|
||||||
|
int neighborIndex = cityNode->getNeighbor(i);
|
||||||
|
|
||||||
|
oldNeighborList.push_back( neighborIndex );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Update the sphere tree
|
||||||
|
|
||||||
|
m_nodeTree->move(cityNode->getSpatialHandle());
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Move the node
|
||||||
|
|
||||||
|
DynamicPathGraph::moveNode(nodeIndex,newPosition);
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Relink the old neighbors and store their new edge lists back into
|
||||||
|
// the objvars. Do this in two passes to ensure that the edges
|
||||||
|
// aren't corrupted (relinking a node can change the edge lists
|
||||||
|
// of other nodes)
|
||||||
|
|
||||||
|
for(i = 0; i < oldEdgeCount; i++)
|
||||||
|
{
|
||||||
|
relinkNode(oldNeighborList[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < oldEdgeCount; i++)
|
||||||
|
{
|
||||||
|
CityPathNode * oldNeighborNode = _getNode(oldNeighborList[i]);
|
||||||
|
|
||||||
|
if(oldNeighborNode) oldNeighborNode->saveEdgesToObjvars();
|
||||||
|
}
|
||||||
|
|
||||||
|
cityNode->saveAllData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CityPathGraph::relinkNode ( int nodeIndex )
|
||||||
|
{
|
||||||
|
CityPathNode * nodeA = _getNode(nodeIndex);
|
||||||
|
|
||||||
|
if(nodeA == NULL) return;
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
//int oldNeighborCode = getNeighborCode(nodeIndex);
|
||||||
|
|
||||||
|
unlinkNode(nodeIndex);
|
||||||
|
|
||||||
|
PathNodeType typeA = nodeA->getType();
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Building nodes always connect only to their entrances
|
||||||
|
|
||||||
|
if(typeA == PNT_CityBuilding)
|
||||||
|
{
|
||||||
|
int listSize = getNodeCount();
|
||||||
|
|
||||||
|
for(int i = 0; i < listSize; i++)
|
||||||
|
{
|
||||||
|
CityPathNode * nodeB = _getNode(i);
|
||||||
|
|
||||||
|
if(nodeB == NULL) continue;
|
||||||
|
if(nodeA == nodeB) continue;
|
||||||
|
|
||||||
|
PathNodeType typeB = nodeB->getType();
|
||||||
|
|
||||||
|
if(typeB != PNT_CityBuildingEntrance) continue;
|
||||||
|
|
||||||
|
if(nodeA->getCreatorObject() == NULL) continue;
|
||||||
|
|
||||||
|
if(nodeB->getCreatorObject() == NULL) continue;
|
||||||
|
|
||||||
|
if(nodeA->getCreatorObject() != nodeB->getCreatorObject()) continue;
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// A is a building, B is an entrance, and they have the same creator
|
||||||
|
|
||||||
|
nodeA->addEdge( nodeB->getIndex() );
|
||||||
|
nodeB->addEdge( nodeA->getIndex() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// return so we don't try and connect to any other nodes
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Building entrances _must_ connect to their building, and may connect
|
||||||
|
// to other nodes as well
|
||||||
|
|
||||||
|
if(typeA == PNT_CityBuildingEntrance)
|
||||||
|
{
|
||||||
|
int listSize = getNodeCount();
|
||||||
|
|
||||||
|
for(int i = 0; i < listSize; i++)
|
||||||
|
{
|
||||||
|
CityPathNode * nodeB = _getNode(i);
|
||||||
|
|
||||||
|
if(nodeB == NULL) continue;
|
||||||
|
if(nodeA == nodeB) continue;
|
||||||
|
|
||||||
|
PathNodeType typeB = nodeB->getType();
|
||||||
|
|
||||||
|
if(typeB != PNT_CityBuilding) continue;
|
||||||
|
|
||||||
|
if(nodeA->getCreatorObject() == NULL) continue;
|
||||||
|
|
||||||
|
if(nodeB->getCreatorObject() == NULL) continue;
|
||||||
|
|
||||||
|
if(nodeA->getCreatorObject() != nodeB->getCreatorObject()) continue;
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// A is an entrance, B is a building, and they have the same creator
|
||||||
|
|
||||||
|
nodeA->addEdge( nodeB->getIndex() );
|
||||||
|
nodeB->addEdge( nodeA->getIndex() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
static std::vector<PathNode*> results;
|
||||||
|
|
||||||
|
results.clear();
|
||||||
|
|
||||||
|
m_nodeTree->findInRange( nodeA->getPosition_p(), g_linkDistance, results );
|
||||||
|
|
||||||
|
int resultCount = results.size();
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < resultCount; i++)
|
||||||
|
{
|
||||||
|
CityPathNode * nodeB = static_cast<CityPathNode*>(results[i]);
|
||||||
|
|
||||||
|
if(nodeB == NULL) continue;
|
||||||
|
if(nodeA == nodeB) continue;
|
||||||
|
|
||||||
|
PathNodeType typeB = nodeB->getType();
|
||||||
|
|
||||||
|
if(typeB == PNT_CityBuilding) continue;
|
||||||
|
|
||||||
|
Vector posA = nodeA->getPosition_p();
|
||||||
|
Vector posB = nodeB->getPosition_p();
|
||||||
|
|
||||||
|
if(posA.magnitudeBetweenSquared(posB) < (g_linkDistance * g_linkDistance))
|
||||||
|
{
|
||||||
|
bool moveAB = (CollisionWorld::canMove( CellProperty::getWorldCellProperty(), posA, posB, 0.5f, true, true, false ) == CMR_MoveOK);
|
||||||
|
bool moveBA = (CollisionWorld::canMove( CellProperty::getWorldCellProperty(), posB, posA, 0.5f, true, true, false ) == CMR_MoveOK);
|
||||||
|
|
||||||
|
if(moveAB && moveBA)
|
||||||
|
{
|
||||||
|
nodeA->addEdge( nodeB->getIndex() );
|
||||||
|
nodeB->addEdge( nodeA->getIndex() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// nodes can't be connected
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Linking done, prune redundant edges
|
||||||
|
|
||||||
|
IGNORE_RETURN( nodeA->markRedundantEdges() );
|
||||||
|
IGNORE_RETURN( nodeA->removeMarkedEdges() );
|
||||||
|
|
||||||
|
// this has to be done in two passes, otherwise node A's neighbor list could be changing
|
||||||
|
// as we prune edges.
|
||||||
|
|
||||||
|
static std::vector<int> neighborList;
|
||||||
|
|
||||||
|
neighborList.clear();
|
||||||
|
|
||||||
|
int edgeCount = nodeA->getEdgeCount();
|
||||||
|
|
||||||
|
for(i = 0; i < edgeCount; i++)
|
||||||
|
{
|
||||||
|
neighborList.push_back( nodeA->getNeighbor(i) );
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < edgeCount; i++)
|
||||||
|
{
|
||||||
|
CityPathNode * neighborNode = _getNode(neighborList[i]);
|
||||||
|
|
||||||
|
if(neighborNode != NULL)
|
||||||
|
{
|
||||||
|
neighborNode->markRedundantEdges();
|
||||||
|
neighborNode->removeMarkedEdges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
/*
|
||||||
|
int newNeighborCode = getNeighborCode(nodeIndex);
|
||||||
|
|
||||||
|
if(oldNeighborCode == newNeighborCode)
|
||||||
|
{
|
||||||
|
DEBUG_REPORT_LOG(true,("neighbors were the same\n"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG_REPORT_LOG(true,("neighbors were different\n"));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
CityPathNode * CityPathGraph::_getNode ( int whichNode )
|
||||||
|
{
|
||||||
|
return safe_cast<CityPathNode *>(getNode(whichNode));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
CityPathNode const * CityPathGraph::_getNode ( int whichNode ) const
|
||||||
|
{
|
||||||
|
return safe_cast<CityPathNode const *>(getNode(whichNode));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
CityPathNode * CityPathGraph::findNodeForObject ( ServerObject const & object )
|
||||||
|
{
|
||||||
|
int nodeCount = getNodeCount();
|
||||||
|
|
||||||
|
for (int i = 0; i < nodeCount; i++)
|
||||||
|
{
|
||||||
|
CityPathNode * node = _getNode(i);
|
||||||
|
|
||||||
|
if(node == NULL) continue;
|
||||||
|
|
||||||
|
ServerObject const * source = node->getSourceObject();
|
||||||
|
|
||||||
|
if(source == NULL) continue;
|
||||||
|
|
||||||
|
if(source == &object)
|
||||||
|
{
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
CityPathNode const * CityPathGraph::findNodeForObject ( ServerObject const & object ) const
|
||||||
|
{
|
||||||
|
int nodeCount = getNodeCount();
|
||||||
|
|
||||||
|
for(int i = 0; i < nodeCount; i++)
|
||||||
|
{
|
||||||
|
CityPathNode const * node = _getNode(i);
|
||||||
|
|
||||||
|
if(node == NULL) continue;
|
||||||
|
|
||||||
|
ServerObject const * source = node->getSourceObject();
|
||||||
|
|
||||||
|
if(source == NULL) continue;
|
||||||
|
|
||||||
|
if(source == &object)
|
||||||
|
{
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
CityPathNode * CityPathGraph::findNearestNodeForName( Unicode::String const & nodeName, Vector const & pos )
|
||||||
|
{
|
||||||
|
if (m_namedNodes == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
std::map<Unicode::String, std::set<CityPathNode *> >::iterator found = m_namedNodes->find(nodeName);
|
||||||
|
if (found != m_namedNodes->end() && !found->second.empty())
|
||||||
|
{
|
||||||
|
std::set<CityPathNode *> & nodes = found->second;
|
||||||
|
if (nodes.size() == 1)
|
||||||
|
return *(nodes.begin());
|
||||||
|
|
||||||
|
CityPathNode * node = NULL;
|
||||||
|
float distance = FLT_MAX;
|
||||||
|
for (std::set<CityPathNode *>::iterator i = nodes.begin(); i != nodes.end(); ++i)
|
||||||
|
{
|
||||||
|
float testDistance = pos.magnitudeBetweenSquared((*i)->getPosition_w());
|
||||||
|
if (node == NULL || testDistance < distance)
|
||||||
|
{
|
||||||
|
distance = testDistance;
|
||||||
|
node = *i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
CityPathNode const * CityPathGraph::findNearestNodeForName( Unicode::String const & nodeName, Vector const & pos ) const
|
||||||
|
{
|
||||||
|
if (m_namedNodes == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
std::map<Unicode::String, std::set<CityPathNode *> >::const_iterator found = m_namedNodes->find(nodeName);
|
||||||
|
if (found != m_namedNodes->end() && !found->second.empty())
|
||||||
|
{
|
||||||
|
std::set<CityPathNode *> const & nodes = found->second;
|
||||||
|
if (nodes.size() == 1)
|
||||||
|
return *(nodes.begin());
|
||||||
|
|
||||||
|
CityPathNode const * node = NULL;
|
||||||
|
float distance = FLT_MAX;
|
||||||
|
for (std::set<CityPathNode *>::const_iterator i = nodes.begin(); i != nodes.end(); ++i)
|
||||||
|
{
|
||||||
|
float testDistance = pos.magnitudeBetweenSquared((*i)->getPosition_w());
|
||||||
|
if (node == NULL || testDistance < distance)
|
||||||
|
{
|
||||||
|
distance = testDistance;
|
||||||
|
node = *i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
int CityPathGraph::findNearestNode ( Vector const & position ) const
|
||||||
|
{
|
||||||
|
PathNode * temp = NULL;
|
||||||
|
|
||||||
|
float dummy1 = REAL_MAX;
|
||||||
|
float dummy2 = REAL_MAX;
|
||||||
|
|
||||||
|
if( m_nodeTree->findClosest(position,REAL_MAX,temp,dummy1,dummy2) )
|
||||||
|
{
|
||||||
|
return temp->getIndex();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//@todo - I have no idea why, but the compiler bitches if this isn't here.
|
||||||
|
|
||||||
|
int CityPathGraph::findNearestNode ( PathNodeType type, Vector const & position_p ) const
|
||||||
|
{
|
||||||
|
return PathGraph::findNearestNode(type,position_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CityPathGraph::findNodesInRange ( Vector const & position_p, float range, PathNodeList & results ) const
|
||||||
|
{
|
||||||
|
m_nodeTree->findInRange(position_p,range,results);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CityPathGraph::saveGraph ( void )
|
||||||
|
{
|
||||||
|
int nodeCount = getNodeCount();
|
||||||
|
|
||||||
|
for(int i = 0; i < nodeCount; i++)
|
||||||
|
{
|
||||||
|
CityPathNode * node = _getNode(i);
|
||||||
|
|
||||||
|
if(node) node->saveToObjvars();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool CityPathGraph::sanityCheck ( bool doWarnings ) const
|
||||||
|
{
|
||||||
|
bool sane = true;
|
||||||
|
|
||||||
|
int nodeCount = getNodeCount();
|
||||||
|
|
||||||
|
for(int i = 0; i < nodeCount; i++)
|
||||||
|
{
|
||||||
|
CityPathNode const * node = _getNode(i);
|
||||||
|
|
||||||
|
if(node)
|
||||||
|
{
|
||||||
|
sane &= node->sanityCheck(doWarnings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sane;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CityPathGraph::reloadPathNodes ( void )
|
||||||
|
{
|
||||||
|
int nodeCount = getNodeCount();
|
||||||
|
|
||||||
|
for(int i = 0; i < nodeCount; i++)
|
||||||
|
{
|
||||||
|
CityPathNode * node = _getNode(i);
|
||||||
|
|
||||||
|
if(node) node->reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
ServerObject const * CityPathGraph::getCreator ( void ) const
|
||||||
|
{
|
||||||
|
return safe_cast<ServerObject const *>(m_creatorId.getObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CityPathGraph::setCreator ( NetworkId const & creatorId )
|
||||||
|
{
|
||||||
|
m_creatorId = creatorId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CityPathGraph::addDirtyBox ( AxialBox const & box )
|
||||||
|
{
|
||||||
|
if(ConfigSharedPathfinding::getEnableDirtyBoxes())
|
||||||
|
{
|
||||||
|
m_dirtyBoxes->push_back(box);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
bool CityPathGraph::isDirty ( Vector const & point_w ) const
|
||||||
|
{
|
||||||
|
int count = m_dirtyBoxes->size();
|
||||||
|
|
||||||
|
for(int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
AxialBox const & box = m_dirtyBoxes->at(i);
|
||||||
|
|
||||||
|
if(Containment2d::TestPointABox(point_w,box))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
float CityPathGraph::getLinkDistance ( void )
|
||||||
|
{
|
||||||
|
return g_linkDistance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CityPathGraph::setLinkDistance ( float dist )
|
||||||
|
{
|
||||||
|
g_linkDistance = dist;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// the neighbor code has to be order-independent, so to make the code
|
||||||
|
// we cast the addresses of all the neighbors to ints, multiply them
|
||||||
|
// by a random large prime number, then xor the bits together.
|
||||||
|
|
||||||
|
int CityPathGraph::getNeighborCode ( int whichNode ) const
|
||||||
|
{
|
||||||
|
CityPathNode const * node = _getNode(whichNode);
|
||||||
|
|
||||||
|
if(node == NULL) return 0;
|
||||||
|
|
||||||
|
int edgeCount = node->getEdgeCount();
|
||||||
|
|
||||||
|
int code = 0;
|
||||||
|
|
||||||
|
for(int i = 0; i < edgeCount; i++)
|
||||||
|
{
|
||||||
|
int neighborId = node->getNeighbor(i);
|
||||||
|
|
||||||
|
CityPathNode const * neighbor = _getNode(neighborId);
|
||||||
|
|
||||||
|
if(neighbor == NULL) continue;
|
||||||
|
|
||||||
|
int neighborInt = reinterpret_cast<int>(neighbor);
|
||||||
|
|
||||||
|
int mungedInt = neighborInt * 1295183;
|
||||||
|
|
||||||
|
code ^= mungedInt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
// ======================================================================
|
||||||
|
//
|
||||||
|
// CityPathGraph.h
|
||||||
|
// Copyright 2001 Sony Online Entertainment Inc.
|
||||||
|
// All Rights Reserved.
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef INCLUDED_CityPathGraph_H
|
||||||
|
#define INCLUDED_CityPathGraph_H
|
||||||
|
|
||||||
|
#include "sharedPathfinding/DynamicPathGraph.h"
|
||||||
|
|
||||||
|
#include "sharedObject/CachedNetworkId.h"
|
||||||
|
|
||||||
|
class CityPathNode;
|
||||||
|
class ServerObject;
|
||||||
|
class PathNodeSphereAccessor;
|
||||||
|
class AxialBox;
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
class SphereTree;
|
||||||
|
|
||||||
|
typedef SphereTree<PathNode *, PathNodeSphereAccessor> PathNodeTree;
|
||||||
|
|
||||||
|
typedef stdvector<AxialBox>::fwd BoxList;
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
// CityPathGraph is a DynamicPathGraph with some specializations that
|
||||||
|
// allow it to be constructed from objvars on server-side waypoint
|
||||||
|
// objects
|
||||||
|
|
||||||
|
class CityPathGraph : public DynamicPathGraph
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
CityPathGraph ( int cityToken );
|
||||||
|
|
||||||
|
virtual ~CityPathGraph();
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
virtual int addNode ( DynamicPathNode * newNode );
|
||||||
|
virtual void removeNode ( int nodeIndex );
|
||||||
|
virtual void moveNode ( int nodeIndex, Vector const & newPosition );
|
||||||
|
|
||||||
|
virtual void relinkNode ( int nodeIndex );
|
||||||
|
virtual void destroyNode ( int nodeIndex );
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
CityPathNode * _getNode ( int whichNode );
|
||||||
|
CityPathNode const * _getNode ( int whichNode ) const;
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
CityPathNode * findNodeForObject ( ServerObject const & object );
|
||||||
|
CityPathNode const * findNodeForObject ( ServerObject const & object ) const;
|
||||||
|
CityPathNode * findNearestNodeForName ( Unicode::String const & nodeName, Vector const & pos );
|
||||||
|
CityPathNode const * findNearestNodeForName ( Unicode::String const & nodeName, Vector const & pos ) const;
|
||||||
|
|
||||||
|
int findNearestNode ( Vector const & position_p ) const;
|
||||||
|
int findNearestNode ( PathNodeType type, Vector const & position_p ) const;
|
||||||
|
|
||||||
|
void findNodesInRange ( Vector const & position_p, float range, PathNodeList & results ) const;
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
void saveGraph ( void );
|
||||||
|
bool sanityCheck ( bool doWarnings ) const;
|
||||||
|
|
||||||
|
void reloadPathNodes ( void );
|
||||||
|
|
||||||
|
int getCityToken ( void ) const;
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
ServerObject const * getCreator ( void ) const;
|
||||||
|
void setCreator ( NetworkId const & creator );
|
||||||
|
|
||||||
|
void addDirtyBox ( AxialBox const & box );
|
||||||
|
bool isDirty ( Vector const & point_w ) const;
|
||||||
|
|
||||||
|
static float getLinkDistance ( void );
|
||||||
|
static void setLinkDistance ( float dist );
|
||||||
|
|
||||||
|
int getNeighborCode ( int whichNode ) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
PathNodeTree * m_nodeTree;
|
||||||
|
//@todo: order the CityPathNodes below in such a way as to make searching for the closest one quick
|
||||||
|
stdmap<Unicode::String, stdset<CityPathNode *>::fwd >::fwd * m_namedNodes;
|
||||||
|
int m_token;
|
||||||
|
|
||||||
|
CachedNetworkId m_creatorId;
|
||||||
|
|
||||||
|
BoxList * m_dirtyBoxes;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
inline int CityPathGraph::getCityToken ( void ) const
|
||||||
|
{
|
||||||
|
return m_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,91 @@
|
|||||||
|
// ======================================================================
|
||||||
|
//
|
||||||
|
// CityPathGraphManager.h
|
||||||
|
// Copyright 2001 Sony Online Entertainment Inc.
|
||||||
|
// All Rights Reserved.
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef INCLUDED_CityPathGraphManager_H
|
||||||
|
#define INCLUDED_CityPathGraphManager_H
|
||||||
|
|
||||||
|
class ServerObject;
|
||||||
|
class PathGraph;
|
||||||
|
class Vector;
|
||||||
|
class CityPathGraph;
|
||||||
|
class CityPathNode;
|
||||||
|
class BuildingObject;
|
||||||
|
|
||||||
|
typedef stdmap< int, CityPathGraph * >::fwd CityGraphMap;
|
||||||
|
|
||||||
|
typedef stdvector< Vector >::fwd PositionList;
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
class CityPathGraphManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static void install ( void );
|
||||||
|
static void remove ( void );
|
||||||
|
|
||||||
|
static void update ( float time );
|
||||||
|
|
||||||
|
static void preloadComplete ( void );
|
||||||
|
|
||||||
|
static void sanityCheck ( void );
|
||||||
|
|
||||||
|
static void addWaypoint ( ServerObject * object );
|
||||||
|
static void removeWaypoint ( ServerObject * object );
|
||||||
|
static void moveWaypoint ( ServerObject * object, Vector const & oldPosition );
|
||||||
|
static void destroyWaypoint ( ServerObject * object );
|
||||||
|
|
||||||
|
static void addBuilding ( BuildingObject * building );
|
||||||
|
static void removeBuilding ( BuildingObject * building );
|
||||||
|
static void moveBuilding ( BuildingObject * building, Vector const & oldPosition );
|
||||||
|
static void destroyBuilding ( BuildingObject * building );
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
static bool destroyPathGraph ( ServerObject const * creator );
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
static bool createPathNodes ( ServerObject * building );
|
||||||
|
static bool destroyPathNodes ( ServerObject * building );
|
||||||
|
|
||||||
|
static bool reloadPathNodes ( void );
|
||||||
|
static bool reloadPathNodes ( stdvector< ServerObject * >::fwd const & objects );
|
||||||
|
|
||||||
|
static bool markCityEntrance ( ServerObject * object );
|
||||||
|
static bool unmarkCityEntrance ( ServerObject * object );
|
||||||
|
|
||||||
|
static float getLinkDistance ( void );
|
||||||
|
static void setLinkDistance ( float dist );
|
||||||
|
|
||||||
|
static void relinkGraph ( CityPathGraph const * graph );
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
static int getGraphCount ( void );
|
||||||
|
static CityPathGraph * getGraph ( int index );
|
||||||
|
|
||||||
|
static CityPathGraph const * getCityGraphFor ( ServerObject const * object );
|
||||||
|
static CityPathGraph const * getCityGraphFor ( Vector const & position );
|
||||||
|
|
||||||
|
static CityPathNode const * getNamedNodeFor( ServerObject const & object, Unicode::String const & nodeName );
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
static bool getClosestPathNodePos ( ServerObject const * object, Vector & outPos );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
CityPathGraphManager();
|
||||||
|
~CityPathGraphManager();
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,558 @@
|
|||||||
|
// ======================================================================
|
||||||
|
//
|
||||||
|
// CityPathNode.cpp
|
||||||
|
// copyright (c) 2001 Sony Online Entertainment
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include "serverPathfinding/FirstServerPathfinding.h"
|
||||||
|
#include "serverPathfinding/CityPathNode.h"
|
||||||
|
|
||||||
|
#include "serverGame/ServerObject.h"
|
||||||
|
#include "serverGame/ServerWorld.h"
|
||||||
|
|
||||||
|
#include "serverPathfinding/CityPathGraph.h"
|
||||||
|
#include "serverPathfinding/ServerPathfindingConstants.h"
|
||||||
|
|
||||||
|
#include "sharedCollision/CollisionWorld.h"
|
||||||
|
#include "sharedCollision/CollisionUtils.h"
|
||||||
|
|
||||||
|
#include "sharedFoundation/DynamicVariable.h"
|
||||||
|
#include "sharedFoundation/DynamicVariableList.h"
|
||||||
|
#include "sharedFoundation/NetworkId.h"
|
||||||
|
|
||||||
|
#include "sharedObject/CellProperty.h"
|
||||||
|
#include "sharedObject/NetworkIdManager.h"
|
||||||
|
|
||||||
|
#include "sharedPathfinding/PathEdge.h"
|
||||||
|
|
||||||
|
#include "sharedTerrain/TerrainObject.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
typedef std::vector<NetworkId> NetworkIdList;
|
||||||
|
|
||||||
|
namespace CityPathNodeNamespace
|
||||||
|
{
|
||||||
|
int gs_debugIdCounter = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
using namespace CityPathNodeNamespace;
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
CityPathNode::CityPathNode ( Vector const & position_w, NetworkId const & sourceId )
|
||||||
|
: DynamicPathNode(position_w),
|
||||||
|
m_source(sourceId),
|
||||||
|
m_creator(),
|
||||||
|
m_relativePosition_o(Vector::zero),
|
||||||
|
m_spatialHandle(NULL),
|
||||||
|
m_debugId( gs_debugIdCounter++ )
|
||||||
|
{
|
||||||
|
snapToTerrain();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
CityPathNode::CityPathNode ( Vector const & position_w, NetworkId const & sourceId, NetworkId const & creatorId )
|
||||||
|
: DynamicPathNode(position_w),
|
||||||
|
m_source(sourceId),
|
||||||
|
m_creator(creatorId),
|
||||||
|
m_relativePosition_o(Vector::zero),
|
||||||
|
m_spatialHandle(NULL),
|
||||||
|
m_debugId( gs_debugIdCounter++ )
|
||||||
|
{
|
||||||
|
updateRelativePosition();
|
||||||
|
|
||||||
|
snapToTerrain();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
CityPathNode::~CityPathNode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CityPathNode::clearEdges ( void )
|
||||||
|
{
|
||||||
|
ServerObject * sourceObject = getSourceObject();
|
||||||
|
|
||||||
|
if(sourceObject)
|
||||||
|
{
|
||||||
|
sourceObject->removeObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_EDGES);
|
||||||
|
}
|
||||||
|
|
||||||
|
DynamicPathNode::clearEdges();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
CellProperty const * CityPathNode::getCell ( void ) const
|
||||||
|
{
|
||||||
|
ServerObject const * sourceObject = getSourceObject();
|
||||||
|
|
||||||
|
if(sourceObject)
|
||||||
|
{
|
||||||
|
return sourceObject->getParentCell();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return CellProperty::getWorldCellProperty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Vector CityPathNode::getPosition_w ( void ) const
|
||||||
|
{
|
||||||
|
return CollisionUtils::transformToWorld(getCell(),getPosition_p());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CityPathNode::setPosition_p ( Vector const & newPosition_p )
|
||||||
|
{
|
||||||
|
DynamicPathNode::setPosition_p(newPosition_p);
|
||||||
|
|
||||||
|
updateRelativePosition();
|
||||||
|
|
||||||
|
snapToTerrain();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CityPathNode::setPosition_w ( Vector const & newPosition_w )
|
||||||
|
{
|
||||||
|
Vector newPosition_p = CollisionUtils::transformFromWorld(newPosition_w,getCell());
|
||||||
|
|
||||||
|
setPosition_p(newPosition_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CityPathNode::updateRelativePosition ( void )
|
||||||
|
{
|
||||||
|
ServerObject const * sourceObject = getSourceObject();
|
||||||
|
|
||||||
|
ServerObject const * creatorObject = getCreatorObject();
|
||||||
|
|
||||||
|
if(sourceObject && creatorObject)
|
||||||
|
{
|
||||||
|
m_relativePosition_o = creatorObject->rotateTranslate_w2o(sourceObject->getPosition_w());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CityPathNode::loadFromObjvars ( void )
|
||||||
|
{
|
||||||
|
loadInfoFromObjvars();
|
||||||
|
loadEdgesFromObjvars();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CityPathNode::loadInfoFromObjvars ( void )
|
||||||
|
{
|
||||||
|
ServerObject const * sourceObject = getSourceObject();
|
||||||
|
|
||||||
|
if(sourceObject == NULL) return;
|
||||||
|
|
||||||
|
const DynamicVariableList & objvars = sourceObject->getObjVars();
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
m_creator = NetworkId::cms_invalid;
|
||||||
|
m_key = -1;
|
||||||
|
m_name.clear();
|
||||||
|
m_type = PNT_Invalid;
|
||||||
|
|
||||||
|
NetworkId creatorId;
|
||||||
|
if (objvars.getItem(OBJVAR_PATHFINDING_WAYPOINT_CREATOR,creatorId))
|
||||||
|
m_creator = creatorId;
|
||||||
|
|
||||||
|
objvars.getItem(OBJVAR_PATHFINDING_WAYPOINT_KEY, m_key);
|
||||||
|
objvars.getItem(OBJVAR_PATHFINDING_WAYPOINT_NAME, m_name);
|
||||||
|
|
||||||
|
int typeInt;
|
||||||
|
if(objvars.getItem(OBJVAR_PATHFINDING_WAYPOINT_TYPE, typeInt))
|
||||||
|
m_type = static_cast<PathNodeType>(typeInt);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CityPathNode::loadEdgesFromObjvars ( void )
|
||||||
|
{
|
||||||
|
ServerObject const * sourceObject = getSourceObject();
|
||||||
|
|
||||||
|
if(sourceObject == NULL) return;
|
||||||
|
|
||||||
|
DynamicVariableList const & objvars = sourceObject->getObjVars();
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
NetworkIdList idList;
|
||||||
|
if(objvars.getItem(OBJVAR_PATHFINDING_WAYPOINT_EDGES,idList))
|
||||||
|
{
|
||||||
|
int idCount = idList.size();
|
||||||
|
|
||||||
|
for(int i = 0; i < idCount; i++)
|
||||||
|
{
|
||||||
|
ServerObject * serverObject = ServerWorld::findObjectByNetworkId( idList[i] );
|
||||||
|
|
||||||
|
if(serverObject == NULL) continue;
|
||||||
|
|
||||||
|
CityPathNode * otherNode = _getGraph()->findNodeForObject(*serverObject);
|
||||||
|
|
||||||
|
if(otherNode == NULL) continue;
|
||||||
|
|
||||||
|
addEdge(otherNode->getIndex());
|
||||||
|
otherNode->addEdge(getIndex());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG_WARNING(true,("CityPathNode::loadEdgesFromObjvars - Source object has no edge list objvar\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CityPathNode::saveToObjvars ( void )
|
||||||
|
{
|
||||||
|
saveInfoToObjvars();
|
||||||
|
saveEdgesToObjvars();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CityPathNode::saveInfoToObjvars ( void )
|
||||||
|
{
|
||||||
|
ServerObject * sourceObject = getSourceObject();
|
||||||
|
|
||||||
|
if(sourceObject == NULL) return;
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
NetworkId const & creatorId = getCreatorId();
|
||||||
|
|
||||||
|
if(creatorId.isValid())
|
||||||
|
{
|
||||||
|
sourceObject->setObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_CREATOR, creatorId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sourceObject->removeObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_CREATOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_key != -1)
|
||||||
|
{
|
||||||
|
sourceObject->setObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_KEY,static_cast<int>(m_key));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sourceObject->removeObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!m_name.empty())
|
||||||
|
{
|
||||||
|
sourceObject->setObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_NAME,m_name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sourceObject->removeObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_type != PNT_Invalid)
|
||||||
|
{
|
||||||
|
sourceObject->setObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_TYPE,static_cast<int>(m_type));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sourceObject->removeObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_TYPE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CityPathNode::saveEdgesToObjvars ( void )
|
||||||
|
{
|
||||||
|
ServerObject * sourceObject = getSourceObject();
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
NetworkIdList idList;
|
||||||
|
|
||||||
|
int edgeCount = getEdgeCount();
|
||||||
|
|
||||||
|
for(int i = 0; i < edgeCount; i++)
|
||||||
|
{
|
||||||
|
int neighborIndex = getNeighbor(i);
|
||||||
|
|
||||||
|
CityPathNode * neighborNode = _getGraph()->_getNode(neighborIndex);
|
||||||
|
|
||||||
|
if(neighborNode == NULL) continue;
|
||||||
|
|
||||||
|
NetworkId const & neighborSourceId = neighborNode->getSourceId();
|
||||||
|
|
||||||
|
if(neighborSourceId.isValid())
|
||||||
|
{
|
||||||
|
idList.push_back(neighborSourceId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!idList.empty())
|
||||||
|
{
|
||||||
|
sourceObject->setObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_EDGES,idList);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sourceObject->removeObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_EDGES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CityPathNode::saveNeighbors ( void )
|
||||||
|
{
|
||||||
|
int edgeCount = getEdgeCount();
|
||||||
|
|
||||||
|
for(int i = 0; i < edgeCount; i++)
|
||||||
|
{
|
||||||
|
int neighborIndex = getNeighbor(i);
|
||||||
|
|
||||||
|
CityPathNode * neighborNode = _getGraph()->_getNode(neighborIndex);
|
||||||
|
|
||||||
|
if(neighborNode == NULL) continue;
|
||||||
|
|
||||||
|
neighborNode->saveToObjvars();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CityPathNode::saveAllData ( void )
|
||||||
|
{
|
||||||
|
saveToObjvars();
|
||||||
|
saveNeighbors();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
ServerObject * CityPathNode::getSourceObject ( void )
|
||||||
|
{
|
||||||
|
return safe_cast<ServerObject*>(m_source.getObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerObject const * CityPathNode::getSourceObject ( void ) const
|
||||||
|
{
|
||||||
|
return safe_cast<ServerObject const *>(m_source.getObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkId const & CityPathNode::getSourceId ( void ) const
|
||||||
|
{
|
||||||
|
return m_source;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
ServerObject * CityPathNode::getCreatorObject ( void )
|
||||||
|
{
|
||||||
|
return safe_cast<ServerObject *>(m_creator.getObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerObject const * CityPathNode::getCreatorObject ( void ) const
|
||||||
|
{
|
||||||
|
return safe_cast<ServerObject const *>(m_creator.getObject());
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkId const & CityPathNode::getCreatorId ( void ) const
|
||||||
|
{
|
||||||
|
return m_creator;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
void CityPathNode::setCreator ( NetworkId const & creatorId )
|
||||||
|
{
|
||||||
|
m_creator = creatorId;
|
||||||
|
|
||||||
|
updateRelativePosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
CityPathGraph * CityPathNode::_getGraph ( void )
|
||||||
|
{
|
||||||
|
return safe_cast<CityPathGraph *>(getGraph());
|
||||||
|
}
|
||||||
|
|
||||||
|
CityPathGraph const * CityPathNode::_getGraph ( void ) const
|
||||||
|
{
|
||||||
|
return safe_cast<CityPathGraph const *>(getGraph());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
int CityPathNode::getDebugId ( void ) const
|
||||||
|
{
|
||||||
|
return m_debugId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool CityPathNode::sanityCheck ( bool doWarnings ) const
|
||||||
|
{
|
||||||
|
UNREF(doWarnings); //for release build
|
||||||
|
int insaneCount = 0;
|
||||||
|
|
||||||
|
int edgeCount = getEdgeCount();
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < edgeCount; i++)
|
||||||
|
{
|
||||||
|
int neighborIndex = getNeighbor(i);
|
||||||
|
|
||||||
|
CityPathNode const * neighborNode = _getGraph()->_getNode(neighborIndex);
|
||||||
|
|
||||||
|
if(neighborNode == NULL)
|
||||||
|
{
|
||||||
|
DEBUG_WARNING(doWarnings,("CityPathNode::sanityCheck - Node has an edge to a non-existent node\n"));
|
||||||
|
insaneCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!neighborNode->hasEdge(getIndex()))
|
||||||
|
{
|
||||||
|
DEBUG_WARNING(doWarnings,("CityPathNode::sanityCheck - Node has a one-way edge to another node\n"));
|
||||||
|
insaneCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkIdList idList;
|
||||||
|
|
||||||
|
ServerObject const * sourceObject = getSourceObject();
|
||||||
|
|
||||||
|
if(sourceObject && sourceObject->getObjVars().getItem(OBJVAR_PATHFINDING_WAYPOINT_EDGES,idList))
|
||||||
|
{
|
||||||
|
int idCount = idList.size();
|
||||||
|
|
||||||
|
for(int i = 0; i < idCount; i++)
|
||||||
|
{
|
||||||
|
if(!hasEdgeTo(idList[i]))
|
||||||
|
{
|
||||||
|
DEBUG_WARNING(doWarnings,("CityPathNode::sanityCheck - Node has a link in its objvar list that's not present in the edge list\n"));
|
||||||
|
insaneCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(getType() != PNT_CityBuilding)
|
||||||
|
{
|
||||||
|
for(i = 0; i < edgeCount; i++)
|
||||||
|
{
|
||||||
|
CityPathNode const * nodeA = this;
|
||||||
|
CityPathNode const * nodeB = _getGraph()->_getNode(getNeighbor(i));
|
||||||
|
|
||||||
|
if(nodeB == NULL) continue;
|
||||||
|
|
||||||
|
if(nodeB->getType() == PNT_CityBuilding) continue;
|
||||||
|
|
||||||
|
Vector posA = nodeA->getPosition_p();
|
||||||
|
Vector posB = nodeB->getPosition_p();
|
||||||
|
|
||||||
|
bool moveAB = (CollisionWorld::canMove( CellProperty::getWorldCellProperty(), posA, posB, 0.0f, true, true, false ) == CMR_MoveOK);
|
||||||
|
|
||||||
|
if(!moveAB)
|
||||||
|
{
|
||||||
|
DEBUG_WARNING(doWarnings,("CityPathNode::sanityCheck - Node has a link that's not traversable\n"));
|
||||||
|
insaneCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int redundantCount = markRedundantEdges();
|
||||||
|
|
||||||
|
if(redundantCount > 0)
|
||||||
|
{
|
||||||
|
DEBUG_WARNING(doWarnings,("CityPathNode::sanityCheck - Node has %d redundant edges\n",redundantCount));
|
||||||
|
insaneCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return insaneCount == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Reload the parts of the node data that are set up by designers
|
||||||
|
|
||||||
|
void CityPathNode::reload ( void )
|
||||||
|
{
|
||||||
|
ServerObject const * sourceObject = getSourceObject();
|
||||||
|
|
||||||
|
if(sourceObject == NULL) return;
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
DynamicVariableList const & objvars = sourceObject->getObjVars();
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
objvars.getItem(OBJVAR_PATHFINDING_WAYPOINT_NAME,m_name);
|
||||||
|
int pathNodeTypeInt;
|
||||||
|
objvars.getItem(OBJVAR_PATHFINDING_WAYPOINT_TYPE,pathNodeTypeInt);
|
||||||
|
m_type = static_cast<PathNodeType>(pathNodeTypeInt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool CityPathNode::hasEdgeTo ( NetworkId const & neighborId ) const
|
||||||
|
{
|
||||||
|
if(!neighborId.isValid()) return false;
|
||||||
|
|
||||||
|
int edgeCount = getEdgeCount();
|
||||||
|
|
||||||
|
for(int i = 0; i < edgeCount; i++)
|
||||||
|
{
|
||||||
|
int neighborIndex = getNeighbor(i);
|
||||||
|
|
||||||
|
CityPathNode const * neighborNode = _getGraph()->_getNode(neighborIndex);
|
||||||
|
|
||||||
|
if(neighborNode == NULL) continue;
|
||||||
|
|
||||||
|
if(neighborNode->getSourceId() == neighborId) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CityPathNode::snapToTerrain ( void )
|
||||||
|
{
|
||||||
|
CellProperty const * cell = getCell();
|
||||||
|
|
||||||
|
if((cell == NULL) || (cell == CellProperty::getWorldCellProperty()))
|
||||||
|
{
|
||||||
|
Vector pos_w = getPosition_w();
|
||||||
|
|
||||||
|
float height = 0.0f;
|
||||||
|
|
||||||
|
if(TerrainObject::getConstInstance ()->getHeightForceChunkCreation(pos_w,height))
|
||||||
|
{
|
||||||
|
if(height > pos_w.y)
|
||||||
|
{
|
||||||
|
pos_w.y = height;
|
||||||
|
|
||||||
|
Vector pos_p = CollisionUtils::transformFromWorld(pos_w,getCell());
|
||||||
|
|
||||||
|
DynamicPathNode::setPosition_p(pos_p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
// ======================================================================
|
||||||
|
//
|
||||||
|
// CityPathNode.h
|
||||||
|
// Copyright 2002 Sony Online Entertainment Inc.
|
||||||
|
// All Rights Reserved.
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef INCLUDED_CityPathNode_H
|
||||||
|
#define INCLUDED_CityPathNode_H
|
||||||
|
|
||||||
|
#include "serverGame/ServerObject.h"
|
||||||
|
#include "sharedFoundation/Watcher.h"
|
||||||
|
#include "sharedPathfinding/DynamicPathNode.h"
|
||||||
|
#include "Unicode.h"
|
||||||
|
|
||||||
|
class CityPathGraph;
|
||||||
|
class SpatialSubdivisionHandle;
|
||||||
|
|
||||||
|
typedef SpatialSubdivisionHandle SpatialHandle;
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
// CityPathNodes are DynamicPathNodes that know how to use objvars to
|
||||||
|
// persist their data.
|
||||||
|
|
||||||
|
class CityPathNode : public DynamicPathNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
CityPathNode ( Vector const & position_w, NetworkId const & sourceId );
|
||||||
|
CityPathNode ( Vector const & position_w, NetworkId const & sourceId, NetworkId const & creatorId );
|
||||||
|
|
||||||
|
virtual ~CityPathNode();
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
virtual void clearEdges ( void );
|
||||||
|
|
||||||
|
virtual CellProperty const * getCell ( void ) const;
|
||||||
|
|
||||||
|
virtual Vector getPosition_w ( void ) const;
|
||||||
|
|
||||||
|
virtual void setPosition_p ( Vector const & newPosition_p );
|
||||||
|
|
||||||
|
virtual void setPosition_w ( Vector const & newPosition_w );
|
||||||
|
|
||||||
|
Vector const & getRelativePosition_o ( void ) const;
|
||||||
|
void setRelativePosition_o ( Vector const & position_o );
|
||||||
|
|
||||||
|
void updateRelativePosition ( void );
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
void loadFromObjvars ( void );
|
||||||
|
void saveToObjvars ( void );
|
||||||
|
|
||||||
|
void loadInfoFromObjvars ( void );
|
||||||
|
void saveInfoToObjvars ( void );
|
||||||
|
|
||||||
|
void loadEdgesFromObjvars ( void );
|
||||||
|
void saveEdgesToObjvars ( void );
|
||||||
|
|
||||||
|
void saveNeighbors ( void );
|
||||||
|
void saveAllData ( void );
|
||||||
|
|
||||||
|
int getDebugId ( void ) const;
|
||||||
|
|
||||||
|
bool sanityCheck ( bool doWarnings ) const;
|
||||||
|
|
||||||
|
void reload ( void );
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
ServerObject * getSourceObject ( void );
|
||||||
|
ServerObject const * getSourceObject ( void ) const;
|
||||||
|
|
||||||
|
NetworkId const & getSourceId ( void ) const;
|
||||||
|
|
||||||
|
ServerObject * getCreatorObject ( void );
|
||||||
|
ServerObject const * getCreatorObject ( void ) const;
|
||||||
|
|
||||||
|
NetworkId const & getCreatorId ( void ) const;
|
||||||
|
|
||||||
|
void setCreator ( NetworkId const & networkId );
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
CityPathGraph * _getGraph ( void );
|
||||||
|
CityPathGraph const * _getGraph ( void ) const;
|
||||||
|
|
||||||
|
Unicode::String const & getName ( void ) const;
|
||||||
|
void setName ( Unicode::String const & name );
|
||||||
|
|
||||||
|
SpatialHandle * getSpatialHandle ( void );
|
||||||
|
SpatialHandle const * getSpatialHandle ( void ) const;
|
||||||
|
|
||||||
|
void setSpatialHandle ( SpatialHandle * newHandle );
|
||||||
|
|
||||||
|
bool hasEdgeTo ( NetworkId const & neighborId ) const;
|
||||||
|
|
||||||
|
void snapToTerrain ( void );
|
||||||
|
|
||||||
|
int getNeighborCode ( void ) const;
|
||||||
|
void setNeighborCode ( int newCode );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
typedef Watcher<ServerObject> ObjectWatcher;
|
||||||
|
|
||||||
|
friend class CityPathGraph;
|
||||||
|
|
||||||
|
CachedNetworkId m_source;
|
||||||
|
CachedNetworkId m_creator;
|
||||||
|
|
||||||
|
Vector m_relativePosition_o; // Position relative to the creator
|
||||||
|
|
||||||
|
Unicode::String m_name;
|
||||||
|
|
||||||
|
SpatialHandle * m_spatialHandle;
|
||||||
|
|
||||||
|
int m_debugId;
|
||||||
|
|
||||||
|
int m_neighborCode;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// position relative to the creator object
|
||||||
|
|
||||||
|
inline Vector const & CityPathNode::getRelativePosition_o ( void ) const
|
||||||
|
{
|
||||||
|
return m_relativePosition_o;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CityPathNode::setRelativePosition_o ( Vector const & position_o )
|
||||||
|
{
|
||||||
|
m_relativePosition_o = position_o;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline Unicode::String const & CityPathNode::getName ( void ) const
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CityPathNode::setName ( Unicode::String const & name )
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline SpatialHandle * CityPathNode::getSpatialHandle ( void )
|
||||||
|
{
|
||||||
|
return m_spatialHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline SpatialHandle const * CityPathNode::getSpatialHandle ( void ) const
|
||||||
|
{
|
||||||
|
return m_spatialHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CityPathNode::setSpatialHandle ( SpatialHandle * newHandle )
|
||||||
|
{
|
||||||
|
m_spatialHandle = newHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// ======================================================================
|
||||||
|
//
|
||||||
|
// FirstServerPathfinding.h
|
||||||
|
// copyright (c) 2001 Sony Online Entertainment
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef INCLUDED_FirstServerPathfinding_H
|
||||||
|
#define INCLUDED_FirstServerPathfinding_H
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include "sharedPathfinding/FirstSharedPathfinding.h"
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,253 @@
|
|||||||
|
//======================================================================
|
||||||
|
//
|
||||||
|
// PathAutoGenerator.cpp
|
||||||
|
// copyright (c) 2005 Sony Online Entertainment
|
||||||
|
//
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
#include "serverPathfinding/FirstServerPathfinding.h"
|
||||||
|
#include "serverPathfinding/PathAutoGenerator.h"
|
||||||
|
|
||||||
|
#include "UnicodeUtils.h"
|
||||||
|
#include "serverGame/Region.h"
|
||||||
|
#include "serverGame/RegionMaster.h"
|
||||||
|
#include "serverGame/ServerObject.h"
|
||||||
|
#include "serverGame/ServerWorld.h"
|
||||||
|
#include "sharedCollision/CollisionWorld.h"
|
||||||
|
#include "sharedMath/MxCifQuadTreeBounds.h"
|
||||||
|
#include "sharedObject/CellProperty.h"
|
||||||
|
#include "sharedTerrain/TerrainObject.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define USE_OBSTACLE_TEMPLATE 0
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace PathAutoGeneratorNamespace
|
||||||
|
{
|
||||||
|
char const * const s_pathWaypointTemplate = "object/path_waypoint/path_waypoint.iff";
|
||||||
|
char const * const s_pathObstacleTemplate = "object/resource_container/energy_solid_lg.iff";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace PathAutoGeneratorNamespace;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Region const * PathAutoGenerator::findPathRegion(Vector const & pos_w)
|
||||||
|
{
|
||||||
|
std::string const & planetName = ServerWorld::getSceneId();
|
||||||
|
|
||||||
|
RegionMaster::RegionVector rv;
|
||||||
|
RegionMaster::getRegionsAtPoint(planetName, pos_w.x, pos_w.z, rv);
|
||||||
|
|
||||||
|
for (RegionMaster::RegionVector::const_iterator it = rv.begin(); it != rv.end(); ++it)
|
||||||
|
{
|
||||||
|
Region const * const r = *it;
|
||||||
|
if (NULL != r)
|
||||||
|
{
|
||||||
|
if (r->getGeography() == RegionNamespace::RG_pathfind)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void PathAutoGenerator::pathAutoGenerate(Vector const & pos_w, float nodeDistance, float obstacleDistance, Unicode::String & result)
|
||||||
|
{
|
||||||
|
Region const * region = findPathRegion(pos_w);
|
||||||
|
if (NULL == region)
|
||||||
|
{
|
||||||
|
result += Unicode::narrowToWide("No pathfinding region at position");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char buf[128];
|
||||||
|
size_t const bufsize = sizeof(buf);
|
||||||
|
snprintf(buf, bufsize, "Auto generating path for region [%s]\n", Unicode::wideToNarrow(region->getName()).c_str());
|
||||||
|
result += Unicode::narrowToWide(buf);
|
||||||
|
|
||||||
|
MxCifQuadTreeBounds const & bounds = region->getBounds();
|
||||||
|
|
||||||
|
float const minX = bounds.getMinX();
|
||||||
|
float const minY = bounds.getMinY();
|
||||||
|
float const maxX = bounds.getMaxX();
|
||||||
|
float const maxY = bounds.getMaxY();
|
||||||
|
|
||||||
|
TerrainObject const * const terrain = TerrainObject::getConstInstance();
|
||||||
|
|
||||||
|
Vector testPos_w;
|
||||||
|
|
||||||
|
Vector const goalOffsets[] =
|
||||||
|
{
|
||||||
|
//-- north
|
||||||
|
Vector(0.0f, 0.0f, obstacleDistance),
|
||||||
|
//-- east
|
||||||
|
Vector(obstacleDistance, 0.0f, 0.0f),
|
||||||
|
//-- south
|
||||||
|
Vector(0.0f, 0.0f, -obstacleDistance),
|
||||||
|
//-- west
|
||||||
|
Vector(-obstacleDistance, 0.0f, 0.0f)
|
||||||
|
};
|
||||||
|
|
||||||
|
int const numGoalOffsets = sizeof(goalOffsets) / sizeof(*goalOffsets);
|
||||||
|
|
||||||
|
{
|
||||||
|
for (testPos_w.x = minX; testPos_w.x < (maxX); testPos_w.x += nodeDistance)
|
||||||
|
{
|
||||||
|
for (testPos_w.z = minY; testPos_w.z < (maxY); testPos_w.z += nodeDistance)
|
||||||
|
{
|
||||||
|
terrain->isPassableForceChunkCreation(testPos_w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int const maxCreateCount = 500;
|
||||||
|
|
||||||
|
int createCount = 0;
|
||||||
|
int obstacleNearbySkipped = 0;
|
||||||
|
|
||||||
|
for (testPos_w.x = minX; testPos_w.x < maxX; testPos_w.x += nodeDistance)
|
||||||
|
{
|
||||||
|
for (testPos_w.z = minY; testPos_w.z < maxY; testPos_w.z += nodeDistance)
|
||||||
|
{
|
||||||
|
if (!bounds.isPointIn(testPos_w.x, testPos_w.z))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!terrain->isPassable(testPos_w))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool skip = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < numGoalOffsets; ++i)
|
||||||
|
{
|
||||||
|
Vector const & goalPos_w = testPos_w + goalOffsets[i];
|
||||||
|
CanMoveResult const cmr =
|
||||||
|
CollisionWorld::canMove(CellProperty::getWorldCellProperty(), testPos_w, goalPos_w, 1.0f, false, false, false);
|
||||||
|
|
||||||
|
if (cmr != CMR_MoveOK)
|
||||||
|
{
|
||||||
|
skip = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skip)
|
||||||
|
{
|
||||||
|
++obstacleNearbySkipped;
|
||||||
|
|
||||||
|
#if USE_OBSTACLE_TEMPLATE
|
||||||
|
if (NULL != PathAutoGeneratorNamespace::s_pathObstacleTemplate)
|
||||||
|
{
|
||||||
|
Transform transform_w;
|
||||||
|
transform_w.setPosition_p(testPos_w);
|
||||||
|
ServerObject * newObject = ServerWorld::createNewObject(s_pathObstacleTemplate, transform_w, 0, false);
|
||||||
|
newObject->addToWorld();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (createCount >= maxCreateCount)
|
||||||
|
{
|
||||||
|
++createCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
Transform transform_w;
|
||||||
|
transform_w.setPosition_p(testPos_w);
|
||||||
|
ServerObject * newObject = ServerWorld::createNewObject(s_pathWaypointTemplate, transform_w, 0, false);
|
||||||
|
|
||||||
|
if (NULL != newObject)
|
||||||
|
{
|
||||||
|
newObject->addToWorld();
|
||||||
|
newObject->persist();
|
||||||
|
++createCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(buf, bufsize, "Nodes created: %d, skipped %d\n", createCount, obstacleNearbySkipped);
|
||||||
|
result += Unicode::narrowToWide(buf);
|
||||||
|
|
||||||
|
if (createCount > maxCreateCount)
|
||||||
|
{
|
||||||
|
snprintf(buf, bufsize, " Max nodes (%d) hit, try changing your parameters\n", maxCreateCount);
|
||||||
|
result += Unicode::narrowToWide(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void PathAutoGenerator::pathAutoCleanup(Vector const & pos_w, Unicode::String & result)
|
||||||
|
{
|
||||||
|
Region const * region = findPathRegion(pos_w);
|
||||||
|
if (NULL == region)
|
||||||
|
{
|
||||||
|
result += Unicode::narrowToWide("No pathfinding region at position");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char buf[128];
|
||||||
|
size_t const bufsize = sizeof(buf);
|
||||||
|
snprintf(buf, bufsize, "Cleanup up pathnodes for region [%s]\n", Unicode::wideToNarrow(region->getName()).c_str());
|
||||||
|
result += Unicode::narrowToWide(buf);
|
||||||
|
|
||||||
|
MxCifQuadTreeBounds const & bounds = region->getBounds();
|
||||||
|
|
||||||
|
float const minX = bounds.getMinX();
|
||||||
|
float const minY = bounds.getMinY();
|
||||||
|
float const maxX = bounds.getMaxX();
|
||||||
|
float const maxY = bounds.getMaxY();
|
||||||
|
|
||||||
|
float const range = std::max(maxX - minX, maxY - minY);
|
||||||
|
|
||||||
|
Vector const center((minX + maxX) * 0.5f, 0.0f, (minY + maxY) * 0.5f);
|
||||||
|
|
||||||
|
typedef stdvector<ServerObject *>::fwd ServerObjectVector;
|
||||||
|
|
||||||
|
ServerObjectVector sv;
|
||||||
|
|
||||||
|
ServerWorld::findObjectsInRange(center, range, sv);
|
||||||
|
|
||||||
|
int destroyCount = 0;
|
||||||
|
int obstacleDestroyCount = 0;
|
||||||
|
for (ServerObjectVector::const_iterator it = sv.begin(); it != sv.end(); ++it)
|
||||||
|
{
|
||||||
|
ServerObject * const so = *it;
|
||||||
|
|
||||||
|
Vector const & pos_w = so->getPosition_w();
|
||||||
|
|
||||||
|
if (bounds.isPointIn(pos_w.x, pos_w.z))
|
||||||
|
{
|
||||||
|
if (!strcmp(so->getTemplateName(), s_pathWaypointTemplate))
|
||||||
|
{
|
||||||
|
so->permanentlyDestroy(DeleteReasons::Script);
|
||||||
|
++destroyCount;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if USE_OBSTACLE_TEMPLATE
|
||||||
|
if (NULL != s_pathObstacleTemplate && !strcmp(so->getTemplateName(), s_pathObstacleTemplate))
|
||||||
|
{
|
||||||
|
so->permanentlyDestroy(DeleteReasons::Script);
|
||||||
|
++obstacleDestroyCount;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(buf, bufsize, "Nodes destroyed: %d, obstacle placeholders destroyed: %d\n", destroyCount, obstacleDestroyCount);
|
||||||
|
result += Unicode::narrowToWide(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
//======================================================================
|
||||||
|
//
|
||||||
|
// PathAutoGenerator.h
|
||||||
|
// copyright (c) 2005 Sony Online Entertainment
|
||||||
|
//
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
#ifndef INCLUDED_PathAutoGenerator_H
|
||||||
|
#define INCLUDED_PathAutoGenerator_H
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
class Region;
|
||||||
|
class Vector;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
|
class PathAutoGenerator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static Region const * findPathRegion(Vector const & pos_w);
|
||||||
|
static void pathAutoGenerate(Vector const & pos_w, float nodeDistance, float obstacleDistance, Unicode::String & result);
|
||||||
|
static void pathAutoCleanup(Vector const & pos_w, Unicode::String & result);
|
||||||
|
};
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
// ======================================================================
|
||||||
|
//
|
||||||
|
// ServerPathBuildManager.cpp
|
||||||
|
// copyright (c) 2001 Sony Online Entertainment
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include "serverPathfinding/FirstServerPathfinding.h"
|
||||||
|
#include "serverPathfinding/ServerPathBuildManager.h"
|
||||||
|
|
||||||
|
#include "serverPathfinding/ServerPathBuilder.h"
|
||||||
|
|
||||||
|
#include "sharedDebug/PerformanceTimer.h"
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
typedef std::list< ServerPathBuilder * > BuildQueue;
|
||||||
|
|
||||||
|
BuildQueue gs_lowQueue;
|
||||||
|
BuildQueue gs_highQueue;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ServerPathBuildManager::install ( void )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerPathBuildManager::remove ( void )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void updateQueue ( BuildQueue * queue, PerformanceTimer const & timer, float timeBudget )
|
||||||
|
{
|
||||||
|
BuildQueue::iterator it = queue->begin();
|
||||||
|
|
||||||
|
while(it != queue->end())
|
||||||
|
{
|
||||||
|
if(timer.getSplitTime() >= timeBudget) return;
|
||||||
|
|
||||||
|
ServerPathBuilder * currentBuilder = (*it);
|
||||||
|
|
||||||
|
currentBuilder->update();
|
||||||
|
|
||||||
|
BuildQueue::iterator old = it;
|
||||||
|
it++;
|
||||||
|
|
||||||
|
if(currentBuilder->buildDone())
|
||||||
|
{
|
||||||
|
currentBuilder->setQueued(false);
|
||||||
|
queue->erase(old);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
void ServerPathBuildManager::update ( float timeBudget )
|
||||||
|
{
|
||||||
|
PerformanceTimer timer;
|
||||||
|
|
||||||
|
timer.start();
|
||||||
|
|
||||||
|
updateQueue( &gs_highQueue, timer, timeBudget );
|
||||||
|
|
||||||
|
updateQueue( &gs_lowQueue, timer, timeBudget );
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool ServerPathBuildManager::queue ( ServerPathBuilder * builder, bool highPriority )
|
||||||
|
{
|
||||||
|
if(builder->getQueued()) return false;
|
||||||
|
|
||||||
|
if(highPriority)
|
||||||
|
{
|
||||||
|
gs_highQueue.push_back(builder);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gs_lowQueue.push_back(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
builder->setQueued(true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ServerPathBuildManager::unqueue ( ServerPathBuilder * builder )
|
||||||
|
{
|
||||||
|
if(!builder->getQueued()) return false;
|
||||||
|
|
||||||
|
BuildQueue::iterator it;
|
||||||
|
|
||||||
|
it = std::find(gs_highQueue.begin(),gs_highQueue.end(),builder);
|
||||||
|
|
||||||
|
if(it != gs_highQueue.end()) gs_highQueue.erase(it);
|
||||||
|
|
||||||
|
it = std::find(gs_lowQueue.begin(),gs_lowQueue.end(),builder);
|
||||||
|
|
||||||
|
if(it != gs_lowQueue.end()) gs_lowQueue.erase(it);
|
||||||
|
|
||||||
|
builder->setQueued(false);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
// ======================================================================
|
||||||
|
//
|
||||||
|
// ServerPathBuildManager.h
|
||||||
|
// Copyright 2001 Sony Online Entertainment Inc.
|
||||||
|
// All Rights Reserved.
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef INCLUDED_ServerPathBuildManager_H
|
||||||
|
#define INCLUDED_ServerPathBuildManager_H
|
||||||
|
|
||||||
|
class ServerPathBuilder;
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
class ServerPathBuildManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static void install ( void );
|
||||||
|
static void remove ( void );
|
||||||
|
|
||||||
|
static void update ( float timeBudget );
|
||||||
|
|
||||||
|
static bool queue ( ServerPathBuilder * builder, bool highPriority );
|
||||||
|
static bool unqueue ( ServerPathBuilder * builder );
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#endif // INCLUDED_ServerPathBuildManager_H
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,182 @@
|
|||||||
|
// ======================================================================
|
||||||
|
//
|
||||||
|
// ServerPathBuilder.h
|
||||||
|
// Copyright 2002 Sony Online Entertainment Inc.
|
||||||
|
// All Rights Reserved.
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef INCLUDED_ServerPathBuilder_H
|
||||||
|
#define INCLUDED_ServerPathBuilder_H
|
||||||
|
|
||||||
|
#include "serverGame/AiLocation.h"
|
||||||
|
#include "Unicode.h"
|
||||||
|
|
||||||
|
class CreatureObject;
|
||||||
|
class AiLocation;
|
||||||
|
class CellProperty;
|
||||||
|
class PortalProperty;
|
||||||
|
class CityPathGraph;
|
||||||
|
class PathGraph;
|
||||||
|
class PathSearch;
|
||||||
|
class PathNode;
|
||||||
|
class ServerObject;
|
||||||
|
|
||||||
|
typedef stdlist<AiLocation>::fwd AiPath;
|
||||||
|
typedef stdvector<int>::fwd IndexList;
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
int findClosestPathNode( CreatureObject const * creature, PathGraph const * graph );
|
||||||
|
int findClosestReachablePathNode( CreatureObject const * creature, PathGraph const * graph );
|
||||||
|
int findClosestReachablePathNode ( CellProperty const * cell, Vector const & start, float radius, PathGraph const * graph );
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
class ServerPathBuilder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
ServerPathBuilder();
|
||||||
|
virtual ~ServerPathBuilder();
|
||||||
|
|
||||||
|
bool buildPath ( CreatureObject const * creature, AiLocation const & goal );
|
||||||
|
bool buildPath ( CreatureObject const * creature, Unicode::String const & goalName );
|
||||||
|
bool buildWorldPath ( AiLocation const & startLocation, AiLocation const & goal );
|
||||||
|
bool buildPathImmediate ( AiLocation const & startLocation, AiLocation const & goalLocation );
|
||||||
|
|
||||||
|
bool buildPath_Async ( CreatureObject const * creature, AiLocation const & goal );
|
||||||
|
bool buildPath_Async ( CreatureObject const * creature, Unicode::String const & goalName );
|
||||||
|
|
||||||
|
void update ( void );
|
||||||
|
|
||||||
|
bool buildDone ( void ) const;
|
||||||
|
bool buildFailed ( void ) const;
|
||||||
|
|
||||||
|
AiPath * getPath ( void );
|
||||||
|
bool getPathIncomplete ( void ) const;
|
||||||
|
|
||||||
|
bool getQueued ( void ) const;
|
||||||
|
void setQueued ( bool queued );
|
||||||
|
|
||||||
|
void setEnableJitter ( bool enable );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool buildPath_ToGoal ( void );
|
||||||
|
bool buildPath_Named ( void );
|
||||||
|
|
||||||
|
bool setupBuildPath ( CreatureObject const * creature, AiLocation const & goal );
|
||||||
|
bool setupBuildPath ( CreatureObject const * creature, Unicode::String const & goalName );
|
||||||
|
|
||||||
|
bool buildPathInternal ( CellProperty const * cell, PathGraph const * graph, int indexA, int indexB );
|
||||||
|
bool buildPathInternal ( PortalProperty const * building, PathGraph const * graph, int indexA, int indexB );
|
||||||
|
|
||||||
|
bool buildPathInternal ( CityPathGraph const * cityGraph, int indexA, int indexB );
|
||||||
|
bool buildPathInternal ( CityPathGraph const * cityGraph, int indexA, IndexList const & indexBList );
|
||||||
|
|
||||||
|
bool expandPath ( CityPathGraph const * cityGraph, IndexList const & path );
|
||||||
|
|
||||||
|
bool buildPath_World ( void );
|
||||||
|
|
||||||
|
void addPathNode ( CellProperty const * cell, PathNode const * node );
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
CreatureObject const * m_creature;
|
||||||
|
|
||||||
|
CellProperty const * m_creatureCell;
|
||||||
|
PathGraph const * m_creatureCellGraph;
|
||||||
|
int m_creatureCellKey;
|
||||||
|
int m_creatureCellNodeIndex;
|
||||||
|
int m_creatureCellPart;
|
||||||
|
PortalProperty const * m_creatureBuilding;
|
||||||
|
PathGraph const * m_creatureBuildingGraph;
|
||||||
|
int m_creatureBuildingKey;
|
||||||
|
int m_creatureBuildingNodeIndex;
|
||||||
|
CityPathGraph const * m_creatureCityGraph;
|
||||||
|
int m_creatureCityNodeIndex;
|
||||||
|
Vector m_creaturePosition;
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
AiLocation m_goal;
|
||||||
|
Unicode::String m_goalName;
|
||||||
|
|
||||||
|
CellProperty const * m_goalCell;
|
||||||
|
PathGraph const * m_goalCellGraph;
|
||||||
|
int m_goalCellKey;
|
||||||
|
int m_goalCellNodeIndex;
|
||||||
|
int m_goalCellPart;
|
||||||
|
PortalProperty const * m_goalBuilding;
|
||||||
|
PathGraph const * m_goalBuildingGraph;
|
||||||
|
int m_goalBuildingKey;
|
||||||
|
int m_goalBuildingNodeIndex;
|
||||||
|
CityPathGraph const * m_goalCityGraph;
|
||||||
|
int m_goalCityNodeIndex;
|
||||||
|
|
||||||
|
AiPath * m_path;
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
bool m_async;
|
||||||
|
bool m_buildDone;
|
||||||
|
bool m_buildFailed;
|
||||||
|
bool m_pathIncomplete;
|
||||||
|
bool m_enableJitter;
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
PathSearch * m_cellSearch;
|
||||||
|
|
||||||
|
PathSearch * m_buildingSearch;
|
||||||
|
|
||||||
|
PathSearch * m_citySearch;
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
bool m_queued;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
inline bool ServerPathBuilder::getQueued ( void ) const
|
||||||
|
{
|
||||||
|
return m_queued;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void ServerPathBuilder::setQueued ( bool queued )
|
||||||
|
{
|
||||||
|
m_queued = queued;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
inline void ServerPathBuilder::setEnableJitter ( bool enable )
|
||||||
|
{
|
||||||
|
m_enableJitter = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
inline AiPath * ServerPathBuilder::getPath ( void )
|
||||||
|
{
|
||||||
|
return m_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
inline bool ServerPathBuilder::buildDone ( void ) const
|
||||||
|
{
|
||||||
|
return m_buildDone;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool ServerPathBuilder::buildFailed ( void ) const
|
||||||
|
{
|
||||||
|
return m_buildFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
// ======================================================================
|
||||||
|
//
|
||||||
|
// ServerPathfinding.cpp
|
||||||
|
// copyright (c) 2001 Sony Online Entertainment
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include "serverPathfinding/FirstServerPathfinding.h"
|
||||||
|
#include "serverPathfinding/ServerPathfinding.h"
|
||||||
|
|
||||||
|
#include "serverPathfinding/CityPathGraphManager.h"
|
||||||
|
#include "serverPathfinding/ServerPathBuildManager.h"
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
|
||||||
|
#include "sharedDebug/PerformanceTimer.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
void ServerPathfinding::update ( float timeBudget )
|
||||||
|
{
|
||||||
|
CityPathGraphManager::update(0.0f);
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
extern float pathfindingTime;
|
||||||
|
|
||||||
|
PerformanceTimer timer;
|
||||||
|
|
||||||
|
timer.start();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ServerPathBuildManager::update(timeBudget);
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
|
||||||
|
timer.stop();
|
||||||
|
|
||||||
|
pathfindingTime = timer.getElapsedTime();
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
// ======================================================================
|
||||||
|
//
|
||||||
|
// ServerPathfinding.h
|
||||||
|
// Copyright 2001 Sony Online Entertainment Inc.
|
||||||
|
// All Rights Reserved.
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef INCLUDED_ServerPathfinding_H
|
||||||
|
#define INCLUDED_ServerPathfinding_H
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
class ServerPathfinding
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static void update ( float timeBudget );
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
// ======================================================================
|
||||||
|
//
|
||||||
|
// ServerPathfindingConstants.cpp
|
||||||
|
// copyright (c) 2001 Sony Online Entertainment
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include "serverPathfinding/FirstServerPathfinding.h"
|
||||||
|
#include "serverPathfinding/ServerPathfindingConstants.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
const int CITY_REGION_TYPE = 20;
|
||||||
|
const int PATHFINDING_REGION_TYPE = 22;
|
||||||
|
|
||||||
|
std::string const SERVER_PATHFINDING_WAYPOINT_TEMPLATE("object/path_waypoint/path_waypoint.iff");
|
||||||
|
std::string const SERVER_PATHFINDING_WAYPOINT_TEMPLATE_BASE("object/path_waypoint/base/path_waypoint_base.iff");
|
||||||
|
std::string const SERVER_PATHFINDING_WAYPOINT_TEMPLATE_AUTO_SPAWN("object/path_waypoint/path_waypoint_auto_spawn.iff");
|
||||||
|
|
||||||
|
std::string const OBJVAR_PATHFINDING("pathfinding");
|
||||||
|
|
||||||
|
std::string const OBJVAR_PATHFINDING_WAYPOINT_CREATOR("pathfinding.waypoint.creator");
|
||||||
|
std::string const OBJVAR_PATHFINDING_WAYPOINT_EDGES("pathfinding.waypoint.edges");
|
||||||
|
std::string const OBJVAR_PATHFINDING_WAYPOINT_KEY("pathfinding.waypoint.key");
|
||||||
|
std::string const OBJVAR_PATHFINDING_WAYPOINT_NAME("pathfinding.waypoint.name");
|
||||||
|
std::string const OBJVAR_PATHFINDING_WAYPOINT_TYPE("pathfinding.waypoint.type");
|
||||||
|
|
||||||
|
std::string const OBJVAR_PATHFINDING_BUILDING_PROCESSED("pathfinding.building.processed");
|
||||||
|
std::string const OBJVAR_PATHFINDING_BUILDING_WAYPOINTS("pathfinding.building.waypoints");
|
||||||
|
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
// ======================================================================
|
||||||
|
//
|
||||||
|
// ServerPathfindingConstants.h
|
||||||
|
// Copyright 2001 Sony Online Entertainment Inc.
|
||||||
|
// All Rights Reserved.
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef INCLUDED_ServerPathfindingConstants_H
|
||||||
|
#define INCLUDED_ServerPathfindingConstants_H
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
extern int const CITY_REGION_TYPE;
|
||||||
|
extern int const PATHFINDING_REGION_TYPE;
|
||||||
|
|
||||||
|
extern std::string const SERVER_PATHFINDING_WAYPOINT_TEMPLATE;
|
||||||
|
extern std::string const SERVER_PATHFINDING_WAYPOINT_TEMPLATE_BASE;
|
||||||
|
extern std::string const SERVER_PATHFINDING_WAYPOINT_TEMPLATE_AUTO_SPAWN;
|
||||||
|
|
||||||
|
extern std::string const OBJVAR_PATHFINDING;
|
||||||
|
|
||||||
|
extern std::string const OBJVAR_PATHFINDING_WAYPOINT_CREATOR;
|
||||||
|
extern std::string const OBJVAR_PATHFINDING_WAYPOINT_EDGES;
|
||||||
|
extern std::string const OBJVAR_PATHFINDING_WAYPOINT_KEY;
|
||||||
|
extern std::string const OBJVAR_PATHFINDING_WAYPOINT_NAME;
|
||||||
|
extern std::string const OBJVAR_PATHFINDING_WAYPOINT_TYPE;
|
||||||
|
|
||||||
|
extern std::string const OBJVAR_PATHFINDING_BUILDING_PROCESSED;
|
||||||
|
extern std::string const OBJVAR_PATHFINDING_BUILDING_WAYPOINTS;
|
||||||
|
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,549 @@
|
|||||||
|
// ======================================================================
|
||||||
|
//
|
||||||
|
// ServerPathfindingMessaging.cpp
|
||||||
|
// copyright (c) 2001 Sony Online Entertainment
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include "serverPathfinding/FirstServerPathfinding.h"
|
||||||
|
#include "serverPathfinding/ServerPathfindingMessaging.h"
|
||||||
|
|
||||||
|
#include "serverGame/AiLocation.h"
|
||||||
|
#include "serverGame/CellObject.h"
|
||||||
|
#include "serverGame/Client.h"
|
||||||
|
#include "serverGame/ContainerInterface.h"
|
||||||
|
#include "serverGame/CreatureController.h"
|
||||||
|
#include "serverGame/CreatureObject.h"
|
||||||
|
#include "serverGame/GameServer.h"
|
||||||
|
#include "serverGame/PlayerCreatureController.h"
|
||||||
|
#include "serverGame/ServerObject.h"
|
||||||
|
#include "serverGame/ServerWorld.h"
|
||||||
|
#include "serverPathfinding/CityPathGraph.h"
|
||||||
|
#include "serverPathfinding/CityPathGraphManager.h"
|
||||||
|
#include "serverPathfinding/CityPathNode.h"
|
||||||
|
#include "serverScript/GameScriptObject.h"
|
||||||
|
#include "serverScript/ScriptFunctionTable.h"
|
||||||
|
#include "serverScript/ScriptParameters.h"
|
||||||
|
#include "sharedCollision/CollisionWorld.h"
|
||||||
|
#include "sharedFoundation/Crc.h"
|
||||||
|
#include "sharedGame/CommandTable.h"
|
||||||
|
#include "sharedNetworkMessages/AIDebuggingMessages.h"
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
ServerPathfindingMessaging * g_messaging = NULL;
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::install ( void )
|
||||||
|
{
|
||||||
|
g_messaging = new ServerPathfindingMessaging();
|
||||||
|
|
||||||
|
g_messaging->connectToMessage(RequestWatchObjectPath::MESSAGE_TYPE);
|
||||||
|
g_messaging->connectToMessage(RequestWatchPathMap::MESSAGE_TYPE);
|
||||||
|
g_messaging->connectToMessage(RequestUnstick::MESSAGE_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::remove ( void )
|
||||||
|
{
|
||||||
|
g_messaging->disconnectFromMessage(RequestWatchObjectPath::MESSAGE_TYPE);
|
||||||
|
g_messaging->disconnectFromMessage(RequestWatchPathMap::MESSAGE_TYPE);
|
||||||
|
g_messaging->disconnectFromMessage(RequestUnstick::MESSAGE_TYPE);
|
||||||
|
|
||||||
|
delete g_messaging;
|
||||||
|
g_messaging = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerPathfindingMessaging & ServerPathfindingMessaging::getInstance ( void )
|
||||||
|
{
|
||||||
|
return *g_messaging;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
ServerPathfindingMessaging::ServerPathfindingMessaging()
|
||||||
|
: m_clientList( new ClientList() ),
|
||||||
|
m_callback( new MessageDispatch::Callback )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerPathfindingMessaging::~ServerPathfindingMessaging()
|
||||||
|
{
|
||||||
|
for(ClientList::iterator it = m_clientList->begin(); it != m_clientList->end(); ++it)
|
||||||
|
{
|
||||||
|
ignorePathMap(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete m_clientList;
|
||||||
|
m_clientList = NULL;
|
||||||
|
|
||||||
|
delete m_callback;
|
||||||
|
m_callback = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::receiveMessage(const MessageDispatch::Emitter & source, const MessageDispatch::MessageBase & message)
|
||||||
|
{
|
||||||
|
UNREF(source);
|
||||||
|
|
||||||
|
if(message.isType(RequestWatchObjectPath::MESSAGE_TYPE))
|
||||||
|
{
|
||||||
|
const RequestWatchObjectPath &m = dynamic_cast<const RequestWatchObjectPath &>(message);
|
||||||
|
CachedNetworkId cid(m.getClientId());
|
||||||
|
ServerObject * s = static_cast<ServerObject *>(cid.getObject());
|
||||||
|
Client * client = s->getClient();
|
||||||
|
if (m.getEnable())
|
||||||
|
{
|
||||||
|
watchObjectPath(client, m.getObjectId());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ignoreObjectPath(client, m.getObjectId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(message.isType(RequestWatchPathMap::MESSAGE_TYPE))
|
||||||
|
{
|
||||||
|
const RequestWatchPathMap &m = dynamic_cast<const RequestWatchPathMap &>(message);
|
||||||
|
CachedNetworkId cid(m.getClientId());
|
||||||
|
ServerObject * s = static_cast<ServerObject *>(cid.getObject());
|
||||||
|
Client * client = s->getClient();
|
||||||
|
if (m.getEnable())
|
||||||
|
{
|
||||||
|
watchPathMap(client);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ignorePathMap(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(message.isType(RequestUnstick::MESSAGE_TYPE))
|
||||||
|
{
|
||||||
|
const RequestUnstick &m = dynamic_cast<const RequestUnstick &>(message);
|
||||||
|
CachedNetworkId cid(m.getClientId());
|
||||||
|
ServerObject * s = static_cast<ServerObject *>(cid.getObject());
|
||||||
|
NOT_NULL(s);
|
||||||
|
|
||||||
|
// Give the scripts a chance to handle the "unsticking"
|
||||||
|
GameScriptObject * const gso = s->getScriptObject();
|
||||||
|
if (gso)
|
||||||
|
{
|
||||||
|
ScriptParams scriptParams;
|
||||||
|
if (SCRIPT_OVERRIDE == gso->trigAllScripts(Scripting::TRIG_UNSTICKING, scriptParams))
|
||||||
|
{
|
||||||
|
//-- script has handled the unstick
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// unsticking a player character in Restuss always takes the character
|
||||||
|
// to the imperial cloning center if he is imperial, rebel cloning
|
||||||
|
// center if he is rebel, or starport if he is neutral
|
||||||
|
if (ServerWorld::getSceneId() == std::string("rori"))
|
||||||
|
{
|
||||||
|
CreatureObject * co = s->asCreatureObject();
|
||||||
|
if (co && PlayerCreatureController::getPlayerObject(co))
|
||||||
|
{
|
||||||
|
Vector const location = s->getPosition_w();
|
||||||
|
|
||||||
|
// restuss_nobuild_1 region
|
||||||
|
if ((location.x >= 4518.0f) && (location.x <= 6118.0f) && (location.z >= 4880.0f) && (location.z <= 6480.0f))
|
||||||
|
{
|
||||||
|
Vector unstickPoint;
|
||||||
|
|
||||||
|
if (PvpData::isImperialFactionId(co->getPvpFaction()))
|
||||||
|
{
|
||||||
|
// imperial installation
|
||||||
|
unstickPoint.x = 5878.0f;
|
||||||
|
unstickPoint.y = 81.0f;
|
||||||
|
unstickPoint.z = 5581.0f;
|
||||||
|
}
|
||||||
|
else if (PvpData::isRebelFactionId(co->getPvpFaction()))
|
||||||
|
{
|
||||||
|
// rebel installation
|
||||||
|
unstickPoint.x = 4863.0f;
|
||||||
|
unstickPoint.y = 77.0f;
|
||||||
|
unstickPoint.z = 5876.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// starport
|
||||||
|
unstickPoint.x = 5304.0f;
|
||||||
|
unstickPoint.y = 80.0f;
|
||||||
|
unstickPoint.z = 6185.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
CreatureController * controller = co->getCreatureController();
|
||||||
|
if (controller)
|
||||||
|
{
|
||||||
|
Transform newTransform = Transform::identity;
|
||||||
|
newTransform.setPosition_p(unstickPoint);
|
||||||
|
controller->teleport(newTransform, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector unstickPoint;
|
||||||
|
CellObject * cell = ContainerInterface::getContainingCellObject(*s);
|
||||||
|
if (cell != NULL && s->asCreatureObject() != NULL)
|
||||||
|
{
|
||||||
|
// try finding a waypoint in the cell first
|
||||||
|
if (!cell->getClosestPathNodePos(*s, unstickPoint))
|
||||||
|
{
|
||||||
|
// if there are no waypoints, use the /eject command
|
||||||
|
s->asCreatureObject()->commandQueueEnqueue(CommandTable::getCommand(
|
||||||
|
Crc::calculate("eject")), NetworkId::cms_invalid, Unicode::String());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// teleport the object to a close-by waypoint
|
||||||
|
if (!CityPathGraphManager::getClosestPathNodePos(s,unstickPoint))
|
||||||
|
{
|
||||||
|
// try using ServerWorld::getGoodLocation to find a spot
|
||||||
|
static const float SEARCH_SIZE = 32.0f;
|
||||||
|
const Vector center(s->getPosition_w());
|
||||||
|
const Vector llArea(center.x - SEARCH_SIZE, center.y, center.z - SEARCH_SIZE);
|
||||||
|
const Vector urArea(center.x + SEARCH_SIZE, center.y, center.z + SEARCH_SIZE);
|
||||||
|
unstickPoint = ServerWorld::getGoodLocation(5.0f, 5.0f, llArea, urArea, false, true);
|
||||||
|
|
||||||
|
// unstick failed - warp them to Mos Eisley starport
|
||||||
|
if(unstickPoint.x == 0 && unstickPoint.y == 0 && unstickPoint.z == 0)
|
||||||
|
{
|
||||||
|
// only warp them to mos eisley if they are on one of the 10 original planets
|
||||||
|
const std::string mySceneId = s->getSceneId();
|
||||||
|
if(mySceneId == "corellia"
|
||||||
|
|| mySceneId == "dantooine"
|
||||||
|
|| mySceneId == "dathomir"
|
||||||
|
|| mySceneId == "endor"
|
||||||
|
|| mySceneId == "lok"
|
||||||
|
|| mySceneId == "naboo"
|
||||||
|
|| mySceneId == "rori"
|
||||||
|
|| mySceneId == "talus"
|
||||||
|
|| mySceneId == "tatooine"
|
||||||
|
|| mySceneId == "yavin4"
|
||||||
|
)
|
||||||
|
{
|
||||||
|
GameServer::getInstance().requestSceneWarp(CachedNetworkId(*s),"tatooine",Vector(3528,5,-4804),NetworkId::cms_invalid,Vector(3528,5,-4804));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (unstickPoint.x != 0 || unstickPoint.y != 0 || unstickPoint.z != 0)
|
||||||
|
{
|
||||||
|
CreatureController * controller = dynamic_cast<CreatureController *>(s->getController());
|
||||||
|
if (controller)
|
||||||
|
{
|
||||||
|
Transform newTransform = Transform::identity;
|
||||||
|
newTransform.setPosition_p(unstickPoint);
|
||||||
|
controller->teleport(newTransform, cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::watchObjectPath(Client * client, const NetworkId &object)
|
||||||
|
{
|
||||||
|
UNREF(client);
|
||||||
|
UNREF(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::ignoreObjectPath(Client * client, const NetworkId &object)
|
||||||
|
{
|
||||||
|
UNREF(client);
|
||||||
|
UNREF(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::watchPathMap(Client * client)
|
||||||
|
{
|
||||||
|
if(client == NULL) return;
|
||||||
|
|
||||||
|
// Add the client to our client list
|
||||||
|
|
||||||
|
m_clientList->insert(client);
|
||||||
|
|
||||||
|
// and send it all the graphs we have
|
||||||
|
|
||||||
|
int count = CityPathGraphManager::getGraphCount();
|
||||||
|
|
||||||
|
for(int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
CityPathGraph const * graph = CityPathGraphManager::getGraph(i);
|
||||||
|
|
||||||
|
sendGraphInfo(graph,client);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_callback->connect(client->getDestroyNotifier(), *this, &ServerPathfindingMessaging::onClientDestroy);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::ignorePathMap(Client * client)
|
||||||
|
{
|
||||||
|
if(client == NULL) return;
|
||||||
|
|
||||||
|
m_clientList->erase(client);
|
||||||
|
|
||||||
|
int count = CityPathGraphManager::getGraphCount();
|
||||||
|
|
||||||
|
for(int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
CityPathGraph const * graph = CityPathGraphManager::getGraph(i);
|
||||||
|
|
||||||
|
sendEraseGraph(graph,client);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_callback->disconnect(client->getDestroyNotifier(), *this, &ServerPathfindingMessaging::onClientDestroy);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::onClientDestroy(ClientDestroy & d)
|
||||||
|
{
|
||||||
|
m_clientList->erase(d.client);
|
||||||
|
|
||||||
|
m_callback->disconnect(d.client->getDestroyNotifier(), *this, &ServerPathfindingMessaging::onClientDestroy);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::sendGraphInfo ( CityPathGraph const * graph )
|
||||||
|
{
|
||||||
|
if(graph == NULL) return;
|
||||||
|
|
||||||
|
for(ClientList::iterator it = m_clientList->begin(); it != m_clientList->end(); ++it)
|
||||||
|
{
|
||||||
|
sendGraphInfo( graph, (*it) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::sendGraphInfo ( CityPathGraph const * graph, Client * client )
|
||||||
|
{
|
||||||
|
if(client == NULL) return;
|
||||||
|
if(graph == NULL) return;
|
||||||
|
|
||||||
|
int nodeCount = graph->getNodeCount();
|
||||||
|
|
||||||
|
for(int i = 0; i < nodeCount; i++)
|
||||||
|
{
|
||||||
|
CityPathNode const * node = graph->_getNode(i);
|
||||||
|
|
||||||
|
if(node) sendNodeInfo(node,client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::sendEraseGraph ( CityPathGraph const * graph )
|
||||||
|
{
|
||||||
|
if(graph == NULL) return;
|
||||||
|
|
||||||
|
for(ClientList::iterator it = m_clientList->begin(); it != m_clientList->end(); ++it)
|
||||||
|
{
|
||||||
|
sendEraseGraph( graph, (*it) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::sendEraseGraph ( CityPathGraph const * graph, Client * client )
|
||||||
|
{
|
||||||
|
if(client == NULL) return;
|
||||||
|
if(graph == NULL) return;
|
||||||
|
|
||||||
|
int nodeCount = graph->getNodeCount();
|
||||||
|
|
||||||
|
for(int i = 0; i < nodeCount; i++)
|
||||||
|
{
|
||||||
|
CityPathNode const * node = graph->_getNode(i);
|
||||||
|
|
||||||
|
if(node) sendEraseNode(node,client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::sendNodeInfo ( CityPathNode const * node )
|
||||||
|
{
|
||||||
|
if(node == NULL) return;
|
||||||
|
|
||||||
|
for(ClientList::iterator it = m_clientList->begin(); it != m_clientList->end(); ++it)
|
||||||
|
{
|
||||||
|
sendNodeInfo( node, (*it) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::sendNodeInfo ( CityPathNode const * node, Client * client )
|
||||||
|
{
|
||||||
|
if(node == NULL) return;
|
||||||
|
if(client == NULL) return;
|
||||||
|
|
||||||
|
AINodeInfo m;
|
||||||
|
|
||||||
|
m.setNodeId(node->getDebugId());
|
||||||
|
m.setLocation(node->getPosition_p());
|
||||||
|
m.setLevel(0);
|
||||||
|
m.setParent(0);
|
||||||
|
|
||||||
|
std::vector<int> children;
|
||||||
|
m.setChildren(children);
|
||||||
|
|
||||||
|
std::vector<int> siblings;
|
||||||
|
|
||||||
|
int edgeCount = node->getEdgeCount();
|
||||||
|
|
||||||
|
for(int i = 0; i < edgeCount; i++)
|
||||||
|
{
|
||||||
|
int neighborIndex = node->getNeighbor(i);
|
||||||
|
|
||||||
|
CityPathNode const * neighbor = node->_getGraph()->_getNode(neighborIndex);
|
||||||
|
|
||||||
|
if(neighbor) siblings.push_back(neighbor->getDebugId());
|
||||||
|
}
|
||||||
|
|
||||||
|
m.setSiblings(siblings);
|
||||||
|
|
||||||
|
m.setType(0);
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
client->send(m, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::sendNeighborInfo ( CityPathNode const * node )
|
||||||
|
{
|
||||||
|
if(node == NULL) return;
|
||||||
|
|
||||||
|
for(ClientList::iterator it = m_clientList->begin(); it != m_clientList->end(); ++it)
|
||||||
|
{
|
||||||
|
sendNeighborInfo( node, (*it) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::sendNeighborInfo ( CityPathNode const * node, Client * client )
|
||||||
|
{
|
||||||
|
if(node == NULL) return;
|
||||||
|
if(client == NULL) return;
|
||||||
|
|
||||||
|
int edgeCount = node->getEdgeCount();
|
||||||
|
|
||||||
|
for(int i = 0; i < edgeCount; i++)
|
||||||
|
{
|
||||||
|
int neighborIndex = node->getNeighbor(i);
|
||||||
|
|
||||||
|
CityPathNode const * neighbor = node->_getGraph()->_getNode(neighborIndex);
|
||||||
|
|
||||||
|
if(neighbor) sendNodeInfo(neighbor,client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::sendEraseNode ( CityPathNode const * node )
|
||||||
|
{
|
||||||
|
if(node == NULL) return;
|
||||||
|
|
||||||
|
for(ClientList::iterator it = m_clientList->begin(); it != m_clientList->end(); ++it)
|
||||||
|
{
|
||||||
|
sendEraseNode( node, (*it) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::sendEraseNode ( CityPathNode const * node, Client * client )
|
||||||
|
{
|
||||||
|
if(node == NULL) return;
|
||||||
|
if(client == NULL) return;
|
||||||
|
|
||||||
|
AINodeInfo m;
|
||||||
|
|
||||||
|
m.setNodeId(node->getDebugId());
|
||||||
|
m.setLocation(Vector::zero);
|
||||||
|
m.setLevel(0);
|
||||||
|
m.setParent(0);
|
||||||
|
m.setType(-1);
|
||||||
|
|
||||||
|
client->send(m, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::sendWaypointInfo ( AiLocation const & loc )
|
||||||
|
{
|
||||||
|
for(ClientList::iterator it = m_clientList->begin(); it != m_clientList->end(); ++it)
|
||||||
|
{
|
||||||
|
sendWaypointInfo( loc, (*it) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::sendWaypointInfo ( AiLocation const & loc, Client * client )
|
||||||
|
{
|
||||||
|
if(client == NULL) return;
|
||||||
|
|
||||||
|
AINodeInfo m;
|
||||||
|
|
||||||
|
m.setNodeId(loc.getDebugId());
|
||||||
|
m.setLocation(loc.getPosition_w());
|
||||||
|
m.setLevel(0);
|
||||||
|
m.setParent(0);
|
||||||
|
|
||||||
|
std::vector<int> children;
|
||||||
|
m.setChildren(children);
|
||||||
|
|
||||||
|
std::vector<int> siblings;
|
||||||
|
m.setSiblings(siblings);
|
||||||
|
|
||||||
|
m.setType(1);
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
client->send(m, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::sendEraseWaypoint ( AiLocation const & loc )
|
||||||
|
{
|
||||||
|
for(ClientList::iterator it = m_clientList->begin(); it != m_clientList->end(); ++it)
|
||||||
|
{
|
||||||
|
sendEraseWaypoint( loc, (*it) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerPathfindingMessaging::sendEraseWaypoint ( AiLocation const & loc, Client * client )
|
||||||
|
{
|
||||||
|
if(client == NULL) return;
|
||||||
|
|
||||||
|
AINodeInfo m;
|
||||||
|
|
||||||
|
m.setNodeId(loc.getDebugId());
|
||||||
|
m.setLocation(Vector::zero);
|
||||||
|
m.setLevel(0);
|
||||||
|
m.setParent(0);
|
||||||
|
m.setType(-1);
|
||||||
|
|
||||||
|
client->send(m, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
// ======================================================================
|
||||||
|
//
|
||||||
|
// ServerPathfindingMessaging.h
|
||||||
|
// Copyright 2001 Sony Online Entertainment Inc.
|
||||||
|
// All Rights Reserved.
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef INCLUDED_ServerPathfindingMessaging_H
|
||||||
|
#define INCLUDED_ServerPathfindingMessaging_H
|
||||||
|
|
||||||
|
#include "sharedMessageDispatch/Receiver.h"
|
||||||
|
#include "sharedMessageDispatch/Transceiver.h"
|
||||||
|
|
||||||
|
class CityPathGraph;
|
||||||
|
class CityPathNode;
|
||||||
|
class Client;
|
||||||
|
class NetworkId;
|
||||||
|
struct ClientDestroy;
|
||||||
|
class AiLocation;
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
class ServerPathfindingMessaging : public MessageDispatch::Receiver
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static void install ( void );
|
||||||
|
static void remove ( void );
|
||||||
|
|
||||||
|
static ServerPathfindingMessaging & getInstance ( void );
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
ServerPathfindingMessaging();
|
||||||
|
virtual ~ServerPathfindingMessaging();
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
void sendGraphInfo ( CityPathGraph const * graph );
|
||||||
|
void sendEraseGraph ( CityPathGraph const * graph );
|
||||||
|
void sendNodeInfo ( CityPathNode const * node );
|
||||||
|
void sendNeighborInfo ( CityPathNode const * node );
|
||||||
|
void sendEraseNode ( CityPathNode const * node );
|
||||||
|
void sendWaypointInfo ( AiLocation const & loc );
|
||||||
|
void sendEraseWaypoint( AiLocation const & loc );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void sendGraphInfo ( CityPathGraph const * graph, Client * client );
|
||||||
|
void sendEraseGraph ( CityPathGraph const * graph, Client * client );
|
||||||
|
void sendNodeInfo ( CityPathNode const * node, Client * client );
|
||||||
|
void sendNeighborInfo ( CityPathNode const * node, Client * client );
|
||||||
|
void sendEraseNode ( CityPathNode const * node, Client * client );
|
||||||
|
void sendWaypointInfo ( AiLocation const & loc, Client * client );
|
||||||
|
void sendEraseWaypoint( AiLocation const & loc, Client * client );
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
void receiveMessage ( MessageDispatch::Emitter const & source, MessageDispatch::MessageBase const & message );
|
||||||
|
|
||||||
|
void watchObjectPath ( Client * client, NetworkId const & object );
|
||||||
|
void ignoreObjectPath ( Client * client, NetworkId const & object );
|
||||||
|
|
||||||
|
void watchPathMap ( Client * client );
|
||||||
|
void ignorePathMap ( Client * client );
|
||||||
|
|
||||||
|
void onClientDestroy ( ClientDestroy & d );
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
typedef stdset<Client*>::fwd ClientList;
|
||||||
|
|
||||||
|
ClientList * m_clientList;
|
||||||
|
|
||||||
|
MessageDispatch::Callback * m_callback;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
// ======================================================================
|
||||||
|
//
|
||||||
|
// ServerPathfindingNotification.cpp
|
||||||
|
// copyright (c) 2001 Sony Online Entertainment
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include "serverPathfinding/FirstServerPathfinding.h"
|
||||||
|
#include "serverPathfinding/ServerPathfindingNotification.h"
|
||||||
|
|
||||||
|
#include "serverGame/ServerObject.h"
|
||||||
|
#include "serverGame/BuildingObject.h"
|
||||||
|
|
||||||
|
#include "serverPathfinding/CityPathGraphManager.h"
|
||||||
|
#include "serverPathfinding/ServerPathfindingConstants.h"
|
||||||
|
|
||||||
|
#include "sharedObject/Object.h"
|
||||||
|
|
||||||
|
namespace ServerPathfindingNotificationNamespace
|
||||||
|
{
|
||||||
|
ServerPathfindingNotification g_notification;
|
||||||
|
};
|
||||||
|
|
||||||
|
using namespace ServerPathfindingNotificationNamespace;
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
// CityPathGraphManager notification
|
||||||
|
|
||||||
|
ServerPathfindingNotification::ServerPathfindingNotification()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerPathfindingNotification::~ServerPathfindingNotification()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ServerPathfindingNotification::addToWorld ( Object & object ) const
|
||||||
|
{
|
||||||
|
BuildingObject * building = dynamic_cast<BuildingObject*>(&object);
|
||||||
|
|
||||||
|
if(building)
|
||||||
|
{
|
||||||
|
CityPathGraphManager::addBuilding( building );
|
||||||
|
}
|
||||||
|
else if(object.asServerObject() != NULL && object.asServerObject()->isWaypoint())
|
||||||
|
{
|
||||||
|
CityPathGraphManager::addWaypoint( object.asServerObject() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerPathfindingNotification::removeFromWorld ( Object & object ) const
|
||||||
|
{
|
||||||
|
BuildingObject * building = dynamic_cast<BuildingObject*>(&object);
|
||||||
|
|
||||||
|
if(building)
|
||||||
|
{
|
||||||
|
CityPathGraphManager::removeBuilding( building );
|
||||||
|
}
|
||||||
|
else if(object.asServerObject() != NULL && object.asServerObject()->isWaypoint())
|
||||||
|
{
|
||||||
|
CityPathGraphManager::removeWaypoint( object.asServerObject() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CityPathGraphManager::destroyPathGraph(object.asServerObject());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ServerPathfindingNotification::positionChanged ( Object & object, bool /*dueToParentChange*/, Vector const & oldPosition) const
|
||||||
|
{
|
||||||
|
BuildingObject * building = dynamic_cast<BuildingObject*>(&object);
|
||||||
|
|
||||||
|
if(building)
|
||||||
|
{
|
||||||
|
CityPathGraphManager::moveBuilding( building, oldPosition );
|
||||||
|
}
|
||||||
|
else if(object.asServerObject() != NULL && object.asServerObject()->isWaypoint())
|
||||||
|
{
|
||||||
|
CityPathGraphManager::moveWaypoint( object.asServerObject(), oldPosition );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ServerPathfindingNotification::positionAndRotationChanged ( Object & object, bool /*dueToParentChange*/, Vector const & oldPosition ) const
|
||||||
|
{
|
||||||
|
BuildingObject * building = dynamic_cast<BuildingObject*>(&object);
|
||||||
|
|
||||||
|
if(building)
|
||||||
|
{
|
||||||
|
CityPathGraphManager::moveBuilding( building, oldPosition );
|
||||||
|
}
|
||||||
|
else if(object.asServerObject() != NULL && object.asServerObject()->isWaypoint())
|
||||||
|
{
|
||||||
|
CityPathGraphManager::moveWaypoint( object.asServerObject(), oldPosition );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ServerPathfindingNotification::destroyBuilding ( BuildingObject * building )
|
||||||
|
{
|
||||||
|
CityPathGraphManager::destroyBuilding(building);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ServerPathfindingNotification::destroyWaypoint ( ServerObject * building )
|
||||||
|
{
|
||||||
|
CityPathGraphManager::destroyWaypoint(building);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
ServerPathfindingNotification & ServerPathfindingNotification::getInstance ( void )
|
||||||
|
{
|
||||||
|
return g_notification;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
// ======================================================================
|
||||||
|
//
|
||||||
|
// ServerPathfindingNotification.h
|
||||||
|
// Copyright 2001 Sony Online Entertainment Inc.
|
||||||
|
// All Rights Reserved.
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef INCLUDED_ServerPathfindingNotification_H
|
||||||
|
#define INCLUDED_ServerPathfindingNotification_H
|
||||||
|
|
||||||
|
#include "sharedObject/ObjectNotification.h"
|
||||||
|
|
||||||
|
class Object;
|
||||||
|
class Vector;
|
||||||
|
class BuildingObject;
|
||||||
|
class ServerObject;
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
class ServerPathfindingNotification : public ObjectNotification
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
ServerPathfindingNotification();
|
||||||
|
virtual ~ServerPathfindingNotification();
|
||||||
|
|
||||||
|
virtual void addToWorld ( Object & object ) const;
|
||||||
|
virtual void removeFromWorld ( Object & object ) const;
|
||||||
|
|
||||||
|
virtual bool positionChanged ( Object & object, bool dueToParentChange, Vector const & oldPosition) const;
|
||||||
|
virtual bool positionAndRotationChanged ( Object & object, bool dueToParentChange, Vector const & oldPosition ) const;
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
|
||||||
|
static void destroyBuilding ( BuildingObject * building );
|
||||||
|
static void destroyWaypoint ( ServerObject * waypoint );
|
||||||
|
|
||||||
|
static ServerPathfindingNotification & getInstance ( void );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ServerPathfindingNotification(const ServerPathfindingNotification &);
|
||||||
|
ServerPathfindingNotification &operator =(const ServerPathfindingNotification &);
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
// ======================================================================
|
||||||
|
//
|
||||||
|
// SetupServerPathfinding.cpp
|
||||||
|
// copyright (c) 2001 Sony Online Entertainment
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include "serverPathfinding/FirstServerPathfinding.h"
|
||||||
|
#include "serverPathfinding/SetupServerPathfinding.h"
|
||||||
|
|
||||||
|
#include "serverPathfinding/CityPathGraphManager.h"
|
||||||
|
#include "serverPathfinding/ServerPathfindingMessaging.h"
|
||||||
|
|
||||||
|
#include "sharedFoundation/ExitChain.h"
|
||||||
|
|
||||||
|
#include "sharedPathfinding/SetupSharedPathfinding.h"
|
||||||
|
|
||||||
|
void SetupServerPathfinding::install ( void )
|
||||||
|
{
|
||||||
|
SetupSharedPathfinding::install();
|
||||||
|
|
||||||
|
ServerPathfindingMessaging::install();
|
||||||
|
|
||||||
|
CityPathGraphManager::install();
|
||||||
|
|
||||||
|
ExitChain::add( SetupServerPathfinding::remove, "SetupServerPathfinding" );
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupServerPathfinding::remove ( void )
|
||||||
|
{
|
||||||
|
CityPathGraphManager::remove();
|
||||||
|
|
||||||
|
ServerPathfindingMessaging::remove();
|
||||||
|
|
||||||
|
SetupSharedPathfinding::remove();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
// ======================================================================
|
||||||
|
//
|
||||||
|
// SetupServerPathfinding.h
|
||||||
|
// Copyright 2001 Sony Online Entertainment Inc.
|
||||||
|
// All Rights Reserved.
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#ifndef INCLUDED_SetupServerPathfinding_H
|
||||||
|
#define INCLUDED_SetupServerPathfinding_H
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
class SetupServerPathfinding
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static void install ( void );
|
||||||
|
static void remove ( void );
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// ======================================================================
|
||||||
|
//
|
||||||
|
// FirstServerPathfinding.cpp
|
||||||
|
// copyright (c) 2001 Sony Online Entertainment
|
||||||
|
//
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
#include "serverPathfinding/FirstServerPathfinding.h"
|
||||||
@@ -126,6 +126,7 @@ include_directories(
|
|||||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedUtility/include/public
|
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedUtility/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/server/library/serverGame/include/public
|
${SWG_ENGINE_SOURCE_DIR}/server/library/serverGame/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/server/library/serverNetworkMessages/include/public
|
${SWG_ENGINE_SOURCE_DIR}/server/library/serverNetworkMessages/include/public
|
||||||
|
${SWG_ENGINE_SOURCE_DIR}/server/library/serverPathfinding/include/public
|
||||||
${SWG_ENGINE_SOURCE_DIR}/server/library/serverUtility/include/public
|
${SWG_ENGINE_SOURCE_DIR}/server/library/serverUtility/include/public
|
||||||
${SWG_GAME_SOURCE_DIR}/shared/library/swgSharedUtility/include/public
|
${SWG_GAME_SOURCE_DIR}/shared/library/swgSharedUtility/include/public
|
||||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/archive/include
|
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/archive/include
|
||||||
|
|||||||
@@ -31,7 +31,8 @@
|
|||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
// grab stlport configuration
|
// grab stlport configuration
|
||||||
#include "stl/config/features.h"
|
//#include "stl/config/features.h" // uncomment for newer stlport versions
|
||||||
|
#include "stl/_config.h"
|
||||||
|
|
||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user