@ -41,19 +41,29 @@ All rights reserved.
INCLUDE_game
const vi2d Pathfinding : : gridSpacing = vf2d { 12 , 12 } ;
void Pathfinding : : Initialize ( ) {
nodes . clear ( ) ;
sNode * lastNodeAdded = nullptr ;
for ( int x = 0 ; x < game - > GetCurrentMapData ( ) . width ; x + = gridSpacing . x )
for ( int y = 0 ; y < game - > GetCurrentMapData ( ) . height ; y + = gridSpacing . y )
for ( int x = 0 ; x < game - > GetCurrentMapData ( ) . width * 24 ; x + = gridSpacing . x )
for ( int y = 0 ; y < game - > GetCurrentMapData ( ) . height * 24 ; y + = gridSpacing . y )
{
sNode & node = nodes [ { x , y } ] ;
node . x = x ; // ...because we give each node its own coordinates
node . y = y ; // ...because we give each node its own coordinates
geom2d : : rect < float > tile = game - > GetTileCollision ( game - > GetCurrentLevel ( ) , { float ( x * gridSpacing . x ) , float ( y * gridSpacing . y ) } ) ;
node . bObstacle = tile . pos ! = game - > NO_COLLISION . pos | | tile . size ! = game - > NO_COLLISION . size ;
tile = game - > GetTileCollision ( game - > GetCurrentLevel ( ) , { float ( x * gridSpacing . x ) , float ( y * gridSpacing . y ) } , true ) ;
node . bObstacleUpper = tile . pos ! = game - > NO_COLLISION . pos | | tile . size ! = game - > NO_COLLISION . size ;
geom2d : : rect < float > tile = game - > GetTileCollision ( game - > GetCurrentLevel ( ) , { float ( x ) , float ( y ) } ) ;
if ( tile . pos = = game - > NO_COLLISION . pos & & tile . size = = game - > NO_COLLISION . size ) {
node . bObstacle = false ;
} else {
node . bObstacle = geom2d : : overlaps ( vf2d { fmodf ( x + gridSpacing . x / 2 , 24 ) , fmodf ( y + gridSpacing . y / 2 , 24 ) } , tile ) ;
}
tile = game - > GetTileCollision ( game - > GetCurrentLevel ( ) , { float ( x ) , float ( y ) } , true ) ;
if ( tile . pos = = game - > NO_COLLISION . pos & & tile . size = = game - > NO_COLLISION . size ) {
node . bObstacleUpper = false ;
} else {
node . bObstacleUpper = geom2d : : overlaps ( vf2d { fmodf ( x , 24 ) , fmodf ( y , 24 ) } , tile ) ;
}
node . parent = nullptr ;
node . bVisited = false ;
if ( nodes . size ( ) = = 1 ) { //This is the first node added, set as the start node.
@ -63,24 +73,28 @@ void Pathfinding::Initialize(){
}
for ( auto & [ key , node ] : nodes ) {
if ( nodes . find ( { node . x , node . y - 1 } ) ! = nodes . end ( ) ) {
node . vecNeighbours . push_back ( & node ) ;
if ( nodes . find ( { node . x , node . y - gridSpacing . y } ) ! = nodes . end ( ) ) {
node . vecNeighbours . push_back ( & nodes [ { node . x , node . y - gridSpacing . y } ] ) ;
}
if ( nodes . find ( { node . x , node . y + 1 } ) ! = nodes . end ( ) ) {
node . vecNeighbours . push_back ( & node ) ;
if ( nodes . find ( { node . x , node . y + gridSpacing . y } ) ! = nodes . end ( ) ) {
node . vecNeighbours . push_back ( & nodes [ { node . x , node . y + gridSpacing . y } ] ) ;
}
if ( nodes . find ( { node . x - 1 , node . y } ) ! = nodes . end ( ) ) {
node . vecNeighbours . push_back ( & node ) ;
if ( nodes . find ( { node . x - gridSpacing . x , node . y } ) ! = nodes . end ( ) ) {
node . vecNeighbours . push_back ( & nodes [ { node . x - gridSpacing . x , node . y } ] ) ;
}
if ( nodes . find ( { node . x + 1 , node . y } ) ! = nodes . end ( ) ) {
node . vecNeighbours . push_back ( & node ) ;
if ( nodes . find ( { node . x + gridSpacing . x , node . y } ) ! = nodes . end ( ) ) {
node . vecNeighbours . push_back ( & nodes [ { node . x + gridSpacing . x , node . y } ] ) ;
}
}
}
std : : vector < vf2d > Pathfinding : : Solve_AStar ( vf2d startPos , vf2d endPos , float maxRange , bool upperLevel ) {
float dist = float ( sqrt ( pow ( endPos . x - startPos . x , 2 ) + pow ( endPos . y - startPos . y , 2 ) ) ) ;
if ( dist > maxRange * game - > GetCurrentMapData ( ) . tilewidth ) return { } ;
if ( dist > maxRange * game - > GetCurrentMapData ( ) . tilewidth ) return { } ;
startPos = vi2d ( startPos / gridSpacing . x ) * gridSpacing . x ;
endPos = vi2d ( endPos / gridSpacing . x ) * gridSpacing . x ;
if ( nodes . find ( startPos ) = = nodes . end ( ) ) return { } ;
if ( nodes . find ( endPos ) = = nodes . end ( ) ) return { } ;
@ -133,7 +147,7 @@ std::vector<vf2d> Pathfinding::Solve_AStar(vf2d startPos,vf2d endPos,float maxRa
nodeCurrent - > bVisited = true ;
for ( auto nodeNeighbour : nodeCurrent - > vecNeighbours )
{
if ( ! nodeNeighbour - > bVisited & & ( ( ! upperLevel & & nodeNeighbour - > bObstacle = = 0 ) | | ( upperLevel & & nodeNeighbour - > bObstacleUpper = = 0 ) ) )
if ( ! nodeNeighbour - > bVisited & & ( ( ! upperLevel & & ! nodeNeighbour - > bObstacle ) | | ( upperLevel & & ! nodeNeighbour - > bObstacleUpper ) ) )
listNotTestedNodes . push_back ( nodeNeighbour ) ;
float fPossiblyLowerGoal = nodeCurrent - > fLocalGoal + distance ( nodeCurrent , nodeNeighbour ) ;
@ -178,7 +192,7 @@ Pathfinding::sSpline Pathfinding::Solve_WalkPath(vf2d startPos,vf2d endPos,float
void Pathfinding : : sSpline : : Initialize ( const std : : vector < vf2d > & points ) {
this - > points . clear ( ) ;
for ( const vf2d & point : points ) {
this - > points . push_back ( { point } ) ;
this - > points . push_back ( { vf2d { point } + gridSpacing / 2 } ) ;
}
fTotalSplineLength = 0.f ;
for ( int i = 0 ; i < this - > points . size ( ) ; i + + )