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 "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 ;
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-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 ;
2010-09-07 23:01:22 +02:00
map = NULL ;
2010-07-11 20:31:02 +02:00
}
2013-11-10 08:25:52 +01:00
int PathFinder : : getPathFindExtendRefreshNodeCount ( FactionState & faction ) {
2016-05-28 01:15:27 +02:00
//int refreshNodeCount = faction.random.randRange(PathFinder::pathFindExtendRefreshNodeCountMin,PathFinder::pathFindExtendRefreshNodeCountMax);
//return refreshNodeCount;
return PathFinder : : pathFindExtendRefreshNodeCountMin ;
2011-06-24 21:40:47 +02:00
}
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
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 ) {
2013-11-08 23:41:17 +01:00
for ( int factionIndex = 0 ; factionIndex < GameConstants : : maxPlayers ; + + factionIndex ) {
FactionState & faction = factions . getFactionState ( factionIndex ) ;
2011-03-18 04:53:06 +01:00
2013-11-08 23:41:17 +01:00
faction . nodePool . resize ( pathFindNodesAbsoluteMax ) ;
faction . useMaxNodeCount = PathFinder : : pathFindNodesMax ;
2011-03-18 04:53:06 +01:00
}
2010-07-11 20:31:02 +02:00
this - > map = map ;
}
2013-05-17 07:21:14 +02:00
void PathFinder : : init ( ) {
minorDebugPathfinder = false ;
map = NULL ;
}
2011-03-18 04:53:06 +01:00
PathFinder : : ~ PathFinder ( ) {
2013-11-08 23:41:17 +01:00
for ( int factionIndex = 0 ; factionIndex < GameConstants : : maxPlayers ; + + factionIndex ) {
FactionState & faction = factions . getFactionState ( factionIndex ) ;
faction . nodePool . clear ( ) ;
2011-03-18 04:53:06 +01:00
}
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
}
2013-02-19 05:53:24 +01:00
void PathFinder : : clearCaches ( ) {
2013-11-08 23:41:17 +01:00
for ( int factionIndex = 0 ; factionIndex < GameConstants : : maxPlayers ; + + factionIndex ) {
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
FactionState & faction = factions . getFactionState ( factionIndex ) ;
2013-11-09 21:44:37 +01:00
MutexSafeWrapper safeMutex ( faction . getMutexPreCache ( ) , mutexOwnerId ) ;
2013-11-08 23:41:17 +01:00
faction . precachedTravelState . clear ( ) ;
faction . precachedPath . clear ( ) ;
2013-02-19 05:53:24 +01:00
}
}
2011-03-18 04:53:06 +01:00
void PathFinder : : clearUnitPrecache ( Unit * unit ) {
2013-05-20 04:51:26 +02:00
if ( unit ! = NULL & & factions . size ( ) > unit - > getFactionIndex ( ) ) {
2013-11-08 23:41:17 +01:00
int factionIndex = unit - > getFactionIndex ( ) ;
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
FactionState & faction = factions . getFactionState ( factionIndex ) ;
2013-11-09 21:44:37 +01:00
MutexSafeWrapper safeMutex ( faction . getMutexPreCache ( ) , mutexOwnerId ) ;
2013-11-08 23:41:17 +01:00
faction . precachedTravelState [ unit - > getId ( ) ] = tsImpossible ;
faction . precachedPath [ unit - > getId ( ) ] . clear ( ) ;
2013-05-20 04:51:26 +02:00
}
2011-03-18 04:53:06 +01:00
}
2011-03-29 12:01:01 +02:00
void PathFinder : : removeUnitPrecache ( Unit * unit ) {
2013-05-20 04:51:26 +02:00
if ( unit ! = NULL & & factions . size ( ) > unit - > getFactionIndex ( ) ) {
2013-11-08 23:41:17 +01:00
int factionIndex = unit - > getFactionIndex ( ) ;
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
FactionState & faction = factions . getFactionState ( factionIndex ) ;
2013-11-09 21:44:37 +01:00
MutexSafeWrapper safeMutex ( faction . getMutexPreCache ( ) , mutexOwnerId ) ;
2013-05-20 04:51:26 +02:00
2013-11-08 23:41:17 +01:00
if ( faction . precachedTravelState . find ( unit - > getId ( ) ) ! = faction . precachedTravelState . end ( ) ) {
faction . precachedTravelState . erase ( unit - > getId ( ) ) ;
2011-03-29 12:01:01 +02:00
}
2013-11-08 23:41:17 +01:00
if ( faction . precachedPath . find ( unit - > getId ( ) ) ! = faction . precachedPath . end ( ) ) {
faction . precachedPath . erase ( unit - > getId ( ) ) ;
2013-05-20 04:51:26 +02:00
}
2011-03-29 12:01:01 +02:00
}
}
2011-03-18 04:53:06 +01:00
TravelState PathFinder : : findPath ( Unit * unit , const Vec2i & finalPos , bool * wasStuck , int frameIndex ) {
2013-11-08 16:30:53 +01:00
TravelState ts = tsImpossible ;
try {
2013-11-10 08:25:52 +01:00
int factionIndex = unit - > getFactionIndex ( ) ;
FactionState & faction = factions . getFactionState ( factionIndex ) ;
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
MutexSafeWrapper safeMutexPrecache ( faction . getMutexPreCache ( ) , mutexOwnerId ) ;
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
2011-03-18 04:53:06 +01:00
if ( frameIndex > = 0 ) {
clearUnitPrecache ( unit ) ;
}
2013-05-20 04:51:26 +02:00
if ( unit - > getFaction ( ) - > canUnitsPathfind ( ) = = true ) {
unit - > getFaction ( ) - > addUnitToPathfindingList ( unit - > getId ( ) ) ;
}
else {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " canUnitsPathfind() == false " ) ;
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
2012-03-31 21:50:45 +02:00
}
2013-05-20 04:51:26 +02:00
return tsBlocked ;
}
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 ) {
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 ( ) ) ;
2013-01-03 18:30:59 +01:00
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __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 ) ;
2013-05-18 00:51:40 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " Unit finalPos [%s] == unit->getPos() [%s] " , finalPos . getString ( ) . c_str ( ) , unit - > getPos ( ) . getString ( ) . c_str ( ) ) ;
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
}
2011-03-18 04:53:06 +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 ) {
2013-09-21 22:50:58 +02:00
commandDesc = command - > getCommandType ( ) - > toString ( false ) ;
2010-10-17 08:34:42 +02:00
}
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 ) {
2013-12-15 07:37:15 +01:00
UnitPathBasic * basic_path = dynamic_cast < UnitPathBasic * > ( path ) ;
if ( basic_path ! = NULL ) {
2011-03-18 04:53:06 +01:00
//route cache
2013-12-15 07:37:15 +01:00
Vec2i pos = basic_path - > pop ( frameIndex < 0 ) ;
2011-03-18 04:53:06 +01:00
if ( map - > canMove ( unit , unit - > getPos ( ) , pos ) ) {
if ( frameIndex < 0 ) {
2016-05-28 01:15:27 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & &
SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynchMax ) . enabled = = true ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " #1 map->canMove to pos [%s] from [%s] " , pos . getString ( ) . c_str ( ) , unit - > getPos ( ) . getString ( ) . c_str ( ) ) ;
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
}
2013-05-18 00:51:40 +02:00
2016-05-28 01:15:27 +02:00
unit - > setTargetPos ( pos , frameIndex < 0 ) ;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & &
SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynchMax ) . enabled = = true ) {
2013-05-18 00:51:40 +02:00
char szBuf [ 8096 ] = " " ;
2016-05-28 01:15:27 +02:00
snprintf ( szBuf , 8096 , " #2 map->canMove to pos [%s] from [%s] " , pos . getString ( ) . c_str ( ) , unit - > getPos ( ) . getString ( ) . c_str ( ) ) ;
2013-05-18 00:51:40 +02:00
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
}
2010-07-21 20:21:40 +02:00
}
2013-05-21 07:43:57 +02:00
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 ( ) ;
2016-05-28 01:15:27 +02:00
unit - > setTargetPos ( pos , frameIndex < 0 ) ;
2010-07-21 20:21:40 +02:00
}
2013-05-21 07:43:57 +02:00
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
2013-02-22 07:52:51 +01:00
if ( path - > isStuck ( ) = = true & &
( unit - > getLastStuckPos ( ) = = finalPos | | path - > getBlockCount ( ) > 500 ) & &
2013-09-23 19:16:34 +02:00
unit - > isLastStuckFrameWithinCurrentFrameTolerance ( frameIndex > = 0 ) = = true ) {
2013-05-18 00:51:40 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
char szBuf [ 8096 ] = " " ;
2013-09-23 19:16:34 +02:00
snprintf ( szBuf , 8096 , " path->isStuck() == true unit->getLastStuckPos() [%s] finalPos [%s] path->getBlockCount() [%d] " , unit - > getLastStuckPos ( ) . getString ( ) . c_str ( ) , finalPos . getString ( ) . c_str ( ) , path - > getBlockCount ( ) ) ;
2013-05-18 00:51:40 +02:00
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
}
2011-04-04 06:32:01 +02:00
return tsBlocked ;
}
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 ) {
maxNodeCount = PathFinder : : pathFindNodesAbsoluteMax ;
2013-05-20 04:51:26 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " maxNodeCount: %d " , maxNodeCount ) ;
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
}
2011-04-14 04:51:13 +02:00
}
2012-05-04 23:03:52 +02:00
bool minorDebugPathfinderPerformance = false ;
Chrono chrono ;
if ( minorDebugPathfinderPerformance ) chrono . start ( ) ;
uint32 searched_node_count = 0 ;
2012-05-04 16:57:59 +02:00
minorDebugPathfinder = false ;
2013-06-13 10:55:48 +02:00
if ( minorDebugPathfinder ) printf ( " Legacy Pathfind Unit [%d - %s] from = %s to = %s frameIndex = %d \n " , unit - > getId ( ) , unit - > getType ( ) - > getName ( false ) . c_str ( ) , unit - > getPos ( ) . getString ( ) . c_str ( ) , finalPos . getString ( ) . c_str ( ) , frameIndex ) ;
2010-12-01 00:32:39 +01:00
2013-05-21 00:54:07 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " calling aStar() " ) ;
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
}
2012-09-22 23:05:06 +02:00
ts = aStar ( unit , finalPos , false , frameIndex , maxNodeCount , & searched_node_count ) ;
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 ) {
2013-11-09 02:26:29 +01:00
2013-06-13 10:55:48 +02:00
if ( minorDebugPathfinder ) printf ( " Pathfind Unit [%d - %s] START BAILOUT ATTEMPT frameIndex = %d \n " , unit - > getId ( ) , unit - > getType ( ) - > getName ( false ) . c_str ( ) , frameIndex ) ;
2012-05-04 18:48:14 +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 , " [attempting to BAIL OUT] finalPos [%s] ts [%d] " ,
2012-05-04 18:48:14 +02:00
finalPos . getString ( ) . c_str ( ) , ts ) ;
2013-01-03 18:30:59 +01:00
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
2012-05-04 18:48:14 +02:00
}
2012-05-04 16:57:59 +02:00
2012-05-04 18:48:14 +02:00
if ( wasStuck ! = NULL ) {
* wasStuck = true ;
}
unit - > setInBailOutAttempt ( true ) ;
2013-11-09 02:26:29 +01:00
bool unitImmediatelyBlocked = false ;
// First check if unit currently blocked all around them, if so don't try to pathfind
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
}
2013-11-09 02:26:29 +01:00
cellCount + + ;
2012-05-04 16:57:59 +02:00
}
2012-05-04 18:48:14 +02:00
}
2013-11-09 02:26:29 +01:00
}
unitImmediatelyBlocked = ( failureCount = = cellCount ) ;
if ( unitImmediatelyBlocked = = false ) {
int factionIndex = unit - > getFactionIndex ( ) ;
FactionState & faction = factions . getFactionState ( factionIndex ) ;
2016-05-28 06:31:39 +02:00
//if(Thread::isCurrentThreadMainThread() == false) {
// throw megaglest_runtime_error("#2 Invalid access to FactionState random from outside main thread current id = " +
// intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId()));
//}
2016-05-28 01:15:27 +02:00
int tryRadius = faction . random . randRange ( 1 , 2 ) ;
//int tryRadius = faction.random.IRandomX(1,2);
//int tryRadius = 1;
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In astar bailout() tryRadius %d " , tryRadius ) ;
if ( frameIndex > = 0 ) {
unit - > logSynchDataThreaded ( __FILE__ , __LINE__ , szBuf ) ;
}
else {
unit - > logSynchData ( __FILE__ , __LINE__ , szBuf ) ;
}
}
2013-11-09 02:26:29 +01:00
// Try to bail out up to PathFinder::pathFindBailoutRadius cells away
2016-05-28 01:15:27 +02:00
if ( tryRadius = = 2 ) {
2013-11-09 02:26:29 +01:00
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 [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " [attempting to BAIL OUT] finalPos [%s] newFinalPos [%s] ts [%d] canUnitMove [%d] " ,
finalPos . getString ( ) . c_str ( ) , newFinalPos . getString ( ) . c_str ( ) , ts , canUnitMove ) ;
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
}
2013-11-08 23:41:17 +01:00
2013-11-09 02:26:29 +01:00
if ( canUnitMove ) {
2012-05-04 18:48:14 +02:00
2013-11-09 02:26:29 +01:00
int maxBailoutNodeCount = ( PathFinder : : pathFindBailoutRadius * 2 ) ;
2012-05-04 18:48:14 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2013-11-09 02:26:29 +01:00
snprintf ( szBuf , 8096 , " calling aStar() " ) ;
2013-01-03 18:30:59 +01:00
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
2012-05-04 18:48:14 +02:00
}
2012-05-04 16:57:59 +02:00
2013-11-09 02:26:29 +01: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
}
2013-11-09 02:26:29 +01: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 [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " [attempting to BAIL OUT] finalPos [%s] newFinalPos [%s] ts [%d] canUnitMove [%d] " ,
finalPos . getString ( ) . c_str ( ) , newFinalPos . getString ( ) . c_str ( ) , ts , canUnitMove ) ;
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
}
if ( canUnitMove ) {
int maxBailoutNodeCount = ( PathFinder : : pathFindBailoutRadius * 2 ) ;
2012-05-04 18:48:14 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2013-11-09 02:26:29 +01:00
snprintf ( szBuf , 8096 , " calling aStar() " ) ;
2013-01-03 18:30:59 +01:00
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
2012-05-04 18:48:14 +02:00
}
2013-11-09 02:26:29 +01: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
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 ;
2013-12-14 08:04:12 +01:00
if ( frameIndex < 0 & & basicPath ! = NULL ) {
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 {
2013-05-20 04:51:26 +02:00
2013-11-08 23:41:17 +01:00
if ( faction . precachedPath [ unit - > getId ( ) ] . size ( ) < = 0 ) {
2012-05-04 18:48:14 +02:00
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
2013-11-08 23:41:17 +01:00
pos = faction . precachedPath [ unit - > getId ( ) ] [ 0 ] ;
2013-11-08 16:30:53 +01:00
2012-05-04 18:48:14 +02:00
}
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 ) {
2016-05-28 01:15:27 +02:00
unit - > setTargetPos ( pos , frameIndex < 0 ) ;
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
2013-06-13 10:55:48 +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 ( false ) . c_str ( ) , ( long long int ) chrono . getMillis ( ) , ts , searched_node_count ) ;
2013-05-21 00:54:07 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " tsBlocked " ) ;
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
}
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 ( ) ;
2016-05-28 01:15:27 +02:00
unit - > setTargetPos ( pos , frameIndex < 0 ) ;
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 ) ;
}
2013-06-13 10:55:48 +02:00
if ( minorDebugPathfinder ) printf ( " Pathfind Unit [%d - %s] INT BAILOUT ATTEMPT BLOCKED frameIndex = %d \n " , unit - > getId ( ) , unit - > getType ( ) - > getName ( false ) . c_str ( ) , frameIndex ) ;
2012-05-04 23:03:52 +02:00
2013-06-13 10:55:48 +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 ( false ) . 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 ;
2013-11-19 07:14:06 +01:00
default :
break ;
2012-05-04 18:48:14 +02:00
}
2013-06-13 10:55:48 +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 ( false ) . c_str ( ) , ( long long int ) chrono . getMillis ( ) , ts , searched_node_count ) ;
2012-05-04 23:03:52 +02:00
2013-11-08 16:30:53 +01:00
}
catch ( const exception & ex ) {
//setRunningStatus(false);
2013-11-14 14:17:58 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2013-11-08 16:30:53 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
throw megaglest_runtime_error ( ex . what ( ) ) ;
}
catch ( . . . ) {
char szBuf [ 8096 ] = " " ;
2013-11-14 14:17:58 +01:00
snprintf ( szBuf , 8096 , " In [%s::%s %d] UNKNOWN error \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2013-11-08 16:30:53 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , szBuf ) ;
throw megaglest_runtime_error ( szBuf ) ;
}
2012-05-04 18:48:14 +02:00
return ts ;
}
// ==================== PRIVATE ====================
2012-05-04 16:57:59 +02: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 ,
2012-05-04 23:03:52 +02:00
int frameIndex , int maxNodeCount , uint32 * searched_node_count ) {
2013-11-08 16:30:53 +01:00
TravelState ts = tsImpossible ;
try {
2013-11-10 08:25:52 +01:00
int unitFactionIndex = unit - > getFactionIndex ( ) ;
int factionIndex = unit - > getFactionIndex ( ) ;
FactionState & faction = factions . getFactionState ( factionIndex ) ;
2011-02-25 23:13:11 +01:00
2013-05-21 07:43:57 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex > = 0 ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In aStar() " ) ;
unit - > logSynchDataThreaded ( __FILE__ , __LINE__ , szBuf ) ;
}
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
2011-04-14 04:51:13 +02:00
if ( maxNodeCount < 0 ) {
2013-11-08 23:41:17 +01:00
int factionIndex = unit - > getFactionIndex ( ) ;
FactionState & faction = factions . getFactionState ( factionIndex ) ;
maxNodeCount = faction . useMaxNodeCount ;
2012-04-29 06:45:51 +02:00
}
2012-05-01 07:12:38 +02:00
if ( maxNodeCount > = 1 & & unit - > getPathfindFailedConsecutiveFrameCount ( ) > = 3 ) {
2012-04-29 06:45:51 +02:00
maxNodeCount = 200 ;
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 ( ) ;
2013-11-08 17:26:36 +01:00
2013-11-08 23:41:17 +01:00
faction . nodePoolCount = 0 ;
faction . openNodesList . clear ( ) ;
faction . openPosList . clear ( ) ;
faction . closedNodesList . clear ( ) ;
2010-10-26 08:43:42 +02: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 ) {
2013-11-08 23:41:17 +01:00
2013-11-09 22:22:51 +01:00
bool foundPrecacheTravelState = ( faction . precachedTravelState . find ( unit - > getId ( ) ) ! = faction . precachedTravelState . end ( ) ) ;
if ( foundPrecacheTravelState = = true ) {
2013-05-19 07:16:21 +02:00
2013-11-09 22:22:51 +01:00
// if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) {
// char szBuf[8096]="";
// snprintf(szBuf,8096,"factions[unitFactionIndex].precachedTravelState[unit->getId()]: %d",faction.precachedTravelState[unit->getId()]);
// unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
// }
bool foundPrecacheTravelStateIsMoving = ( faction . precachedTravelState [ unit - > getId ( ) ] = = tsMoving ) ;
if ( foundPrecacheTravelStateIsMoving = = true ) {
2011-03-18 04:53:06 +01:00
bool canMoveToCells = true ;
Vec2i lastPos = unit - > getPos ( ) ;
2013-05-20 04:51:26 +02:00
2013-11-10 06:27:59 +01:00
int unitPrecachePathSize = ( int ) faction . precachedPath [ unit - > getId ( ) ] . size ( ) ;
2013-11-10 06:23:59 +01:00
for ( int i = 0 ; i < unitPrecachePathSize ; i + + ) {
2013-11-08 23:41:17 +01:00
Vec2i nodePos = faction . precachedPath [ unit - > getId ( ) ] [ i ] ;
2013-11-10 06:23:59 +01:00
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 < unit - > getPathFindRefreshCellCount ( ) | |
2013-11-10 06:23:59 +01:00
( unitPrecachePathSize > = pathFindExtendRefreshForNodeCount & &
2013-11-10 08:25:52 +01:00
i < getPathFindExtendRefreshNodeCount ( faction ) ) ) {
2013-11-10 06:23:59 +01:00
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 ( ) ;
2013-11-19 07:14:06 +01:00
//UnitPathBasic *basicPathFinder = dynamic_cast<UnitPathBasic *>(path);
2011-03-18 04:53:06 +01:00
2013-11-10 06:27:59 +01:00
int unitPrecachePathSize = ( int ) faction . precachedPath [ unit - > getId ( ) ] . size ( ) ;
2013-11-10 06:23:59 +01:00
for ( int i = 0 ; i < unitPrecachePathSize ; i + + ) {
2013-11-08 23:41:17 +01:00
Vec2i nodePos = faction . precachedPath [ unit - > getId ( ) ] [ i ] ;
2013-11-10 06:23:59 +01:00
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 ( ) | |
2013-11-10 06:23:59 +01:00
( unitPrecachePathSize > = pathFindExtendRefreshForNodeCount & &
2013-11-10 08:25:52 +01:00
i < getPathFindExtendRefreshNodeCount ( faction ) ) ) {
2011-03-18 04:53:06 +01:00
path - > add ( nodePos ) ;
}
}
2011-04-14 04:51:13 +02:00
unit - > setUsePathfinderExtendedMaxNodes ( false ) ;
2013-05-21 00:54:07 +02:00
2016-05-28 01:15:27 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " return factions[unitFactionIndex].precachedTravelState[unit->getId()]; " ) ;
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
}
2013-05-21 00:54:07 +02:00
2013-11-08 23:41:17 +01:00
return faction . precachedTravelState [ unit - > getId ( ) ] ;
2011-03-18 04:53:06 +01:00
}
else {
clearUnitPrecache ( unit ) ;
}
}
2013-05-20 04:51:26 +02:00
else {
2013-11-09 22:22:51 +01:00
bool foundPrecacheTravelStateIsBlocked = ( faction . precachedTravelState [ unit - > getId ( ) ] = = tsBlocked ) ;
if ( foundPrecacheTravelStateIsBlocked = = true ) {
2013-05-20 04:51:26 +02:00
path - > incBlockCount ( ) ;
unit - > setUsePathfinderExtendedMaxNodes ( false ) ;
2013-05-21 00:54:07 +02:00
2013-11-09 22:22:51 +01:00
// if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) {
// char szBuf[8096]="";
// snprintf(szBuf,8096,"return factions[unitFactionIndex].precachedTravelState[unit->getId()];");
// unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf);
// }
2013-05-21 00:54:07 +02:00
2013-11-08 23:41:17 +01:00
return faction . precachedTravelState [ unit - > getId ( ) ] ;
2013-05-20 04:51:26 +02:00
}
2011-03-18 04:53:06 +01:00
}
}
}
else {
clearUnitPrecache ( unit ) ;
2013-05-20 04:51:26 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " [clearUnitPrecache] " ) ;
2013-05-20 23:52:36 +02:00
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
2013-05-20 04:51:26 +02:00
}
2011-03-18 04:53:06 +01:00
}
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 ) ;
2016-05-28 01:15:27 +02:00
float dist = unitPos . dist ( finalPos ) ;
2013-11-08 17:26:36 +01:00
2013-11-08 23:41:17 +01:00
faction . useMaxNodeCount = PathFinder : : pathFindNodesMax ;
2011-02-23 08:03:38 +01:00
2013-01-03 18:30:59 +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 " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-12-05 00:19:43 +01:00
2010-07-11 20:31:02 +02:00
//path find algorithm
//a) push starting pos into openNodes
2013-11-08 23:41:17 +01:00
Node * firstNode = newNode ( faction , maxNodeCount ) ;
2010-10-17 08:34:42 +02:00
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 ;
2013-11-08 23:41:17 +01:00
if ( faction . openNodesList . find ( firstNode - > heuristic ) = = faction . openNodesList . end ( ) ) {
faction . openNodesList [ firstNode - > heuristic ] . clear ( ) ;
2011-02-16 20:44:12 +01:00
}
2013-11-08 23:41:17 +01:00
faction . openNodesList [ firstNode - > heuristic ] . push_back ( firstNode ) ;
faction . 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
2013-01-03 18:30:59 +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 " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __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 ) {
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 ;
2013-05-19 07:16:21 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " nodeLimitReached: %d failureCount: %d cellCount: %d " , nodeLimitReached , failureCount , cellCount ) ;
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
}
2013-06-13 10:55:48 +02:00
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 " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , unit - > getId ( ) , unit - > getFullName ( false ) . c_str ( ) , unitPos . getString ( ) . c_str ( ) , finalPos . getString ( ) . c_str ( ) , dist , ( long long int ) chrono . getMillis ( ) , nodeLimitReached , failureCount ) ;
2011-02-25 17:32:27 +01:00
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 ) {
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 ;
2013-05-19 07:16:21 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " nodeLimitReached: %d failureCount: %d cellCount: %d " , nodeLimitReached , failureCount , cellCount ) ;
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
}
2013-06-13 10:55:48 +02:00
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 " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , unit - > getId ( ) , unit - > getFullName ( false ) . c_str ( ) , unitPos . getString ( ) . c_str ( ) , finalPos . getString ( ) . c_str ( ) , dist , ( long long int ) chrono . getMillis ( ) , nodeLimitReached , failureCount ) ;
2011-02-25 17:32:27 +01:00
}
}
2013-05-20 04:51:26 +02:00
else {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " inBailout: %d unitPos: [%s] finalPos [%s] " , inBailout , unitPos . getString ( ) . c_str ( ) , finalPos . getString ( ) . c_str ( ) ) ;
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
}
}
2011-02-25 17:32:27 +01:00
//
2011-03-29 18:27:01 +02:00
// START
2011-09-27 01:55:18 +02:00
std : : map < std : : pair < Vec2i , Vec2i > , bool > canAddNode ;
std : : map < Vec2i , bool > closedNodes ;
std : : map < Vec2i , Vec2i > cameFrom ;
cameFrom [ unitPos ] = Vec2i ( - 1 , - 1 ) ;
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 ) {
2011-09-27 01:55:18 +02:00
2013-05-18 05:11:26 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " Calling doAStarPathSearch nodeLimitReached: %d whileLoopCount: %d unitFactionIndex: %d pathFound: %d finalPos [%s] maxNodeCount: %d frameIndex: %d " , nodeLimitReached , whileLoopCount , unitFactionIndex ,
pathFound , finalPos . getString ( ) . c_str ( ) , maxNodeCount , frameIndex ) ;
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
}
2012-04-21 05:42:25 +02:00
doAStarPathSearch ( nodeLimitReached , whileLoopCount , unitFactionIndex ,
2013-11-08 18:01:32 +01:00
pathFound , node , finalPos ,
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 ;
}
2013-11-09 02:26:29 +01:00
// Now see if the unit is eligible for pathfind max nodes boost?
2012-04-29 06:45:51 +02:00
if ( nodeLimitReached = = true ) {
unit - > incrementPathfindFailedConsecutiveFrameCount ( ) ;
}
else {
unit - > resetPathfindFailedConsecutiveFrameCount ( ) ;
}
2013-05-18 05:11:26 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " Calling doAStarPathSearch nodeLimitReached: %d whileLoopCount: %d unitFactionIndex: %d pathFound: %d finalPos [%s] maxNodeCount: %d pathFindNodesAbsoluteMax: %d frameIndex: %d " , nodeLimitReached , whileLoopCount , unitFactionIndex ,
pathFound , finalPos . getString ( ) . c_str ( ) , maxNodeCount , pathFindNodesAbsoluteMax , frameIndex ) ;
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
}
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 ) ;
}
2013-05-21 00:54:07 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " calling aStar() " ) ;
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
}
2011-04-14 04:51:13 +02:00
return aStar ( unit , targetPos , false , frameIndex , pathFindNodesAbsoluteMax ) ;
}
2010-07-11 20:31:02 +02:00
}
2011-04-14 04:51:13 +02:00
}
2013-05-20 04:51:26 +02:00
else {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " nodeLimitReached: %d " , nodeLimitReached ) ;
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
}
}
2010-07-11 20:31:02 +02: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 ) {
2013-11-08 23:41:17 +01:00
2013-11-09 04:16:41 +01:00
if ( faction . closedNodesList . empty ( ) = = false ) {
2016-05-28 01:15:27 +02:00
float bestHeuristic = truncateDecimal < float > ( faction . closedNodesList . begin ( ) - > first , 6 ) ;
2013-12-14 08:04:12 +01:00
if ( lastNode ! = NULL & & bestHeuristic < lastNode - > heuristic ) {
2016-05-28 01:15:27 +02:00
lastNode = faction . closedNodesList . begin ( ) - > second . front ( ) ;
2010-10-26 08:43:42 +02:00
}
}
2010-07-11 20:31:02 +02:00
}
2013-01-03 18:30:59 +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 " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __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 ) {
2013-09-21 22:50:58 +02:00
commandDesc = command - > getCommandType ( ) - > toString ( false ) ;
2010-10-17 08:34:42 +02:00
}
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
2013-01-03 18:30:59 +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 " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __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
2013-01-03 18:30:59 +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 " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __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 ( ) ;
}
2013-11-19 07:14:06 +01:00
//UnitPathBasic *basicPathFinder = dynamic_cast<UnitPathBasic *>(path);
2010-07-11 20:31:02 +02:00
currNode = firstNode ;
2013-11-10 06:23:59 +01:00
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
}
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 ) {
2013-11-08 23:41:17 +01:00
faction . 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 < unit - > getPathFindRefreshCellCount ( ) | |
2011-06-24 21:40:47 +02:00
( whileLoopCount > = pathFindExtendRefreshForNodeCount & &
2013-11-10 08:25:52 +01:00
i < getPathFindExtendRefreshNodeCount ( faction ) ) ) {
2011-03-18 04:53:06 +01:00
path - > add ( 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
2013-01-03 18:30:59 +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 " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-12-05 00:19:43 +01:00
2016-05-28 01:15:27 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & &
SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynchMax ) . enabled = = true ) {
2012-10-19 03:31:20 +02:00
char szBuf [ 8096 ] = " " ;
2011-02-16 20:44:12 +01:00
string pathToTake = " " ;
2016-05-28 01:15:27 +02:00
if ( frameIndex < 0 ) {
vector < Vec2i > pathQueue = path - > getQueue ( ) ;
for ( unsigned int index = 0 ; index < pathQueue . size ( ) ; + + index ) {
Vec2i & pos = pathQueue [ index ] ;
if ( pathToTake ! = " " ) {
pathToTake + = " , " ;
}
pathToTake + = pos . getString ( ) ;
}
}
else {
for ( unsigned int index = 0 ; index < faction . precachedPath [ unit - > getId ( ) ] . size ( ) ; + + index ) {
Vec2i & pos = faction . precachedPath [ unit - > getId ( ) ] [ index ] ;
if ( pathToTake ! = " " ) {
pathToTake + = " , " ;
}
pathToTake + = pos . getString ( ) ;
2011-02-16 20:44:12 +01:00
}
}
2012-10-19 03:31:20 +02:00
snprintf ( szBuf , 8096 , " Path for unit to take = %s " , pathToTake . c_str ( ) ) ;
2016-05-28 01:15:27 +02:00
if ( frameIndex < 0 ) {
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
}
else {
unit - > logSynchDataThreaded ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
}
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 ) {
2013-09-21 22:50:58 +02:00
commandDesc = command - > getCommandType ( ) - > toString ( false ) ;
2010-10-17 08:34:42 +02: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 ( ) ) ;
2010-10-17 08:34:42 +02:00
unit - > setCurrentUnitTitle ( szBuf ) ;
}
2010-12-05 00:19:43 +01:00
2013-01-03 18:30:59 +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 " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-07-11 20:31:02 +02:00
}
2013-11-08 17:26:36 +01:00
2013-11-08 23:41:17 +01:00
faction . openNodesList . clear ( ) ;
faction . openPosList . clear ( ) ;
faction . closedNodesList . clear ( ) ;
2010-07-11 20:31:02 +02:00
2013-01-03 18:30:59 +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 " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , chrono . getMillis ( ) ) ;
2010-12-05 00:19:43 +01:00
2011-03-18 04:53:06 +01:00
if ( frameIndex > = 0 ) {
2013-11-09 22:22:51 +01:00
FactionState & faction = factions . getFactionState ( factionIndex ) ;
2013-11-08 23:41:17 +01:00
faction . precachedTravelState [ unit - > getId ( ) ] = ts ;
2011-03-18 04:53:06 +01:00
}
else {
2013-01-03 18:30:59 +01:00
if ( SystemFlags : : VERBOSE_MODE_ENABLED & & chrono . getMillis ( ) > = 5 ) printf ( " In [%s::%s Line: %d] astar took [%lld] msecs, ts = %d. \n " , extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __FUNCTION__ , __LINE__ , ( long long int ) chrono . getMillis ( ) , ts ) ;
2011-03-18 04:53:06 +01:00
}
2011-04-04 06:32:01 +02:00
2013-05-21 00:54:07 +02:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugWorldSynch ) . enabled = = true & & frameIndex < 0 ) {
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " return ts: %d " , ts ) ;
unit - > logSynchData ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) , __LINE__ , szBuf ) ;
}
2013-11-08 16:30:53 +01:00
}
catch ( const exception & ex ) {
2013-11-14 14:17:58 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2013-11-08 16:30:53 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
throw megaglest_runtime_error ( ex . what ( ) ) ;
}
catch ( . . . ) {
char szBuf [ 8096 ] = " " ;
2013-11-14 14:17:58 +01:00
snprintf ( szBuf , 8096 , " In [%s::%s %d] UNKNOWN error \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2013-11-08 16:30:53 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , szBuf ) ;
throw megaglest_runtime_error ( szBuf ) ;
}
2010-07-11 20:31:02 +02:00
return ts ;
}
2013-10-03 02:17:51 +02:00
void PathFinder : : processNearestFreePos ( const Vec2i & finalPos , int i , int j , int size , Field field , int teamIndex , Vec2i unitPos , Vec2i & nearestPos , float & nearestDist ) {
2013-11-08 16:30:53 +01:00
try {
2016-05-28 01:15:27 +02:00
Vec2i currPos = finalPos + Vec2i ( i , j ) ;
2013-11-08 16:30:53 +01:00
2016-05-28 01:15:27 +02:00
if ( map - > isAproxFreeCells ( currPos , size , field , teamIndex ) ) {
float dist = currPos . dist ( finalPos ) ;
2011-02-04 07:34:32 +01:00
2016-05-28 01:15:27 +02:00
//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 ;
}
2011-02-04 07:34:32 +01:00
}
}
2013-11-08 16:30:53 +01:00
}
catch ( const exception & ex ) {
2013-11-14 14:17:58 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2013-11-08 16:30:53 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
throw megaglest_runtime_error ( ex . what ( ) ) ;
2011-02-04 07:34:32 +01:00
}
2013-11-08 16:30:53 +01:00
catch ( . . . ) {
char szBuf [ 8096 ] = " " ;
2013-11-14 14:17:58 +01:00
snprintf ( szBuf , 8096 , " In [%s::%s %d] UNKNOWN error \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2013-11-08 16:30:53 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , szBuf ) ;
throw megaglest_runtime_error ( szBuf ) ;
}
2011-02-04 07:34:32 +01:00
}
2010-10-17 08:34:42 +02:00
Vec2i PathFinder : : computeNearestFreePos ( const Unit * unit , const Vec2i & finalPos ) {
2013-11-08 16:30:53 +01:00
Vec2i nearestPos ( 0 , 0 ) ;
try {
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
2013-02-04 09:30:43 +01:00
Vec2i unitPos = unit - > getPosNotThreadSafe ( ) ;
2013-11-08 16:30:53 +01:00
nearestPos = unitPos ;
2016-05-28 01:15:27 +02:00
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
}
}
2013-11-08 16:30:53 +01:00
}
catch ( const exception & ex ) {
2013-11-14 14:17:58 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , " In [%s::%s Line: %d] Error [%s] \n " , __FILE__ , __FUNCTION__ , __LINE__ , ex . what ( ) ) ;
2013-11-08 16:30:53 +01:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
throw megaglest_runtime_error ( ex . what ( ) ) ;
}
catch ( . . . ) {
char szBuf [ 8096 ] = " " ;
2013-11-14 14:17:58 +01:00
snprintf ( szBuf , 8096 , " In [%s::%s %d] UNKNOWN error \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2013-11-08 16:30:53 +01:00
SystemFlags : : OutputDebug ( SystemFlags : : debugError , szBuf ) ;
throw megaglest_runtime_error ( szBuf ) ;
}
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 ;
}
2017-10-10 05:21:14 +02:00
//bool PathFinder::unitCannotMove(Unit *unit) {
// bool unitImmediatelyBlocked = false;
//
// try {
// // First check if unit currently blocked all around them, if so don't try to pathfind
// 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++;
// }
// cellCount++;
// }
// }
// }
// unitImmediatelyBlocked = (failureCount == cellCount);
//
// }
// catch(const exception &ex) {
// //setRunningStatus(false);
//
// SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
// if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//
// throw megaglest_runtime_error(ex.what());
// }
// catch(...) {
// char szBuf[8096]="";
// snprintf(szBuf,8096,"In [%s::%s %d] UNKNOWN error\n",__FILE__,__FUNCTION__,__LINE__);
// SystemFlags::OutputDebug(SystemFlags::debugError,szBuf);
// throw megaglest_runtime_error(szBuf);
// }
//
// return unitImmediatelyBlocked;
//}
2013-02-22 07:52:51 +01:00
2012-03-10 04:27:25 +01:00
void PathFinder : : saveGame ( XmlNode * rootNode ) {
std : : map < string , string > mapTagReplacements ;
XmlNode * pathfinderNode = rootNode - > addChild ( " PathFinder " ) ;
pathfinderNode - > addAttribute ( " pathFindNodesMax " , intToStr ( pathFindNodesMax ) , mapTagReplacements ) ;
pathfinderNode - > addAttribute ( " pathFindNodesAbsoluteMax " , intToStr ( pathFindNodesAbsoluteMax ) , mapTagReplacements ) ;
2013-11-19 07:14:06 +01:00
for ( unsigned int i = 0 ; i < ( unsigned int ) factions . size ( ) ; + + i ) {
2013-11-08 23:41:17 +01:00
FactionState & factionState = factions . getFactionState ( i ) ;
2012-03-10 04:27:25 +01:00
XmlNode * factionsNode = pathfinderNode - > addChild ( " factions " ) ;
2013-11-19 07:14:06 +01:00
for ( unsigned int j = 0 ; j < ( unsigned int ) factionState . nodePool . size ( ) ; + + j ) {
2012-03-10 04:27:25 +01:00
Node * curNode = & factionState . nodePool [ j ] ;
XmlNode * nodePoolNode = factionsNode - > addChild ( " nodePool " ) ;
nodePoolNode - > addAttribute ( " pos " , curNode - > pos . getString ( ) , mapTagReplacements ) ;
int nextIdx = findNodeIndex ( curNode - > next , factionState . nodePool ) ;
nodePoolNode - > addAttribute ( " next " , intToStr ( nextIdx ) , mapTagReplacements ) ;
int prevIdx = findNodeIndex ( curNode - > prev , factionState . nodePool ) ;
2012-03-28 08:25:57 +02:00
nodePoolNode - > addAttribute ( " prev " , intToStr ( prevIdx ) , mapTagReplacements ) ;
2013-10-03 02:17:51 +02:00
nodePoolNode - > addAttribute ( " heuristic " , floatToStr ( curNode - > heuristic , 6 ) , mapTagReplacements ) ;
2012-03-10 04:27:25 +01:00
nodePoolNode - > addAttribute ( " exploredCell " , intToStr ( curNode - > exploredCell ) , mapTagReplacements ) ;
}
2012-03-13 16:21:25 +01:00
factionsNode - > addAttribute ( " nodePoolCount " , intToStr ( factionState . nodePoolCount ) , mapTagReplacements ) ;
factionsNode - > addAttribute ( " random " , intToStr ( factionState . random . getLastNumber ( ) ) , mapTagReplacements ) ;
factionsNode - > addAttribute ( " useMaxNodeCount " , intToStr ( factionState . useMaxNodeCount ) , mapTagReplacements ) ;
2012-03-10 04:27:25 +01:00
}
}
2012-03-13 16:21:25 +01:00
void PathFinder : : loadGame ( const XmlNode * rootNode ) {
const XmlNode * pathfinderNode = rootNode - > getChild ( " PathFinder " ) ;
vector < XmlNode * > factionsNodeList = pathfinderNode - > getChildList ( " factions " ) ;
2013-11-19 07:14:06 +01:00
for ( unsigned int i = 0 ; i < ( unsigned int ) factionsNodeList . size ( ) ; + + i ) {
2012-03-13 16:21:25 +01:00
XmlNode * factionsNode = factionsNodeList [ i ] ;
2013-11-08 23:41:17 +01:00
FactionState & factionState = factions . getFactionState ( i ) ;
2012-03-13 16:21:25 +01:00
vector < XmlNode * > nodePoolListNode = factionsNode - > getChildList ( " nodePool " ) ;
2013-11-19 07:14:06 +01:00
for ( unsigned int j = 0 ; j < ( unsigned int ) nodePoolListNode . size ( ) & & j < ( unsigned int ) pathFindNodesAbsoluteMax ; + + j ) {
2012-03-13 16:21:25 +01:00
XmlNode * nodePoolNode = nodePoolListNode [ j ] ;
Node * curNode = & factionState . nodePool [ j ] ;
curNode - > pos = Vec2i : : strToVec2 ( nodePoolNode - > getAttribute ( " pos " ) - > getValue ( ) ) ;
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 ;
}
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
curNode - > heuristic = nodePoolNode - > getAttribute ( " heuristic " ) - > getFloatValue ( ) ;
2012-04-16 22:15:57 +02:00
curNode - > exploredCell = nodePoolNode - > getAttribute ( " exploredCell " ) - > getIntValue ( ) ! = 0 ;
2012-03-13 16:21:25 +01:00
}
factionState . nodePoolCount = factionsNode - > getAttribute ( " nodePoolCount " ) - > getIntValue ( ) ;
factionState . random . setLastNumber ( factionsNode - > getAttribute ( " random " ) - > getIntValue ( ) ) ;
2013-01-03 18:30:59 +01:00
factionState . useMaxNodeCount = PathFinder : : pathFindNodesMax ;
2012-03-13 16:21:25 +01:00
}
}
2010-07-11 20:31:02 +02:00
} } //end namespace