bool CCPathFinderNetwork::findPath(CCCollideable *objectToPath, Path &pathResult, const PathNode *fromNode, const PathNode *toNode) { if( fromNode != NULL && toNode != NULL ) { NodesList<const PathNode, 50> previousNodes; previousNodes.add( fromNode ); pathTargetNode = toNode; path.distance = 0.0f; pathingFrom = fromNode; if( followPath( objectToPath, path, 0, 0.0f, previousNodes, fromNode, toNode ) ) { pathResult = path; return true; } } return false; }
bool CCPathFinderNetwork::followPath(CCCollideable *objectToPath, Path &path, const int currentDirection, const float currentDistance, NodesList<const PathNode, 50> &previousNodes, const PathNode *fromNode, const PathNode *toNode) { // Node found if( fromNode == toNode ) { path.endDirection = currentDirection; path.distance = currentDistance; return true; } const int nextDirection = currentDirection+1; if( nextDirection >= 50 ) { // Give up return false; } pathFromNode = fromNode; const CCList<PathNode::PathConnection> &connections = fromNode->connections; int *values = new int[connections.length]; for( int i=0; i<connections.length; ++i ) { values[i] = i; } qsort( values, connections.length, sizeof( int ), compare ); for( int i=0; i<connections.length; ++i ) { const PathNode::PathConnection *nextConnection = connections.list[values[i]]; const PathNode *targetNode = nextConnection->node; // Previously followed? if( previousNodes.find( targetNode ) != -1 ) { continue; } CCCollideable *collidedWith = CCOctreeMovementCollisionCheck( objectToPath, fromNode->point, targetNode->point ); if( collidedWith != NULL ) { continue; } const float pathDistance = currentDistance + nextConnection->distance; if( previousNodes.add( targetNode ) == false ) { delete[] values; return false; } if( followPath( objectToPath, path, nextDirection, pathDistance, previousNodes, targetNode, toNode ) ) { path.directions[currentDirection] = values[i]; delete[] values; return true; } } delete[] values; return false; }