2007-08-08 22:28:56 +03:00
# include "stdafx.h"
2007-08-07 16:49:15 +03:00
# include "global.h"
# include "CPathfinder.h"
2007-08-17 20:42:21 +03:00
# include "CGameInfo.h"
2007-08-30 13:11:53 +03:00
# include "hch\CAmbarCendamo.h"
2007-08-29 15:18:31 +03:00
# include "mapHandler.h"
2007-09-30 19:16:00 +03:00
int3 CPath : : endPos ( )
2007-09-22 04:16:31 +03:00
{
return int3 ( nodes [ 0 ] . coord . x , nodes [ 0 ] . coord . y , nodes [ 0 ] . coord . z ) ;
}
2007-09-30 19:16:00 +03:00
int3 CPath : : startPos ( )
2007-09-22 04:16:31 +03:00
{
return int3 ( nodes [ nodes . size ( ) - 1 ] . coord . x , nodes [ nodes . size ( ) - 1 ] . coord . y , nodes [ nodes . size ( ) - 1 ] . coord . z ) ;
}
CPath * CPathfinder : : getPath ( const int3 & src , const int3 & dest , const CHeroInstance * hero ) //TODO: test it (seems to be finished, but relies on unwritten functions :()
2007-08-07 16:49:15 +03:00
{
if ( src . z ! = dest . z ) //first check
return NULL ;
//graph initialization
graph . resize ( CGI - > ac - > map . width ) ;
for ( int i = 0 ; i < graph . size ( ) ; + + i )
{
graph [ i ] . resize ( CGI - > ac - > map . height ) ;
for ( int j = 0 ; j < graph [ i ] . size ( ) ; + + j )
{
2007-08-12 20:48:05 +03:00
graph [ i ] [ j ] = new CPathNode ;
graph [ i ] [ j ] - > accesible = ! CGI - > mh - > ttiles [ i ] [ j ] [ src . z ] . blocked ;
2007-09-18 20:01:47 +03:00
if ( i = = dest . x & & j = = dest . y & & CGI - > mh - > ttiles [ i ] [ j ] [ src . z ] . visitable )
graph [ i ] [ j ] - > accesible = true ; //for allowing visiting objects
2007-08-12 20:48:05 +03:00
graph [ i ] [ j ] - > dist = - 1 ;
graph [ i ] [ j ] - > theNodeBefore = NULL ;
graph [ i ] [ j ] - > visited = false ;
2007-09-22 04:16:31 +03:00
graph [ i ] [ j ] - > coord . x = i ;
graph [ i ] [ j ] - > coord . y = j ;
graph [ i ] [ j ] - > coord . z = dest . z ;
2007-08-07 16:49:15 +03:00
}
}
2007-08-12 20:48:05 +03:00
//graph initialized
graph [ src . x ] [ src . y ] - > dist = 0 ;
std : : queue < CPathNode * > mq ;
mq . push ( graph [ src . x ] [ src . y ] ) ;
2007-08-17 20:42:21 +03:00
unsigned int curDist = 4000000000 ;
2007-08-12 20:48:05 +03:00
while ( ! mq . empty ( ) )
2007-08-07 16:49:15 +03:00
{
2007-08-12 20:48:05 +03:00
CPathNode * cp = mq . front ( ) ;
mq . pop ( ) ;
2007-09-22 04:16:31 +03:00
if ( ( cp - > coord . x = = dest . x ) & & ( cp - > coord . y = = dest . y ) )
2007-08-17 20:42:21 +03:00
{
if ( cp - > dist < curDist )
curDist = cp - > dist ;
}
else
{
if ( cp - > dist > curDist )
continue ;
}
2007-09-22 04:16:31 +03:00
if ( cp - > coord . x > 0 )
2007-08-12 20:48:05 +03:00
{
2007-09-22 04:16:31 +03:00
CPathNode * dp = graph [ cp - > coord . x - 1 ] [ cp - > coord . y ] ;
if ( ( dp - > dist = = - 1 | | ( dp - > dist > cp - > dist + CGI - > mh - > getCost ( int3 ( cp - > coord . x , cp - > coord . y , src . z ) , int3 ( cp - > coord . x - 1 , cp - > coord . y , src . z ) , hero ) ) ) & & dp - > accesible )
2007-08-12 20:48:05 +03:00
{
2007-09-22 04:16:31 +03:00
dp - > dist = cp - > dist + CGI - > mh - > getCost ( int3 ( cp - > coord . x , cp - > coord . y , src . z ) , int3 ( cp - > coord . x - 1 , cp - > coord . y , src . z ) , hero ) ;
2007-08-17 20:42:21 +03:00
dp - > theNodeBefore = cp ;
mq . push ( dp ) ;
2007-08-12 20:48:05 +03:00
}
}
2007-09-22 04:16:31 +03:00
if ( cp - > coord . y > 0 )
2007-08-12 20:48:05 +03:00
{
2007-09-22 04:16:31 +03:00
CPathNode * dp = graph [ cp - > coord . x ] [ cp - > coord . y - 1 ] ;
if ( ( dp - > dist = = - 1 | | ( dp - > dist > cp - > dist + CGI - > mh - > getCost ( int3 ( cp - > coord . x , cp - > coord . y , src . z ) , int3 ( cp - > coord . x , cp - > coord . y - 1 , src . z ) , hero ) ) ) & & dp - > accesible )
2007-08-12 20:48:05 +03:00
{
2007-09-22 04:16:31 +03:00
dp - > dist = cp - > dist + CGI - > mh - > getCost ( int3 ( cp - > coord . x , cp - > coord . y , src . z ) , int3 ( cp - > coord . x - 1 , cp - > coord . y , src . z ) , hero ) ;
2007-08-17 20:42:21 +03:00
dp - > theNodeBefore = cp ;
mq . push ( dp ) ;
2007-08-12 20:48:05 +03:00
}
}
2007-09-22 04:16:31 +03:00
if ( cp - > coord . x > 0 & & cp - > coord . y > 0 )
2007-08-12 20:48:05 +03:00
{
2007-09-22 04:16:31 +03:00
CPathNode * dp = graph [ cp - > coord . x - 1 ] [ cp - > coord . y - 1 ] ;
if ( ( dp - > dist = = - 1 | | ( dp - > dist > cp - > dist + CGI - > mh - > getCost ( int3 ( cp - > coord . x , cp - > coord . y , src . z ) , int3 ( cp - > coord . x - 1 , cp - > coord . y - 1 , src . z ) , hero ) ) ) & & dp - > accesible )
2007-08-12 20:48:05 +03:00
{
2007-09-22 04:16:31 +03:00
dp - > dist = cp - > dist + CGI - > mh - > getCost ( int3 ( cp - > coord . x , cp - > coord . y , src . z ) , int3 ( cp - > coord . x - 1 , cp - > coord . y - 1 , src . z ) , hero ) ;
2007-08-17 20:42:21 +03:00
dp - > theNodeBefore = cp ;
mq . push ( dp ) ;
2007-08-12 20:48:05 +03:00
}
}
2007-09-22 04:16:31 +03:00
if ( cp - > coord . x < graph . size ( ) - 1 )
2007-08-12 20:48:05 +03:00
{
2007-09-22 04:16:31 +03:00
CPathNode * dp = graph [ cp - > coord . x + 1 ] [ cp - > coord . y ] ;
if ( ( dp - > dist = = - 1 | | ( dp - > dist > cp - > dist + CGI - > mh - > getCost ( int3 ( cp - > coord . x , cp - > coord . y , src . z ) , int3 ( cp - > coord . x + 1 , cp - > coord . y , src . z ) , hero ) ) ) & & dp - > accesible )
2007-08-12 20:48:05 +03:00
{
2007-09-22 04:16:31 +03:00
dp - > dist = cp - > dist + CGI - > mh - > getCost ( int3 ( cp - > coord . x , cp - > coord . y , src . z ) , int3 ( cp - > coord . x + 1 , cp - > coord . y , src . z ) , hero ) ;
2007-08-17 20:42:21 +03:00
dp - > theNodeBefore = cp ;
mq . push ( dp ) ;
2007-08-12 20:48:05 +03:00
}
}
2007-09-22 04:16:31 +03:00
if ( cp - > coord . y < graph [ 0 ] . size ( ) - 1 )
2007-08-07 16:49:15 +03:00
{
2007-09-22 04:16:31 +03:00
CPathNode * dp = graph [ cp - > coord . x ] [ cp - > coord . y + 1 ] ;
if ( ( dp - > dist = = - 1 | | ( dp - > dist > cp - > dist + CGI - > mh - > getCost ( int3 ( cp - > coord . x , cp - > coord . y , src . z ) , int3 ( cp - > coord . x , cp - > coord . y + 1 , src . z ) , hero ) ) ) & & dp - > accesible )
2007-08-07 16:49:15 +03:00
{
2007-09-22 04:16:31 +03:00
dp - > dist = cp - > dist + CGI - > mh - > getCost ( int3 ( cp - > coord . x , cp - > coord . y , src . z ) , int3 ( cp - > coord . x , cp - > coord . y + 1 , src . z ) , hero ) ;
2007-08-17 20:42:21 +03:00
dp - > theNodeBefore = cp ;
mq . push ( dp ) ;
2007-08-07 16:49:15 +03:00
}
2007-08-12 20:48:05 +03:00
}
2007-09-22 04:16:31 +03:00
if ( cp - > coord . x < graph . size ( ) - 1 & & cp - > coord . y < graph [ 0 ] . size ( ) - 1 )
2007-08-12 20:48:05 +03:00
{
2007-09-22 04:16:31 +03:00
CPathNode * dp = graph [ cp - > coord . x + 1 ] [ cp - > coord . y + 1 ] ;
if ( ( dp - > dist = = - 1 | | ( dp - > dist > cp - > dist + CGI - > mh - > getCost ( int3 ( cp - > coord . x , cp - > coord . y , src . z ) , int3 ( cp - > coord . x + 1 , cp - > coord . y + 1 , src . z ) , hero ) ) ) & & dp - > accesible )
2007-08-07 16:49:15 +03:00
{
2007-09-22 04:16:31 +03:00
dp - > dist = cp - > dist + CGI - > mh - > getCost ( int3 ( cp - > coord . x , cp - > coord . y , src . z ) , int3 ( cp - > coord . x + 1 , cp - > coord . y + 1 , src . z ) , hero ) ;
2007-08-17 20:42:21 +03:00
dp - > theNodeBefore = cp ;
mq . push ( dp ) ;
2007-08-12 20:48:05 +03:00
}
}
2007-09-22 04:16:31 +03:00
if ( cp - > coord . x > 0 & & cp - > coord . y < graph [ 0 ] . size ( ) - 1 )
2007-08-12 20:48:05 +03:00
{
2007-09-22 04:16:31 +03:00
CPathNode * dp = graph [ cp - > coord . x - 1 ] [ cp - > coord . y + 1 ] ;
if ( ( dp - > dist = = - 1 | | ( dp - > dist > cp - > dist + CGI - > mh - > getCost ( int3 ( cp - > coord . x , cp - > coord . y , src . z ) , int3 ( cp - > coord . x - 1 , cp - > coord . y + 1 , src . z ) , hero ) ) ) & & dp - > accesible )
2007-08-12 20:48:05 +03:00
{
2007-09-22 04:16:31 +03:00
dp - > dist = cp - > dist + CGI - > mh - > getCost ( int3 ( cp - > coord . x , cp - > coord . y , src . z ) , int3 ( cp - > coord . x - 1 , cp - > coord . y + 1 , src . z ) , hero ) ;
2007-08-17 20:42:21 +03:00
dp - > theNodeBefore = cp ;
mq . push ( dp ) ;
2007-08-12 20:48:05 +03:00
}
}
2007-09-22 04:16:31 +03:00
if ( cp - > coord . x < graph . size ( ) - 1 & & cp - > coord . y > 0 )
2007-08-12 20:48:05 +03:00
{
2007-09-22 04:16:31 +03:00
CPathNode * dp = graph [ cp - > coord . x + 1 ] [ cp - > coord . y - 1 ] ;
if ( ( dp - > dist = = - 1 | | ( dp - > dist > cp - > dist + CGI - > mh - > getCost ( int3 ( cp - > coord . x , cp - > coord . y , src . z ) , int3 ( cp - > coord . x + 1 , cp - > coord . y - 1 , src . z ) , hero ) ) ) & & dp - > accesible )
2007-08-12 20:48:05 +03:00
{
2007-09-22 04:16:31 +03:00
dp - > dist = cp - > dist + CGI - > mh - > getCost ( int3 ( cp - > coord . x , cp - > coord . y , src . z ) , int3 ( cp - > coord . x + 1 , cp - > coord . y - 1 , src . z ) , hero ) ;
2007-08-17 20:42:21 +03:00
dp - > theNodeBefore = cp ;
mq . push ( dp ) ;
2007-08-07 16:49:15 +03:00
}
}
}
2007-08-12 20:48:05 +03:00
CPathNode * curNode = graph [ dest . x ] [ dest . y ] ;
CPath * ret = new CPath ;
while ( curNode ! = graph [ src . x ] [ src . y ] & & curNode ! = NULL )
{
2007-08-17 20:42:21 +03:00
ret - > nodes . push_back ( * curNode ) ;
2007-08-12 20:48:05 +03:00
curNode = curNode - > theNodeBefore ;
}
2007-08-17 20:42:21 +03:00
ret - > nodes . push_back ( * graph [ src . x ] [ src . y ] ) ;
2007-08-12 20:48:05 +03:00
for ( int i = 0 ; i < graph . size ( ) ; + + i )
{
2007-08-17 20:42:21 +03:00
for ( int j = 0 ; j < graph [ 0 ] . size ( ) ; + + j )
2007-08-12 20:48:05 +03:00
delete graph [ i ] [ j ] ;
}
return ret ;
2007-08-07 16:49:15 +03:00
}