mirror of
https://github.com/glest/glest-source.git
synced 2025-02-24 19:52:25 +01:00
991 lines
37 KiB
C++
991 lines
37 KiB
C++
// ==============================================================
|
|
// This file is part of Glest (www.glest.org)
|
|
//
|
|
// Copyright (C) 2001-2008 Martiño Figueroa
|
|
//
|
|
// 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 "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"
|
|
#include "network_manager.h"
|
|
#include "platform_util.h"
|
|
#include "leak_dumper.h"
|
|
|
|
using namespace Shared::Util;
|
|
using namespace Shared::Graphics;
|
|
|
|
// =====================================================
|
|
// class AiInterface
|
|
// =====================================================
|
|
|
|
namespace Glest{ namespace Game{
|
|
|
|
// =====================================================
|
|
// class FactionThread
|
|
// =====================================================
|
|
|
|
AiInterfaceThread::AiInterfaceThread(AiInterface *aiIntf) : BaseThread() {
|
|
this->masterController = NULL;
|
|
this->triggerIdMutex = new Mutex(CODE_AT_LINE);
|
|
this->aiIntf = aiIntf;
|
|
uniqueID = "AiInterfaceThread";
|
|
}
|
|
|
|
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);
|
|
deleteSelfIfRequired();
|
|
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;
|
|
}
|
|
|
|
void AiInterfaceThread::signalQuit() {
|
|
if(this->aiIntf != NULL) {
|
|
MutexSafeWrapper safeMutex(this->aiIntf->getMutex(),string(__FILE__) + "_" + intToStr(__LINE__));
|
|
this->aiIntf = NULL;
|
|
}
|
|
|
|
BaseThread::signalQuit();
|
|
}
|
|
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);
|
|
|
|
//bool minorDebugPerformance = false;
|
|
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();
|
|
|
|
static string masterSlaveOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MasterSlaveThreadControllerSafeWrapper safeMasterController(masterController,20000,masterSlaveOwnerId);
|
|
|
|
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) {
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
this->aiMutex = new Mutex(CODE_AT_LINE);
|
|
this->workerThread = NULL;
|
|
this->world= game.getWorld();
|
|
this->commander= game.getCommander();
|
|
this->console= game.getConsole();
|
|
this->gameSettings = game.getGameSettings();
|
|
|
|
this->factionIndex= factionIndex;
|
|
this->teamIndex= teamIndex;
|
|
timer= 0;
|
|
|
|
//init ai
|
|
ai.init(this,useStartLocation);
|
|
|
|
//config
|
|
logLevel= Config::getInstance().getInt("AiLog");
|
|
redir= Config::getInstance().getBool("AiRedir");
|
|
|
|
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;
|
|
}
|
|
|
|
//clear log file
|
|
if(logLevel > 0) {
|
|
#ifdef WIN32
|
|
fp = _wfopen(::Shared::Platform::utf8_decode(aiLogFile).c_str(), L"wt");
|
|
#else
|
|
fp = fopen(aiLogFile.c_str(), "wt");
|
|
#endif
|
|
if(fp == NULL) {
|
|
throw megaglest_runtime_error("Can't open file: [" + aiLogFile + "]");
|
|
}
|
|
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);
|
|
}
|
|
|
|
|
|
if( Config::getInstance().getBool("EnableAIWorkerThreads","true") == true) {
|
|
if(workerThread != NULL) {
|
|
workerThread->signalQuit();
|
|
if(workerThread->shutdownAndWait() == true) {
|
|
delete workerThread;
|
|
}
|
|
workerThread = NULL;
|
|
}
|
|
static string mutexOwnerId = string(extractFileFromDirectoryPath(__FILE__).c_str()) + string("_") + intToStr(__LINE__);
|
|
this->workerThread = new AiInterfaceThread(this);
|
|
this->workerThread->setUniqueID(mutexOwnerId);
|
|
this->workerThread->start();
|
|
}
|
|
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
AiInterface::~AiInterface() {
|
|
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);
|
|
cacheUnitHarvestResourceLookup.clear();
|
|
|
|
if(workerThread != NULL) {
|
|
workerThread->signalQuit();
|
|
sleep(0);
|
|
if(workerThread->canShutdown(true) == true &&
|
|
workerThread->shutdownAndWait() == true) {
|
|
delete workerThread;
|
|
}
|
|
workerThread = NULL;
|
|
}
|
|
|
|
if(fp) {
|
|
fclose(fp);
|
|
fp = NULL;
|
|
}
|
|
|
|
delete aiMutex;
|
|
aiMutex = NULL;
|
|
}
|
|
|
|
void AiInterface::signalWorkerThread(int frameIndex) {
|
|
if(workerThread != NULL) {
|
|
workerThread->signal(frameIndex);
|
|
}
|
|
else {
|
|
this->update();
|
|
}
|
|
}
|
|
|
|
bool AiInterface::isWorkerThreadSignalCompleted(int frameIndex) {
|
|
if(workerThread != NULL) {
|
|
return workerThread->isSignalCompleted(frameIndex);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// ==================== main ====================
|
|
|
|
void AiInterface::update() {
|
|
timer++;
|
|
ai.update();
|
|
}
|
|
|
|
// ==================== misc ====================
|
|
|
|
bool AiInterface::isLogLevelEnabled(int level) {
|
|
return (this->logLevel >= level);
|
|
}
|
|
|
|
void AiInterface::printLog(int logLevel, const string &s){
|
|
if(isLogLevelEnabled(logLevel) == true) {
|
|
string logString= "(" + intToStr(factionIndex) + ") " + s;
|
|
|
|
MutexSafeWrapper safeMutex(aiMutex,string(__FILE__) + "_" + intToStr(__LINE__));
|
|
//print log to file
|
|
if(fp != NULL) {
|
|
fprintf(fp, "%s\n", logString.c_str());
|
|
}
|
|
|
|
//redirect to console
|
|
if(redir) {
|
|
console->addLine(logString);
|
|
}
|
|
}
|
|
}
|
|
|
|
// ==================== interaction ====================
|
|
|
|
Faction *AiInterface::getMyFaction() {
|
|
return world->getFaction(factionIndex);
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
std::pair<CommandResult,string> AiInterface::giveCommandSwitchTeamVote(const Faction* faction, SwitchTeamVote *vote) {
|
|
assert(this->gameSettings != NULL);
|
|
|
|
commander->trySwitchTeamVote(faction,vote);
|
|
return std::pair<CommandResult,string>(crSuccess,"");
|
|
}
|
|
|
|
std::pair<CommandResult,string> AiInterface::giveCommand(int unitIndex, CommandClass commandClass, const Vec2i &pos){
|
|
assert(this->gameSettings != NULL);
|
|
|
|
std::pair<CommandResult,string> result(crFailUndefined,"");
|
|
if(executeCommandOverNetwork() == true) {
|
|
const Unit *unit = getMyUnit(unitIndex);
|
|
result = commander->tryGiveCommand(unit, unit->getType()->getFirstCtOfClass(commandClass), pos, unit->getType(),CardinalDir::NORTH);
|
|
return result;
|
|
}
|
|
else {
|
|
Command *c= new Command (world->getFaction(factionIndex)->getUnit(unitIndex)->getType()->getFirstCtOfClass(commandClass), pos);
|
|
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
|
result = world->getFaction(factionIndex)->getUnit(unitIndex)->giveCommand(c);
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
std::pair<CommandResult,string> AiInterface::giveCommand(const Unit *unit, const CommandType *commandType, const Vec2i &pos, int unitGroupCommandId) {
|
|
assert(this->gameSettings != NULL);
|
|
|
|
std::pair<CommandResult,string> result(crFailUndefined,"");
|
|
if(unit == NULL) {
|
|
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);
|
|
throw megaglest_runtime_error(szBuf);
|
|
}
|
|
const UnitType* unitType= unit->getType();
|
|
if(unitType == NULL) {
|
|
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);
|
|
throw megaglest_runtime_error(szBuf);
|
|
}
|
|
if(commandType == NULL) {
|
|
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);
|
|
throw megaglest_runtime_error(szBuf);
|
|
}
|
|
const CommandType* ct= unit->getType()->findCommandTypeById(commandType->getId());
|
|
if(ct == NULL) {
|
|
char szBuf[8096]="";
|
|
snprintf(szBuf,8096,"In [%s::%s Line: %d]\nCan not find AI command type for:\nunit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nGame out of synch.",
|
|
__FILE__,__FUNCTION__,__LINE__,
|
|
unit->getId(), unit->getFullName(false).c_str(),unit->getDesc(false).c_str(),
|
|
unit->getFaction()->getIndex());
|
|
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n",szBuf);
|
|
|
|
std::string worldLog = world->DumpWorldToLog();
|
|
std::string sError = "worldLog = " + worldLog + " " + string(szBuf);
|
|
throw megaglest_runtime_error(sError);
|
|
}
|
|
|
|
if(executeCommandOverNetwork() == true) {
|
|
result = commander->tryGiveCommand(unit, commandType, pos,
|
|
unit->getType(),CardinalDir::NORTH, false, NULL,unitGroupCommandId);
|
|
return result;
|
|
}
|
|
else {
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
Faction *faction = world->getFaction(unit->getFactionIndex());
|
|
Unit *unitToCommand = faction->findUnit(unit->getId());
|
|
Command *cmd = new Command(commandType, pos);
|
|
cmd->setUnitCommandGroupId(unitGroupCommandId);
|
|
result = unitToCommand->giveCommand(cmd);
|
|
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
std::pair<CommandResult,string> AiInterface::giveCommand(int unitIndex, const CommandType *commandType, const Vec2i &pos, int unitGroupCommandId) {
|
|
assert(this->gameSettings != NULL);
|
|
|
|
std::pair<CommandResult,string> result(crFailUndefined,"");
|
|
const Unit *unit = getMyUnit(unitIndex);
|
|
if(unit == NULL) {
|
|
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);
|
|
throw megaglest_runtime_error(szBuf);
|
|
}
|
|
const UnitType* unitType= unit->getType();
|
|
if(unitType == NULL) {
|
|
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);
|
|
throw megaglest_runtime_error(szBuf);
|
|
}
|
|
const CommandType* ct= unit->getType()->findCommandTypeById(commandType->getId());
|
|
if(ct == NULL) {
|
|
char szBuf[8096]="";
|
|
snprintf(szBuf,8096,"In [%s::%s Line: %d]\nCan not find AI command type for:\nunit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nGame out of synch.",
|
|
__FILE__,__FUNCTION__,__LINE__,
|
|
unit->getId(), unit->getFullName(false).c_str(),unit->getDesc(false).c_str(),
|
|
unit->getFaction()->getIndex());
|
|
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n",szBuf);
|
|
|
|
std::string worldLog = world->DumpWorldToLog();
|
|
std::string sError = "worldLog = " + worldLog + " " + string(szBuf);
|
|
throw megaglest_runtime_error(sError);
|
|
}
|
|
|
|
if(executeCommandOverNetwork() == true) {
|
|
const Unit *unit = getMyUnit(unitIndex);
|
|
result = commander->tryGiveCommand(unit, commandType, pos, unit->getType(),CardinalDir::NORTH);
|
|
return result;
|
|
}
|
|
else {
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
Command *cmd = new Command(commandType, pos);
|
|
cmd->setUnitCommandGroupId(unitGroupCommandId);
|
|
result = world->getFaction(factionIndex)->getUnit(unitIndex)->giveCommand(cmd);
|
|
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
std::pair<CommandResult,string> AiInterface::giveCommand(int unitIndex, const CommandType *commandType, const Vec2i &pos, const UnitType *ut) {
|
|
assert(this->gameSettings != NULL);
|
|
|
|
std::pair<CommandResult,string> result(crFailUndefined,"");
|
|
const Unit *unit = getMyUnit(unitIndex);
|
|
if(unit == NULL) {
|
|
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);
|
|
throw megaglest_runtime_error(szBuf);
|
|
}
|
|
const UnitType* unitType= unit->getType();
|
|
if(unitType == NULL) {
|
|
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);
|
|
throw megaglest_runtime_error(szBuf);
|
|
}
|
|
const CommandType* ct= unit->getType()->findCommandTypeById(commandType->getId());
|
|
if(ct == NULL) {
|
|
char szBuf[8096]="";
|
|
snprintf(szBuf,8096,"In [%s::%s Line: %d]\nCan not find AI command type for:\nunit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nGame out of synch.",
|
|
__FILE__,__FUNCTION__,__LINE__,
|
|
unit->getId(), unit->getFullName(false).c_str(),unit->getDesc(false).c_str(),
|
|
unit->getFaction()->getIndex());
|
|
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n",szBuf);
|
|
|
|
std::string worldLog = world->DumpWorldToLog();
|
|
std::string sError = "worldLog = " + worldLog + " " + string(szBuf);
|
|
throw megaglest_runtime_error(sError);
|
|
}
|
|
|
|
if(executeCommandOverNetwork() == true) {
|
|
const Unit *unit = getMyUnit(unitIndex);
|
|
result = commander->tryGiveCommand(unit, commandType, pos, ut,CardinalDir::NORTH);
|
|
return result;
|
|
}
|
|
else {
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
result = world->getFaction(factionIndex)->getUnit(unitIndex)->giveCommand(new Command(commandType, pos, ut, CardinalDir::NORTH));
|
|
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
std::pair<CommandResult,string> AiInterface::giveCommand(int unitIndex, const CommandType *commandType, Unit *u){
|
|
assert(this->gameSettings != NULL);
|
|
assert(this->commander != NULL);
|
|
|
|
std::pair<CommandResult,string> result(crFailUndefined,"");
|
|
const Unit *unit = getMyUnit(unitIndex);
|
|
if(unit == NULL) {
|
|
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);
|
|
throw megaglest_runtime_error(szBuf);
|
|
}
|
|
const UnitType* unitType= unit->getType();
|
|
if(unitType == NULL) {
|
|
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);
|
|
throw megaglest_runtime_error(szBuf);
|
|
}
|
|
const CommandType* ct= (commandType != NULL ? unit->getType()->findCommandTypeById(commandType->getId()) : NULL);
|
|
if(ct == NULL) {
|
|
char szBuf[8096]="";
|
|
snprintf(szBuf,8096,"In [%s::%s Line: %d]\nCan not find AI command type for:\nunit = %d\n[%s]\n[%s]\nactual local factionIndex = %d.\nGame out of synch.",
|
|
__FILE__,__FUNCTION__,__LINE__,
|
|
unit->getId(), unit->getFullName(false).c_str(),unit->getDesc(false).c_str(),
|
|
unit->getFaction()->getIndex());
|
|
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s\n",szBuf);
|
|
|
|
std::string worldLog = world->DumpWorldToLog();
|
|
std::string sError = "worldLog = " + worldLog + " " + string(szBuf);
|
|
throw megaglest_runtime_error(sError);
|
|
}
|
|
|
|
if(executeCommandOverNetwork() == true) {
|
|
Unit *targetUnit = u;
|
|
const Unit *unit = getMyUnit(unitIndex);
|
|
|
|
result = commander->tryGiveCommand(unit, commandType, Vec2i(0), unit->getType(),CardinalDir::NORTH,false,targetUnit);
|
|
|
|
return result;
|
|
}
|
|
else {
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
result = world->getFaction(factionIndex)->getUnit(unitIndex)->giveCommand(new Command(commandType, u));
|
|
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
// ==================== get data ====================
|
|
|
|
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();
|
|
}
|
|
|
|
int AiInterface::onSightUnitCount() {
|
|
int count=0;
|
|
Map *map= world->getMap();
|
|
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) {
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
const Resource *AiInterface::getResource(const ResourceType *rt){
|
|
return world->getFaction(factionIndex)->getResource(rt);
|
|
}
|
|
|
|
Unit *AiInterface::getMyUnitPtr(int unitIndex) {
|
|
if(unitIndex >= world->getFaction(factionIndex)->getUnitCount()) {
|
|
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());
|
|
throw megaglest_runtime_error(szBuf);
|
|
}
|
|
|
|
return world->getFaction(factionIndex)->getUnit(unitIndex);
|
|
}
|
|
|
|
const Unit *AiInterface::getMyUnit(int unitIndex) {
|
|
return getMyUnitPtr(unitIndex);
|
|
}
|
|
|
|
const Unit *AiInterface::getOnSightUnit(int unitIndex) {
|
|
|
|
int count=0;
|
|
Map *map= world->getMap();
|
|
|
|
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;
|
|
}
|
|
else {
|
|
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();
|
|
}
|
|
|
|
|
|
bool AiInterface::isResourceInRegion(const Vec2i &pos, const ResourceType *rt, Vec2i &resourcePos, int range) const {
|
|
const Map *map= world->getMap();
|
|
|
|
int xi=1;
|
|
int xj=1;
|
|
|
|
if(rand() % 2==1){
|
|
xi=-1;
|
|
}
|
|
if(rand() % 2==1){
|
|
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;
|
|
}
|
|
|
|
|
|
|
|
//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);
|
|
|
|
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;
|
|
|
|
if(pos.dist(resourcePos) <= size) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool AiInterface::getNearestSightedResource(const ResourceType *rt, const Vec2i &pos,
|
|
Vec2i &resultPos, bool usableResourceTypeOnly) {
|
|
Faction *faction = world->getFaction(factionIndex);
|
|
//float tmpDist=0;
|
|
float nearestDist= infinity;
|
|
bool anyResource= false;
|
|
resultPos.x = -1;
|
|
resultPos.y = -1;
|
|
|
|
bool canUseResourceType = (usableResourceTypeOnly == false);
|
|
if(usableResourceTypeOnly == true) {
|
|
// can any unit harvest this resource yet?
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(canUseResourceType == true) {
|
|
bool isResourceClose = isResourceNear(pos, rt, resultPos, faction, true);
|
|
|
|
// Found a resource
|
|
if(isResourceClose == true || resultPos.x >= 0) {
|
|
anyResource= true;
|
|
}
|
|
else {
|
|
const Map *map = world->getMap();
|
|
for(int i = 0; i < map->getW(); ++i) {
|
|
for(int j = 0; j < map->getH(); ++j) {
|
|
Vec2i resPos = Vec2i(i, j);
|
|
Vec2i surfPos= Map::toSurfCoords(resPos);
|
|
SurfaceCell *sc = map->getSurfaceCell(surfPos);
|
|
|
|
//if explored cell
|
|
if(sc != NULL && sc->isExplored(teamIndex)) {
|
|
Resource *r= sc->getResource();
|
|
|
|
//if resource cell
|
|
if(r != NULL) {
|
|
if(r->getType() == rt) {
|
|
float tmpDist= pos.dist(resPos);
|
|
if(tmpDist < nearestDist) {
|
|
anyResource= true;
|
|
nearestDist= tmpDist;
|
|
resultPos= resPos;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
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);
|
|
}
|
|
|
|
bool AiInterface::checkCosts(const ProducibleType *pt, const CommandType *ct) {
|
|
return world->getFaction(factionIndex)->checkCosts(pt,ct);
|
|
}
|
|
|
|
bool AiInterface::isFreeCells(const Vec2i &pos, int size, Field field){
|
|
return world->getMap()->isFreeCells(pos, size, field);
|
|
}
|
|
|
|
void AiInterface::removeEnemyWarningPositionFromList(Vec2i &checkPos) {
|
|
for(int i = (int)enemyWarningPositionList.size() - 1; i >= 0; --i) {
|
|
Vec2i &pos = enemyWarningPositionList[i];
|
|
|
|
if(checkPos == pos) {
|
|
enemyWarningPositionList.erase(enemyWarningPositionList.begin()+i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
const Unit *AiInterface::getFirstOnSightEnemyUnit(Vec2i &pos, Field &field, int radius) {
|
|
Map *map= world->getMap();
|
|
|
|
const int CHECK_RADIUS = 12;
|
|
const int WARNING_ENEMY_COUNT = 6;
|
|
|
|
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");
|
|
|
|
// 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);
|
|
}
|
|
}
|
|
return unit;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
Map * AiInterface::getMap() {
|
|
Map *map= world->getMap();
|
|
return map;
|
|
}
|
|
|
|
bool AiInterface::factionUsesResourceType(const FactionType *factionType, const ResourceType *rt) {
|
|
bool factionUsesResourceType = factionType->factionUsesResourceType(rt);
|
|
return factionUsesResourceType;
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
// 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;
|
|
//factionIndex = aiInterfaceNode->getAttribute("factionIndex")->getIntValue();
|
|
// int teamIndex;
|
|
//teamIndex = aiInterfaceNode->getAttribute("teamIndex")->getIntValue();
|
|
// //config
|
|
// bool redir;
|
|
redir = aiInterfaceNode->getAttribute("redir")->getIntValue() != 0;
|
|
// 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);
|
|
// }
|
|
}
|
|
}
|
|
|
|
}}//end namespace
|