2010-07-11 20:31:02 +02:00
// This file is part of Glest (www.glest.org)
//
2011-12-14 08:40:48 +01:00
// Copyright (C) 2001-2008 Martiño 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-09-24 22:30:41 +02:00
int PathFinder : : pathFindNodesMax = 2000 ;
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 ( ) {
2012-05-04 16:57:59 +02:00
minorDebugPathfinder = false ;
2011-03-18 04:53:06 +01:00
for ( int i = 0 ; i < GameConstants : : maxPlayers ; + + i ) {
factions . push_back ( FactionState ( ) ) ;
2012-05-04 16:57:59 +02:00
//factions.resize(GameConstants::maxPlayers);
2011-03-18 04:53:06 +01:00
}
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 ) {
2012-05-04 16:57:59 +02:00
minorDebugPathfinder = false ;
2011-03-18 04:53:06 +01:00
for ( int i = 0 ; i < GameConstants : : maxPlayers ; + + i ) {
factions . push_back ( FactionState ( ) ) ;
2012-05-04 16:57:59 +02:00
//factions.resize(GameConstants::maxPlayers);
2011-03-18 04:53:06 +01:00
}
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 ( ) ;
}
2011-09-27 19:15:56 +02:00
factions . 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 ( ) ;
2012-04-13 22:20:40 +02:00
factions [ unit - > getFactionIndex ( ) ] . badCellList . clear ( ) ;
2011-03-18 04:53:06 +01:00
}
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 ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " map == NULL " ) ;
2010-09-07 23:01:22 +02:00
}
2012-03-31 21:50:45 +02:00
2012-05-04 16:57:59 +02:00
unit - > setCurrentPathFinderDesiredFinalPos ( finalPos ) ;
2012-05-10 01:56:14 +02:00
//printf("Unit Pathfind Unit [%d - %s] from = %s to = %s frameIndex = %d\n",unit->getId(),unit->getType()->getName().c_str(),unit->getPos().getString().c_str(),finalPos.getString().c_str(),frameIndex);
2011-03-18 04:53:06 +01:00
if ( frameIndex > = 0 ) {
clearUnitPrecache ( unit ) ;
}
2012-05-10 01:56:14 +02:00
//else {
2012-03-31 21:50:45 +02:00
if ( unit - > getFaction ( ) - > canUnitsPathfind ( ) = = true ) {
unit - > getFaction ( ) - > addUnitToPathfindingList ( unit - > getId ( ) ) ;
}
else {
return tsBlocked ;
}
2012-05-10 01:56:14 +02:00
//}
2010-11-09 10:06:52 +01:00
2011-10-05 23:46:41 +02:00
// if(frameIndex != factions[unit->getFactionIndex()].lastFromToNodeListFrame) {
// if(factions[unit->getFactionIndex()].mapFromToNodeList.size() > 0) {
2012-11-10 07:37:23 +01:00
// printf("clear duplicate list = " MG_SIZE_T_SPECIFIER " for faction = %d frameIndex = %d\n",factions[unit->getFactionIndex()].mapFromToNodeList.size(),unit->getFactionIndex(),frameIndex);
2011-10-05 23:46:41 +02:00
// factions[unit->getFactionIndex()].mapFromToNodeList.clear();
// }
// factions[unit->getFactionIndex()].lastFromToNodeListFrame = frameIndex;
// }
2011-04-03 04:42:45 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " [findPath] unit->getPos() [%s] finalPos [%s] " ,
2010-12-02 00:38:03 +01:00
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 ( ) ;
}
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " State: arrived#1 at pos: %s, command [%s] " , finalPos . getString ( ) . c_str ( ) , commandDesc . c_str ( ) ) ;
2010-10-17 08:34:42 +02:00
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 {
2012-04-14 23:21:09 +02:00
throw megaglest_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 ;
}
2012-09-22 22:37:42 +02:00
//int unitFactionIndex = unit->getFactionIndex();
2010-07-11 20:31:02 +02:00
2012-05-04 23:03:52 +02:00
bool minorDebugPathfinderPerformance = false ;
Chrono chrono ;
//if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
if ( minorDebugPathfinderPerformance ) chrono . start ( ) ;
uint32 searched_node_count = 0 ;
2012-05-04 16:57:59 +02:00
minorDebugPathfinder = false ;
2012-09-22 23:05:06 +02:00
if ( minorDebugPathfinder ) printf ( " Legacy Pathfind Unit [%d - %s] from = %s to = %s frameIndex = %d \n " , unit - > getId ( ) , unit - > getType ( ) - > getName ( ) . c_str ( ) , unit - > getPos ( ) . getString ( ) . c_str ( ) , finalPos . getString ( ) . c_str ( ) , frameIndex ) ;
2010-12-01 00:32:39 +01:00
2012-09-22 23:05:06 +02:00
ts = aStar ( unit , finalPos , false , frameIndex , maxNodeCount , & searched_node_count ) ;
2012-05-04 16:57:59 +02:00
2012-05-04 18:48:14 +02:00
//post actions
switch ( ts ) {
case tsBlocked :
case tsArrived :
// 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 ) {
//printf("$$$$ Unit START BAILOUT ATTEMPT for [%d - %s]\n",unit->getId(),unit->getFullName().c_str());
if ( minorDebugPathfinder ) printf ( " Pathfind Unit [%d - %s] START BAILOUT ATTEMPT frameIndex = %d \n " , unit - > getId ( ) , unit - > getType ( ) - > getName ( ) . c_str ( ) , frameIndex ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " [attempting to BAIL OUT] finalPos [%s] ts [%d] " ,
2012-05-04 18:48:14 +02:00
finalPos . getString ( ) . c_str ( ) , ts ) ;
unit - > logSynchData ( __FILE__ , __LINE__ , szBuf ) ;
}
2012-05-04 16:57:59 +02:00
2012-05-04 18:48:14 +02:00
if ( wasStuck ! = NULL ) {
* wasStuck = true ;
}
unit - > setInBailOutAttempt ( true ) ;
bool useBailoutRadius = Config : : getInstance ( ) . getBool ( " EnableBailoutPathfinding " , " true " ) ;
if ( useBailoutRadius = = true ) {
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 + + ;
2012-05-04 16:57:59 +02:00
}
2012-05-04 18:48:14 +02:00
cellCount + + ;
2012-05-04 16:57:59 +02:00
}
}
2012-05-04 18:48:14 +02:00
}
unitImmediatelyBlocked = ( failureCount = = cellCount ) ;
2012-05-04 16:57:59 +02:00
2012-05-04 18:48:14 +02:00
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 ) ;
}
2012-05-04 16:57:59 +02:00
2012-05-04 18:48:14 +02:00
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 ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " [attempting to BAIL OUT] finalPos [%s] newFinalPos [%s] ts [%d] canUnitMove [%d] " ,
2012-05-04 18:48:14 +02:00
finalPos . getString ( ) . c_str ( ) , newFinalPos . getString ( ) . c_str ( ) , ts , canUnitMove ) ;
unit - > logSynchData ( __FILE__ , __LINE__ , szBuf ) ;
}
2012-05-04 16:57:59 +02:00
2012-05-04 18:48:14 +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());
2012-05-04 16:57:59 +02:00
2012-05-04 18:48:14 +02:00
int maxBailoutNodeCount = ( PathFinder : : pathFindBailoutRadius * 2 ) ;
2012-09-22 23:05:06 +02:00
ts = aStar ( unit , newFinalPos , true , frameIndex , maxBailoutNodeCount , & searched_node_count ) ;
2012-05-04 16:57:59 +02:00
}
}
}
2012-05-04 18:48:14 +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 ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " [attempting to BAIL OUT] finalPos [%s] newFinalPos [%s] ts [%d] canUnitMove [%d] " ,
2012-05-04 18:48:14 +02:00
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());
int maxBailoutNodeCount = ( PathFinder : : pathFindBailoutRadius * 2 ) ;
2012-05-04 16:57:59 +02:00
2012-09-22 23:05:06 +02:00
ts = aStar ( unit , newFinalPos , true , frameIndex , maxBailoutNodeCount , & searched_node_count ) ;
2012-05-04 16:57:59 +02:00
}
}
2011-01-28 08:17:32 +01:00
}
}
}
2012-05-04 18:48:14 +02:00
}
unit - > setInBailOutAttempt ( false ) ;
2012-05-04 16:57:59 +02:00
2012-05-04 18:48:14 +02:00
//printf("$$$$ Unit END BAILOUT ATTEMPT for [%d - %s] ts = %d\n",unit->getId(),unit->getFullName().c_str(),ts);
2011-04-14 04:51:13 +02:00
2012-05-04 18:48:14 +02:00
if ( ts = = tsBlocked ) {
unit - > setLastStuckFrameToCurrentFrame ( ) ;
unit - > setLastStuckPos ( finalPos ) ;
2011-04-14 04:51:13 +02:00
}
2012-05-04 18:48:14 +02:00
}
if ( ts = = tsArrived | | ts = = tsBlocked ) {
if ( frameIndex < 0 ) {
unit - > setCurrSkill ( scStop ) ;
}
}
break ;
case tsMoving :
{
if ( dynamic_cast < UnitPathBasic * > ( path ) ! = NULL ) {
UnitPathBasic * basicPath = dynamic_cast < UnitPathBasic * > ( path ) ;
Vec2i pos ;
2012-05-04 16:57:59 +02:00
if ( frameIndex < 0 ) {
2012-05-04 18:48:14 +02:00
pos = basicPath - > pop ( frameIndex < 0 ) ;
2012-05-04 16:57:59 +02:00
}
2012-05-04 18:48:14 +02:00
else {
if ( factions [ unit - > getFactionIndex ( ) ] . precachedPath [ unit - > getId ( ) ] . size ( ) < = 0 ) {
throw megaglest_runtime_error ( " factions[unit->getFactionIndex() ] . precachedPath [ unit - > getId ( ) ] . size ( ) < = 0 ! " ) ;
2012-05-04 16:57:59 +02:00
}
2011-04-14 04:51:13 +02:00
2012-05-04 18:48:14 +02:00
pos = factions [ unit - > getFactionIndex ( ) ] . precachedPath [ unit - > getId ( ) ] [ 0 ] ;
}
2011-04-14 04:51:13 +02:00
2012-05-04 18:48:14 +02:00
if ( map - > canMove ( unit , unit - > getPos ( ) , pos ) ) {
if ( frameIndex < 0 ) {
unit - > setTargetPos ( pos ) ;
2012-05-04 16:57:59 +02:00
}
}
2012-05-04 18:48:14 +02:00
else {
if ( frameIndex < 0 ) {
unit - > setCurrSkill ( scStop ) ;
2011-04-14 04:51:13 +02:00
}
2012-05-04 23:03:52 +02:00
if ( minorDebugPathfinderPerformance & & chrono . getMillis ( ) > = 1 ) printf ( " Unit [%d - %s] astar #2 took [%lld] msecs, ts = %d searched_node_count = %d. \n " , unit - > getId ( ) , unit - > getType ( ) - > getName ( ) . c_str ( ) , ( long long int ) chrono . getMillis ( ) , ts , searched_node_count ) ;
2012-05-04 18:48:14 +02:00
return tsBlocked ;
}
}
else if ( dynamic_cast < UnitPath * > ( path ) ! = NULL ) {
UnitPath * advPath = dynamic_cast < UnitPath * > ( path ) ;
Vec2i pos = advPath - > peek ( ) ;
if ( map - > canMove ( unit , unit - > getPos ( ) , pos ) ) {
if ( frameIndex < 0 ) {
advPath - > pop ( ) ;
unit - > setTargetPos ( pos ) ;
2012-05-04 16:57:59 +02:00
}
2011-04-14 04:51:13 +02:00
}
else {
2012-05-04 18:48:14 +02:00
if ( frameIndex < 0 ) {
unit - > setCurrSkill ( scStop ) ;
}
if ( minorDebugPathfinder ) printf ( " Pathfind Unit [%d - %s] INT BAILOUT ATTEMPT BLOCKED frameIndex = %d \n " , unit - > getId ( ) , unit - > getType ( ) - > getName ( ) . c_str ( ) , frameIndex ) ;
2012-05-04 23:03:52 +02:00
if ( minorDebugPathfinderPerformance & & chrono . getMillis ( ) > = 1 ) printf ( " Unit [%d - %s] astar #3 took [%lld] msecs, ts = %d searched_node_count = %d. \n " , unit - > getId ( ) , unit - > getType ( ) - > getName ( ) . c_str ( ) , ( long long int ) chrono . getMillis ( ) , ts , searched_node_count ) ;
2012-05-04 18:48:14 +02:00
return tsBlocked ;
2012-05-04 16:57:59 +02:00
}
}
2012-05-04 18:48:14 +02:00
else {
throw megaglest_runtime_error ( " unsupported or missing path finder detected! " ) ;
}
}
break ;
}
2012-05-04 23:03:52 +02:00
if ( minorDebugPathfinderPerformance & & chrono . getMillis ( ) > = 1 ) printf ( " Unit [%d - %s] astar took [%lld] msecs, ts = %d searched_node_count = %d. \n " , unit - > getId ( ) , unit - > getType ( ) - > getName ( ) . c_str ( ) , ( long long int ) chrono . getMillis ( ) , ts , searched_node_count ) ;
2012-05-04 18:48:14 +02:00
return ts ;
}
// ==================== PRIVATE ====================
2012-05-04 16:57:59 +02:00
2011-09-27 01:55:18 +02:00
bool PathFinder : : addToOpenSet ( Unit * unit , Node * node , const Vec2i finalPos , Vec2i sucPos , bool & nodeLimitReached , int maxNodeCount , Node * * newNodeAdded , bool bypassChecks ) {
bool result = false ;
* newNodeAdded = NULL ;
//Vec2i sucPos= node->pos + Vec2i(i, j);
if ( bypassChecks = = true | |
2012-04-13 22:20:40 +02:00
( canUnitMoveSoon ( unit , node - > pos , sucPos ) = = true & & openPos ( sucPos , factions [ unit - > getFactionIndex ( ) ] ) = = false ) ) {
2011-09-27 01:55:18 +02:00
//if node is not open and canMove then generate another node
Node * sucNode = newNode ( factions [ unit - > getFactionIndex ( ) ] , maxNodeCount ) ;
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 ( ) ) ;
if ( factions [ unit - > getFactionIndex ( ) ] . openNodesList . find ( sucNode - > heuristic ) = = factions [ unit - > getFactionIndex ( ) ] . openNodesList . end ( ) ) {
factions [ unit - > getFactionIndex ( ) ] . openNodesList [ sucNode - > heuristic ] . clear ( ) ;
}
factions [ unit - > getFactionIndex ( ) ] . openNodesList [ sucNode - > heuristic ] . push_back ( sucNode ) ;
factions [ unit - > getFactionIndex ( ) ] . openPosList [ sucNode - > pos ] = true ;
* newNodeAdded = sucNode ;
result = true ;
}
else {
nodeLimitReached = true ;
}
}
return result ;
}
2011-12-02 17:07:59 +01:00
direction PathFinder : : directionOfMove ( Vec2i to , Vec2i from ) const {
2011-09-27 01:55:18 +02:00
if ( from . x = = to . x ) {
if ( from . y = = to . y )
return - 1 ;
else if ( from . y < to . y )
return 4 ;
else // from.y > to.y
return 0 ;
}
else if ( from . x < to . x ) {
if ( from . y = = to . y )
return 2 ;
else if ( from . y < to . y )
return 3 ;
else // from.y > to.y
return 1 ;
}
else { // from.x > to.x
if ( from . y = = to . y )
return 6 ;
else if ( from . y < to . y )
return 5 ;
else // from.y > to.y
return 7 ;
}
}
2011-12-02 18:46:02 +01:00
direction PathFinder : : directionWeCameFrom ( Vec2i node , Vec2i nodeFrom ) const {
2011-09-27 01:55:18 +02:00
direction result = NO_DIRECTION ;
if ( nodeFrom . x > = 0 & & nodeFrom . y > = 0 ) {
result = directionOfMove ( node , nodeFrom ) ;
}
//printf("directionWeCameFrom node [%s] nodeFrom [%s] result = %d\n",node.getString().c_str(),nodeFrom.getString().c_str(),result);
return result ;
}
// is this coordinate contained within the map bounds?
bool PathFinder : : contained ( Vec2i c ) {
return ( map - > isInside ( c ) = = true & & map - > isInsideSurface ( map - > toSurfCoords ( c ) ) = = true ) ;
}
// is this coordinate within the map bounds, and also walkable?
bool PathFinder : : isEnterable ( Vec2i coord ) {
//node node = getIndex (astar->bounds, coord);
//return contained(coord) && astar->grid[node];
return contained ( coord ) ;
}
// the coordinate one tile in the given direction
Vec2i PathFinder : : adjustInDirection ( Vec2i c , int dir ) {
// we want to implement "rotation" - that is, for instance, we can
// subtract 2 from the direction "north" and get "east"
// C's modulo operator doesn't quite behave the right way to do this,
// but for our purposes this kluge should be good enough
switch ( ( dir + 65536 ) % 8 ) {
2011-09-27 02:17:15 +02:00
case 0 : return Vec2i ( c . x , c . y - 1 ) ;
case 1 : return Vec2i ( c . x + 1 , c . y - 1 ) ;
case 2 : return Vec2i ( c . x + 1 , c . y ) ;
case 3 : return Vec2i ( c . x + 1 , c . y + 1 ) ;
case 4 : return Vec2i ( c . x , c . y + 1 ) ;
case 5 : return Vec2i ( c . x - 1 , c . y + 1 ) ;
case 6 : return Vec2i ( c . x - 1 , c . y ) ;
case 7 : return Vec2i ( c . x - 1 , c . y - 1 ) ;
2011-09-27 01:55:18 +02:00
}
2011-09-27 02:17:15 +02:00
return Vec2i ( - 1 , - 1 ) ;
2011-09-27 01:55:18 +02:00
}
2011-12-02 17:07:59 +01:00
bool PathFinder : : directionIsDiagonal ( direction dir ) const {
2011-09-27 01:55:18 +02:00
return ( dir % 2 ) ! = 0 ;
}
// logical implication operator
2011-12-02 17:07:59 +01:00
bool PathFinder : : implies ( bool a , bool b ) const {
2011-09-27 01:55:18 +02:00
return a ? b : true ;
}
2011-12-02 17:07:59 +01:00
directionset PathFinder : : addDirectionToSet ( directionset dirs , direction dir ) const {
2011-09-27 01:55:18 +02:00
return dirs | 1 < < dir ;
}
directionset PathFinder : : forcedNeighbours ( Vec2i coord , direction dir ) {
if ( dir = = NO_DIRECTION )
return 0 ;
directionset dirs = 0 ;
# define ENTERABLE(n) isEnterable(adjustInDirection(coord, (dir + (n)) % 8))
if ( directionIsDiagonal ( dir ) ) {
if ( ! implies ( ENTERABLE ( 6 ) , ENTERABLE ( 5 ) ) )
dirs = addDirectionToSet ( dirs , ( dir + 6 ) % 8 ) ;
if ( ! implies ( ENTERABLE ( 2 ) , ENTERABLE ( 3 ) ) )
dirs = addDirectionToSet ( dirs , ( dir + 2 ) % 8 ) ;
}
else {
if ( ! implies ( ENTERABLE ( 7 ) , ENTERABLE ( 6 ) ) )
dirs = addDirectionToSet ( dirs , ( dir + 7 ) % 8 ) ;
if ( ! implies ( ENTERABLE ( 1 ) , ENTERABLE ( 2 ) ) )
dirs = addDirectionToSet ( dirs , ( dir + 1 ) % 8 ) ;
}
# undef ENTERABLE
return dirs ;
}
2011-12-02 18:46:02 +01:00
directionset PathFinder : : naturalNeighbours ( direction dir ) const {
2011-09-27 01:55:18 +02:00
if ( dir = = NO_DIRECTION )
return 255 ;
directionset dirs = 0 ;
dirs = addDirectionToSet ( dirs , dir ) ;
if ( directionIsDiagonal ( dir ) ) {
dirs = addDirectionToSet ( dirs , ( dir + 1 ) % 8 ) ;
dirs = addDirectionToSet ( dirs , ( dir + 7 ) % 8 ) ;
}
return dirs ;
}
// return and remove a direction from the set
// returns NO_DIRECTION if the set was empty
2011-12-02 17:07:59 +01:00
direction PathFinder : : nextDirectionInSet ( directionset * dirs ) const {
2011-09-27 01:55:18 +02:00
for ( int i = 0 ; i < 8 ; i + + ) {
char bit = 1 < < i ;
if ( * dirs & bit ) {
* dirs ^ = bit ;
return i ;
}
}
return NO_DIRECTION ;
}
// directly translated from "algorithm 2" in the paper
Vec2i PathFinder : : jump ( Vec2i dest , direction dir , Vec2i start , std : : vector < Vec2i > & path , int pathLength ) {
Vec2i coord = adjustInDirection ( start , dir ) ;
//printf("jump dir [%u] start [%s] coord [%s] dest [%s]\n",dir,start.getString().c_str(),coord.getString().c_str(),dest.getString().c_str());
if ( ! isEnterable ( coord ) )
return Vec2i ( - 1 , - 1 ) ;
2011-10-01 01:55:07 +02:00
if ( path . size ( ) > max ( 300 , pathLength * 2 ) ) {
2011-09-27 01:55:18 +02:00
//if(path.size() > 2000) {
//printf("path.size() > pathLength [%d]\n",pathLength);
//return Vec2i(-1,-1);
return coord ;
}
path . push_back ( coord ) ;
//int node = getIndex (astar->bounds, coord);
if ( coord = = dest | | forcedNeighbours ( coord , dir ) ) {
//path.push_back(coord);
//printf("jump #1 = %d [%d]\n",(int)path.size(),pathLength);
return coord ;
}
if ( directionIsDiagonal ( dir ) ) {
Vec2i next = jump ( dest , ( dir + 7 ) % 8 , coord , path , pathLength ) ;
if ( next . x > = 0 ) {
//path.push_back(coord);
//printf("jump #2 = %d [%d]\n",(int)path.size(),pathLength);
return coord ;
}
next = jump ( dest , ( dir + 1 ) % 8 , coord , path , pathLength ) ;
if ( next . x > = 0 ) {
//path.push_back(coord);
//printf("jump #3 = %d [%d]\n",(int)path.size(),pathLength);
return coord ;
}
}
//else {
//path.push_back(coord);
//}
return jump ( dest , dir , coord , path , pathLength ) ;
}
2012-03-31 21:50:45 +02:00
void PathFinder : : astarJPS ( std : : map < Vec2i , Vec2i > cameFrom , Node * & node ,
const Vec2i & finalPos , std : : map < Vec2i , bool > closedNodes ,
std : : map < std : : pair < Vec2i , Vec2i > , bool > canAddNode , Unit * & unit ,
bool & nodeLimitReached , int & maxNodeCount ) {
Vec2i cameFromPos ( - 1 , - 1 ) ;
if ( cameFrom . find ( node - > pos ) ! = cameFrom . end ( ) ) {
cameFromPos = cameFrom [ node - > pos ] ;
}
direction from = directionWeCameFrom ( node - > pos , cameFromPos ) ;
directionset dirs = forcedNeighbours ( node - > pos , from ) | naturalNeighbours ( from ) ;
bool canAddEntirePath = false ;
bool foundQuickRoute = false ;
for ( int dir = nextDirectionInSet ( & dirs ) ; dir ! = NO_DIRECTION ; dir = nextDirectionInSet ( & dirs ) ) {
//for (int dir = 0; dir < 8; dir++) {
std : : vector < Vec2i > path ;
Vec2i newNode = jump ( finalPos , dir , node - > pos , path , ( int ) node - > pos . dist ( finalPos ) ) ;
//Vec2i newNode = adjustInDirection(node->pos, dir);
//printf("examine node from [%u][%u] - current node [%s] next possible node [%s]\n",from,dirs,node->pos.getString().c_str(),newNode.getString().c_str());
//coord_t newCoord = getCoord (bounds, newNode);
// this'll also bail out if jump() returned -1
if ( ! contained ( newNode ) )
continue ;
if ( closedNodes . find ( newNode ) ! = closedNodes . end ( ) )
continue ;
//if(factions[unit->getFactionIndex()].closedNodesList.find(node->heuristic) == factions[unit->getFactionIndex()].closedNodesList.end()) {
//addToOpenSet (&astar, newNode, node);
//printf("JPS #2 node->pos [%s] newNode [%s] path.size() [%d] pos [%s]\n",node->pos.getString().c_str(),newNode.getString().c_str(),(int)path.size(),path[0].getString().c_str());
Vec2i newPath = path [ 0 ] ;
//bool canUnitMoveToCell = map->aproxCanMove(unit, node->pos, newPath);
//bool posOpen = (openPos(newPath, factions[unit->getFactionIndex()]) == false);
//bool isFreeCell = map->isFreeCell(newPath,unit->getType()->getField());
if ( canAddNode . find ( make_pair ( node - > pos , newPath ) ) = = canAddNode . end ( ) ) {
Node * newNode = NULL ;
if ( addToOpenSet ( unit , node , finalPos , newPath , nodeLimitReached , maxNodeCount , & newNode , false ) = = true ) {
//cameFrom = node->pos;
cameFrom [ newPath ] = node - > pos ;
foundQuickRoute = true ;
if ( path . size ( ) > 1 & & path [ path . size ( ) - 1 ] = = finalPos ) {
canAddEntirePath = true ;
for ( unsigned int x = 1 ; x < path . size ( ) ; + + x ) {
Vec2i futureNode = path [ x ] ;
2012-04-13 22:20:40 +02:00
bool canUnitMoveToCell = canUnitMoveSoon ( unit , newNode - > pos , futureNode ) ;
2012-03-31 21:50:45 +02:00
if ( canUnitMoveToCell ! = true | | openPos ( futureNode , factions [ unit - > getFactionIndex ( ) ] ) = = true ) {
canAddEntirePath = false ;
canAddNode [ make_pair ( node - > pos , futureNode ) ] = false ;
//printf("COULD NOT ADD ENTIRE PATH! canUnitMoveToCell = %d\n",canUnitMoveToCell);
break ;
}
}
if ( canAddEntirePath = = true ) {
//printf("add node - ENTIRE PATH!\n");
for ( unsigned int x = 1 ; x < path . size ( ) ; + + x ) {
Vec2i futureNode = path [ x ] ;
Node * newNode2 = NULL ;
addToOpenSet ( unit , newNode , finalPos , futureNode , nodeLimitReached , maxNodeCount , & newNode2 , true ) ;
newNode = newNode2 ;
}
//Node *result = factions[unit->getFactionIndex()].openNodesList.begin()->second[0];
//if(result->pos == finalPos || result->exploredCell == false) {
// printf("Will break out of pathfinding now!\n");
//}
}
}
//printf("add node - current node [%s] next possible node [%s] canUnitMoveToCell [%d] posOpen [%d] isFreeCell [%d]\n",node->pos.getString().c_str(),newPath.getString().c_str(),canUnitMoveToCell,posOpen,isFreeCell);
}
else {
//printf("COULD NOT add node - current node [%s] next possible node [%s] canUnitMoveToCell [%d] posOpen [%d] isFreeCell [%d]\n",node->pos.getString().c_str(),newPath.getString().c_str(),canUnitMoveToCell,posOpen,isFreeCell);
canAddNode [ make_pair ( node - > pos , newPath ) ] = false ;
}
}
//if(canAddEntirePath == true) {
// break;
//}
}
if ( foundQuickRoute = = false ) {
for ( int dir = 0 ; dir < 8 ; dir + + ) {
Vec2i newNode = adjustInDirection ( node - > pos , dir ) ;
//printf("examine node from [%u][%u] - current node [%s] next possible node [%s]\n",from,dirs,node->pos.getString().c_str(),newNode.getString().c_str());
//coord_t newCoord = getCoord (bounds, newNode);
// this'll also bail out if jump() returned -1
if ( ! contained ( newNode ) )
continue ;
if ( closedNodes . find ( newNode ) ! = closedNodes . end ( ) )
continue ;
//if(factions[unit->getFactionIndex()].closedNodesList.find(node->heuristic) == factions[unit->getFactionIndex()].closedNodesList.end()) {
//addToOpenSet (&astar, newNode, node);
//printf("JPS #3 node->pos [%s] newNode [%s]\n",node->pos.getString().c_str(),newNode.getString().c_str());
Vec2i newPath = newNode ;
//bool canUnitMoveToCell = map->aproxCanMove(unit, node->pos, newPath);
//bool posOpen = (openPos(newPath, factions[unit->getFactionIndex()]) == false);
//bool isFreeCell = map->isFreeCell(newPath,unit->getType()->getField());
if ( canAddNode . find ( make_pair ( node - > pos , newPath ) ) = = canAddNode . end ( ) ) {
Node * newNode = NULL ;
if ( addToOpenSet ( unit , node , finalPos , newPath , nodeLimitReached , maxNodeCount , & newNode , false ) = = true ) {
//cameFrom = node->pos;
cameFrom [ newPath ] = node - > pos ;
foundQuickRoute = true ;
//printf("#2 add node - current node [%s] next possible node [%s] canUnitMoveToCell [%d] posOpen [%d] isFreeCell [%d]\n",node->pos.getString().c_str(),newPath.getString().c_str(),canUnitMoveToCell,posOpen,isFreeCell);
}
else {
//printf("#2 COULD NOT add node - current node [%s] next possible node [%s] canUnitMoveToCell [%d] posOpen [%d] isFreeCell [%d]\n",node->pos.getString().c_str(),newPath.getString().c_str(),canUnitMoveToCell,posOpen,isFreeCell);
canAddNode [ make_pair ( node - > pos , newPath ) ] = false ;
}
}
}
}
}
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 ,
2012-05-04 23:03:52 +02:00
int frameIndex , int maxNodeCount , uint32 * searched_node_count ) {
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 ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " map == NULL " ) ;
2010-09-07 23:01:22 +02:00
}
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 ;
2012-04-29 06:45:51 +02:00
//printf("AStar set maxNodeCount = %d\n",maxNodeCount);
}
2012-05-01 07:12:38 +02:00
if ( maxNodeCount > = 1 & & unit - > getPathfindFailedConsecutiveFrameCount ( ) > = 3 ) {
2012-09-22 22:37:42 +02:00
//int orgmaxNodeCount = maxNodeCount;
2012-04-29 06:45:51 +02:00
maxNodeCount = 200 ;
2012-05-01 07:12:38 +02:00
//printf("AStar maxpath cut for unit [%d - %s] to %d [orig: %d] [unit->getPathfindFailedConsecutiveFrameCount(): %d]\n",unit->getId(),unit->getFullName().c_str(), maxNodeCount,orgmaxNodeCount,unit->getPathfindFailedConsecutiveFrameCount());
2011-04-14 04:51:13 +02:00
}
2012-04-29 06:45:51 +02:00
2011-03-18 04:53:06 +01:00
UnitPathInterface * path = unit - > getPath ( ) ;
2012-03-31 21:50:45 +02:00
int unitFactionIndex = unit - > getFactionIndex ( ) ;
2011-03-18 04:53:06 +01:00
2012-03-31 21:50:45 +02:00
factions [ unitFactionIndex ] . nodePoolCount = 0 ;
factions [ unitFactionIndex ] . openNodesList . clear ( ) ;
factions [ unitFactionIndex ] . openPosList . clear ( ) ;
factions [ unitFactionIndex ] . 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
2012-03-31 21:50:45 +02:00
// check the pre-cache to see if we can re-use a cached path
2011-03-18 04:53:06 +01:00
if ( frameIndex < 0 ) {
2012-03-31 21:50:45 +02:00
if ( factions [ unitFactionIndex ] . precachedTravelState . find ( unit - > getId ( ) ) ! = factions [ unitFactionIndex ] . precachedTravelState . end ( ) ) {
if ( factions [ unitFactionIndex ] . precachedTravelState [ unit - > getId ( ) ] = = tsMoving ) {
2011-03-18 04:53:06 +01:00
bool canMoveToCells = true ;
Vec2i lastPos = unit - > getPos ( ) ;
2012-03-31 21:50:45 +02:00
for ( int i = 0 ; i < factions [ unitFactionIndex ] . precachedPath [ unit - > getId ( ) ] . size ( ) ; i + + ) {
Vec2i nodePos = factions [ unitFactionIndex ] . precachedPath [ unit - > getId ( ) ] [ i ] ;
2011-03-18 04:53:06 +01:00
if ( map - > isInside ( nodePos ) = = false | | map - > isInsideSurface ( map - > toSurfCoords ( nodePos ) ) = = false ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " Pathfinder invalid node path position = " + nodePos . getString ( ) + " i = " + intToStr ( i ) ) ;
2011-03-18 04:53:06 +01:00
}
2012-05-12 03:06:55 +02:00
//if(i < pathFindRefresh ||
if ( i < unit - > getPathFindRefreshCellCount ( ) | |
2012-03-31 21:50:45 +02:00
( factions [ unitFactionIndex ] . precachedPath [ unit - > getId ( ) ] . size ( ) > = pathFindExtendRefreshForNodeCount & &
i < getPathFindExtendRefreshNodeCount ( unitFactionIndex ) ) ) {
2011-09-27 01:55:18 +02:00
//!!! Test MV
2012-04-13 22:20:40 +02:00
if ( canUnitMoveSoon ( unit , lastPos , nodePos ) = = false ) {
2011-03-18 04:53:06 +01:00
canMoveToCells = false ;
break ;
}
lastPos = nodePos ;
}
else {
break ;
}
}
if ( canMoveToCells = = true ) {
path - > clear ( ) ;
UnitPathBasic * basicPathFinder = dynamic_cast < UnitPathBasic * > ( path ) ;
2012-03-31 21:50:45 +02:00
for ( int i = 0 ; i < factions [ unitFactionIndex ] . precachedPath [ unit - > getId ( ) ] . size ( ) ; i + + ) {
Vec2i nodePos = factions [ unitFactionIndex ] . precachedPath [ unit - > getId ( ) ] [ i ] ;
2011-03-18 04:53:06 +01:00
if ( map - > isInside ( nodePos ) = = false | | map - > isInsideSurface ( map - > toSurfCoords ( nodePos ) ) = = false ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " Pathfinder invalid node path position = " + nodePos . getString ( ) + " i = " + intToStr ( i ) ) ;
2011-03-18 04:53:06 +01:00
}
2012-05-12 03:06:55 +02:00
//if(i < pathFindRefresh ||
if ( i < unit - > getPathFindRefreshCellCount ( ) | |
2012-03-31 21:50:45 +02:00
( factions [ unitFactionIndex ] . precachedPath [ unit - > getId ( ) ] . size ( ) > = pathFindExtendRefreshForNodeCount & &
i < getPathFindExtendRefreshNodeCount ( unitFactionIndex ) ) ) {
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 ) ;
2012-03-31 21:50:45 +02:00
return factions [ unitFactionIndex ] . precachedTravelState [ unit - > getId ( ) ] ;
2011-03-18 04:53:06 +01:00
}
else {
clearUnitPrecache ( unit ) ;
}
}
2012-03-31 21:50:45 +02:00
else if ( factions [ unitFactionIndex ] . precachedTravelState [ unit - > getId ( ) ] = = tsBlocked ) {
2011-03-18 04:53:06 +01:00
path - > incBlockCount ( ) ;
2011-04-14 04:51:13 +02:00
unit - > setUsePathfinderExtendedMaxNodes ( false ) ;
2012-03-31 21:50:45 +02:00
return factions [ unitFactionIndex ] . precachedTravelState [ unit - > getId ( ) ] ;
2011-03-18 04:53:06 +01:00
}
}
}
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 ) ;
2012-03-31 21:50:45 +02:00
factions [ unitFactionIndex ] . 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 ( ) ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " k >= cachedPath.size() k = " + intToStr(k) + " cachedPath . size ( ) = " + intToStr(cachedPath.size())) ;
2011-02-23 08:03:38 +01:00
}
2011-03-18 22:23:34 +01:00
if ( frameIndex > = 0 ) {
2012-03-31 21:50:45 +02:00
factions [ unitFactionIndex ] . precachedPath [ unit - > getId ( ) ] . push_back ( cachedPath [ k ] ) ;
2011-03-18 22:23:34 +01:00
}
else {
2012-05-12 03:06:55 +02:00
//if(pathCount < pathFindRefresh) {
if ( pathCount < unit - > getPathFindRefreshCellCount ( ) ) {
2011-03-18 22:23:34 +01:00
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 ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2012-11-10 07:37:23 +01:00
snprintf ( szBuf , 8096 , " [Setting new path for unit] openNodesList.size() [ " MG_SIZE_T_SPECIFIER " ] openPosList.size() [ " MG_SIZE_T_SPECIFIER " ] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d] " ,
2012-03-31 21:50:45 +02:00
factions [ unitFactionIndex ] . openNodesList . size ( ) , factions [ unitFactionIndex ] . 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
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " 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 ( ) ) ;
2011-02-23 08:03:38 +01:00
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 ;
}
2012-05-12 03:06:55 +02:00
//else if(j - i > pathFindRefresh) {
else if ( j - i > unit - > getPathFindRefreshCellCount ( ) ) {
2011-02-23 08:03:38 +01:00
//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 ( ) ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " #2 k >= cachedPath.size() k = " + intToStr(k) + " cachedPath . size ( ) = " + intToStr(cachedPath.size())) ;
2011-02-23 08:03:38 +01:00
}
2011-03-18 22:23:34 +01:00
if ( frameIndex > = 0 ) {
2012-03-31 21:50:45 +02:00
factions [ unitFactionIndex ] . precachedPath [ unit - > getId ( ) ] . push_back ( cachedPath [ k ] ) ;
2011-03-18 22:23:34 +01:00
}
else {
2012-05-12 03:06:55 +02:00
//if(pathCount < pathFindRefresh) {
if ( pathCount < unit - > getPathFindRefreshCellCount ( ) ) {
2011-03-18 22:23:34 +01:00
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 ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2012-11-10 07:37:23 +01:00
snprintf ( szBuf , 8096 , " [Setting new path for unit] openNodesList.size() [ " MG_SIZE_T_SPECIFIER " ] openPosList.size() [ " MG_SIZE_T_SPECIFIER " ] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d] " ,
2012-03-31 21:50:45 +02:00
factions [ unitFactionIndex ] . openNodesList . size ( ) , factions [ unitFactionIndex ] . 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
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " 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 ( ) ) ;
2011-02-23 08:03:38 +01:00
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
2012-03-31 21:50:45 +02:00
Node * firstNode = newNode ( factions [ unitFactionIndex ] , maxNodeCount ) ;
2010-10-17 08:34:42 +02:00
assert ( firstNode ! = NULL ) ;
if ( firstNode = = NULL ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " firstNode == NULL " ) ;
2010-10-17 08:34:42 +02:00
}
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 ;
2012-03-31 21:50:45 +02:00
if ( factions [ unitFactionIndex ] . openNodesList . find ( firstNode - > heuristic ) = = factions [ unitFactionIndex ] . openNodesList . end ( ) ) {
factions [ unitFactionIndex ] . openNodesList [ firstNode - > heuristic ] . clear ( ) ;
2011-02-16 20:44:12 +01:00
}
2012-03-31 21:50:45 +02:00
factions [ unitFactionIndex ] . openNodesList [ firstNode - > heuristic ] . push_back ( firstNode ) ;
factions [ unitFactionIndex ] . 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 ) {
2011-09-27 01:55:18 +02:00
//!!! Test MV
2012-04-13 22:20:40 +02:00
bool canUnitMoveToCell = canUnitMoveSoon ( unit , unitPos , pos ) ;
2011-02-25 17:32:27 +01:00
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 ) {
2011-09-27 01:55:18 +02:00
//!!! Test MV
2012-04-13 22:20:40 +02:00
bool canUnitMoveToCell = canUnitMoveSoon ( unit , pos , finalPos ) ;
2011-02-25 17:32:27 +01:00
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-09-27 01:55:18 +02:00
//Vec2i cameFrom= unit->getPos();
//Vec2i cameFrom(-1,-1);
std : : map < std : : pair < Vec2i , Vec2i > , bool > canAddNode ;
std : : map < Vec2i , bool > closedNodes ;
std : : map < Vec2i , Vec2i > cameFrom ;
cameFrom [ unitPos ] = Vec2i ( - 1 , - 1 ) ;
//cameFrom[unitPos] = unit->getPos();
2011-04-04 06:32:01 +02:00
// Do the a-star base pathfind work if required
2012-03-31 21:50:45 +02:00
2010-10-26 08:43:42 +02:00
int whileLoopCount = 0 ;
2011-04-14 04:51:13 +02:00
if ( nodeLimitReached = = false ) {
2011-09-27 01:55:18 +02:00
//printf("\n\n\n====== START AStar-JPS Pathfinder start [%s] end [%s]\n",unitPos.getString().c_str(),finalPos.getString().c_str());
2011-09-27 03:11:11 +02:00
const bool tryJPSPathfinder = false ;
2011-09-27 01:55:18 +02:00
2012-04-21 05:42:25 +02:00
doAStarPathSearch ( nodeLimitReached , whileLoopCount , unitFactionIndex ,
pathFound , node , finalPos , tryJPSPathfinder ,
2012-04-29 06:45:51 +02:00
closedNodes , cameFrom , canAddNode , unit , maxNodeCount , frameIndex ) ;
2011-04-14 04:51:13 +02:00
2012-05-04 23:03:52 +02:00
if ( searched_node_count ! = NULL ) {
* searched_node_count = whileLoopCount ;
}
2011-04-14 04:51:13 +02:00
// Now see if the unit is eligble for pathfind max nodes boost?
2012-04-29 06:45:51 +02:00
if ( nodeLimitReached = = true ) {
unit - > incrementPathfindFailedConsecutiveFrameCount ( ) ;
}
else {
unit - > resetPathfindFailedConsecutiveFrameCount ( ) ;
}
2011-04-14 04:51:13 +02:00
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
2012-03-31 21:50:45 +02: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 [ unitFactionIndex ] . nodePoolCount ) ;
2011-02-23 08:03:38 +01:00
if ( showConsoleDebugInfo & & chrono . getMillis ( ) > 2 ) {
2012-03-31 21:50:45 +02: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 [ unitFactionIndex ] . 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 ) {
2012-03-31 21:50:45 +02:00
if ( factions [ unitFactionIndex ] . closedNodesList . size ( ) > 0 ) {
float bestHeuristic = factions [ unitFactionIndex ] . closedNodesList . begin ( ) - > first ;
2010-10-26 08:43:42 +02:00
if ( bestHeuristic < lastNode - > heuristic ) {
2012-03-31 21:50:45 +02:00
lastNode = factions [ unitFactionIndex ] . 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 ) {
2012-05-04 16:57:59 +02:00
if ( minorDebugPathfinder ) printf ( " Legacy Pathfind Unit [%d - %s] NOT FOUND PATH count = %d frameIndex = %d \n " , unit - > getId ( ) , unit - > getType ( ) - > getName ( ) . c_str ( ) , whileLoopCount , frameIndex ) ;
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
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " 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 ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2012-11-10 07:37:23 +01:00
snprintf ( szBuf , 8096 , " [path for unit BLOCKED] openNodesList.size() [ " MG_SIZE_T_SPECIFIER " ] openPosList.size() [ " MG_SIZE_T_SPECIFIER " ] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d] " ,
2012-03-31 21:50:45 +02:00
factions [ unitFactionIndex ] . openNodesList . size ( ) , factions [ unitFactionIndex ] . 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 {
2012-05-04 16:57:59 +02:00
if ( minorDebugPathfinder ) printf ( " Legacy Pathfind Unit [%d - %s] FOUND PATH count = %d frameIndex = %d \n " , unit - > getId ( ) , unit - > getType ( ) - > getName ( ) . c_str ( ) , whileLoopCount , frameIndex ) ;
2010-07-11 20:31:02 +02:00
//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-09-27 01:55:18 +02:00
if ( pathFound = = true ) {
//printf("FULL PATH FOUND from [%s] to [%s]\n",unitPos.getString().c_str(),finalPos.getString().c_str());
}
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 ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " Pathfinder invalid node path position = " + nodePos . getString ( ) + " i = " + intToStr ( i ) ) ;
2011-02-23 08:03:38 +01:00
}
2011-09-27 01:55:18 +02:00
//printf("nodePos [%s]\n",nodePos.getString().c_str());
2012-05-04 16:57:59 +02:00
if ( minorDebugPathfinder ) printf ( " nodePos [%s] \n " , nodePos . getString ( ) . c_str ( ) ) ;
2011-09-27 01:55:18 +02:00
2011-03-18 04:53:06 +01:00
if ( frameIndex > = 0 ) {
2012-03-31 21:50:45 +02:00
factions [ unitFactionIndex ] . precachedPath [ unit - > getId ( ) ] . push_back ( nodePos ) ;
2011-02-23 08:03:38 +01:00
}
2011-03-18 04:53:06 +01:00
else {
2012-05-12 03:06:55 +02:00
//if(i < pathFindRefresh ||
if ( i < unit - > getPathFindRefreshCellCount ( ) | |
2011-06-24 21:40:47 +02:00
( whileLoopCount > = pathFindExtendRefreshForNodeCount & &
2012-03-31 21:50:45 +02:00
i < getPathFindExtendRefreshNodeCount ( unitFactionIndex ) ) ) {
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 ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2012-11-10 07:37:23 +01:00
snprintf ( szBuf , 8096 , " [Setting new path for unit] openNodesList.size() [ " MG_SIZE_T_SPECIFIER " ] openPosList.size() [ " MG_SIZE_T_SPECIFIER " ] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d] " ,
2012-03-31 21:50:45 +02:00
factions [ unitFactionIndex ] . openNodesList . size ( ) , factions [ unitFactionIndex ] . 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 ) ;
2012-10-19 03:31:20 +02:00
snprintf ( szBuf , 8096 , " 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 ( ) ;
}
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " 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 ( ) ) ;
2010-10-17 08:34:42 +02:00
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
}
2012-03-31 21:50:45 +02:00
factions [ unitFactionIndex ] . openNodesList . clear ( ) ;
factions [ unitFactionIndex ] . openPosList . clear ( ) ;
factions [ unitFactionIndex ] . 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 ) {
2012-03-31 21:50:45 +02:00
factions [ unitFactionIndex ] . precachedTravelState [ unit - > getId ( ) ] = ts ;
2011-03-18 04:53:06 +01:00
}
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-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 ) {
2012-04-14 23:21:09 +02:00
throw megaglest_runtime_error ( " map == NULL " ) ;
2010-09-07 23:01:22 +02:00
}
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 ;
}
2012-03-10 04:27:25 +01:00
int PathFinder : : findNodeIndex ( Node * node , Nodes & nodeList ) {
int index = - 1 ;
if ( node ! = NULL ) {
for ( unsigned int i = 0 ; i < nodeList . size ( ) ; + + i ) {
Node * curnode = nodeList [ i ] ;
if ( node = = curnode ) {
index = i ;
break ;
}
}
}
return index ;
}
int PathFinder : : findNodeIndex ( Node * node , std : : vector < Node > & nodeList ) {
int index = - 1 ;
if ( node ! = NULL ) {
for ( unsigned int i = 0 ; i < nodeList . size ( ) ; + + i ) {
Node & curnode = nodeList [ i ] ;
if ( node = = & curnode ) {
index = i ;
break ;
}
}
}
return index ;
}
void PathFinder : : saveGame ( XmlNode * rootNode ) {
std : : map < string , string > mapTagReplacements ;
XmlNode * pathfinderNode = rootNode - > addChild ( " PathFinder " ) ;
// static int pathFindNodesMax;
pathfinderNode - > addAttribute ( " pathFindNodesMax " , intToStr ( pathFindNodesMax ) , mapTagReplacements ) ;
// static int pathFindNodesAbsoluteMax;
pathfinderNode - > addAttribute ( " pathFindNodesAbsoluteMax " , intToStr ( pathFindNodesAbsoluteMax ) , mapTagReplacements ) ;
// FactionStateList factions;
for ( unsigned int i = 0 ; i < factions . size ( ) ; + + i ) {
FactionState & factionState = factions [ i ] ;
XmlNode * factionsNode = pathfinderNode - > addChild ( " factions " ) ;
// std::map<Vec2i, bool> openPosList;
2012-03-13 16:21:25 +01:00
// XmlNode *openPosListNode = factionsNode->addChild("openPosList");
// for(std::map<Vec2i, bool>::iterator iterMap = factionState.openPosList.begin();
// iterMap != factionState.openPosList.end(); ++iterMap) {
// openPosListNode->addAttribute("key",iterMap->first.getString(), mapTagReplacements);
// openPosListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements);
// }
//// std::map<float, Nodes> openNodesList;
// XmlNode *openNodesListNode = factionsNode->addChild("openNodesList");
// for(std::map<float, Nodes>::iterator iterMap = factionState.openNodesList.begin();
// iterMap != factionState.openNodesList.end(); ++iterMap) {
//
// Nodes &nodeList = iterMap->second;
// for(unsigned int j = 0; j < nodeList.size(); ++j) {
// Node *curNode = nodeList[j];
// XmlNode *openNodesListNodeNode = factionsNode->addChild("openNodesListNode");
// openNodesListNodeNode->addAttribute("key",floatToStr(iterMap->first), mapTagReplacements);
//
//// Vec2i pos;
// openNodesListNodeNode->addAttribute("pos",curNode->pos.getString(), mapTagReplacements);
//// Node *next;
// int nextIdx = findNodeIndex(curNode->next, nodeList);
// openNodesListNodeNode->addAttribute("next",intToStr(nextIdx), mapTagReplacements);
//// Node *prev;
// int prevIdx = findNodeIndex(curNode->prev, nodeList);
// openNodesListNodeNode->addAttribute("prev",intToStr(nextIdx), mapTagReplacements);
//// float heuristic;
// openNodesListNodeNode->addAttribute("heuristic",floatToStr(curNode->heuristic), mapTagReplacements);
//// bool exploredCell;
// openNodesListNodeNode->addAttribute("exploredCell",intToStr(curNode->exploredCell), mapTagReplacements);
// }
// }
//
//// std::map<float, Nodes> closedNodesList;
// XmlNode *closedNodesListNode = factionsNode->addChild("closedNodesList");
// for(std::map<float, Nodes>::iterator iterMap = factionState.closedNodesList.begin();
// iterMap != factionState.closedNodesList.end(); ++iterMap) {
//
// Nodes &nodeList = iterMap->second;
// for(unsigned int j = 0; j < nodeList.size(); ++j) {
// Node *curNode = nodeList[j];
// XmlNode *closedNodesListNodeNode = factionsNode->addChild("closedNodesListNode");
// closedNodesListNodeNode->addAttribute("key",floatToStr(iterMap->first), mapTagReplacements);
//
//// Vec2i pos;
// closedNodesListNodeNode->addAttribute("pos",curNode->pos.getString(), mapTagReplacements);
//// Node *next;
// int nextIdx = findNodeIndex(curNode->next, nodeList);
// closedNodesListNodeNode->addAttribute("next",intToStr(nextIdx), mapTagReplacements);
//// Node *prev;
// int prevIdx = findNodeIndex(curNode->prev, nodeList);
// closedNodesListNodeNode->addAttribute("prev",intToStr(nextIdx), mapTagReplacements);
//// float heuristic;
// closedNodesListNodeNode->addAttribute("heuristic",floatToStr(curNode->heuristic), mapTagReplacements);
//// bool exploredCell;
// closedNodesListNodeNode->addAttribute("exploredCell",intToStr(curNode->exploredCell), mapTagReplacements);
// }
// }
2012-03-10 04:27:25 +01:00
// std::vector<Node> nodePool;
for ( unsigned int j = 0 ; j < factionState . nodePool . size ( ) ; + + j ) {
Node * curNode = & factionState . nodePool [ j ] ;
XmlNode * nodePoolNode = factionsNode - > addChild ( " nodePool " ) ;
//closedNodesListNodeNode->addAttribute("key",iterMap->first.getString(), mapTagReplacements);
// Vec2i pos;
nodePoolNode - > addAttribute ( " pos " , curNode - > pos . getString ( ) , mapTagReplacements ) ;
// Node *next;
int nextIdx = findNodeIndex ( curNode - > next , factionState . nodePool ) ;
nodePoolNode - > addAttribute ( " next " , intToStr ( nextIdx ) , mapTagReplacements ) ;
// Node *prev;
int prevIdx = findNodeIndex ( curNode - > prev , factionState . nodePool ) ;
2012-03-28 08:25:57 +02:00
nodePoolNode - > addAttribute ( " prev " , intToStr ( prevIdx ) , mapTagReplacements ) ;
2012-03-10 04:27:25 +01:00
// float heuristic;
nodePoolNode - > addAttribute ( " heuristic " , floatToStr ( curNode - > heuristic ) , mapTagReplacements ) ;
// bool exploredCell;
nodePoolNode - > addAttribute ( " exploredCell " , intToStr ( curNode - > exploredCell ) , mapTagReplacements ) ;
}
// int nodePoolCount;
2012-03-13 16:21:25 +01:00
factionsNode - > addAttribute ( " nodePoolCount " , intToStr ( factionState . nodePoolCount ) , mapTagReplacements ) ;
2012-03-10 04:27:25 +01:00
// RandomGen random;
2012-03-13 16:21:25 +01:00
factionsNode - > addAttribute ( " random " , intToStr ( factionState . random . getLastNumber ( ) ) , mapTagReplacements ) ;
2012-03-10 04:27:25 +01:00
// int useMaxNodeCount;
2012-03-13 16:21:25 +01:00
factionsNode - > addAttribute ( " useMaxNodeCount " , intToStr ( factionState . useMaxNodeCount ) , mapTagReplacements ) ;
2012-03-10 04:27:25 +01:00
//
// std::map<int,TravelState> precachedTravelState;
// std::map<int,std::vector<Vec2i> > precachedPath;
}
// const Map *map;
}
2012-03-13 16:21:25 +01:00
void PathFinder : : loadGame ( const XmlNode * rootNode ) {
const XmlNode * pathfinderNode = rootNode - > getChild ( " PathFinder " ) ;
//attackWarnRange = unitupdaterNode->getAttribute("attackWarnRange")->getFloatValue();
// static int pathFindNodesMax;
pathFindNodesMax = pathfinderNode - > getAttribute ( " pathFindNodesMax " ) - > getIntValue ( ) ;
// static int pathFindNodesAbsoluteMax;
pathFindNodesAbsoluteMax = pathfinderNode - > getAttribute ( " pathFindNodesAbsoluteMax " ) - > getIntValue ( ) ;
vector < XmlNode * > factionsNodeList = pathfinderNode - > getChildList ( " factions " ) ;
for ( unsigned int i = 0 ; i < factionsNodeList . size ( ) ; + + i ) {
XmlNode * factionsNode = factionsNodeList [ i ] ;
FactionState & factionState = factions [ i ] ;
// std::vector<Node> nodePool;
vector < XmlNode * > nodePoolListNode = factionsNode - > getChildList ( " nodePool " ) ;
for ( unsigned int j = 0 ; j < nodePoolListNode . size ( ) ; + + j ) {
XmlNode * nodePoolNode = nodePoolListNode [ j ] ;
Node * curNode = & factionState . nodePool [ j ] ;
//closedNodesListNodeNode->addAttribute("key",iterMap->first.getString(), mapTagReplacements);
// Vec2i pos;
curNode - > pos = Vec2i : : strToVec2 ( nodePoolNode - > getAttribute ( " pos " ) - > getValue ( ) ) ;
// Node *next;
2012-04-04 17:36:09 +02:00
int nextNode = nodePoolNode - > getAttribute ( " next " ) - > getIntValue ( ) ;
if ( nextNode > = 0 ) {
curNode - > next = & factionState . nodePool [ nextNode ] ;
}
else {
curNode - > next = NULL ;
}
2012-03-13 16:21:25 +01:00
// Node *prev;
2012-04-04 17:36:09 +02:00
int prevNode = nodePoolNode - > getAttribute ( " prev " ) - > getIntValue ( ) ;
if ( prevNode > = 0 ) {
curNode - > prev = & factionState . nodePool [ prevNode ] ;
}
else {
curNode - > prev = NULL ;
}
2012-03-13 16:21:25 +01:00
// float heuristic;
curNode - > heuristic = nodePoolNode - > getAttribute ( " heuristic " ) - > getFloatValue ( ) ;
// bool exploredCell;
2012-04-16 22:15:57 +02:00
curNode - > exploredCell = nodePoolNode - > getAttribute ( " exploredCell " ) - > getIntValue ( ) ! = 0 ;
2012-03-13 16:21:25 +01:00
}
// int nodePoolCount;
factionState . nodePoolCount = factionsNode - > getAttribute ( " nodePoolCount " ) - > getIntValue ( ) ;
// RandomGen random;
factionState . random . setLastNumber ( factionsNode - > getAttribute ( " random " ) - > getIntValue ( ) ) ;
// int useMaxNodeCount;
factionState . useMaxNodeCount = factionsNode - > getAttribute ( " useMaxNodeCount " ) - > getIntValue ( ) ;
//
// std::map<int,TravelState> precachedTravelState;
// std::map<int,std::vector<Vec2i> > precachedPath;
}
// const Map *map;
}
2010-07-11 20:31:02 +02:00
} } //end namespace