Added serverPathfinding library

This commit is contained in:
Anonymous
2014-01-15 09:54:09 -07:00
parent 7d149b2784
commit cd99b53a31
43 changed files with 5888 additions and 2 deletions
@@ -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"