2010-03-24 21:26:17 +00:00
// ==============================================================
// This file is part of Glest (www.glest.org)
//
2011-12-14 07:40:48 +00:00
// Copyright (C) 2001-2008 Martiño Figueroa
2010-03-24 21:26:17 +00:00
//
2011-01-02 00:39:13 +00: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
2010-03-24 21:26:17 +00:00
// License, or (at your option) any later version
// ==============================================================
# include "ai_interface.h"
# include "ai.h"
# include "command_type.h"
# include "faction.h"
# include "unit.h"
# include "unit_type.h"
# include "object.h"
# include "game.h"
# include "config.h"
2010-06-02 22:06:10 +00:00
# include "network_manager.h"
2011-05-24 22:51:45 +00:00
# include "platform_util.h"
2010-03-24 21:26:17 +00:00
# include "leak_dumper.h"
using namespace Shared : : Util ;
using namespace Shared : : Graphics ;
// =====================================================
// class AiInterface
// =====================================================
namespace Glest { namespace Game {
2013-01-01 18:55:26 +00:00
// =====================================================
// class FactionThread
// =====================================================
AiInterfaceThread : : AiInterfaceThread ( AiInterface * aiIntf ) : BaseThread ( ) {
2013-01-10 21:16:28 +00:00
this - > masterController = NULL ;
2013-12-24 22:27:44 -08:00
this - > triggerIdMutex = new Mutex ( CODE_AT_LINE ) ;
2013-01-01 18:55:26 +00:00
this - > aiIntf = aiIntf ;
2013-05-21 20:28:42 +00:00
uniqueID = " AiInterfaceThread " ;
2013-01-01 18:55:26 +00:00
}
AiInterfaceThread : : ~ AiInterfaceThread ( ) {
delete triggerIdMutex ;
triggerIdMutex = NULL ;
}
void AiInterfaceThread : : setQuitStatus ( bool value ) {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s] Line: %d value = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , value ) ;
BaseThread : : setQuitStatus ( value ) ;
if ( value = = true ) {
signal ( - 1 ) ;
}
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s] Line: %d \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
}
void AiInterfaceThread : : signal ( int frameIndex ) {
if ( frameIndex > = 0 ) {
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
MutexSafeWrapper safeMutex ( triggerIdMutex , mutexOwnerId ) ;
this - > frameIndex . first = frameIndex ;
this - > frameIndex . second = false ;
safeMutex . ReleaseLock ( ) ;
}
semTaskSignalled . signal ( ) ;
}
void AiInterfaceThread : : setTaskCompleted ( int frameIndex ) {
if ( frameIndex > = 0 ) {
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
MutexSafeWrapper safeMutex ( triggerIdMutex , mutexOwnerId ) ;
if ( this - > frameIndex . first = = frameIndex ) {
this - > frameIndex . second = true ;
}
safeMutex . ReleaseLock ( ) ;
}
}
bool AiInterfaceThread : : canShutdown ( bool deleteSelfIfShutdownDelayed ) {
bool ret = ( getExecutingTask ( ) = = false ) ;
if ( ret = = false & & deleteSelfIfShutdownDelayed = = true ) {
setDeleteSelfOnExecutionDone ( deleteSelfIfShutdownDelayed ) ;
2013-06-04 00:31:41 +00:00
deleteSelfIfRequired ( ) ;
2013-01-01 18:55:26 +00:00
signalQuit ( ) ;
}
return ret ;
}
bool AiInterfaceThread : : isSignalCompleted ( int frameIndex ) {
if ( getRunningStatus ( ) = = false ) {
return true ;
}
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
MutexSafeWrapper safeMutex ( triggerIdMutex , mutexOwnerId ) ;
//bool result = (event != NULL ? event->eventCompleted : true);
bool result = ( this - > frameIndex . first = = frameIndex & & this - > frameIndex . second = = true ) ;
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] worker thread this = %p, this->frameIndex.first = %d, this->frameIndex.second = %d\n",__FILE__,__FUNCTION__,__LINE__,this,this->frameIndex.first,this->frameIndex.second);
safeMutex . ReleaseLock ( ) ;
return result ;
}
2013-01-27 07:26:35 +00:00
void AiInterfaceThread : : signalQuit ( ) {
if ( this - > aiIntf ! = NULL ) {
MutexSafeWrapper safeMutex ( this - > aiIntf - > getMutex ( ) , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
this - > aiIntf = NULL ;
}
BaseThread : : signalQuit ( ) ;
}
2013-01-01 18:55:26 +00:00
void AiInterfaceThread : : execute ( ) {
RunningStatusSafeWrapper runningStatus ( this ) ;
try {
//setRunningStatus(true);
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " In [%s::%s Line: %d] ****************** STARTING worker thread this = %p \n " , __FILE__ , __FUNCTION__ , __LINE__ , this ) ;
2013-10-25 05:45:54 +00:00
//bool minorDebugPerformance = false;
2013-01-01 18:55:26 +00:00
Chrono chrono ;
//unsigned int idx = 0;
for ( ; this - > aiIntf ! = NULL ; ) {
if ( getQuitStatus ( ) = = true ) {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
break ;
}
semTaskSignalled . waitTillSignalled ( ) ;
2013-01-10 21:16:28 +00:00
static string masterSlaveOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
MasterSlaveThreadControllerSafeWrapper safeMasterController ( masterController , 20000 , masterSlaveOwnerId ) ;
2013-01-01 18:55:26 +00:00
if ( getQuitStatus ( ) = = true ) {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
break ;
}
static string mutexOwnerId = string ( __FILE__ ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
MutexSafeWrapper safeMutex ( triggerIdMutex , mutexOwnerId ) ;
bool executeTask = ( frameIndex . first > = 0 ) ;
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] frameIndex = %d this = %p executeTask = %d\n",__FILE__,__FUNCTION__,__LINE__,frameIndex.first, this, executeTask);
safeMutex . ReleaseLock ( ) ;
if ( executeTask = = true ) {
ExecutingTaskSafeWrapper safeExecutingTaskMutex ( this ) ;
MutexSafeWrapper safeMutex ( this - > aiIntf - > getMutex ( ) , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
this - > aiIntf - > update ( ) ;
safeMutex . ReleaseLock ( ) ;
setTaskCompleted ( frameIndex . first ) ;
}
if ( getQuitStatus ( ) = = true ) {
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
break ;
}
}
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
if ( SystemFlags : : VERBOSE_MODE_ENABLED ) printf ( " In [%s::%s Line: %d] ****************** ENDING worker thread this = %p \n " , __FILE__ , __FUNCTION__ , __LINE__ , this ) ;
}
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 ( ) ) ;
}
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s] Line: %d \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
}
AiInterface : : AiInterface ( Game & game , int factionIndex , int teamIndex ,
int useStartLocation ) : fp ( NULL ) {
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-06-01 16:54:44 +00:00
2013-12-24 22:27:44 -08:00
this - > aiMutex = new Mutex ( CODE_AT_LINE ) ;
2013-01-01 18:55:26 +00:00
this - > workerThread = NULL ;
2010-03-24 21:26:17 +00:00
this - > world = game . getWorld ( ) ;
this - > commander = game . getCommander ( ) ;
this - > console = game . getConsole ( ) ;
2010-06-01 16:54:44 +00:00
this - > gameSettings = game . getGameSettings ( ) ;
2010-03-24 21:26:17 +00:00
this - > factionIndex = factionIndex ;
this - > teamIndex = teamIndex ;
timer = 0 ;
//init ai
2010-10-18 23:09:43 +00:00
ai . init ( this , useStartLocation ) ;
2010-03-24 21:26:17 +00:00
//config
logLevel = Config : : getInstance ( ) . getInt ( " AiLog " ) ;
redir = Config : : getInstance ( ) . getBool ( " AiRedir " ) ;
2012-03-17 19:22:03 +00:00
aiLogFile = getLogFilename ( ) ;
if ( getGameReadWritePath ( GameConstants : : path_logs_CacheLookupKey ) ! = " " ) {
aiLogFile = getGameReadWritePath ( GameConstants : : path_logs_CacheLookupKey ) + aiLogFile ;
}
else {
string userData = Config : : getInstance ( ) . getString ( " UserData_Root " , " " ) ;
if ( userData ! = " " ) {
endPathWithSlash ( userData ) ;
}
aiLogFile = userData + aiLogFile ;
}
2010-03-24 21:26:17 +00:00
//clear log file
2012-03-17 19:22:03 +00:00
if ( logLevel > 0 ) {
2011-05-18 21:49:11 +00:00
# ifdef WIN32
2013-11-19 22:47:22 +00:00
fp = _wfopen ( : : Shared : : Platform : : utf8_decode ( aiLogFile ) . c_str ( ) , L " wt " ) ;
2011-05-18 21:49:11 +00:00
# else
2012-03-17 19:22:03 +00:00
fp = fopen ( aiLogFile . c_str ( ) , " wt " ) ;
2011-05-18 21:49:11 +00:00
# endif
2012-03-17 19:22:03 +00:00
if ( fp = = NULL ) {
2012-04-14 21:21:09 +00:00
throw megaglest_runtime_error ( " Can't open file: [ " + aiLogFile + " ] " ) ;
2010-03-24 21:26:17 +00:00
}
2012-03-17 19:22:03 +00:00
fprintf ( fp , " MegaGlest AI log file for Tech [%s] Faction [%s] #%d \n \n " , this - > gameSettings - > getTech ( ) . c_str ( ) , this - > world - > getFaction ( this - > factionIndex ) - > getType ( ) - > getName ( ) . c_str ( ) , this - > factionIndex ) ;
2010-03-24 21:26:17 +00:00
}
2013-01-01 18:55:26 +00:00
if ( Config : : getInstance ( ) . getBool ( " EnableAIWorkerThreads " , " true " ) = = true ) {
if ( workerThread ! = NULL ) {
workerThread - > signalQuit ( ) ;
if ( workerThread - > shutdownAndWait ( ) = = true ) {
delete workerThread ;
}
workerThread = NULL ;
}
2013-01-23 14:51:28 +00:00
static string mutexOwnerId = string ( extractFileFromDirectoryPath ( __FILE__ ) . c_str ( ) ) + string ( " _ " ) + intToStr ( __LINE__ ) ;
2013-01-01 18:55:26 +00:00
this - > workerThread = new AiInterfaceThread ( this ) ;
2013-01-23 14:51:28 +00:00
this - > workerThread - > setUniqueID ( mutexOwnerId ) ;
2013-01-01 18:55:26 +00:00
this - > workerThread - > start ( ) ;
}
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-03-24 21:26:17 +00:00
}
2013-05-17 05:21:14 +00:00
void AiInterface : : init ( ) {
world = NULL ; ;
commander = NULL ; ;
console = NULL ; ;
gameSettings = NULL ; ;
timer = 0 ;
factionIndex = 0 ;
teamIndex = 0 ;
redir = false ;
logLevel = 0 ;
fp = NULL ; ;
aiMutex = NULL ;
workerThread = NULL ;
}
2011-01-11 22:09:46 +00:00
AiInterface : : ~ AiInterface ( ) {
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] deleting AI factionIndex = %d, teamIndex = %d \n " , __FILE__ , __FUNCTION__ , __LINE__ , this - > factionIndex , this - > teamIndex ) ;
2011-01-11 22:09:46 +00:00
cacheUnitHarvestResourceLookup . clear ( ) ;
2012-03-17 19:22:03 +00:00
2013-01-01 18:55:26 +00:00
if ( workerThread ! = NULL ) {
workerThread - > signalQuit ( ) ;
2013-02-16 10:07:36 +00:00
sleep ( 0 ) ;
if ( workerThread - > canShutdown ( true ) = = true & &
workerThread - > shutdownAndWait ( ) = = true ) {
2013-01-01 18:55:26 +00:00
delete workerThread ;
}
workerThread = NULL ;
}
2012-03-17 19:22:03 +00:00
if ( fp ) {
fclose ( fp ) ;
fp = NULL ;
}
2013-01-01 18:55:26 +00:00
delete aiMutex ;
aiMutex = NULL ;
}
void AiInterface : : signalWorkerThread ( int frameIndex ) {
if ( workerThread ! = NULL ) {
workerThread - > signal ( frameIndex ) ;
}
else {
this - > update ( ) ;
}
2011-01-11 22:09:46 +00:00
}
2013-01-01 18:55:26 +00:00
bool AiInterface : : isWorkerThreadSignalCompleted ( int frameIndex ) {
if ( workerThread ! = NULL ) {
return workerThread - > isSignalCompleted ( frameIndex ) ;
}
return true ;
}
2011-01-02 00:39:13 +00:00
// ==================== main ====================
2010-03-24 21:26:17 +00:00
2010-11-11 08:02:50 +00:00
void AiInterface : : update ( ) {
2010-03-24 21:26:17 +00:00
timer + + ;
ai . update ( ) ;
}
2011-01-02 00:39:13 +00:00
// ==================== misc ====================
2010-03-24 21:26:17 +00:00
2013-01-12 01:11:53 +00:00
bool AiInterface : : isLogLevelEnabled ( int level ) {
return ( this - > logLevel > = level ) ;
}
2010-03-24 21:26:17 +00:00
void AiInterface : : printLog ( int logLevel , const string & s ) {
2013-01-12 01:11:53 +00:00
if ( isLogLevelEnabled ( logLevel ) = = true ) {
2010-03-24 21:26:17 +00:00
string logString = " ( " + intToStr ( factionIndex ) + " ) " + s ;
2013-01-01 18:55:26 +00:00
MutexSafeWrapper safeMutex ( aiMutex , string ( __FILE__ ) + " _ " + intToStr ( __LINE__ ) ) ;
2010-03-24 21:26:17 +00:00
//print log to file
2012-03-17 19:22:03 +00:00
if ( fp ! = NULL ) {
fprintf ( fp , " %s \n " , logString . c_str ( ) ) ;
2010-03-24 21:26:17 +00:00
}
2011-01-02 00:39:13 +00:00
2010-03-24 21:26:17 +00:00
//redirect to console
if ( redir ) {
console - > addLine ( logString ) ;
}
}
}
2011-01-02 00:39:13 +00:00
// ==================== interaction ====================
2010-03-24 21:26:17 +00:00
2010-11-11 08:02:50 +00:00
Faction * AiInterface : : getMyFaction ( ) {
return world - > getFaction ( factionIndex ) ;
}
2010-09-14 19:10:37 +00:00
bool AiInterface : : executeCommandOverNetwork ( ) {
bool enableServerControlledAI = gameSettings - > getEnableServerControlledAI ( ) ;
bool isNetworkGame = gameSettings - > isNetworkGame ( ) ;
NetworkRole role = NetworkManager : : getInstance ( ) . getNetworkRole ( ) ;
Faction * faction = world - > getFaction ( factionIndex ) ;
return faction - > getCpuControl ( enableServerControlledAI , isNetworkGame , role ) ;
}
2012-11-10 19:39:55 +00:00
std : : pair < CommandResult , string > AiInterface : : giveCommandSwitchTeamVote ( const Faction * faction , SwitchTeamVote * vote ) {
2011-09-21 06:51:28 +00:00
assert ( this - > gameSettings ! = NULL ) ;
commander - > trySwitchTeamVote ( faction , vote ) ;
2012-11-10 19:39:55 +00:00
return std : : pair < CommandResult , string > ( crSuccess , " " ) ;
2011-09-21 06:51:28 +00:00
}
2012-11-10 19:39:55 +00:00
std : : pair < CommandResult , string > AiInterface : : giveCommand ( int unitIndex , CommandClass commandClass , const Vec2i & pos ) {
2010-06-01 16:54:44 +00:00
assert ( this - > gameSettings ! = NULL ) ;
2010-05-01 09:27:08 +00:00
2012-11-10 19:39:55 +00:00
std : : pair < CommandResult , string > result ( crFailUndefined , " " ) ;
2010-09-14 19:10:37 +00:00
if ( executeCommandOverNetwork ( ) = = true ) {
2010-06-08 07:40:32 +00:00
const Unit * unit = getMyUnit ( unitIndex ) ;
2012-11-10 19:39:55 +00:00
result = commander - > tryGiveCommand ( unit , unit - > getType ( ) - > getFirstCtOfClass ( commandClass ) , pos , unit - > getType ( ) , CardinalDir : : NORTH ) ;
2010-06-01 16:54:44 +00:00
return result ;
}
else {
Command * c = new Command ( world - > getFaction ( factionIndex ) - > getUnit ( unitIndex ) - > getType ( ) - > getFirstCtOfClass ( commandClass ) , pos ) ;
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2012-11-10 19:39:55 +00:00
result = world - > getFaction ( factionIndex ) - > getUnit ( unitIndex ) - > giveCommand ( c ) ;
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-06-01 16:54:44 +00:00
return result ;
}
2010-03-24 21:26:17 +00:00
}
2012-11-10 19:39:55 +00:00
std : : pair < CommandResult , string > AiInterface : : giveCommand ( const Unit * unit , const CommandType * commandType , const Vec2i & pos , int unitGroupCommandId ) {
2010-11-11 08:02:50 +00:00
assert ( this - > gameSettings ! = NULL ) ;
2012-11-10 19:39:55 +00:00
std : : pair < CommandResult , string > result ( crFailUndefined , " " ) ;
2010-11-11 08:02:50 +00:00
if ( unit = = NULL ) {
2012-10-19 01:31:20 +00:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] Can not find AI unit in AI factionIndex = %d. Game out of synch. " , __FILE__ , __FUNCTION__ , __LINE__ , factionIndex ) ;
2012-04-14 21:21:09 +00:00
throw megaglest_runtime_error ( szBuf ) ;
2010-11-11 08:02:50 +00:00
}
const UnitType * unitType = unit - > getType ( ) ;
if ( unitType = = NULL ) {
2012-10-19 01:31:20 +00:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] Can not find AI unittype with unit id: %d, AI factionIndex = %d. Game out of synch. " , __FILE__ , __FUNCTION__ , __LINE__ , unit - > getId ( ) , factionIndex ) ;
2012-04-14 21:21:09 +00:00
throw megaglest_runtime_error ( szBuf ) ;
2010-11-11 08:02:50 +00:00
}
2011-02-26 00:41:00 +00:00
if ( commandType = = NULL ) {
2012-10-19 01:31:20 +00:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] commandType == NULL, unit id: %d, AI factionIndex = %d. Game out of synch. " , __FILE__ , __FUNCTION__ , __LINE__ , unit - > getId ( ) , factionIndex ) ;
2012-04-14 21:21:09 +00:00
throw megaglest_runtime_error ( szBuf ) ;
2011-02-26 00:41:00 +00:00
}
2010-11-11 08:02:50 +00:00
const CommandType * ct = unit - > getType ( ) - > findCommandTypeById ( commandType - > getId ( ) ) ;
if ( ct = = NULL ) {
2012-10-19 01:31:20 +00:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] \n Can not find AI command type for: \n unit = %d \n [%s] \n [%s] \n actual local factionIndex = %d. \n Game out of synch. " ,
2010-11-11 08:02:50 +00:00
__FILE__ , __FUNCTION__ , __LINE__ ,
2013-06-13 08:55:48 +00:00
unit - > getId ( ) , unit - > getFullName ( false ) . c_str ( ) , unit - > getDesc ( false ) . c_str ( ) ,
2010-11-11 08:02:50 +00:00
unit - > getFaction ( ) - > getIndex ( ) ) ;
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " %s \n " , szBuf ) ;
2010-11-11 08:02:50 +00:00
std : : string worldLog = world - > DumpWorldToLog ( ) ;
std : : string sError = " worldLog = " + worldLog + " " + string ( szBuf ) ;
2012-04-14 21:21:09 +00:00
throw megaglest_runtime_error ( sError ) ;
2010-11-11 08:02:50 +00:00
}
if ( executeCommandOverNetwork ( ) = = true ) {
2012-11-10 19:39:55 +00:00
result = commander - > tryGiveCommand ( unit , commandType , pos ,
2011-07-05 04:37:35 +00:00
unit - > getType ( ) , CardinalDir : : NORTH , false , NULL , unitGroupCommandId ) ;
2010-11-11 08:02:50 +00:00
return result ;
}
else {
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-11-11 08:02:50 +00:00
2011-02-25 16:32:27 +00:00
Faction * faction = world - > getFaction ( unit - > getFactionIndex ( ) ) ;
Unit * unitToCommand = faction - > findUnit ( unit - > getId ( ) ) ;
2011-07-05 04:37:35 +00:00
Command * cmd = new Command ( commandType , pos ) ;
cmd - > setUnitCommandGroupId ( unitGroupCommandId ) ;
2012-11-10 19:39:55 +00:00
result = unitToCommand - > giveCommand ( cmd ) ;
2010-11-11 08:02:50 +00:00
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-11-11 08:02:50 +00:00
return result ;
}
}
2012-11-10 19:39:55 +00:00
std : : pair < CommandResult , string > AiInterface : : giveCommand ( int unitIndex , const CommandType * commandType , const Vec2i & pos , int unitGroupCommandId ) {
2010-06-01 16:54:44 +00:00
assert ( this - > gameSettings ! = NULL ) ;
2012-11-10 19:39:55 +00:00
std : : pair < CommandResult , string > result ( crFailUndefined , " " ) ;
2010-06-09 00:38:15 +00:00
const Unit * unit = getMyUnit ( unitIndex ) ;
if ( unit = = NULL ) {
2012-10-19 01:31:20 +00:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] Can not find AI unit with index: %d, AI factionIndex = %d. Game out of synch. " , __FILE__ , __FUNCTION__ , __LINE__ , unitIndex , factionIndex ) ;
2012-04-14 21:21:09 +00:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-09 00:38:15 +00:00
}
const UnitType * unitType = unit - > getType ( ) ;
if ( unitType = = NULL ) {
2012-10-19 01:31:20 +00:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] Can not find AI unittype with unit index: %d, AI factionIndex = %d. Game out of synch. " , __FILE__ , __FUNCTION__ , __LINE__ , unitIndex , factionIndex ) ;
2012-04-14 21:21:09 +00:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-09 00:38:15 +00:00
}
const CommandType * ct = unit - > getType ( ) - > findCommandTypeById ( commandType - > getId ( ) ) ;
if ( ct = = NULL ) {
2012-10-19 01:31:20 +00:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] \n Can not find AI command type for: \n unit = %d \n [%s] \n [%s] \n actual local factionIndex = %d. \n Game out of synch. " ,
2010-06-09 00:38:15 +00:00
__FILE__ , __FUNCTION__ , __LINE__ ,
2013-06-13 08:55:48 +00:00
unit - > getId ( ) , unit - > getFullName ( false ) . c_str ( ) , unit - > getDesc ( false ) . c_str ( ) ,
2010-06-09 00:38:15 +00:00
unit - > getFaction ( ) - > getIndex ( ) ) ;
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " %s \n " , szBuf ) ;
2010-06-09 00:38:15 +00:00
std : : string worldLog = world - > DumpWorldToLog ( ) ;
std : : string sError = " worldLog = " + worldLog + " " + string ( szBuf ) ;
2012-04-14 21:21:09 +00:00
throw megaglest_runtime_error ( sError ) ;
2010-06-09 00:38:15 +00:00
}
2010-09-14 19:10:37 +00:00
if ( executeCommandOverNetwork ( ) = = true ) {
2010-06-08 07:40:32 +00:00
const Unit * unit = getMyUnit ( unitIndex ) ;
2012-11-10 19:39:55 +00:00
result = commander - > tryGiveCommand ( unit , commandType , pos , unit - > getType ( ) , CardinalDir : : NORTH ) ;
2010-06-01 16:54:44 +00:00
return result ;
}
else {
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-06-01 16:54:44 +00:00
2011-07-05 04:37:35 +00:00
Command * cmd = new Command ( commandType , pos ) ;
cmd - > setUnitCommandGroupId ( unitGroupCommandId ) ;
2012-11-10 19:39:55 +00:00
result = world - > getFaction ( factionIndex ) - > getUnit ( unitIndex ) - > giveCommand ( cmd ) ;
2010-06-01 16:54:44 +00:00
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-06-01 16:54:44 +00:00
return result ;
}
2010-03-24 21:26:17 +00:00
}
2012-11-10 19:39:55 +00:00
std : : pair < CommandResult , string > AiInterface : : giveCommand ( int unitIndex , const CommandType * commandType , const Vec2i & pos , const UnitType * ut ) {
2010-06-01 16:54:44 +00:00
assert ( this - > gameSettings ! = NULL ) ;
2012-11-10 19:39:55 +00:00
std : : pair < CommandResult , string > result ( crFailUndefined , " " ) ;
2010-06-09 00:38:15 +00:00
const Unit * unit = getMyUnit ( unitIndex ) ;
if ( unit = = NULL ) {
2012-10-19 01:31:20 +00:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] Can not find AI unit with index: %d, AI factionIndex = %d. Game out of synch. " , __FILE__ , __FUNCTION__ , __LINE__ , unitIndex , factionIndex ) ;
2012-04-14 21:21:09 +00:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-09 00:38:15 +00:00
}
const UnitType * unitType = unit - > getType ( ) ;
if ( unitType = = NULL ) {
2012-10-19 01:31:20 +00:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] Can not find AI unittype with unit index: %d, AI factionIndex = %d. Game out of synch. " , __FILE__ , __FUNCTION__ , __LINE__ , unitIndex , factionIndex ) ;
2012-04-14 21:21:09 +00:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-09 00:38:15 +00:00
}
const CommandType * ct = unit - > getType ( ) - > findCommandTypeById ( commandType - > getId ( ) ) ;
if ( ct = = NULL ) {
2012-10-19 01:31:20 +00:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] \n Can not find AI command type for: \n unit = %d \n [%s] \n [%s] \n actual local factionIndex = %d. \n Game out of synch. " ,
2010-06-09 00:38:15 +00:00
__FILE__ , __FUNCTION__ , __LINE__ ,
2013-06-13 08:55:48 +00:00
unit - > getId ( ) , unit - > getFullName ( false ) . c_str ( ) , unit - > getDesc ( false ) . c_str ( ) ,
2010-06-09 00:38:15 +00:00
unit - > getFaction ( ) - > getIndex ( ) ) ;
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " %s \n " , szBuf ) ;
2010-06-09 00:38:15 +00:00
std : : string worldLog = world - > DumpWorldToLog ( ) ;
std : : string sError = " worldLog = " + worldLog + " " + string ( szBuf ) ;
2012-04-14 21:21:09 +00:00
throw megaglest_runtime_error ( sError ) ;
2010-06-09 00:38:15 +00:00
}
2010-09-14 19:10:37 +00:00
if ( executeCommandOverNetwork ( ) = = true ) {
2010-06-08 07:40:32 +00:00
const Unit * unit = getMyUnit ( unitIndex ) ;
2012-11-10 19:39:55 +00:00
result = commander - > tryGiveCommand ( unit , commandType , pos , ut , CardinalDir : : NORTH ) ;
2010-06-01 16:54:44 +00:00
return result ;
}
else {
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-06-01 16:54:44 +00:00
2012-11-10 19:39:55 +00:00
result = world - > getFaction ( factionIndex ) - > getUnit ( unitIndex ) - > giveCommand ( new Command ( commandType , pos , ut , CardinalDir : : NORTH ) ) ;
2010-06-01 16:54:44 +00:00
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-05-01 09:27:08 +00:00
2010-06-01 16:54:44 +00:00
return result ;
}
2010-03-24 21:26:17 +00:00
}
2012-11-10 19:39:55 +00:00
std : : pair < CommandResult , string > AiInterface : : giveCommand ( int unitIndex , const CommandType * commandType , Unit * u ) {
2010-06-01 16:54:44 +00:00
assert ( this - > gameSettings ! = NULL ) ;
assert ( this - > commander ! = NULL ) ;
2010-05-01 09:27:08 +00:00
2012-11-10 19:39:55 +00:00
std : : pair < CommandResult , string > result ( crFailUndefined , " " ) ;
2010-06-09 00:38:15 +00:00
const Unit * unit = getMyUnit ( unitIndex ) ;
if ( unit = = NULL ) {
2012-10-19 01:31:20 +00:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] Can not find AI unit with index: %d, AI factionIndex = %d. Game out of synch. " , __FILE__ , __FUNCTION__ , __LINE__ , unitIndex , factionIndex ) ;
2012-04-14 21:21:09 +00:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-09 00:38:15 +00:00
}
const UnitType * unitType = unit - > getType ( ) ;
if ( unitType = = NULL ) {
2012-10-19 01:31:20 +00:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] Can not find AI unittype with unit index: %d, AI factionIndex = %d. Game out of synch. " , __FILE__ , __FUNCTION__ , __LINE__ , unitIndex , factionIndex ) ;
2012-04-14 21:21:09 +00:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-09 00:38:15 +00:00
}
2010-06-10 14:58:06 +00:00
const CommandType * ct = ( commandType ! = NULL ? unit - > getType ( ) - > findCommandTypeById ( commandType - > getId ( ) ) : NULL ) ;
2010-06-09 00:38:15 +00:00
if ( ct = = NULL ) {
2012-10-19 01:31:20 +00:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] \n Can not find AI command type for: \n unit = %d \n [%s] \n [%s] \n actual local factionIndex = %d. \n Game out of synch. " ,
2010-06-09 00:38:15 +00:00
__FILE__ , __FUNCTION__ , __LINE__ ,
2013-06-13 08:55:48 +00:00
unit - > getId ( ) , unit - > getFullName ( false ) . c_str ( ) , unit - > getDesc ( false ) . c_str ( ) ,
2010-06-09 00:38:15 +00:00
unit - > getFaction ( ) - > getIndex ( ) ) ;
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " %s \n " , szBuf ) ;
2010-06-09 00:38:15 +00:00
std : : string worldLog = world - > DumpWorldToLog ( ) ;
std : : string sError = " worldLog = " + worldLog + " " + string ( szBuf ) ;
2012-04-14 21:21:09 +00:00
throw megaglest_runtime_error ( sError ) ;
2010-06-09 00:38:15 +00:00
}
2010-09-14 19:10:37 +00:00
if ( executeCommandOverNetwork ( ) = = true ) {
2010-06-08 07:40:32 +00:00
Unit * targetUnit = u ;
const Unit * unit = getMyUnit ( unitIndex ) ;
2010-06-01 16:54:44 +00:00
2012-11-10 19:39:55 +00:00
result = commander - > tryGiveCommand ( unit , commandType , Vec2i ( 0 ) , unit - > getType ( ) , CardinalDir : : NORTH , false , targetUnit ) ;
2010-06-01 16:54:44 +00:00
return result ;
}
else {
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-06-01 16:54:44 +00:00
2012-11-10 19:39:55 +00:00
result = world - > getFaction ( factionIndex ) - > getUnit ( unitIndex ) - > giveCommand ( new Command ( commandType , u ) ) ;
2010-06-01 16:54:44 +00:00
2011-03-28 03:54:23 +00:00
if ( SystemFlags : : getSystemSettingType ( SystemFlags : : debugSystem ) . enabled ) SystemFlags : : OutputDebug ( SystemFlags : : debugSystem , " In [%s::%s Line: %d] \n " , __FILE__ , __FUNCTION__ , __LINE__ ) ;
2010-06-01 16:54:44 +00:00
return result ;
}
2010-03-24 21:26:17 +00:00
}
2011-01-02 00:39:13 +00:00
// ==================== get data ====================
2010-03-24 21:26:17 +00:00
int AiInterface : : getMapMaxPlayers ( ) {
return world - > getMaxPlayers ( ) ;
}
Vec2i AiInterface : : getHomeLocation ( ) {
return world - > getMap ( ) - > getStartLocation ( world - > getFaction ( factionIndex ) - > getStartLocationIndex ( ) ) ;
}
Vec2i AiInterface : : getStartLocation ( int loactionIndex ) {
return world - > getMap ( ) - > getStartLocation ( loactionIndex ) ;
}
int AiInterface : : getFactionCount ( ) {
return world - > getFactionCount ( ) ;
}
int AiInterface : : getMyUnitCount ( ) const {
return world - > getFaction ( factionIndex ) - > getUnitCount ( ) ;
}
int AiInterface : : getMyUpgradeCount ( ) const {
return world - > getFaction ( factionIndex ) - > getUpgradeManager ( ) - > getUpgradeCount ( ) ;
}
2011-02-03 19:19:27 +00:00
int AiInterface : : onSightUnitCount ( ) {
2010-03-24 21:26:17 +00:00
int count = 0 ;
Map * map = world - > getMap ( ) ;
2011-02-03 19:19:27 +00:00
for ( int i = 0 ; i < world - > getFactionCount ( ) ; + + i ) {
for ( int j = 0 ; j < world - > getFaction ( i ) - > getUnitCount ( ) ; + + j ) {
Unit * unit = world - > getFaction ( i ) - > getUnit ( j ) ;
SurfaceCell * sc = map - > getSurfaceCell ( Map : : toSurfCoords ( unit - > getPos ( ) ) ) ;
bool cannotSeeUnit = ( unit - > getType ( ) - > hasCellMap ( ) = = true & &
unit - > getType ( ) - > getAllowEmptyCellMap ( ) = = true & &
unit - > getType ( ) - > hasEmptyCellMap ( ) = = true ) ;
if ( sc - > isVisible ( teamIndex ) & & cannotSeeUnit = = false ) {
2011-01-02 00:39:13 +00:00
count + + ;
2010-03-24 21:26:17 +00:00
}
2011-01-02 00:39:13 +00:00
}
2010-03-24 21:26:17 +00:00
}
return count ;
}
const Resource * AiInterface : : getResource ( const ResourceType * rt ) {
return world - > getFaction ( factionIndex ) - > getResource ( rt ) ;
}
2011-05-01 05:36:04 +00:00
Unit * AiInterface : : getMyUnitPtr ( int unitIndex ) {
2010-06-08 07:40:32 +00:00
if ( unitIndex > = world - > getFaction ( factionIndex ) - > getUnitCount ( ) ) {
2012-10-19 01:31:20 +00:00
char szBuf [ 8096 ] = " " ;
snprintf ( szBuf , 8096 , " In [%s::%s Line: %d] unitIndex >= world->getFaction(factionIndex)->getUnitCount(), unitIndex = %d, world->getFaction(factionIndex)->getUnitCount() = %d " , __FILE__ , __FUNCTION__ , __LINE__ , unitIndex , world - > getFaction ( factionIndex ) - > getUnitCount ( ) ) ;
2012-04-14 21:21:09 +00:00
throw megaglest_runtime_error ( szBuf ) ;
2010-06-08 07:40:32 +00:00
}
return world - > getFaction ( factionIndex ) - > getUnit ( unitIndex ) ;
2010-03-24 21:26:17 +00:00
}
2011-05-01 05:36:04 +00:00
const Unit * AiInterface : : getMyUnit ( int unitIndex ) {
return getMyUnitPtr ( unitIndex ) ;
}
2011-02-03 19:19:27 +00:00
const Unit * AiInterface : : getOnSightUnit ( int unitIndex ) {
2011-01-02 00:39:13 +00:00
2010-03-24 21:26:17 +00:00
int count = 0 ;
Map * map = world - > getMap ( ) ;
2011-02-03 19:19:27 +00:00
for ( int i = 0 ; i < world - > getFactionCount ( ) ; + + i ) {
for ( int j = 0 ; j < world - > getFaction ( i ) - > getUnitCount ( ) ; + + j ) {
Unit * unit = world - > getFaction ( i ) - > getUnit ( j ) ;
SurfaceCell * sc = map - > getSurfaceCell ( Map : : toSurfCoords ( unit - > getPos ( ) ) ) ;
bool cannotSeeUnit = ( unit - > getType ( ) - > hasCellMap ( ) = = true & &
unit - > getType ( ) - > getAllowEmptyCellMap ( ) = = true & &
unit - > getType ( ) - > hasEmptyCellMap ( ) = = true ) ;
if ( sc - > isVisible ( teamIndex ) & & cannotSeeUnit = = false ) {
if ( count = = unitIndex ) {
return unit ;
2010-03-24 21:26:17 +00:00
}
2011-02-03 19:19:27 +00:00
else {
2010-03-24 21:26:17 +00:00
count + + ;
}
}
}
}
return NULL ;
}
const FactionType * AiInterface : : getMyFactionType ( ) {
return world - > getFaction ( factionIndex ) - > getType ( ) ;
}
const ControlType AiInterface : : getControlType ( ) {
return world - > getFaction ( factionIndex ) - > getControlType ( ) ;
}
const TechTree * AiInterface : : getTechTree ( ) {
return world - > getTechTree ( ) ;
}
2011-06-25 18:14:20 +00:00
bool AiInterface : : isResourceInRegion ( const Vec2i & pos , const ResourceType * rt , Vec2i & resourcePos , int range ) const {
const Map * map = world - > getMap ( ) ;
2014-01-27 19:23:31 +01:00
2011-06-25 18:14:20 +00:00
int xi = 1 ;
int xj = 1 ;
2014-01-27 19:23:31 +01:00
if ( rand ( ) % 2 = = 1 ) {
2011-06-25 18:14:20 +00:00
xi = - 1 ;
}
2014-01-27 19:23:31 +01:00
if ( rand ( ) % 2 = = 1 ) {
2011-06-25 18:14:20 +00:00
xj = - 1 ;
}
for ( int i = - range ; i < = range ; + + i ) {
for ( int j = - range ; j < = range ; + + j ) {
int ii = xi * i ;
int jj = xj * j ;
if ( map - > isInside ( pos . x + ii , pos . y + jj ) ) {
Resource * r = map - > getSurfaceCell ( map - > toSurfCoords ( Vec2i ( pos . x + ii , pos . y + jj ) ) ) - > getResource ( ) ;
if ( r ! = NULL ) {
if ( r - > getType ( ) = = rt ) {
resourcePos = pos + Vec2i ( ii , jj ) ;
return true ;
}
}
}
}
}
return false ;
}
2010-11-07 03:27:06 +00:00
//returns if there is a resource next to a unit, in "resourcePos" is stored the relative position of the resource
bool AiInterface : : isResourceNear ( const Vec2i & pos , const ResourceType * rt , Vec2i & resourcePos , Faction * faction , bool fallbackToPeersHarvestingSameResource ) const {
const Map * map = world - > getMap ( ) ;
int size = 1 ;
for ( int i = - 1 ; i < = size ; + + i ) {
for ( int j = - 1 ; j < = size ; + + j ) {
if ( map - > isInside ( pos . x + i , pos . y + j ) ) {
Resource * r = map - > getSurfaceCell ( map - > toSurfCoords ( Vec2i ( pos . x + i , pos . y + j ) ) ) - > getResource ( ) ;
if ( r ! = NULL ) {
if ( r - > getType ( ) = = rt ) {
resourcePos = pos + Vec2i ( i , j ) ;
2010-11-30 23:32:39 +00:00
2010-11-07 03:27:06 +00:00
return true ;
}
}
}
}
}
if ( fallbackToPeersHarvestingSameResource = = true & & faction ! = NULL ) {
// Look for another unit that is currently harvesting the same resource
// type right now
// Check the faction cache for a known position where we can harvest
// this resource type
Vec2i result = faction - > getClosestResourceTypeTargetFromCache ( pos , rt ) ;
if ( result . x > = 0 ) {
resourcePos = result ;
2010-11-30 23:32:39 +00:00
2010-11-07 03:27:06 +00:00
if ( pos . dist ( resourcePos ) < = size ) {
return true ;
}
}
}
return false ;
}
2010-10-02 01:11:59 +00:00
bool AiInterface : : getNearestSightedResource ( const ResourceType * rt , const Vec2i & pos ,
Vec2i & resultPos , bool usableResourceTypeOnly ) {
2010-11-09 09:06:52 +00:00
Faction * faction = world - > getFaction ( factionIndex ) ;
2011-08-31 23:10:43 +00:00
//float tmpDist=0;
2010-03-24 21:26:17 +00:00
float nearestDist = infinity ;
bool anyResource = false ;
2010-11-09 09:06:52 +00:00
resultPos . x = - 1 ;
resultPos . y = - 1 ;
2010-03-24 21:26:17 +00:00
2010-10-02 01:11:59 +00:00
bool canUseResourceType = ( usableResourceTypeOnly = = false ) ;
if ( usableResourceTypeOnly = = true ) {
// can any unit harvest this resource yet?
2010-11-09 09:06:52 +00:00
std : : map < const ResourceType * , int > : : iterator iterFind = cacheUnitHarvestResourceLookup . find ( rt ) ;
if ( iterFind ! = cacheUnitHarvestResourceLookup . end ( ) & &
faction - > findUnit ( iterFind - > second ) ! = NULL ) {
canUseResourceType = true ;
}
else {
int unitCount = getMyUnitCount ( ) ;
for ( int i = 0 ; i < unitCount ; + + i ) {
const Unit * unit = getMyUnit ( i ) ;
const HarvestCommandType * hct = unit - > getType ( ) - > getFirstHarvestCommand ( rt , unit - > getFaction ( ) ) ;
if ( hct ! = NULL ) {
canUseResourceType = true ;
cacheUnitHarvestResourceLookup [ rt ] = unit - > getId ( ) ;
break ;
}
2010-10-02 01:11:59 +00:00
}
}
}
if ( canUseResourceType = = true ) {
2010-11-09 09:06:52 +00:00
bool isResourceClose = isResourceNear ( pos , rt , resultPos , faction , true ) ;
// Found a resource
if ( isResourceClose = = true | | resultPos . x > = 0 ) {
2010-11-07 03:27:06 +00:00
anyResource = true ;
}
else {
2010-11-09 09:06:52 +00:00
const Map * map = world - > getMap ( ) ;
2010-11-07 03:27:06 +00:00
for ( int i = 0 ; i < map - > getW ( ) ; + + i ) {
for ( int j = 0 ; j < map - > getH ( ) ; + + j ) {
2010-11-09 09:06:52 +00:00
Vec2i resPos = Vec2i ( i , j ) ;
Vec2i surfPos = Map : : toSurfCoords ( resPos ) ;
SurfaceCell * sc = map - > getSurfaceCell ( surfPos ) ;
2010-11-07 03:27:06 +00:00
//if explored cell
2010-11-09 09:06:52 +00:00
if ( sc ! = NULL & & sc - > isExplored ( teamIndex ) ) {
Resource * r = sc - > getResource ( ) ;
2010-11-07 03:27:06 +00:00
//if resource cell
2010-11-09 09:06:52 +00:00
if ( r ! = NULL ) {
if ( r - > getType ( ) = = rt ) {
2011-08-31 23:10:43 +00:00
float tmpDist = pos . dist ( resPos ) ;
2010-11-09 09:06:52 +00:00
if ( tmpDist < nearestDist ) {
anyResource = true ;
nearestDist = tmpDist ;
resultPos = resPos ;
}
2010-11-07 03:27:06 +00:00
}
2010-10-02 01:11:59 +00:00
}
2010-03-24 21:26:17 +00:00
}
}
}
}
}
return anyResource ;
}
bool AiInterface : : isAlly ( const Unit * unit ) const {
return world - > getFaction ( factionIndex ) - > isAlly ( unit - > getFaction ( ) ) ;
}
bool AiInterface : : reqsOk ( const RequirableType * rt ) {
return world - > getFaction ( factionIndex ) - > reqsOk ( rt ) ;
}
bool AiInterface : : reqsOk ( const CommandType * ct ) {
return world - > getFaction ( factionIndex ) - > reqsOk ( ct ) ;
}
2012-03-27 03:23:03 +00:00
bool AiInterface : : checkCosts ( const ProducibleType * pt , const CommandType * ct ) {
return world - > getFaction ( factionIndex ) - > checkCosts ( pt , ct ) ;
2010-03-24 21:26:17 +00:00
}
bool AiInterface : : isFreeCells ( const Vec2i & pos , int size , Field field ) {
return world - > getMap ( ) - > isFreeCells ( pos , size , field ) ;
}
2013-01-12 01:55:13 +00:00
void AiInterface : : removeEnemyWarningPositionFromList ( Vec2i & checkPos ) {
2013-11-02 11:04:52 +00:00
for ( int i = ( int ) enemyWarningPositionList . size ( ) - 1 ; i > = 0 ; - - i ) {
2013-01-12 01:55:13 +00:00
Vec2i & pos = enemyWarningPositionList [ i ] ;
if ( checkPos = = pos ) {
enemyWarningPositionList . erase ( enemyWarningPositionList . begin ( ) + i ) ;
break ;
}
}
}
2011-02-04 06:34:32 +00:00
const Unit * AiInterface : : getFirstOnSightEnemyUnit ( Vec2i & pos , Field & field , int radius ) {
Map * map = world - > getMap ( ) ;
2013-01-12 01:55:13 +00:00
const int CHECK_RADIUS = 12 ;
const int WARNING_ENEMY_COUNT = 6 ;
2011-02-04 06:34:32 +00:00
for ( int i = 0 ; i < world - > getFactionCount ( ) ; + + i ) {
for ( int j = 0 ; j < world - > getFaction ( i ) - > getUnitCount ( ) ; + + j ) {
Unit * unit = world - > getFaction ( i ) - > getUnit ( j ) ;
SurfaceCell * sc = map - > getSurfaceCell ( Map : : toSurfCoords ( unit - > getPos ( ) ) ) ;
bool cannotSeeUnit = ( unit - > getType ( ) - > hasCellMap ( ) = = true & &
unit - > getType ( ) - > getAllowEmptyCellMap ( ) = = true & &
unit - > getType ( ) - > hasEmptyCellMap ( ) = = true ) ;
if ( sc - > isVisible ( teamIndex ) & & cannotSeeUnit = = false & &
isAlly ( unit ) = = false & & unit - > isAlive ( ) = = true ) {
pos = unit - > getPos ( ) ;
field = unit - > getCurrField ( ) ;
if ( pos . dist ( getHomeLocation ( ) ) < radius ) {
printLog ( 2 , " Being attacked at pos " + intToStr ( pos . x ) + " , " + intToStr ( pos . y ) + " \n " ) ;
2013-01-12 01:55:13 +00:00
// Now check if there are more than x enemies in sight and if
// so make note of the position
int foundEnemies = 0 ;
std : : map < int , bool > foundEnemyList ;
for ( int aiX = pos . x - CHECK_RADIUS ; aiX < pos . x + CHECK_RADIUS ; + + aiX ) {
for ( int aiY = pos . y - CHECK_RADIUS ; aiY < pos . y + CHECK_RADIUS ; + + aiY ) {
Vec2i checkPos ( aiX , aiY ) ;
if ( map - > isInside ( checkPos ) & & map - > isInsideSurface ( map - > toSurfCoords ( checkPos ) ) ) {
Cell * cAI = map - > getCell ( checkPos ) ;
SurfaceCell * scAI = map - > getSurfaceCell ( Map : : toSurfCoords ( checkPos ) ) ;
if ( scAI ! = NULL & & cAI ! = NULL & & cAI - > getUnit ( field ) ! = NULL & & sc - > isVisible ( teamIndex ) ) {
const Unit * checkUnit = cAI - > getUnit ( field ) ;
if ( foundEnemyList . find ( checkUnit - > getId ( ) ) = = foundEnemyList . end ( ) ) {
bool cannotSeeUnitAI = ( checkUnit - > getType ( ) - > hasCellMap ( ) = = true & &
checkUnit - > getType ( ) - > getAllowEmptyCellMap ( ) = = true & &
checkUnit - > getType ( ) - > hasEmptyCellMap ( ) = = true ) ;
if ( cannotSeeUnitAI = = false & & isAlly ( checkUnit ) = = false
& & checkUnit - > isAlive ( ) = = true ) {
foundEnemies + + ;
foundEnemyList [ checkUnit - > getId ( ) ] = true ;
}
}
}
}
}
}
if ( foundEnemies > = WARNING_ENEMY_COUNT ) {
if ( std : : find ( enemyWarningPositionList . begin ( ) , enemyWarningPositionList . end ( ) , pos ) = = enemyWarningPositionList . end ( ) ) {
enemyWarningPositionList . push_back ( pos ) ;
}
}
2011-02-04 06:34:32 +00:00
return unit ;
}
}
}
}
return NULL ;
}
2011-02-25 16:32:27 +00:00
Map * AiInterface : : getMap ( ) {
Map * map = world - > getMap ( ) ;
return map ;
}
2011-02-04 06:34:32 +00:00
2011-04-06 15:44:33 +00:00
bool AiInterface : : factionUsesResourceType ( const FactionType * factionType , const ResourceType * rt ) {
2011-04-06 17:50:20 +00:00
bool factionUsesResourceType = factionType - > factionUsesResourceType ( rt ) ;
2011-04-06 15:44:33 +00:00
return factionUsesResourceType ;
}
2012-03-10 03:27:25 +00:00
void AiInterface : : saveGame ( XmlNode * rootNode ) const {
std : : map < string , string > mapTagReplacements ;
XmlNode * aiInterfaceNode = rootNode - > addChild ( " AiInterface " ) ;
// World *world;
// Commander *commander;
// Console *console;
// GameSettings *gameSettings;
//
// Ai ai;
ai . saveGame ( aiInterfaceNode ) ;
// int timer;
aiInterfaceNode - > addAttribute ( " timer " , intToStr ( timer ) , mapTagReplacements ) ;
// int factionIndex;
aiInterfaceNode - > addAttribute ( " factionIndex " , intToStr ( factionIndex ) , mapTagReplacements ) ;
// int teamIndex;
aiInterfaceNode - > addAttribute ( " teamIndex " , intToStr ( teamIndex ) , mapTagReplacements ) ;
// //config
// bool redir;
aiInterfaceNode - > addAttribute ( " redir " , intToStr ( redir ) , mapTagReplacements ) ;
// int logLevel;
aiInterfaceNode - > addAttribute ( " logLevel " , intToStr ( logLevel ) , mapTagReplacements ) ;
// std::map<const ResourceType *,int> cacheUnitHarvestResourceLookup;
for ( std : : map < const ResourceType * , int > : : const_iterator iterMap = cacheUnitHarvestResourceLookup . begin ( ) ;
iterMap ! = cacheUnitHarvestResourceLookup . end ( ) ; + + iterMap ) {
XmlNode * cacheUnitHarvestResourceLookupNode = aiInterfaceNode - > addChild ( " cacheUnitHarvestResourceLookup " ) ;
cacheUnitHarvestResourceLookupNode - > addAttribute ( " key " , iterMap - > first - > getName ( ) , mapTagReplacements ) ;
cacheUnitHarvestResourceLookupNode - > addAttribute ( " value " , intToStr ( iterMap - > second ) , mapTagReplacements ) ;
}
}
2012-03-13 15:21:25 +00:00
// AiInterface::AiInterface(Game &game, int factionIndex, int teamIndex, int useStartLocation) {
void AiInterface : : loadGame ( const XmlNode * rootNode , Faction * faction ) {
XmlNode * aiInterfaceNode = NULL ;
vector < XmlNode * > aiInterfaceNodeList = rootNode - > getChildList ( " AiInterface " ) ;
for ( unsigned int i = 0 ; i < aiInterfaceNodeList . size ( ) ; + + i ) {
XmlNode * node = aiInterfaceNodeList [ i ] ;
if ( node - > getAttribute ( " factionIndex " ) - > getIntValue ( ) = = faction - > getIndex ( ) ) {
aiInterfaceNode = node ;
break ;
}
}
if ( aiInterfaceNode ! = NULL ) {
factionIndex = aiInterfaceNode - > getAttribute ( " factionIndex " ) - > getIntValue ( ) ;
teamIndex = aiInterfaceNode - > getAttribute ( " teamIndex " ) - > getIntValue ( ) ;
ai . loadGame ( aiInterfaceNode , faction ) ;
//firstTime = timeflowNode->getAttribute("firstTime")->getFloatValue();
timer = aiInterfaceNode - > getAttribute ( " timer " ) - > getIntValue ( ) ;
// int factionIndex;
2012-10-06 07:06:40 +00:00
//factionIndex = aiInterfaceNode->getAttribute("factionIndex")->getIntValue();
2012-03-13 15:21:25 +00:00
// int teamIndex;
2012-10-06 07:06:40 +00:00
//teamIndex = aiInterfaceNode->getAttribute("teamIndex")->getIntValue();
2012-03-13 15:21:25 +00:00
// //config
// bool redir;
2012-04-16 20:15:57 +00:00
redir = aiInterfaceNode - > getAttribute ( " redir " ) - > getIntValue ( ) ! = 0 ;
2012-03-13 15:21:25 +00:00
// int logLevel;
logLevel = aiInterfaceNode - > getAttribute ( " logLevel " ) - > getIntValue ( ) ;
// std::map<const ResourceType *,int> cacheUnitHarvestResourceLookup;
// for(std::map<const ResourceType *,int>::const_iterator iterMap = cacheUnitHarvestResourceLookup.begin();
// iterMap != cacheUnitHarvestResourceLookup.end(); ++iterMap) {
// XmlNode *cacheUnitHarvestResourceLookupNode = aiInterfaceNode->addChild("cacheUnitHarvestResourceLookup");
//
// cacheUnitHarvestResourceLookupNode->addAttribute("key",iterMap->first->getName(), mapTagReplacements);
// cacheUnitHarvestResourceLookupNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements);
// }
}
}
2010-03-24 21:26:17 +00:00
} } //end namespace