mirror of
https://github.com/SWG-Source/src.git
synced 2026-07-28 22:15:49 -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(ZLib REQUIRED)
|
||||
|
||||
#include_directories(${STLPORT_INCLUDE_DIR})
|
||||
include_directories(${STLPORT_INCLUDE_DIR})
|
||||
|
||||
add_subdirectory(external)
|
||||
add_subdirectory(engine)
|
||||
|
||||
@@ -3,5 +3,6 @@ add_subdirectory(serverGame)
|
||||
add_subdirectory(serverKeyShare)
|
||||
add_subdirectory(serverMetrics)
|
||||
add_subdirectory(serverNetworkMessages)
|
||||
add_subdirectory(serverPathfinding)
|
||||
add_subdirectory(serverScript)
|
||||
add_subdirectory(serverUtility)
|
||||
|
||||
@@ -714,32 +714,41 @@ endif()
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shared
|
||||
${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/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/sharedFractal/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/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/sharedNetwork/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/serverMetrics/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_GAME_SOURCE_DIR}/shared/library/swgSharedUtility/include/public
|
||||
${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/localizationArchive/include/public
|
||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/singleton/include
|
||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicode/include
|
||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicodeArchive/include/public
|
||||
${Boost_INCLUDE_DIR}
|
||||
${JNI_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
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}/server/library/serverGame/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_GAME_SOURCE_DIR}/shared/library/swgSharedUtility/include/public
|
||||
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/archive/include
|
||||
|
||||
@@ -31,7 +31,8 @@
|
||||
// ======================================================================
|
||||
|
||||
// grab stlport configuration
|
||||
#include "stl/config/features.h"
|
||||
//#include "stl/config/features.h" // uncomment for newer stlport versions
|
||||
#include "stl/_config.h"
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user