2010-07-11 20:31:02 +02:00
// This file is part of Glest (www.glest.org)
//
2010-08-22 22:13:30 +02:00
// Copyright (C) 2001-2008 Martio Figueroa
2010-07-11 20:31:02 +02:00
//
// You can redistribute this code and/or modify it under
// the terms of the GNU General Public License as published
// by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version
// ==============================================================
# include "path_finder.h"
# include <algorithm>
# include <cassert>
# include "config.h"
# include "map.h"
# include "unit.h"
# include "unit_type.h"
2010-08-22 22:13:30 +02:00
# include "platform_common.h"
2010-10-17 08:34:42 +02:00
# include "command.h"
2010-10-20 00:26:49 +02:00
# include "faction.h"
2011-01-28 08:17:32 +01:00
# include "randomgen.h"
2010-07-11 20:31:02 +02:00
# include "leak_dumper.h"
using namespace std ;
using namespace Shared : : Graphics ;
using namespace Shared : : Util ;
2010-08-22 22:13:30 +02:00
using namespace Shared : : PlatformCommon ;
2011-01-28 08:17:32 +01:00
using Shared : : Util : : RandomGen ;
2010-07-11 20:31:02 +02:00
namespace Glest { namespace Game {
// =====================================================
// class PathFinder
// =====================================================
// ===================== PUBLIC ========================
2011-01-28 08:17:32 +01:00
const int PathFinder : : maxFreeSearchRadius = 10 ;
2010-10-17 08:34:42 +02:00
//const int PathFinder::pathFindNodesMax= 400;
2011-04-14 04:51:13 +02:00
2011-06-25 20:14:20 +02:00
int PathFinder : : pathFindNodesAbsoluteMax = 900 ;
2011-06-02 09:09:19 +02:00
int PathFinder : : pathFindNodesMax = 1500 ;
2011-02-15 04:32:14 +01:00
const int PathFinder : : pathFindRefresh = 10 ;
2011-01-28 08:17:32 +01:00
const int PathFinder : : pathFindBailoutRadius = 20 ;
2011-04-26 23:51:18 +02:00
const int PathFinder : : pathFindExtendRefreshForNodeCount = 25 ;
2011-06-25 22:44:46 +02:00
const int PathFinder : : pathFindExtendRefreshNodeCountMin = 40 ;
2011-06-27 01:51:37 +02:00
const int PathFinder : : pathFindExtendRefreshNodeCountMax = 40 ;
2010-07-11 20:31:02 +02:00
2010-10-17 08:34:42 +02:00
PathFinder : : PathFinder ( ) {
2011-03-18 04:53:06 +01:00
for ( int i = 0 ; i < GameConstants : : maxPlayers ; + + i ) {
factions . push_back ( FactionState ( ) ) ;
}
2010-09-07 23:01:22 +02:00
map = NULL ;
2010-07-11 20:31:02 +02:00
}
2011-06-24 21:40:47 +02:00
int PathFinder : : getPathFindExtendRefreshNodeCount ( int factionIndex ) {
int refreshNodeCount = factions [ factionIndex ] . random . randRange ( PathFinder : : pathFindExtendRefreshNodeCountMin , PathFinder : : pathFindExtendRefreshNodeCountMax ) ;
return refreshNodeCount ;
}
2010-10-17 08:34:42 +02:00
PathFinder : : PathFinder ( const Map * map ) {
2011-03-18 04:53:06 +01:00
for ( int i = 0 ; i < GameConstants : : maxPlayers ; + + i ) {
factions . push_back ( FactionState ( ) ) ;
}
2010-09-07 23:01:22 +02:00
map = NULL ;
2010-07-30 03:05:52 +02:00
init ( map ) ;
2010-07-11 20:31:02 +02:00
}
2010-10-17 08:34:42 +02:00
void PathFinder : : init ( const Map * map ) {
2011-02-13 04:31:05 +01:00
PathFinder : : pathFindNodesMax = Config : : getInstance ( ) . getInt ( " MaxPathfinderNodeCount " , intToStr ( PathFinder : : pathFindNodesMax ) . c_str ( ) ) ;
2011-03-18 04:53:06 +01:00
for ( int i = 0 ; i < GameConstants : : maxPlayers ; + + i ) {
2011-04-14 04:51:13 +02:00
factions [ i ] . nodePool . resize ( pathFindNodesAbsoluteMax ) ;
2011-03-18 04:53:06 +01:00
factions [ i ] . useMaxNodeCount = PathFinder : : pathFindNodesMax ;
}
2010-07-11 20:31:02 +02:00
this - > map = map ;
}
2011-03-18 04:53:06 +01:00
PathFinder : : ~ PathFinder ( ) {
for ( int i = 0 ; i < GameConstants : : maxPlayers ; + + i ) {
factions [ i ] . nodePool . clear ( ) ;
}
2010-09-07 23:01:22 +02:00
map = NULL ;
2010-07-11 20:31:02 +02:00
}
2011-03-18 04:53:06 +01:00
void PathFinder : : clearUnitPrecache ( Unit * unit ) {
factions [ unit - > getFactionIndex ( ) ] . precachedTravelState [ unit - > getId ( ) ] = tsImpossible ;
factions [ unit - > getFactionIndex ( ) ] . precachedPath [ unit - > getId ( ) ] . clear ( ) ;
}
2011-03-29 12:01:01 +02:00
void PathFinder : : removeUnitPrecache ( Unit * unit ) {
if ( factions . size ( ) > unit - > getFactionIndex ( ) ) {
if ( factions [ unit - > getFactionIndex ( ) ] . precachedTravelState . find ( unit - > getId ( ) ) ! = factions [ unit - > getFactionIndex ( ) ] . precachedTravelState . end ( ) ) {
factions [ unit - > getFactionIndex ( ) ] . precachedTravelState . erase ( unit - > getId ( ) ) ;
}
if ( factions [ unit - > getFactionIndex ( ) ] . precachedPath . find ( unit - > getId ( ) ) ! = factions [ unit - > getFactionIndex ( ) ] . precachedPath . end ( ) ) {
factions [ unit - > getFactionIndex ( ) ] . precachedPath . erase ( unit - > getId ( ) ) ;
}
}
}
2011-03-18 04:53:06 +01:00
TravelState PathFinder : : findPath ( Unit * unit , const Vec2i & finalPos , bool * wasStuck , int frameIndex ) {
2010-09-07 23:01:22 +02:00
if ( map = = NULL ) {
throw runtime_error ( " map == NULL " ) ;
}
2011-03-18 04:53:06 +01:00
if ( frameIndex > = 0 ) {
clearUnitPrecache ( unit ) ;
}
2010-11-09 10:06:52 +01:00
2011-04-03 04:42:45 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
2010-12-01 00:32:39 +01:00
char szBuf [ 4096 ] = " " ;
2010-12-02 00:38:03 +01:00
sprintf ( szBuf , " [findPath] unit->getPos() [%s] finalPos [%s] " ,
unit - > getPos ( ) . getString ( ) . c_str ( ) , finalPos . getString ( ) . c_str ( ) ) ;
unit - > logSynchData ( __FILE__ , __LINE__ , szBuf ) ;
2010-11-09 10:06:52 +01:00
}
2010-07-11 20:31:02 +02:00
//route cache
2010-10-17 08:34:42 +02:00
if ( finalPos = = unit - > getPos ( ) ) {
2011-03-18 04:53:06 +01:00
if ( frameIndex < 0 ) {
//if arrived
unit - > setCurrSkill ( scStop ) ;
}
2010-10-17 08:34:42 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPathFinder ) . enabled = = true ) {
string commandDesc = " none " ;
Command * command = unit - > getCurrCommand ( ) ;
if ( command ! = NULL & & command - > getCommandType ( ) ! = NULL ) {
commandDesc = command - > getCommandType ( ) - > toString ( ) ;
}
char szBuf [ 1024 ] = " " ;
sprintf ( szBuf , " State: arrived#1 at pos: %s, command [%s] " , finalPos . getString ( ) . c_str ( ) , commandDesc . c_str ( ) ) ;
unit - > setCurrentUnitTitle ( szBuf ) ;
}
2010-07-11 20:31:02 +02:00
return tsArrived ;
}
2010-10-26 08:43:42 +02:00
2011-03-18 04:53:06 +01:00
UnitPathInterface * path = unit - > getPath ( ) ;
if ( path - > isEmpty ( ) = = false ) {
if ( dynamic_cast < UnitPathBasic * > ( path ) ! = NULL ) {
//route cache
UnitPathBasic * basicPath = dynamic_cast < UnitPathBasic * > ( path ) ;
Vec2i pos = basicPath - > pop ( frameIndex < 0 ) ;
if ( map - > canMove ( unit , unit - > getPos ( ) , pos ) ) {
if ( frameIndex < 0 ) {
2010-07-21 20:21:40 +02:00
unit - > setTargetPos ( pos ) ;
}
2011-03-18 04:53:06 +01:00
return tsMoving ;
2010-07-21 20:21:40 +02:00
}
2011-03-18 04:53:06 +01:00
}
else if ( dynamic_cast < UnitPath * > ( path ) ! = NULL ) {
UnitPath * advPath = dynamic_cast < UnitPath * > ( path ) ;
//route cache
Vec2i pos = advPath - > peek ( ) ;
if ( map - > canMove ( unit , unit - > getPos ( ) , pos ) ) {
if ( frameIndex < 0 ) {
2010-07-21 21:17:45 +02:00
advPath - > pop ( ) ;
2010-07-21 20:21:40 +02:00
unit - > setTargetPos ( pos ) ;
}
2011-03-18 04:53:06 +01:00
return tsMoving ;
2010-07-21 20:21:40 +02:00
}
2011-03-18 04:53:06 +01:00
}
else {
throw runtime_error ( " unsupported or missing path finder detected! " ) ;
2010-07-21 21:17:45 +02:00
}
2010-07-11 20:31:02 +02:00
}
2011-03-18 04:53:06 +01:00
2011-04-04 06:32:01 +02:00
if ( path - > isStuck ( ) = = true & & unit - > getLastStuckPos ( ) = = finalPos & &
unit - > isLastStuckFrameWithinCurrentFrameTolerance ( ) = = true ) {
//printf("$$$$ Unit STILL BLOCKED for [%d - %s]\n",unit->getId(),unit->getFullName().c_str());
return tsBlocked ;
}
2010-10-20 00:26:49 +02:00
TravelState ts = tsImpossible ;
2011-03-29 18:27:01 +02:00
//route cache miss
2011-04-14 04:51:13 +02:00
int maxNodeCount = - 1 ;
if ( unit - > getUsePathfinderExtendedMaxNodes ( ) = = true ) {
const bool showConsoleDebugInfo = Config : : getInstance ( ) . getBool ( " EnablePathfinderDistanceOutput " , " false " ) ;
if ( showConsoleDebugInfo | | SystemFlags : : VERBOSE_MODE_ENABLED ) {
printf ( " \n \n \n \n ### Continued call to AStar with LARGE maxnodes for unit [%d - %s] \n \n " , unit - > getId ( ) , unit - > getFullName ( ) . c_str ( ) ) ;
}
maxNodeCount = PathFinder : : pathFindNodesAbsoluteMax ;
}
ts = aStar ( unit , finalPos , false , frameIndex , maxNodeCount ) ;
2010-07-11 20:31:02 +02:00
//post actions
2010-10-17 08:34:42 +02:00
switch ( ts ) {
2010-07-11 20:31:02 +02:00
case tsBlocked :
case tsArrived :
2010-10-20 00:26:49 +02:00
2010-10-17 08:34:42 +02:00
// The unit is stuck (not only blocked but unable to go anywhere for a while)
// We will try to bail out of the immediate area
if ( ts = = tsBlocked & & unit - > getInBailOutAttempt ( ) = = false & &
path - > isStuck ( ) = = true ) {
2010-12-01 00:32:39 +01:00
2011-04-04 06:32:01 +02:00
//printf("$$$$ Unit START BAILOUT ATTEMPT for [%d - %s]\n",unit->getId(),unit->getFullName().c_str());
2011-04-03 04:42:45 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
2010-12-01 00:32:39 +01:00
char szBuf [ 4096 ] = " " ;
2010-12-02 00:38:03 +01:00
sprintf ( szBuf , " [attempting to BAIL OUT] finalPos [%s] ts [%d] " ,
finalPos . getString ( ) . c_str ( ) , ts ) ;
unit - > logSynchData ( __FILE__ , __LINE__ , szBuf ) ;
2010-12-01 00:32:39 +01:00
}
2010-10-19 18:54:48 +02:00
if ( wasStuck ! = NULL ) {
* wasStuck = true ;
}
2010-10-17 08:34:42 +02:00
unit - > setInBailOutAttempt ( true ) ;
2011-01-28 08:17:32 +01:00
2011-02-16 04:48:13 +01:00
bool useBailoutRadius = Config : : getInstance ( ) . getBool ( " EnableBailoutPathfinding " , " true " ) ;
2011-01-28 08:17:32 +01:00
if ( useBailoutRadius = = true ) {
2011-04-04 06:32:01 +02:00
2011-04-14 04:51:13 +02:00
//!!!
bool unitImmediatelyBlocked = false ;
// First check if unit currently blocked all around them, if so don't try to pathfind
const bool showConsoleDebugInfo = Config : : getInstance ( ) . getBool ( " EnablePathfinderDistanceOutput " , " false " ) ;
const Vec2i unitPos = unit - > getPos ( ) ;
int failureCount = 0 ;
int cellCount = 0 ;
for ( int i = - 1 ; i < = 1 ; + + i ) {
for ( int j = - 1 ; j < = 1 ; + + j ) {
Vec2i pos = unitPos + Vec2i ( i , j ) ;
if ( pos ! = unitPos ) {
bool canUnitMoveToCell = map - > aproxCanMove ( unit , unitPos , pos ) ;
if ( canUnitMoveToCell = = false ) {
failureCount + + ;
2011-01-28 08:17:32 +01:00
}
2011-04-14 04:51:13 +02:00
cellCount + + ;
2011-01-28 08:17:32 +01:00
}
}
}
2011-04-14 04:51:13 +02:00
unitImmediatelyBlocked = ( failureCount = = cellCount ) ;
//if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] **Check if dest blocked, distance for unit [%d - %s] from [%s] to [%s] is %.2f took msecs: %lld unitImmediatelyBlocked = %d, failureCount = %d\n",__FILE__,__FUNCTION__,__LINE__,unit->getId(),unit->getFullName().c_str(), unitPos.getString().c_str(), finalPos.getString().c_str(), dist,(long long int)chrono.getMillis(),unitImmediatelyBlocked,failureCount);
if ( showConsoleDebugInfo & & unitImmediatelyBlocked ) {
printf ( " **Check if src blocked [%d], unit [%d - %s] from [%s] to [%s] unitImmediatelyBlocked = %d, failureCount = %d [%d] \n " ,
unitImmediatelyBlocked , unit - > getId ( ) , unit - > getFullName ( ) . c_str ( ) , unitPos . getString ( ) . c_str ( ) , finalPos . getString ( ) . c_str ( ) , unitImmediatelyBlocked , failureCount , cellCount ) ;
}
// if(unitImmediatelyBlocked == false) {
// // First check if final destination blocked
// failureCount = 0;
// cellCount = 0;
//
// for(int i = -1; i <= 1; ++i) {
// for(int j = -1; j <= 1; ++j) {
// Vec2i pos = finalPos + Vec2i(i, j);
// if(pos != finalPos) {
// bool canUnitMoveToCell = map->aproxCanMove(unit, pos, finalPos);
// if(canUnitMoveToCell == false) {
// failureCount++;
// }
// cellCount++;
// }
// }
// }
// unitImmediatelyBlocked = (failureCount == cellCount);
//
// if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] **Check if dest blocked, distance for unit [%d - %s] from [%s] to [%s] is %.2f took msecs: %lld unitImmediatelyBlocked = %d, failureCount = %d\n",__FILE__,__FUNCTION__,__LINE__,unit->getId(),unit->getFullName().c_str(), unitPos.getString().c_str(), finalPos.getString().c_str(), dist,(long long int)chrono.getMillis(),unitImmediatelyBlocked,failureCount);
// if(showConsoleDebugInfo && nodeLimitReached) {
// printf("**Check if dest blocked [%d - %d], unit [%d - %s] from [%s] to [%s] distance %.2f took msecs: %lld unitImmediatelyBlocked = %d, failureCount = %d [%d]\n",
// nodeLimitReached, inBailout, unit->getId(),unit->getFullName().c_str(), unitPos.getString().c_str(), finalPos.getString().c_str(), dist,(long long int)chrono.getMillis(),unitImmediatelyBlocked,failureCount,cellCount);
// }
// }
//
//!!!
if ( unitImmediatelyBlocked = = false ) {
int tryRadius = factions [ unit - > getFactionIndex ( ) ] . random . randRange ( 0 , 1 ) ;
// Try to bail out up to PathFinder::pathFindBailoutRadius cells away
if ( tryRadius > 0 ) {
for ( int bailoutX = - PathFinder : : pathFindBailoutRadius ; bailoutX < = PathFinder : : pathFindBailoutRadius & & ts = = tsBlocked ; + + bailoutX ) {
for ( int bailoutY = - PathFinder : : pathFindBailoutRadius ; bailoutY < = PathFinder : : pathFindBailoutRadius & & ts = = tsBlocked ; + + bailoutY ) {
const Vec2i newFinalPos = finalPos + Vec2i ( bailoutX , bailoutY ) ;
bool canUnitMove = map - > canMove ( unit , unit - > getPos ( ) , newFinalPos ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " [attempting to BAIL OUT] finalPos [%s] newFinalPos [%s] ts [%d] canUnitMove [%d] " ,
finalPos . getString ( ) . c_str ( ) , newFinalPos . getString ( ) . c_str ( ) , ts , canUnitMove ) ;
unit - > logSynchData ( __FILE__ , __LINE__ , szBuf ) ;
}
if ( canUnitMove ) {
//printf("$$$$ Unit BAILOUT(1) ASTAR ATTEMPT for [%d - %s] newFinalPos = [%s]\n",unit->getId(),unit->getFullName().c_str(),newFinalPos.getString().c_str());
2011-06-02 09:09:19 +02:00
int maxBailoutNodeCount = ( PathFinder : : pathFindBailoutRadius * 2 ) ;
ts = aStar ( unit , newFinalPos , true , frameIndex , maxBailoutNodeCount ) ;
2011-04-14 04:51:13 +02:00
}
2011-01-28 08:17:32 +01:00
}
2011-04-14 04:51:13 +02:00
}
}
else {
for ( int bailoutX = PathFinder : : pathFindBailoutRadius ; bailoutX > = - PathFinder : : pathFindBailoutRadius & & ts = = tsBlocked ; - - bailoutX ) {
for ( int bailoutY = PathFinder : : pathFindBailoutRadius ; bailoutY > = - PathFinder : : pathFindBailoutRadius & & ts = = tsBlocked ; - - bailoutY ) {
const Vec2i newFinalPos = finalPos + Vec2i ( bailoutX , bailoutY ) ;
bool canUnitMove = map - > canMove ( unit , unit - > getPos ( ) , newFinalPos ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
char szBuf [ 4096 ] = " " ;
sprintf ( szBuf , " [attempting to BAIL OUT] finalPos [%s] newFinalPos [%s] ts [%d] canUnitMove [%d] " ,
finalPos . getString ( ) . c_str ( ) , newFinalPos . getString ( ) . c_str ( ) , ts , canUnitMove ) ;
unit - > logSynchData ( __FILE__ , __LINE__ , szBuf ) ;
}
2011-01-28 08:17:32 +01:00
2011-04-14 04:51:13 +02:00
if ( canUnitMove ) {
//printf("$$$$ Unit BAILOUT(1) ASTAR ATTEMPT for [%d - %s] newFinalPos = [%s]\n",unit->getId(),unit->getFullName().c_str(),newFinalPos.getString().c_str());
2011-06-02 09:09:19 +02:00
int maxBailoutNodeCount = ( PathFinder : : pathFindBailoutRadius * 2 ) ;
ts = aStar ( unit , newFinalPos , true , frameIndex , maxBailoutNodeCount ) ;
2011-04-14 04:51:13 +02:00
}
2011-01-28 08:17:32 +01:00
}
}
2010-10-17 08:34:42 +02:00
}
}
}
unit - > setInBailOutAttempt ( false ) ;
2011-04-04 06:32:01 +02:00
//printf("$$$$ Unit END BAILOUT ATTEMPT for [%d - %s] ts = %d\n",unit->getId(),unit->getFullName().c_str(),ts);
if ( ts = = tsBlocked ) {
unit - > setLastStuckFrameToCurrentFrame ( ) ;
unit - > setLastStuckPos ( finalPos ) ;
}
2010-10-19 18:54:48 +02:00
}
if ( ts = = tsArrived | | ts = = tsBlocked ) {
2011-03-18 04:53:06 +01:00
if ( frameIndex < 0 ) {
unit - > setCurrSkill ( scStop ) ;
}
2010-10-17 08:34:42 +02:00
}
2010-07-11 20:31:02 +02:00
break ;
2010-07-22 00:05:50 +02:00
case tsMoving :
2010-07-21 20:21:40 +02:00
{
if ( dynamic_cast < UnitPathBasic * > ( path ) ! = NULL ) {
2010-07-21 21:17:45 +02:00
UnitPathBasic * basicPath = dynamic_cast < UnitPathBasic * > ( path ) ;
2011-03-18 04:53:06 +01:00
Vec2i pos ;
if ( frameIndex < 0 ) {
pos = basicPath - > pop ( frameIndex < 0 ) ;
}
else {
pos = factions [ unit - > getFactionIndex ( ) ] . precachedPath [ unit - > getId ( ) ] [ 0 ] ;
}
2010-10-26 08:43:42 +02:00
2010-11-28 01:07:08 +01:00
if ( map - > canMove ( unit , unit - > getPos ( ) , pos ) ) {
2011-03-18 04:53:06 +01:00
if ( frameIndex < 0 ) {
unit - > setTargetPos ( pos ) ;
}
2010-07-21 20:21:40 +02:00
}
else {
2011-03-18 04:53:06 +01:00
if ( frameIndex < 0 ) {
unit - > setCurrSkill ( scStop ) ;
}
2010-07-21 20:21:40 +02:00
return tsBlocked ;
}
}
else if ( dynamic_cast < UnitPath * > ( path ) ! = NULL ) {
UnitPath * advPath = dynamic_cast < UnitPath * > ( path ) ;
Vec2i pos = advPath - > peek ( ) ;
2010-11-28 01:07:08 +01:00
if ( map - > canMove ( unit , unit - > getPos ( ) , pos ) ) {
2011-03-18 04:53:06 +01:00
if ( frameIndex < 0 ) {
advPath - > pop ( ) ;
unit - > setTargetPos ( pos ) ;
}
2010-07-21 20:21:40 +02:00
}
else {
2011-03-18 04:53:06 +01:00
if ( frameIndex < 0 ) {
unit - > setCurrSkill ( scStop ) ;
}
2010-07-21 20:21:40 +02:00
return tsBlocked ;
}
}
2010-07-21 21:17:45 +02:00
else {
throw runtime_error ( " unsupported or missing path finder detected! " ) ;
}
2010-07-11 20:31:02 +02:00
}
break ;
}
return ts ;
}
// ==================== PRIVATE ====================
2011-02-04 07:34:32 +01:00
2011-04-14 04:51:13 +02:00
bool PathFinder : : processNode ( Unit * unit , Node * node , const Vec2i finalPos , int i , int j , bool & nodeLimitReached , int maxNodeCount ) {
2011-02-23 08:03:38 +01:00
bool result = false ;
2011-02-04 07:34:32 +01:00
Vec2i sucPos = node - > pos + Vec2i ( i , j ) ;
bool canUnitMoveToCell = map - > aproxCanMove ( unit , node - > pos , sucPos ) ;
2011-04-04 06:32:01 +02:00
if ( canUnitMoveToCell = = true & & openPos ( sucPos , factions [ unit - > getFactionIndex ( ) ] ) = = false ) {
2011-02-04 07:34:32 +01:00
//if node is not open and canMove then generate another node
2011-04-14 04:51:13 +02:00
Node * sucNode = newNode ( factions [ unit - > getFactionIndex ( ) ] , maxNodeCount ) ;
2011-02-04 07:34:32 +01:00
if ( sucNode ! = NULL ) {
sucNode - > pos = sucPos ;
sucNode - > heuristic = heuristic ( sucNode - > pos , finalPos ) ;
sucNode - > prev = node ;
sucNode - > next = NULL ;
sucNode - > exploredCell = map - > getSurfaceCell ( Map : : toSurfCoords ( sucPos ) ) - > isExplored ( unit - > getTeam ( ) ) ;
2011-03-18 04:53:06 +01:00
if ( factions [ unit - > getFactionIndex ( ) ] . openNodesList . find ( sucNode - > heuristic ) = = factions [ unit - > getFactionIndex ( ) ] . openNodesList . end ( ) ) {
factions [ unit - > getFactionIndex ( ) ] . openNodesList [ sucNode - > heuristic ] . clear ( ) ;
2011-02-16 20:44:12 +01:00
}
2011-03-18 04:53:06 +01:00
factions [ unit - > getFactionIndex ( ) ] . openNodesList [ sucNode - > heuristic ] . push_back ( sucNode ) ;
factions [ unit - > getFactionIndex ( ) ] . openPosList [ sucNode - > pos ] = true ;
2011-02-23 08:03:38 +01:00
result = true ;
2011-02-04 07:34:32 +01:00
}
else {
nodeLimitReached = true ;
}
}
2011-02-23 08:03:38 +01:00
return result ;
2011-02-04 07:34:32 +01:00
}
2010-07-11 20:31:02 +02:00
//route a unit using A* algorithm
2011-03-18 04:53:06 +01:00
TravelState PathFinder : : aStar ( Unit * unit , const Vec2i & targetPos , bool inBailout ,
2011-04-14 04:51:13 +02:00
int frameIndex , int maxNodeCount ) {
2011-02-25 23:13:11 +01:00
2010-12-05 00:19:43 +01:00
Chrono chrono ;
2011-03-29 18:27:01 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled ) chrono . start ( ) ;
2010-12-05 00:19:43 +01:00
2010-09-07 23:01:22 +02:00
if ( map = = NULL ) {
throw runtime_error ( " map == NULL " ) ;
}
2011-03-18 22:23:34 +01:00
const bool showConsoleDebugInfo = Config : : getInstance ( ) . getBool ( " EnablePathfinderDistanceOutput " , " false " ) ;
const bool tryLastPathCache = Config : : getInstance ( ) . getBool ( " EnablePathfinderCache " , " false " ) ;
2011-04-14 04:51:13 +02:00
if ( maxNodeCount < 0 ) {
maxNodeCount = factions [ unit - > getFactionIndex ( ) ] . useMaxNodeCount ;
}
2011-03-18 04:53:06 +01:00
UnitPathInterface * path = unit - > getPath ( ) ;
factions [ unit - > getFactionIndex ( ) ] . nodePoolCount = 0 ;
factions [ unit - > getFactionIndex ( ) ] . openNodesList . clear ( ) ;
factions [ unit - > getFactionIndex ( ) ] . openPosList . clear ( ) ;
factions [ unit - > getFactionIndex ( ) ] . closedNodesList . clear ( ) ;
2010-10-26 08:43:42 +02:00
2011-02-12 00:32:24 +01:00
TravelState ts = tsImpossible ;
2011-03-18 04:53:06 +01:00
if ( frameIndex < 0 ) {
if ( factions [ unit - > getFactionIndex ( ) ] . precachedTravelState . find ( unit - > getId ( ) ) ! = factions [ unit - > getFactionIndex ( ) ] . precachedTravelState . end ( ) ) {
if ( factions [ unit - > getFactionIndex ( ) ] . precachedTravelState [ unit - > getId ( ) ] = = tsMoving ) {
bool canMoveToCells = true ;
Vec2i lastPos = unit - > getPos ( ) ;
for ( int i = 0 ; i < factions [ unit - > getFactionIndex ( ) ] . precachedPath [ unit - > getId ( ) ] . size ( ) ; i + + ) {
Vec2i nodePos = factions [ unit - > getFactionIndex ( ) ] . precachedPath [ unit - > getId ( ) ] [ i ] ;
if ( map - > isInside ( nodePos ) = = false | | map - > isInsideSurface ( map - > toSurfCoords ( nodePos ) ) = = false ) {
throw runtime_error ( " Pathfinder invalid node path position = " + nodePos . getString ( ) + " i = " + intToStr ( i ) ) ;
}
2011-04-26 23:51:18 +02:00
if ( i < pathFindRefresh | |
2011-06-24 21:40:47 +02:00
( factions [ unit - > getFactionIndex ( ) ] . precachedPath [ unit - > getId ( ) ] . size ( ) > = pathFindExtendRefreshForNodeCount & &
i < getPathFindExtendRefreshNodeCount ( unit - > getFactionIndex ( ) ) ) ) {
2011-03-18 04:53:06 +01:00
if ( map - > aproxCanMove ( unit , lastPos , nodePos ) = = false ) {
canMoveToCells = false ;
break ;
}
lastPos = nodePos ;
}
else {
break ;
}
}
if ( canMoveToCells = = true ) {
path - > clear ( ) ;
UnitPathBasic * basicPathFinder = dynamic_cast < UnitPathBasic * > ( path ) ;
for ( int i = 0 ; i < factions [ unit - > getFactionIndex ( ) ] . precachedPath [ unit - > getId ( ) ] . size ( ) ; i + + ) {
Vec2i nodePos = factions [ unit - > getFactionIndex ( ) ] . precachedPath [ unit - > getId ( ) ] [ i ] ;
if ( map - > isInside ( nodePos ) = = false | | map - > isInsideSurface ( map - > toSurfCoords ( nodePos ) ) = = false ) {
throw runtime_error ( " Pathfinder invalid node path position = " + nodePos . getString ( ) + " i = " + intToStr ( i ) ) ;
}
2011-04-26 23:51:18 +02:00
if ( i < pathFindRefresh | |
2011-06-24 21:40:47 +02:00
( factions [ unit - > getFactionIndex ( ) ] . precachedPath [ unit - > getId ( ) ] . size ( ) > = pathFindExtendRefreshForNodeCount & &
i < getPathFindExtendRefreshNodeCount ( unit - > getFactionIndex ( ) ) ) ) {
2011-03-18 04:53:06 +01:00
path - > add ( nodePos ) ;
}
2011-04-18 18:51:30 +02:00
//else if(tryLastPathCache == false) {
// break;
//}
2011-03-18 22:23:34 +01:00
2011-04-18 18:51:30 +02:00
//if(tryLastPathCache == true && basicPathFinder) {
if ( basicPathFinder ) {
2011-03-18 22:23:34 +01:00
basicPathFinder - > addToLastPathCache ( nodePos ) ;
}
2011-03-18 04:53:06 +01:00
}
2011-04-14 04:51:13 +02:00
unit - > setUsePathfinderExtendedMaxNodes ( false ) ;
2011-03-18 04:53:06 +01:00
return factions [ unit - > getFactionIndex ( ) ] . precachedTravelState [ unit - > getId ( ) ] ;
}
else {
clearUnitPrecache ( unit ) ;
}
}
else if ( factions [ unit - > getFactionIndex ( ) ] . precachedTravelState [ unit - > getId ( ) ] = = tsBlocked ) {
path - > incBlockCount ( ) ;
2011-04-14 04:51:13 +02:00
unit - > setUsePathfinderExtendedMaxNodes ( false ) ;
2011-03-18 04:53:06 +01:00
return factions [ unit - > getFactionIndex ( ) ] . precachedTravelState [ unit - > getId ( ) ] ;
}
}
}
else {
clearUnitPrecache ( unit ) ;
}
2011-02-12 00:32:24 +01:00
const Vec2i unitPos = unit - > getPos ( ) ;
2010-07-11 20:31:02 +02:00
const Vec2i finalPos = computeNearestFreePos ( unit , targetPos ) ;
2011-02-23 08:03:38 +01:00
float dist = unitPos . dist ( finalPos ) ;
2011-03-18 04:53:06 +01:00
factions [ unit - > getFactionIndex ( ) ] . useMaxNodeCount = PathFinder : : pathFindNodesMax ;
2011-02-23 08:03:38 +01:00
2011-02-04 07:34:32 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled = = true & & chrono . getMillis ( ) > 4 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-12-05 00:19:43 +01:00
2011-02-12 00:32:24 +01:00
// Check the previous path find cache for the unit to see if its good to
// use
2011-03-29 18:27:01 +02:00
if ( showConsoleDebugInfo | | tryLastPathCache ) {
if ( showConsoleDebugInfo & & dist > 60 ) printf ( " Distance from [%d - %s] to destination is %.2f tryLastPathCache = %d \n " , unit - > getId ( ) , unit - > getFullName ( ) . c_str ( ) , dist , tryLastPathCache ) ;
2011-02-23 08:03:38 +01:00
if ( tryLastPathCache = = true & & path ! = NULL ) {
UnitPathBasic * basicPathFinder = dynamic_cast < UnitPathBasic * > ( path ) ;
if ( basicPathFinder ! = NULL & & basicPathFinder - > getLastPathCacheQueueCount ( ) > 0 ) {
vector < Vec2i > cachedPath = basicPathFinder - > getLastPathCacheQueue ( ) ;
for ( int i = 0 ; i < cachedPath . size ( ) ; + + i ) {
Vec2i & pos1 = cachedPath [ i ] ;
// Looking to find if the unit is in one of the cells in the cached path
if ( unitPos = = pos1 ) {
// Now see if we can re-use this path to get to the final destination
for ( int j = i + 1 ; j < cachedPath . size ( ) ; + + j ) {
Vec2i & pos2 = cachedPath [ j ] ;
bool canUnitMoveToCell = map - > aproxCanMove ( unit , pos1 , pos2 ) ;
if ( canUnitMoveToCell = = true ) {
if ( pos2 = = finalPos ) {
//on the way
ts = tsMoving ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled = = true & & chrono . getMillis ( ) > 4 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
//store path
2011-03-18 22:23:34 +01:00
if ( frameIndex < 0 ) {
basicPathFinder - > clear ( ) ;
}
2011-02-23 08:03:38 +01:00
int pathCount = 0 ;
for ( int k = i + 1 ; k < = j ; k + + ) {
if ( k > = cachedPath . size ( ) ) {
throw runtime_error ( " k >= cachedPath.size() k = " + intToStr(k) + " cachedPath . size ( ) = " + intToStr(cachedPath.size())) ;
}
2011-03-18 22:23:34 +01:00
if ( frameIndex > = 0 ) {
factions [ unit - > getFactionIndex ( ) ] . precachedPath [ unit - > getId ( ) ] . push_back ( cachedPath [ k ] ) ;
}
else {
if ( pathCount < pathFindRefresh ) {
basicPathFinder - > add ( cachedPath [ k ] ) ;
}
basicPathFinder - > addToLastPathCache ( cachedPath [ k ] ) ;
2011-02-23 08:03:38 +01:00
}
pathCount + + ;
2011-02-12 00:32:24 +01:00
}
2011-02-23 08:03:38 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled = = true & & chrono . getMillis ( ) > 4 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2011-02-12 00:32:24 +01:00
2011-04-03 04:42:45 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
2011-02-23 08:03:38 +01:00
char szBuf [ 4096 ] = " " ;
2011-03-01 00:33:11 +01:00
sprintf ( szBuf , " [Setting new path for unit] openNodesList.size() [%lu] openPosList.size() [%lu] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d] " ,
2011-03-18 04:53:06 +01:00
factions [ unit - > getFactionIndex ( ) ] . openNodesList . size ( ) , factions [ unit - > getFactionIndex ( ) ] . openPosList . size ( ) , finalPos . getString ( ) . c_str ( ) , targetPos . getString ( ) . c_str ( ) , inBailout , ts ) ;
2011-02-23 08:03:38 +01:00
unit - > logSynchData ( __FILE__ , __LINE__ , szBuf ) ;
2011-02-12 00:32:24 +01:00
}
2011-02-23 08:03:38 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPathFinder ) . enabled = = true ) {
string commandDesc = " none " ;
Command * command = unit - > getCurrCommand ( ) ;
if ( command ! = NULL & & command - > getCommandType ( ) ! = NULL ) {
commandDesc = command - > getCommandType ( ) - > toString ( ) ;
}
2011-02-12 00:32:24 +01:00
2011-02-23 08:03:38 +01:00
char szBuf [ 1024 ] = " " ;
sprintf ( szBuf , " State: moving, cmd [%s] pos: %s dest pos: %s, Queue= %d " , commandDesc . c_str ( ) , unit - > getPos ( ) . getString ( ) . c_str ( ) , targetPos . getString ( ) . c_str ( ) , path - > getQueueCount ( ) ) ;
unit - > setCurrentUnitTitle ( szBuf ) ;
}
2011-02-12 00:32:24 +01:00
2011-02-23 08:03:38 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled = = true & & chrono . getMillis ( ) > 4 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2011-02-12 00:32:24 +01:00
2011-04-14 04:51:13 +02:00
unit - > setUsePathfinderExtendedMaxNodes ( false ) ;
2011-02-23 08:03:38 +01:00
return ts ;
}
else if ( j - i > pathFindRefresh ) {
//on the way
ts = tsMoving ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled = = true & & chrono . getMillis ( ) > 4 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
//store path
2011-03-18 22:23:34 +01:00
if ( frameIndex < 0 ) {
basicPathFinder - > clear ( ) ;
}
2011-02-23 08:03:38 +01:00
int pathCount = 0 ;
for ( int k = i + 1 ; k < cachedPath . size ( ) ; k + + ) {
if ( k > = cachedPath . size ( ) ) {
throw runtime_error ( " #2 k >= cachedPath.size() k = " + intToStr(k) + " cachedPath . size ( ) = " + intToStr(cachedPath.size())) ;
}
2011-03-18 22:23:34 +01:00
if ( frameIndex > = 0 ) {
factions [ unit - > getFactionIndex ( ) ] . precachedPath [ unit - > getId ( ) ] . push_back ( cachedPath [ k ] ) ;
}
else {
if ( pathCount < pathFindRefresh ) {
basicPathFinder - > add ( cachedPath [ k ] ) ;
}
basicPathFinder - > addToLastPathCache ( cachedPath [ k ] ) ;
2011-02-23 08:03:38 +01:00
}
pathCount + + ;
}
2011-02-12 00:32:24 +01:00
2011-02-23 08:03:38 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled = = true & & chrono . getMillis ( ) > 4 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2011-02-12 00:32:24 +01:00
2011-04-03 04:42:45 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
2011-02-23 08:03:38 +01:00
char szBuf [ 4096 ] = " " ;
2011-03-01 00:33:11 +01:00
sprintf ( szBuf , " [Setting new path for unit] openNodesList.size() [%lu] openPosList.size() [%lu] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d] " ,
2011-03-18 04:53:06 +01:00
factions [ unit - > getFactionIndex ( ) ] . openNodesList . size ( ) , factions [ unit - > getFactionIndex ( ) ] . openPosList . size ( ) , finalPos . getString ( ) . c_str ( ) , targetPos . getString ( ) . c_str ( ) , inBailout , ts ) ;
2011-02-23 08:03:38 +01:00
unit - > logSynchData ( __FILE__ , __LINE__ , szBuf ) ;
2011-02-12 00:32:24 +01:00
}
2011-02-23 08:03:38 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPathFinder ) . enabled = = true ) {
string commandDesc = " none " ;
Command * command = unit - > getCurrCommand ( ) ;
if ( command ! = NULL & & command - > getCommandType ( ) ! = NULL ) {
commandDesc = command - > getCommandType ( ) - > toString ( ) ;
}
2011-02-12 00:32:24 +01:00
2011-02-23 08:03:38 +01:00
char szBuf [ 1024 ] = " " ;
sprintf ( szBuf , " State: moving, cmd [%s] pos: %s dest pos: %s, Queue= %d " , commandDesc . c_str ( ) , unit - > getPos ( ) . getString ( ) . c_str ( ) , targetPos . getString ( ) . c_str ( ) , path - > getQueueCount ( ) ) ;
unit - > setCurrentUnitTitle ( szBuf ) ;
2011-02-12 00:32:24 +01:00
}
2011-02-23 08:03:38 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled = = true & & chrono . getMillis ( ) > 4 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2011-02-12 00:32:24 +01:00
2011-04-14 04:51:13 +02:00
unit - > setUsePathfinderExtendedMaxNodes ( false ) ;
2011-02-23 08:03:38 +01:00
return ts ;
}
2011-02-12 00:32:24 +01:00
}
2011-02-23 08:03:38 +01:00
pos1 = pos2 ;
2011-02-12 00:32:24 +01:00
}
2011-02-23 08:03:38 +01:00
break ;
2011-02-12 00:32:24 +01:00
}
}
}
}
}
2010-07-11 20:31:02 +02:00
//path find algorithm
//a) push starting pos into openNodes
2011-04-14 04:51:13 +02:00
Node * firstNode = newNode ( factions [ unit - > getFactionIndex ( ) ] , maxNodeCount ) ;
2010-10-17 08:34:42 +02:00
assert ( firstNode ! = NULL ) ;
if ( firstNode = = NULL ) {
throw runtime_error ( " firstNode == NULL " ) ;
}
2010-07-11 20:31:02 +02:00
firstNode - > next = NULL ;
firstNode - > prev = NULL ;
2010-09-07 23:01:22 +02:00
firstNode - > pos = unitPos ;
firstNode - > heuristic = heuristic ( unitPos , finalPos ) ;
2010-07-11 20:31:02 +02:00
firstNode - > exploredCell = true ;
2011-03-18 04:53:06 +01:00
if ( factions [ unit - > getFactionIndex ( ) ] . openNodesList . find ( firstNode - > heuristic ) = = factions [ unit - > getFactionIndex ( ) ] . openNodesList . end ( ) ) {
factions [ unit - > getFactionIndex ( ) ] . openNodesList [ firstNode - > heuristic ] . clear ( ) ;
2011-02-16 20:44:12 +01:00
}
2011-03-18 04:53:06 +01:00
factions [ unit - > getFactionIndex ( ) ] . openNodesList [ firstNode - > heuristic ] . push_back ( firstNode ) ;
factions [ unit - > getFactionIndex ( ) ] . openPosList [ firstNode - > pos ] = true ;
2010-07-11 20:31:02 +02:00
//b) loop
2010-11-09 10:06:52 +01:00
bool pathFound = true ;
bool nodeLimitReached = false ;
Node * node = NULL ;
2010-08-22 22:13:30 +02:00
2011-02-04 07:34:32 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled = = true & & chrono . getMillis ( ) > 4 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-12-05 00:19:43 +01:00
2011-03-29 18:27:01 +02:00
// First check if unit currently blocked all around them, if so don't try to pathfind
2011-02-25 17:32:27 +01:00
if ( inBailout = = false & & unitPos ! = finalPos ) {
int failureCount = 0 ;
int cellCount = 0 ;
for ( int i = - 1 ; i < = 1 ; + + i ) {
for ( int j = - 1 ; j < = 1 ; + + j ) {
Vec2i pos = unitPos + Vec2i ( i , j ) ;
if ( pos ! = unitPos ) {
bool canUnitMoveToCell = map - > aproxCanMove ( unit , unitPos , pos ) ;
if ( canUnitMoveToCell = = false ) {
failureCount + + ;
}
cellCount + + ;
}
}
}
nodeLimitReached = ( failureCount = = cellCount ) ;
pathFound = ! nodeLimitReached ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled = = true & & chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] **Check if dest blocked, distance for unit [%d - %s] from [%s] to [%s] is %.2f took msecs: %lld nodeLimitReached = %d, failureCount = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , unit - > getId ( ) , unit - > getFullName ( ) . c_str ( ) , unitPos . getString ( ) . c_str ( ) , finalPos . getString ( ) . c_str ( ) , dist , ( long long int ) chrono . getMillis ( ) , nodeLimitReached , failureCount ) ;
if ( showConsoleDebugInfo & & nodeLimitReached ) {
printf ( " **Check if src blocked [%d - %d], unit [%d - %s] from [%s] to [%s] distance %.2f took msecs: %lld nodeLimitReached = %d, failureCount = %d [%d] \n " ,
nodeLimitReached , inBailout , unit - > getId ( ) , unit - > getFullName ( ) . c_str ( ) , unitPos . getString ( ) . c_str ( ) , finalPos . getString ( ) . c_str ( ) , dist , ( long long int ) chrono . getMillis ( ) , nodeLimitReached , failureCount , cellCount ) ;
}
if ( nodeLimitReached = = false ) {
// First check if final destination blocked
failureCount = 0 ;
cellCount = 0 ;
for ( int i = - 1 ; i < = 1 ; + + i ) {
for ( int j = - 1 ; j < = 1 ; + + j ) {
Vec2i pos = finalPos + Vec2i ( i , j ) ;
if ( pos ! = finalPos ) {
bool canUnitMoveToCell = map - > aproxCanMove ( unit , pos , finalPos ) ;
if ( canUnitMoveToCell = = false ) {
failureCount + + ;
}
cellCount + + ;
}
}
}
nodeLimitReached = ( failureCount = = cellCount ) ;
pathFound = ! nodeLimitReached ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled = = true & & chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] **Check if dest blocked, distance for unit [%d - %s] from [%s] to [%s] is %.2f took msecs: %lld nodeLimitReached = %d, failureCount = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , unit - > getId ( ) , unit - > getFullName ( ) . c_str ( ) , unitPos . getString ( ) . c_str ( ) , finalPos . getString ( ) . c_str ( ) , dist , ( long long int ) chrono . getMillis ( ) , nodeLimitReached , failureCount ) ;
if ( showConsoleDebugInfo & & nodeLimitReached ) {
printf ( " **Check if dest blocked [%d - %d], unit [%d - %s] from [%s] to [%s] distance %.2f took msecs: %lld nodeLimitReached = %d, failureCount = %d [%d] \n " ,
nodeLimitReached , inBailout , unit - > getId ( ) , unit - > getFullName ( ) . c_str ( ) , unitPos . getString ( ) . c_str ( ) , finalPos . getString ( ) . c_str ( ) , dist , ( long long int ) chrono . getMillis ( ) , nodeLimitReached , failureCount , cellCount ) ;
}
}
}
//
2011-03-29 18:27:01 +02:00
// START
2011-04-04 06:32:01 +02:00
// Do the a-star base pathfind work if required
2010-10-26 08:43:42 +02:00
int whileLoopCount = 0 ;
2011-04-14 04:51:13 +02:00
if ( nodeLimitReached = = false ) {
while ( nodeLimitReached = = false ) {
whileLoopCount + + ;
//b1) is open nodes is empty => failed to find the path
if ( factions [ unit - > getFactionIndex ( ) ] . openNodesList . empty ( ) = = true ) {
//printf("$$$$ Path for Unit [%d - %s] inBailout = %d BLOCKED\n",unit->getId(),unit->getFullName().c_str(),inBailout);
pathFound = false ;
break ;
}
2010-07-11 20:31:02 +02:00
2011-04-14 04:51:13 +02:00
//b2) get the minimum heuristic node
//Nodes::iterator it = minHeuristic();
node = minHeuristicFastLookup ( factions [ unit - > getFactionIndex ( ) ] ) ;
2010-07-11 20:31:02 +02:00
2011-04-14 04:51:13 +02:00
//b3) if minHeuristic is the finalNode, or the path is no more explored => path was found
if ( node - > pos = = finalPos | | node - > exploredCell = = false ) {
pathFound = true ;
break ;
}
2010-07-11 20:31:02 +02:00
2011-04-14 04:51:13 +02:00
//printf("$$$$ Path for Unit [%d - %s] node [%s] whileLoopCount = %d nodePoolCount = %d inBailout = %d\n",unit->getId(),unit->getFullName().c_str(), node->pos.getString().c_str(), whileLoopCount,factions[unit->getFactionIndex()].nodePoolCount,inBailout);
2011-04-04 06:32:01 +02:00
2011-04-14 04:51:13 +02:00
//b4) move this node from closedNodes to openNodes
//add all succesors that are not in closedNodes or openNodes to openNodes
if ( factions [ unit - > getFactionIndex ( ) ] . closedNodesList . find ( node - > heuristic ) = = factions [ unit - > getFactionIndex ( ) ] . closedNodesList . end ( ) ) {
factions [ unit - > getFactionIndex ( ) ] . closedNodesList [ node - > heuristic ] . clear ( ) ;
}
factions [ unit - > getFactionIndex ( ) ] . closedNodesList [ node - > heuristic ] . push_back ( node ) ;
factions [ unit - > getFactionIndex ( ) ] . openPosList [ node - > pos ] = true ;
2010-10-26 08:43:42 +02:00
2011-04-14 04:51:13 +02:00
int failureCount = 0 ;
int cellCount = 0 ;
2011-02-23 08:03:38 +01:00
2011-04-14 04:51:13 +02:00
int tryDirection = factions [ unit - > getFactionIndex ( ) ] . random . randRange ( 0 , 3 ) ;
if ( tryDirection = = 3 ) {
for ( int i = 1 ; i > = - 1 & & nodeLimitReached = = false ; - - i ) {
for ( int j = - 1 ; j < = 1 & & nodeLimitReached = = false ; + + j ) {
if ( processNode ( unit , node , finalPos , i , j , nodeLimitReached , maxNodeCount ) = = false ) {
failureCount + + ;
}
cellCount + + ;
2011-02-23 08:03:38 +01:00
}
2011-02-04 07:34:32 +01:00
}
}
2011-04-14 04:51:13 +02:00
else if ( tryDirection = = 2 ) {
for ( int i = - 1 ; i < = 1 & & nodeLimitReached = = false ; + + i ) {
for ( int j = 1 ; j > = - 1 & & nodeLimitReached = = false ; - - j ) {
if ( processNode ( unit , node , finalPos , i , j , nodeLimitReached , maxNodeCount ) = = false ) {
failureCount + + ;
}
cellCount + + ;
2011-02-23 08:03:38 +01:00
}
2011-02-04 07:34:32 +01:00
}
}
2011-04-14 04:51:13 +02:00
else if ( tryDirection = = 1 ) {
for ( int i = - 1 ; i < = 1 & & nodeLimitReached = = false ; + + i ) {
for ( int j = - 1 ; j < = 1 & & nodeLimitReached = = false ; + + j ) {
if ( processNode ( unit , node , finalPos , i , j , nodeLimitReached , maxNodeCount ) = = false ) {
failureCount + + ;
}
cellCount + + ;
2011-02-23 08:03:38 +01:00
}
2011-01-28 09:58:16 +01:00
}
}
2011-04-14 04:51:13 +02:00
else {
for ( int i = 1 ; i > = - 1 & & nodeLimitReached = = false ; - - i ) {
for ( int j = 1 ; j > = - 1 & & nodeLimitReached = = false ; - - j ) {
if ( processNode ( unit , node , finalPos , i , j , nodeLimitReached , maxNodeCount ) = = false ) {
failureCount + + ;
}
cellCount + + ;
2011-02-23 08:03:38 +01:00
}
2010-07-11 20:31:02 +02:00
}
}
2011-04-14 04:51:13 +02:00
} //while
// Now see if the unit is eligble for pathfind max nodes boost?
if ( nodeLimitReached = = true & & maxNodeCount ! = pathFindNodesAbsoluteMax ) {
if ( unit - > isLastPathfindFailedFrameWithinCurrentFrameTolerance ( ) = = true ) {
if ( frameIndex < 0 ) {
unit - > setLastPathfindFailedFrameToCurrentFrame ( ) ;
unit - > setLastPathfindFailedPos ( finalPos ) ;
}
if ( showConsoleDebugInfo | | SystemFlags : : VERBOSE_MODE_ENABLED ) {
printf ( " \n \n \n \n $$$ Calling AStar with LARGE maxnodes for unit [%d - %s] \n \n " , unit - > getId ( ) , unit - > getFullName ( ) . c_str ( ) ) ;
}
return aStar ( unit , targetPos , false , frameIndex , pathFindNodesAbsoluteMax ) ;
}
2010-07-11 20:31:02 +02:00
}
2011-04-14 04:51:13 +02:00
}
2010-07-11 20:31:02 +02:00
2011-03-18 04:53:06 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled = = true & & chrono . getMillis ( ) > 1 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld nodeLimitReached = %d whileLoopCount = %d nodePoolCount = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) , nodeLimitReached , whileLoopCount , factions [ unit - > getFactionIndex ( ) ] . nodePoolCount ) ;
2011-02-23 08:03:38 +01:00
if ( showConsoleDebugInfo & & chrono . getMillis ( ) > 2 ) {
2011-03-18 04:53:06 +01:00
printf ( " Distance for unit [%d - %s] from [%s] to [%s] is %.2f took msecs: %lld nodeLimitReached = %d whileLoopCount = %d nodePoolCount = %d \n " , unit - > getId ( ) , unit - > getFullName ( ) . c_str ( ) , unitPos . getString ( ) . c_str ( ) , finalPos . getString ( ) . c_str ( ) , dist , ( long long int ) chrono . getMillis ( ) , nodeLimitReached , whileLoopCount , factions [ unit - > getFactionIndex ( ) ] . nodePoolCount ) ;
2011-02-23 08:03:38 +01:00
}
2010-12-05 00:19:43 +01:00
2010-07-11 20:31:02 +02:00
Node * lastNode = node ;
2010-08-25 09:29:35 +02:00
//if consumed all nodes find best node (to avoid strange behaviour)
2010-10-17 08:34:42 +02:00
if ( nodeLimitReached = = true ) {
2011-03-18 04:53:06 +01:00
if ( factions [ unit - > getFactionIndex ( ) ] . closedNodesList . size ( ) > 0 ) {
float bestHeuristic = factions [ unit - > getFactionIndex ( ) ] . closedNodesList . begin ( ) - > first ;
2010-10-26 08:43:42 +02:00
if ( bestHeuristic < lastNode - > heuristic ) {
2011-03-18 04:53:06 +01:00
lastNode = factions [ unit - > getFactionIndex ( ) ] . closedNodesList . begin ( ) - > second [ 0 ] ;
2010-10-26 08:43:42 +02:00
}
}
2010-07-11 20:31:02 +02:00
}
2011-02-04 07:34:32 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled = = true & & chrono . getMillis ( ) > 4 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-12-05 00:19:43 +01:00
2010-07-11 20:31:02 +02:00
//check results of path finding
2011-02-12 00:32:24 +01:00
ts = tsImpossible ;
2010-10-17 08:34:42 +02:00
if ( pathFound = = false | | lastNode = = firstNode ) {
2010-07-11 20:31:02 +02:00
//blocked
2010-10-17 08:34:42 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPathFinder ) . enabled = = true ) {
string commandDesc = " none " ;
Command * command = unit - > getCurrCommand ( ) ;
if ( command ! = NULL & & command - > getCommandType ( ) ! = NULL ) {
commandDesc = command - > getCommandType ( ) - > toString ( ) ;
}
2010-12-01 00:32:39 +01:00
std : : pair < Vec2i , int > lastHarvest = unit - > getLastHarvestResourceTarget ( ) ;
2010-10-17 10:50:27 +02:00
2010-10-17 08:34:42 +02:00
char szBuf [ 1024 ] = " " ;
2010-12-01 00:32:39 +01:00
sprintf ( szBuf , " State: blocked, cmd [%s] pos: [%s], dest pos: [%s], lastHarvest = [%s - %d], reason A= %d, B= %d, C= %d, D= %d, E= %d, F = %d " , commandDesc . c_str ( ) , unit - > getPos ( ) . getString ( ) . c_str ( ) , targetPos . getString ( ) . c_str ( ) , lastHarvest . first . getString ( ) . c_str ( ) , lastHarvest . second , pathFound , ( lastNode = = firstNode ) , path - > getBlockCount ( ) , path - > isBlocked ( ) , nodeLimitReached , path - > isStuck ( ) ) ;
2010-10-17 08:34:42 +02:00
unit - > setCurrentUnitTitle ( szBuf ) ;
}
2011-04-14 04:51:13 +02:00
if ( frameIndex < 0 ) {
unit - > setUsePathfinderExtendedMaxNodes ( false ) ;
}
2010-07-11 20:31:02 +02:00
ts = tsBlocked ;
2011-03-18 04:53:06 +01:00
if ( frameIndex < 0 ) {
path - > incBlockCount ( ) ;
}
2010-12-01 00:32:39 +01:00
2011-04-03 04:42:45 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
2010-12-01 00:32:39 +01:00
char szBuf [ 4096 ] = " " ;
2011-03-01 00:33:11 +01:00
sprintf ( szBuf , " [path for unit BLOCKED] openNodesList.size() [%lu] openPosList.size() [%lu] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d] " ,
2011-03-18 04:53:06 +01:00
factions [ unit - > getFactionIndex ( ) ] . openNodesList . size ( ) , factions [ unit - > getFactionIndex ( ) ] . openPosList . size ( ) , finalPos . getString ( ) . c_str ( ) , targetPos . getString ( ) . c_str ( ) , inBailout , ts ) ;
2010-12-02 00:38:03 +01:00
unit - > logSynchData ( __FILE__ , __LINE__ , szBuf ) ;
2010-12-01 00:32:39 +01:00
}
2010-12-05 00:19:43 +01:00
2011-02-04 07:34:32 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled = = true & & chrono . getMillis ( ) > 4 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-07-11 20:31:02 +02:00
}
else {
//on the way
2010-07-22 00:05:50 +02:00
ts = tsMoving ;
2010-07-11 20:31:02 +02:00
//build next pointers
Node * currNode = lastNode ;
2010-10-17 08:34:42 +02:00
while ( currNode - > prev ! = NULL ) {
2010-07-11 20:31:02 +02:00
currNode - > prev - > next = currNode ;
currNode = currNode - > prev ;
}
2010-12-05 00:19:43 +01:00
2011-02-04 07:34:32 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled = = true & & chrono . getMillis ( ) > 4 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-12-05 00:19:43 +01:00
2011-04-14 04:51:13 +02:00
if ( frameIndex < 0 ) {
if ( maxNodeCount = = pathFindNodesAbsoluteMax ) {
unit - > setUsePathfinderExtendedMaxNodes ( true ) ;
}
else {
unit - > setUsePathfinderExtendedMaxNodes ( false ) ;
}
}
2010-07-11 20:31:02 +02:00
//store path
2011-03-18 04:53:06 +01:00
if ( frameIndex < 0 ) {
path - > clear ( ) ;
}
2011-02-12 00:32:24 +01:00
UnitPathBasic * basicPathFinder = dynamic_cast < UnitPathBasic * > ( path ) ;
2010-07-11 20:31:02 +02:00
currNode = firstNode ;
2011-02-12 00:32:24 +01:00
for ( int i = 0 ; currNode - > next ! = NULL ; currNode = currNode - > next , i + + ) {
2011-02-23 08:03:38 +01:00
Vec2i nodePos = currNode - > next - > pos ;
if ( map - > isInside ( nodePos ) = = false | | map - > isInsideSurface ( map - > toSurfCoords ( nodePos ) ) = = false ) {
throw runtime_error ( " Pathfinder invalid node path position = " + nodePos . getString ( ) + " i = " + intToStr ( i ) ) ;
}
2011-03-18 04:53:06 +01:00
if ( frameIndex > = 0 ) {
factions [ unit - > getFactionIndex ( ) ] . precachedPath [ unit - > getId ( ) ] . push_back ( nodePos ) ;
2011-02-23 08:03:38 +01:00
}
2011-03-18 04:53:06 +01:00
else {
2011-04-26 23:51:18 +02:00
if ( i < pathFindRefresh | |
2011-06-24 21:40:47 +02:00
( whileLoopCount > = pathFindExtendRefreshForNodeCount & &
i < getPathFindExtendRefreshNodeCount ( unit - > getFactionIndex ( ) ) ) ) {
2011-03-18 04:53:06 +01:00
path - > add ( nodePos ) ;
}
2011-04-18 18:51:30 +02:00
//else if(tryLastPathCache == false) {
// break;
//}
2011-02-23 08:03:38 +01:00
2011-04-18 18:51:30 +02:00
//if(tryLastPathCache == true && basicPathFinder) {
if ( basicPathFinder ) {
2011-03-18 04:53:06 +01:00
basicPathFinder - > addToLastPathCache ( nodePos ) ;
}
2011-02-12 00:32:24 +01:00
}
2010-07-11 20:31:02 +02:00
}
2010-10-17 08:34:42 +02:00
2011-02-04 07:34:32 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled = = true & & chrono . getMillis ( ) > 4 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-12-05 00:19:43 +01:00
2011-04-03 04:42:45 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
2010-12-01 00:32:39 +01:00
char szBuf [ 4096 ] = " " ;
2011-03-01 00:33:11 +01:00
sprintf ( szBuf , " [Setting new path for unit] openNodesList.size() [%lu] openPosList.size() [%lu] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d] " ,
2011-03-18 04:53:06 +01:00
factions [ unit - > getFactionIndex ( ) ] . openNodesList . size ( ) , factions [ unit - > getFactionIndex ( ) ] . openPosList . size ( ) , finalPos . getString ( ) . c_str ( ) , targetPos . getString ( ) . c_str ( ) , inBailout , ts ) ;
2010-12-02 00:38:03 +01:00
unit - > logSynchData ( __FILE__ , __LINE__ , szBuf ) ;
2011-02-16 20:44:12 +01:00
string pathToTake = " " ;
for ( int i = 0 ; i < path - > getQueueCount ( ) ; + + i ) {
Vec2i & pos = path - > getQueue ( ) [ i ] ;
if ( pathToTake ! = " " ) {
pathToTake + = " , " ;
}
pathToTake + = pos . getString ( ) ;
}
unit - > logSynchData ( __FILE__ , __LINE__ , szBuf ) ;
sprintf ( szBuf , " Path for unit to take = %s " , pathToTake . c_str ( ) ) ;
2010-12-01 00:32:39 +01:00
}
2010-10-17 08:34:42 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPathFinder ) . enabled = = true ) {
string commandDesc = " none " ;
Command * command = unit - > getCurrCommand ( ) ;
if ( command ! = NULL & & command - > getCommandType ( ) ! = NULL ) {
commandDesc = command - > getCommandType ( ) - > toString ( ) ;
}
char szBuf [ 1024 ] = " " ;
sprintf ( szBuf , " State: moving, cmd [%s] pos: %s dest pos: %s, Queue= %d " , commandDesc . c_str ( ) , unit - > getPos ( ) . getString ( ) . c_str ( ) , targetPos . getString ( ) . c_str ( ) , path - > getQueueCount ( ) ) ;
unit - > setCurrentUnitTitle ( szBuf ) ;
}
2010-12-05 00:19:43 +01:00
2011-02-04 07:34:32 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled = = true & & chrono . getMillis ( ) > 4 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s Line: %d] took msecs: %lld \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-07-11 20:31:02 +02:00
}
2011-03-18 04:53:06 +01:00
factions [ unit - > getFactionIndex ( ) ] . openNodesList . clear ( ) ;
factions [ unit - > getFactionIndex ( ) ] . openPosList . clear ( ) ;
factions [ unit - > getFactionIndex ( ) ] . closedNodesList . clear ( ) ;
2010-07-11 20:31:02 +02:00
2011-02-04 07:34:32 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugPerformance ) . enabled = = true & & chrono . getMillis ( ) > 4 ) SystemFlags : : OutputDebug ( SystemFlags : : debugPerformance , " In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] --------------------------- \n " , __FILE__ , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-12-05 00:19:43 +01:00
2011-03-18 04:53:06 +01:00
if ( frameIndex > = 0 ) {
factions [ unit - > getFactionIndex ( ) ] . precachedTravelState [ unit - > getId ( ) ] = ts ;
}
else {
if ( SystemFlags : : VERBOSE_MODE_ENABLED & & chrono . getMillis ( ) > = 5 ) printf ( " In [%s::%s Line: %d] astar took [%lld] msecs, ts = %d. \n " , __FILE__ , __FUNCTION__ , __LINE__ , ( long long int ) chrono . getMillis ( ) , ts ) ;
}
2011-04-04 06:32:01 +02:00
//printf("$$$$ Path for Unit [%d - %s] return value = %d inBailout = %d\n",unit->getId(),unit->getFullName().c_str(),ts,inBailout);
2010-07-11 20:31:02 +02:00
return ts ;
}
2011-04-14 04:51:13 +02:00
PathFinder : : Node * PathFinder : : newNode ( FactionState & faction , int maxNodeCount ) {
2011-03-18 04:53:06 +01:00
if ( faction . nodePoolCount < faction . nodePool . size ( ) & &
2011-04-14 04:51:13 +02:00
//faction.nodePoolCount < faction.useMaxNodeCount) {
faction . nodePoolCount < maxNodeCount ) {
2011-03-18 04:53:06 +01:00
Node * node = & ( faction . nodePool [ faction . nodePoolCount ] ) ;
2011-02-16 20:44:12 +01:00
node - > clear ( ) ;
2011-03-18 04:53:06 +01:00
faction . nodePoolCount + + ;
2010-07-11 20:31:02 +02:00
return node ;
}
return NULL ;
}
2011-02-04 07:34:32 +01:00
void PathFinder : : processNearestFreePos ( const Vec2i & finalPos , int i , int j , int size , Field field , int teamIndex , Vec2i unitPos , Vec2i & nearestPos , float & nearestDist ) {
Vec2i currPos = finalPos + Vec2i ( i , j ) ;
if ( map - > isAproxFreeCells ( currPos , size , field , teamIndex ) ) {
float dist = currPos . dist ( finalPos ) ;
//if nearer from finalPos
if ( dist < nearestDist ) {
nearestPos = currPos ;
nearestDist = dist ;
}
//if the distance is the same compare distance to unit
else if ( dist = = nearestDist ) {
if ( currPos . dist ( unitPos ) < nearestPos . dist ( unitPos ) ) {
nearestPos = currPos ;
}
}
}
}
2010-10-17 08:34:42 +02:00
Vec2i PathFinder : : computeNearestFreePos ( const Unit * unit , const Vec2i & finalPos ) {
2010-09-07 23:01:22 +02:00
if ( map = = NULL ) {
throw runtime_error ( " map == NULL " ) ;
}
2010-07-11 20:31:02 +02:00
//unit data
int size = unit - > getType ( ) - > getSize ( ) ;
Field field = unit - > getCurrField ( ) ;
int teamIndex = unit - > getTeam ( ) ;
//if finalPos is free return it
2010-10-17 08:34:42 +02:00
if ( map - > isAproxFreeCells ( finalPos , size , field , teamIndex ) ) {
2010-07-11 20:31:02 +02:00
return finalPos ;
}
//find nearest pos
2010-10-17 08:34:42 +02:00
Vec2i unitPos = unit - > getPos ( ) ;
2010-07-11 20:31:02 +02:00
Vec2i nearestPos = unitPos ;
float nearestDist = unitPos . dist ( finalPos ) ;
2011-02-04 07:34:32 +01:00
2010-10-17 08:34:42 +02:00
for ( int i = - maxFreeSearchRadius ; i < = maxFreeSearchRadius ; + + i ) {
for ( int j = - maxFreeSearchRadius ; j < = maxFreeSearchRadius ; + + j ) {
2011-02-04 07:34:32 +01:00
processNearestFreePos ( finalPos , i , j , size , field , teamIndex , unitPos , nearestPos , nearestDist ) ;
2010-07-11 20:31:02 +02:00
}
}
return nearestPos ;
}
2010-10-17 08:34:42 +02:00
float PathFinder : : heuristic ( const Vec2i & pos , const Vec2i & finalPos ) {
2010-07-11 20:31:02 +02:00
return pos . dist ( finalPos ) ;
}
2011-03-18 04:53:06 +01:00
PathFinder : : Node * PathFinder : : minHeuristicFastLookup ( FactionState & faction ) {
assert ( faction . openNodesList . empty ( ) = = false ) ;
if ( faction . openNodesList . empty ( ) = = true ) {
2010-10-26 08:43:42 +02:00
throw runtime_error ( " openNodesList.empty() = = true " ) ;
}
2011-03-18 04:53:06 +01:00
Node * result = faction . openNodesList . begin ( ) - > second [ 0 ] ;
faction . openNodesList . begin ( ) - > second . erase ( faction . openNodesList . begin ( ) - > second . begin ( ) ) ;
if ( faction . openNodesList . begin ( ) - > second . size ( ) = = 0 ) {
faction . openNodesList . erase ( faction . openNodesList . begin ( ) ) ;
2010-10-26 08:43:42 +02:00
}
return result ;
}
2011-03-18 04:53:06 +01:00
bool PathFinder : : openPos ( const Vec2i & sucPos , FactionState & faction ) {
if ( faction . openPosList . find ( sucPos ) = = faction . openPosList . end ( ) ) {
2010-10-26 08:43:42 +02:00
return false ;
}
return true ;
2010-07-11 20:31:02 +02:00
}
} } //end namespace