- allow logging of AI behavior to logfiles using: AiLog=10

(this produces a logfile for each AI player called aix.log where x is the ai player #)
- changed some AI behavior so that AI player can use overidable min static resource count from faction xml
- changed some AI behavior so that AI player is more smart about producing resource producers and resources.
This commit is contained in:
Mark Vejvoda 2012-03-17 19:22:03 +00:00
parent 91dce63aac
commit e6028a0555
7 changed files with 264 additions and 58 deletions

View File

@ -311,8 +311,11 @@ void Ai::update() {
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] AI for faction# %d voted %s [%d] factionSwitchTeamRequestCountCurrent [%d] settings->getAiAcceptSwitchTeamPercentChance() [%d]\n",__FILE__,__FUNCTION__,__LINE__,aiInterface->getMyFaction()->getIndex(),(voteResult->allowSwitchTeam ? "Yes" : "No"),allowJoinTeam,factionSwitchTeamRequestCountCurrent,settings->getAiAcceptSwitchTeamPercentChance());
//printf("AI for faction# %d voted %s [%d] factionSwitchTeamRequestCountCurrent [%d]\n",aiInterface->getMyFaction()->getIndex(),(voteResult->allowSwitchTeam ? "Yes" : "No"),allowJoinTeam,factionSwitchTeamRequestCountCurrent);
char szBuf[8096]="";
sprintf(szBuf,"AI for faction# %d voted %s [%d] CountCurrent [%d] PercentChance [%d]",aiInterface->getMyFaction()->getIndex(),(voteResult->allowSwitchTeam ? "Yes" : "No"),allowJoinTeam,factionSwitchTeamRequestCountCurrent,settings->getAiAcceptSwitchTeamPercentChance());
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,szBuf);
aiInterface->printLog(3, szBuf);
aiInterface->giveCommandSwitchTeamVote(aiInterface->getMyFaction(),voteResult);
}
@ -397,55 +400,62 @@ const ResourceType *Ai::getNeededResource(int unitIndex) {
const ResourceType *rt= tt->getResourceType(i);
const Resource *r= aiInterface->getResource(rt);
if( rt->getClass() != rcStatic && rt->getClass() != rcConsumable) {
char szBuf[8096]="";
sprintf(szBuf,"Examining resource [%s] amount [%d] (previous amount [%d]",rt->getName().c_str(),r->getAmount(),amount);
aiInterface->printLog(3, szBuf);
}
if( rt->getClass() != rcStatic && rt->getClass() != rcConsumable &&
r->getAmount() < amount) {
// Now MAKE SURE the unit has a harvest command for this resource
// AND that the resource is within eye-sight to avoid units
// standing around doing nothing.
const HarvestCommandType *hct= unit->getType()->getFirstHarvestCommand(rt,unit->getFaction());
// Only have up to x units going for this resource so we can focus
// on other needed resources for other units
const int maxUnitsToHarvestResource = 5;
Vec2i resPos;
if(hct != NULL && aiInterface->getNearestSightedResource(rt, aiInterface->getHomeLocation(), resPos, false)) {
amount= r->getAmount();
neededResource= rt;
vector<int> unitsGettingResource = findUnitsHarvestingResourceType(rt);
if(unitsGettingResource.size() <= maxUnitsToHarvestResource) {
// Now MAKE SURE the unit has a harvest command for this resource
// AND that the resource is within eye-sight to avoid units
// standing around doing nothing.
const HarvestCommandType *hct= unit->getType()->getFirstHarvestCommand(rt,unit->getFaction());
Vec2i resPos;
if(hct != NULL && aiInterface->getNearestSightedResource(rt, aiInterface->getHomeLocation(), resPos, false)) {
amount= r->getAmount();
neededResource= rt;
}
}
}
}
char szBuf[8096]="";
sprintf(szBuf,"Unit [%d - %s] looking for resources (not static or consumable)",unit->getId(),unit->getType()->getName().c_str());
aiInterface->printLog(3, szBuf);
sprintf(szBuf,"[resource type count %d] Needed resource [%s].",tt->getResourceTypeCount(),(neededResource != NULL ? neededResource->getName().c_str() : "<none>"));
aiInterface->printLog(3, szBuf);
return neededResource;
}
bool Ai::beingAttacked(Vec2i &pos, Field &field, int radius){
const Unit *enemy = aiInterface->getFirstOnSightEnemyUnit(pos, field, radius);
return (enemy != NULL);
/*
int count= aiInterface->onSightUnitCount();
const Unit *unit;
for(int i=0; i<count; ++i){
unit= aiInterface->getOnSightUnit(i);
if(!aiInterface->isAlly(unit) && unit->isAlive()){
pos= unit->getPos();
field= unit->getCurrField();
if(pos.dist(aiInterface->getHomeLocation())<radius){
aiInterface->printLog(2, "Being attacked at pos "+intToStr(pos.x)+","+intToStr(pos.y)+"\n");
return true;
}
}
}
return false;
*/
}
bool Ai::isStableBase() {
UnitClass ucWorkerType = ucWorker;
if(getCountOfClass(ucWarrior,&ucWorkerType) > minWarriors) {
aiInterface->printLog(4, "Base is stable\n");
char szBuf[8096]="";
sprintf(szBuf,"Base is stable [minWarriors = %d found = %d]",minWarriors,ucWorkerType);
aiInterface->printLog(4, szBuf);
return true;
}
else{
aiInterface->printLog(4, "Base is not stable\n");
char szBuf[8096]="";
sprintf(szBuf,"Base is NOT stable [minWarriors = %d found = %d]",minWarriors,ucWorkerType);
aiInterface->printLog(4, szBuf);
return false;
}
}
@ -472,6 +482,83 @@ bool Ai::findAbleUnit(int *unitIndex, CommandClass ability, bool idleOnly){
}
}
vector<int> Ai::findUnitsHarvestingResourceType(const ResourceType *rt) {
vector<int> units;
Map *map= aiInterface->getMap();
for(int i = 0; i < aiInterface->getMyUnitCount(); ++i) {
const Unit *unit= aiInterface->getMyUnit(i);
if(unit->getType()->hasCommandClass(ccHarvest)) {
if(unit->anyCommand() && unit->getCurrCommand()->getCommandType()->getClass() == ccHarvest) {
Command *command= unit->getCurrCommand();
const HarvestCommandType *hct= dynamic_cast<const HarvestCommandType*>(command->getCommandType());
if(hct != NULL) {
const Vec2i unitTargetPos = unit->getTargetPos();
SurfaceCell *sc= map->getSurfaceCell(Map::toSurfCoords(unitTargetPos));
Resource *r= sc->getResource();
if (r != NULL && r->getType() == rt) {
units.push_back(i);
}
}
}
}
else if(unit->getType()->hasCommandClass(ccProduce)) {
if(unit->anyCommand() && unit->getCurrCommand()->getCommandType()->getClass() == ccProduce) {
Command *command= unit->getCurrCommand();
const ProduceCommandType *pct= dynamic_cast<const ProduceCommandType*>(command->getCommandType());
if(pct != NULL) {
const UnitType *ut = pct->getProducedUnit();
if(ut != NULL) {
const Resource *r = ut->getCost(rt);
if(r != NULL) {
if (r != NULL && r->getAmount() < 0) {
units.push_back(i);
}
}
}
}
}
}
else if(unit->getType()->hasCommandClass(ccBuild)) {
if(unit->anyCommand() && unit->getCurrCommand()->getCommandType()->getClass() == ccBuild) {
Command *command= unit->getCurrCommand();
const BuildCommandType *bct= dynamic_cast<const BuildCommandType*>(command->getCommandType());
if(bct != NULL) {
for(unsigned int j = 0; j < bct->getBuildingCount(); ++j) {
const UnitType *ut = bct->getBuilding(j);
if(ut != NULL) {
const Resource *r = ut->getCost(rt);
if(r != NULL) {
if (r != NULL && r->getAmount() < 0) {
units.push_back(i);
break;
}
}
}
}
}
}
}
}
return units;
}
vector<int> Ai::findUnitsDoingCommand(CommandClass currentCommand) {
vector<int> units;
for(int i = 0; i < aiInterface->getMyUnitCount(); ++i) {
const Unit *unit= aiInterface->getMyUnit(i);
if(unit->getType()->hasCommandClass(currentCommand)) {
if(unit->anyCommand() && unit->getCurrCommand()->getCommandType()->getClass() == currentCommand) {
units.push_back(i);
}
}
}
return units;
}
bool Ai::findAbleUnit(int *unitIndex, CommandClass ability, CommandClass currentCommand){
vector<int> units;

View File

@ -190,6 +190,9 @@ public:
bool findPosForBuilding(const UnitType* building, const Vec2i &searchPos, Vec2i &pos);
bool findAbleUnit(int *unitIndex, CommandClass ability, bool idleOnly);
bool findAbleUnit(int *unitIndex, CommandClass ability, CommandClass currentCommand);
vector<int> findUnitsDoingCommand(CommandClass currentCommand);
vector<int> findUnitsHarvestingResourceType(const ResourceType *rt);
bool beingAttacked(Vec2i &pos, Field &field, int radius);
//tasks

View File

@ -51,18 +51,29 @@ AiInterface::AiInterface(Game &game, int factionIndex, int teamIndex, int useSta
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){
if(logLevel > 0) {
#ifdef WIN32
FILE *f= _wfopen(Shared::Platform::utf8_decode(getLogFilename()).c_str(), L"wt");
fp = _wfopen(Shared::Platform::utf8_decode(aiLogFile).c_str(), L"wt");
#else
FILE *f= fopen(getLogFilename().c_str(), "wt");
fp = fopen(aiLogFile.c_str(), "wt");
#endif
if(f==NULL){
throw runtime_error("Can't open file: "+getLogFilename());
if(fp == NULL) {
throw runtime_error("Can't open file: [" + aiLogFile + "]");
}
fprintf(f, "%s", "MegaGlest AI log file\n\n");
fclose(f);
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(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
@ -70,6 +81,11 @@ AiInterface::AiInterface(Game &game, int factionIndex, int teamIndex, int useSta
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(fp) {
fclose(fp);
fp = NULL;
}
}
// ==================== main ====================
@ -81,20 +97,13 @@ void AiInterface::update() {
// ==================== misc ====================
void AiInterface::printLog(int logLevel, const string &s){
if(this->logLevel>=logLevel){
if(this->logLevel >= logLevel) {
string logString= "(" + intToStr(factionIndex) + ") " + s;
//print log to file
#ifdef WIN32
FILE *f= _wfopen(utf8_decode(getLogFilename()).c_str(), L"at");
#else
FILE *f= fopen(getLogFilename().c_str(), "at");
#endif
if(f==NULL){
throw runtime_error("Can't open file: "+getLogFilename());
if(fp != NULL) {
fprintf(fp, "%s\n", logString.c_str());
}
fprintf(f, "%s\n", logString.c_str());
fclose(f);
//redirect to console
if(redir) {

View File

@ -47,6 +47,9 @@ private:
//config
bool redir;
int logLevel;
std::string aiLogFile;
FILE *fp;
std::map<const ResourceType *,int> cacheUnitHarvestResourceLookup;
public:

View File

@ -400,10 +400,13 @@ void AiRuleAddTasks::execute(){
//standard tasks
if(ai->outputAIBehaviourToConsole()) printf("Add a TASK - AiRuleAddTasks adding ProduceTask(ucWorker) workerCount = %d, RULE Name[%s]\n",workerCount,this->getName().c_str());
//ai->getAiInterface()->printLog(4, "Add a TASK - AiRuleAddTasks adding ProduceTask(ucWorker) workerCount = %d, RULE Name[%s]",workerCount,this->getName().c_str());
//emergency workers
if(workerCount < 4){
if(ai->outputAIBehaviourToConsole()) printf("AAA AiRuleAddTasks adding ProduceTask(ucWorker) workerCount = %d, RULE Name[%s]\n",workerCount,this->getName().c_str());
//ai->getAiInterface()->printLog(4, "AAA AiRuleAddTasks adding ProduceTask(ucWorker) workerCount = %d, RULE Name[%s]",workerCount,this->getName().c_str());
ai->addPriorityTask(new ProduceTask(ucWorker));
}
else{
@ -412,6 +415,8 @@ void AiRuleAddTasks::execute(){
{
if(ai->outputAIBehaviourToConsole()) printf("AAA AiRuleAddTasks adding #1 workerCount = %d[%.2f], buildingCount = %d[%.2f] warriorCount = %d[%.2f] upgradeCount = %d RULE Name[%s]\n",
workerCount,workerRatio,buildingCount,buildingRatio,warriorCount,warriorRatio,upgradeCount,this->getName().c_str());
//ai->getAiInterface()->printLog(4, "AAA AiRuleAddTasks adding #1 workerCount = %d[%.2f], buildingCount = %d[%.2f] warriorCount = %d[%.2f] upgradeCount = %d RULE Name[%s]",
// workerCount,workerRatio,buildingCount,buildingRatio,warriorCount,warriorRatio,upgradeCount,this->getName().c_str());
//workers
if(workerCount<5) ai->addTask(new ProduceTask(ucWorker));
@ -455,6 +460,8 @@ void AiRuleAddTasks::execute(){
if(ai->outputAIBehaviourToConsole()) printf("AAA AiRuleAddTasks adding #2 workerCount = %d[%.2f], buildingCount = %d[%.2f] warriorCount = %d[%.2f] upgradeCount = %d RULE Name[%s]\n",
workerCount,workerRatio,buildingCount,buildingRatio,warriorCount,warriorRatio,upgradeCount,this->getName().c_str());
//ai->getAiInterface()->printLog(4, "AAA AiRuleAddTasks adding #2 workerCount = %d[%.2f], buildingCount = %d[%.2f] warriorCount = %d[%.2f] upgradeCount = %d RULE Name[%s]\n",
// workerCount,workerRatio,buildingCount,buildingRatio,warriorCount,warriorRatio,upgradeCount,this->getName().c_str());
//workers
if(workerCount<buildingCount+2) ai->addTask(new ProduceTask(ucWorker));
@ -481,6 +488,8 @@ void AiRuleAddTasks::execute(){
{// normal CPU / UltraCPU ...
if(ai->outputAIBehaviourToConsole()) printf("AAA AiRuleAddTasks adding #3 workerCount = %d[%.2f], buildingCount = %d[%.2f] warriorCount = %d[%.2f] upgradeCount = %d RULE Name[%s]\n",
workerCount,workerRatio,buildingCount,buildingRatio,warriorCount,warriorRatio,upgradeCount,this->getName().c_str());
//ai->getAiInterface()->printLog(4, "AAA AiRuleAddTasks adding #3 workerCount = %d[%.2f], buildingCount = %d[%.2f] warriorCount = %d[%.2f] upgradeCount = %d RULE Name[%s]\n",
// workerCount,workerRatio,buildingCount,buildingRatio,warriorCount,warriorRatio,upgradeCount,this->getName().c_str());
//workers
if(workerCount<5) ai->addTask(new ProduceTask(ucWorker));
@ -542,6 +551,8 @@ bool AiRuleBuildOneFarm::test(){
//printf("AiRuleBuildOneFarm returning true, RULE Name[%s] ut [%s] producedType [%s]\n",this->getName().c_str(),ut->getName().c_str(),producedType->getName().c_str());
if(ai->outputAIBehaviourToConsole()) printf("AiRuleBuildOneFarm returning true, RULE Name[%s]\n",this->getName().c_str());
//aiInterface->printLog(4, "AiRuleBuildOneFarm returning true, RULE Name[%s]\n",this->getName().c_str());
return true;
}
}
@ -577,6 +588,10 @@ bool AiRuleProduceResourceProducer::test(){
const Resource *r= aiInterface->getResource(rt);
if(ai->outputAIBehaviourToConsole()) printf("CONSUMABLE [%s][%d] Testing AI RULE Name[%s]\n",rt->getName().c_str(), r->getBalance(), this->getName().c_str());
//aiInterface->printLog(4, "CONSUMABLE [%s][%d] Testing AI RULE Name[%s]",rt->getName().c_str(), r->getBalance(), this->getName().c_str());
char szBuf[8096]="";
sprintf(szBuf,"CONSUMABLE [%s][%d] Testing AI RULE Name[%s]",rt->getName().c_str(), r->getBalance(), this->getName().c_str());
aiInterface->printLog(4, szBuf);
bool factionUsesResourceType = aiInterface->factionUsesResourceType(aiInterface->getMyFactionType(), rt);
//if(rt->getClass()==rcConsumable && r->getBalance()<0){
@ -587,14 +602,22 @@ bool AiRuleProduceResourceProducer::test(){
}
}
int targetStaticResourceCount = minStaticResources;
if(aiInterface->getMyFactionType()->getAIBehaviorMinStaticResourceCount() != INT_MAX) {
targetStaticResourceCount = aiInterface->getMyFactionType()->getAIBehaviorMinStaticResourceCount();
}
//statics second
for(int i=0; i < aiInterface->getTechTree()->getResourceTypeCount(); ++i) {
rt= aiInterface->getTechTree()->getResourceType(i);
const Resource *r= aiInterface->getResource(rt);
if(ai->outputAIBehaviourToConsole()) printf("STATIC [%s][%d] [min %d] Testing AI RULE Name[%s]\n",rt->getName().c_str(), r->getAmount(), minStaticResources, this->getName().c_str());
if(ai->outputAIBehaviourToConsole()) printf("STATIC [%s][%d] [min %d] Testing AI RULE Name[%s]\n",rt->getName().c_str(), r->getAmount(), targetStaticResourceCount, this->getName().c_str());
char szBuf[8096]="";
sprintf(szBuf,"STATIC resource check [%s][%d] [min %d] Testing AI RULE Name[%s]",rt->getName().c_str(), r->getAmount(), targetStaticResourceCount, this->getName().c_str());
aiInterface->printLog(4, szBuf);
if(rt->getClass() == rcStatic && r->getAmount() < minStaticResources) {
if(rt->getClass() == rcStatic && r->getAmount() < targetStaticResourceCount) {
bool factionUsesResourceType = aiInterface->factionUsesResourceType(aiInterface->getMyFactionType(), rt);
if(factionUsesResourceType == true) {
interval= longInterval;
@ -604,6 +627,7 @@ bool AiRuleProduceResourceProducer::test(){
}
if(ai->outputAIBehaviourToConsole()) printf("STATIC returning FALSE\n");
aiInterface->printLog(4, "Static Resource check returning FALSE");
interval= shortInterval;
return false;
@ -635,18 +659,23 @@ bool AiRuleProduce::test(){
return true;
}
void AiRuleProduce::execute(){
if(produceTask!=NULL){
void AiRuleProduce::execute() {
AiInterface *aiInterface= ai->getAiInterface();
if(produceTask!=NULL) {
if(ai->outputAIBehaviourToConsole()) printf("AiRuleProduce producing [%s]\n",(produceTask->getUnitType() != NULL ? produceTask->getUnitType()->getName().c_str() : "null"));
//aiInterface->printLog(4, "AiRuleProduce producing [%s]",(produceTask->getUnitType() != NULL ? produceTask->getUnitType()->getName().c_str() : "null"));
char szBuf[8096]="";
sprintf(szBuf,"AiRuleProduce producing [%s]",(produceTask->getUnitType() != NULL ? produceTask->getUnitType()->getName().c_str() : "null"));
aiInterface->printLog(4, szBuf);
//generic produce task, produce random unit that has the skill or produces the resource
if(produceTask->getUnitType()==NULL){
if(produceTask->getUnitType() == NULL) {
produceGeneric(produceTask);
}
//specific produce task, produce if possible, retry if not enough resources
else{
else {
produceSpecific(produceTask);
}
@ -721,6 +750,7 @@ void AiRuleProduce::produceGeneric(const ProduceTask *pt) {
bool produceIt= false;
if(ai->outputAIBehaviourToConsole()) printf("produceGeneric [%p] Testing AI RULE Name[%s]\n",pt->getResourceType(), this->getName().c_str());
//aiInterface->printLog(4, "produceGeneric [%p] Testing AI RULE Name[%s]",pt->getResourceType(), this->getName().c_str());
//if the unit produces the resource
if(pt->getResourceType() != NULL) {
@ -728,6 +758,7 @@ void AiRuleProduce::produceGeneric(const ProduceTask *pt) {
if(r != NULL) {
if(ai->outputAIBehaviourToConsole()) printf("produceGeneric r = [%s][%d] Testing AI RULE Name[%s]\n",r->getDescription().c_str(),r->getAmount(), this->getName().c_str());
//aiInterface->printLog(4, "produceGeneric r = [%s][%d] Testing AI RULE Name[%s]",r->getDescription().c_str(),r->getAmount(), this->getName().c_str());
}
if(r != NULL && r->getAmount() < 0) {
@ -738,6 +769,7 @@ void AiRuleProduce::produceGeneric(const ProduceTask *pt) {
else {
//if the unit is from the right class
if(ai->outputAIBehaviourToConsole()) printf("produceGeneric right class = [%d] Testing AI RULE Name[%s]\n",producedUnit->isOfClass(pt->getUnitClass()), this->getName().c_str());
//aiInterface->printLog(4, "produceGeneric right class = [%d] Testing AI RULE Name[%s]",producedUnit->isOfClass(pt->getUnitClass()), this->getName().c_str());
if(producedUnit->isOfClass(pt->getUnitClass())){
if(aiInterface->reqsOk(ct) && aiInterface->reqsOk(producedUnit)){
@ -760,6 +792,7 @@ void AiRuleProduce::produceGeneric(const ProduceTask *pt) {
if(ableUnits.empty() == false) {
if(ai->outputAIBehaviourToConsole()) printf("produceGeneric !ableUnits.empty(), ableUnits.size() = [%d] Testing AI RULE Name[%s]\n",(int)ableUnits.size(), this->getName().c_str());
//aiInterface->printLog(4, "produceGeneric !ableUnits.empty(), ableUnits.size() = [%d] Testing AI RULE Name[%s]",(int)ableUnits.size(), this->getName().c_str());
//priority for non produced units
for(unsigned int i=0; i < ableUnits.size(); ++i) {
@ -780,15 +813,24 @@ void AiRuleProduce::produceSpecific(const ProduceTask *pt){
AiInterface *aiInterface= ai->getAiInterface();
if(ai->outputAIBehaviourToConsole()) printf("produceSpecific aiInterface->reqsOk(pt->getUnitType()) = [%d] Testing AI RULE Name[%s]\n",aiInterface->reqsOk(pt->getUnitType()), this->getName().c_str());
if(ai->outputAIBehaviourToConsole()) printf("produceSpecific aiInterface->reqsOk(pt->getUnitType()) = [%s][%d] Testing AI RULE Name[%s]\n",pt->getUnitType()->getName().c_str(),aiInterface->reqsOk(pt->getUnitType()), this->getName().c_str());
char szBuf[8096]="";
sprintf(szBuf,"produceSpecific aiInterface->reqsOk(pt->getUnitType()) = [%s][%d] Testing AI RULE Name[%s]",pt->getUnitType()->getName().c_str(),aiInterface->reqsOk(pt->getUnitType()), this->getName().c_str());
aiInterface->printLog(4, szBuf);
//if unit meets requirements
if(aiInterface->reqsOk(pt->getUnitType())){
if(aiInterface->reqsOk(pt->getUnitType())) {
if(ai->outputAIBehaviourToConsole()) printf("produceSpecific aiInterface->checkCosts(pt->getUnitType()) = [%d] Testing AI RULE Name[%s]\n",aiInterface->checkCosts(pt->getUnitType()), this->getName().c_str());
//aiInterface->printLog(4, "produceSpecific aiInterface->checkCosts(pt->getUnitType()) = [%d] Testing AI RULE Name[%s]",aiInterface->checkCosts(pt->getUnitType()), this->getName().c_str());
sprintf(szBuf,"produceSpecific aiInterface->checkCosts(pt->getUnitType()) = [%d] Testing AI RULE Name[%s]",aiInterface->checkCosts(pt->getUnitType()), this->getName().c_str());
aiInterface->printLog(4, szBuf);
//if unit doesnt meet resources retry
if(!aiInterface->checkCosts(pt->getUnitType())){
if(aiInterface->checkCosts(pt->getUnitType()) == false) {
sprintf(szBuf,"Check costs FAILED.");
aiInterface->printLog(4, szBuf);
ai->retryTask(pt);
return;
}
@ -816,6 +858,7 @@ void AiRuleProduce::produceSpecific(const ProduceTask *pt){
if(producedUnit == pt->getUnitType()){
if(ai->outputAIBehaviourToConsole()) printf("produceSpecific aiInterface->reqsOk(ct) = [%d] Testing AI RULE Name[%s]\n",aiInterface->reqsOk(ct), this->getName().c_str());
//aiInterface->printLog(4, "produceSpecific aiInterface->reqsOk(ct) = [%d] Testing AI RULE Name[%s]",aiInterface->reqsOk(ct), this->getName().c_str());
if(aiInterface->reqsOk(ct)){
defCt= ct;
@ -828,9 +871,32 @@ void AiRuleProduce::produceSpecific(const ProduceTask *pt){
}
//produce from random producer
if(!producers.empty()){
if(producers.empty() == false) {
if(ai->outputAIBehaviourToConsole()) printf("produceSpecific producers.empty() = [%d] Testing AI RULE Name[%s]\n",producers.empty(), this->getName().c_str());
//aiInterface->printLog(4, "produceSpecific producers.empty() = [%d] Testing AI RULE Name[%s]",producers.empty(), this->getName().c_str());
sprintf(szBuf,"produceSpecific producers.empty() = [%d] Testing AI RULE Name[%s]",producers.empty(), this->getName().c_str());
aiInterface->printLog(4, szBuf);
// Narrow down producers list to those who are not busy if possible
vector<int> idle_producers;
for(unsigned int i = 0; i < producers.size(); ++i) {
int currentProducerIndex = producers[i];
if(currentProducerIndex >= aiInterface->getMyUnitCount()) {
char szBuf[1024]="";
printf("In [%s::%s Line: %d] currentProducerIndex >= aiInterface->getMyUnitCount(), currentProducerIndex = %d, aiInterface->getMyUnitCount() = %d, i = %d,producers.size() = %lu\n",__FILE__,__FUNCTION__,__LINE__,currentProducerIndex,aiInterface->getMyUnitCount(),i,(unsigned long)producers.size());
sprintf(szBuf,"In [%s::%s Line: %d] currentProducerIndex >= aiInterface->getMyUnitCount(), currentProducerIndex = %d, aiInterface->getMyUnitCount() = %d, i = %d,producers.size() = %lu",__FILE__,__FUNCTION__,__LINE__,currentProducerIndex,aiInterface->getMyUnitCount(),i,(unsigned long)producers.size());
throw runtime_error(szBuf);
}
const Unit *unit = aiInterface->getMyUnit(currentProducerIndex);
if(unit->anyCommand() == false) {
idle_producers.push_back(currentProducerIndex);
}
}
if(idle_producers.size() > 0) {
producers = idle_producers;
}
if( aiInterface->getControlType() == ctCpuMega ||
aiInterface->getControlType() == ctNetworkCpuMega)
@ -877,8 +943,9 @@ void AiRuleProduce::produceSpecific(const ProduceTask *pt){
if( aiInterface->getMyUnit(bestIndex)->getCommandSize() > 2) {
// maybe we need another producer of this kind if possible!
if(aiInterface->reqsOk(aiInterface->getMyUnit(bestIndex)->getType())) {
if(ai->getCountOfClass(ucBuilding) > 5)
if(ai->getCountOfClass(ucBuilding) > 5) {
ai->addTask(new BuildTask(aiInterface->getMyUnit(bestIndex)->getType()));
}
}
// need to calculate another producer, maybe its better to produce another warrior with another producer
vector<int> backupProducers;
@ -957,6 +1024,10 @@ void AiRuleProduce::produceSpecific(const ProduceTask *pt){
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
if(ai->outputAIBehaviourToConsole()) printf("mega #1 produceSpecific giveCommand to unit [%s] commandType [%s]\n",aiInterface->getMyUnit(bestIndex)->getType()->getName().c_str(),ut->getCommandType(commandIndex)->getName().c_str());
//aiInterface->printLog(4, "mega #1 produceSpecific giveCommand to unit [%s] commandType [%s]",aiInterface->getMyUnit(bestIndex)->getType()->getName().c_str(),ut->getCommandType(commandIndex)->getName().c_str());
sprintf(szBuf,"mega #1 produceSpecific giveCommand to unit [%s] commandType [%s]",aiInterface->getMyUnit(bestIndex)->getType()->getName().c_str(),ut->getCommandType(commandIndex)->getName().c_str());
aiInterface->printLog(4, szBuf);
aiInterface->giveCommand(bestIndex, ut->getCommandType(commandIndex));
}
else
@ -973,6 +1044,10 @@ void AiRuleProduce::produceSpecific(const ProduceTask *pt){
}
if(ai->outputAIBehaviourToConsole()) printf("mega #2 produceSpecific giveCommand to unit [%s] commandType [%s]\n",aiInterface->getMyUnit(bestIndex)->getType()->getName().c_str(),defCt->getName().c_str());
//aiInterface->printLog(4, "mega #2 produceSpecific giveCommand to unit [%s] commandType [%s]",aiInterface->getMyUnit(bestIndex)->getType()->getName().c_str(),defCt->getName().c_str());
sprintf(szBuf,"mega #2 produceSpecific giveCommand to unit [%s] commandType [%s]",aiInterface->getMyUnit(bestIndex)->getType()->getName().c_str(),defCt->getName().c_str());
aiInterface->printLog(4, szBuf);
aiInterface->giveCommand(bestIndex, defCt);
}
}
@ -992,6 +1067,10 @@ void AiRuleProduce::produceSpecific(const ProduceTask *pt){
}
if(ai->outputAIBehaviourToConsole()) printf("mega #3 produceSpecific giveCommand to unit [%s] commandType [%s]\n",aiInterface->getMyUnit(bestIndex)->getType()->getName().c_str(),defCt->getName().c_str());
//aiInterface->printLog(4, "mega #3 produceSpecific giveCommand to unit [%s] commandType [%s]",aiInterface->getMyUnit(bestIndex)->getType()->getName().c_str(),defCt->getName().c_str());
sprintf(szBuf,"mega #3 produceSpecific giveCommand to unit [%s] commandType [%s]",aiInterface->getMyUnit(bestIndex)->getType()->getName().c_str(),defCt->getName().c_str());
aiInterface->printLog(4, szBuf);
aiInterface->giveCommand(bestIndex, defCt);
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -1006,6 +1085,10 @@ void AiRuleProduce::produceSpecific(const ProduceTask *pt){
defCt = producersDefaultCommandType[bestIndex][bestCommandTypeIndex];
}
if(ai->outputAIBehaviourToConsole()) printf("mega #4 produceSpecific giveCommand to unit [%s] commandType [%s]\n",aiInterface->getMyUnit(bestIndex)->getType()->getName().c_str(),defCt->getName().c_str());
//aiInterface->printLog(4, "mega #4 produceSpecific giveCommand to unit [%s] commandType [%s]",aiInterface->getMyUnit(bestIndex)->getType()->getName().c_str(),defCt->getName().c_str());
sprintf(szBuf,"mega #4 produceSpecific giveCommand to unit [%s] commandType [%s]",aiInterface->getMyUnit(bestIndex)->getType()->getName().c_str(),defCt->getName().c_str());
aiInterface->printLog(4, szBuf);
aiInterface->giveCommand(bestIndex, defCt);
}
}
@ -1026,6 +1109,10 @@ void AiRuleProduce::produceSpecific(const ProduceTask *pt){
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] producers.size() = %d, producerIndex = %d, pIndex = %d, producersDefaultCommandType.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,producers.size(),producerIndex,pIndex,producersDefaultCommandType.size());
if(ai->outputAIBehaviourToConsole()) printf("produceSpecific giveCommand to unit [%s] commandType [%s]\n",aiInterface->getMyUnit(producerIndex)->getType()->getName().c_str(),defCt->getName().c_str());
//aiInterface->printLog(4, "produceSpecific giveCommand to unit [%s] commandType [%s]",aiInterface->getMyUnit(producerIndex)->getType()->getName().c_str(),defCt->getName().c_str());
sprintf(szBuf,"produceSpecific giveCommand to unit [%s] commandType [%s]",aiInterface->getMyUnit(producerIndex)->getType()->getName().c_str(),defCt->getName().c_str());
aiInterface->printLog(4, szBuf);
aiInterface->giveCommand(producerIndex, defCt);
}
}
@ -1057,6 +1144,7 @@ bool AiRuleBuild::test(){
void AiRuleBuild::execute() {
if(buildTask!=NULL) {
if(ai->outputAIBehaviourToConsole()) printf("BUILD AiRuleBuild Unit Name[%s]\n",(buildTask->getUnitType() != NULL ? buildTask->getUnitType()->getName().c_str() : "null"));
//aiInterface->printLog(4, "BUILD AiRuleBuild Unit Name[%s]",(buildTask->getUnitType() != NULL ? buildTask->getUnitType()->getName().c_str() : "null"));
//generic build task, build random building that can be built
if(buildTask->getUnitType() == NULL) {
@ -1318,6 +1406,7 @@ void AiRuleBuild::buildSpecific(const BuildTask *bt) {
bool AiRuleBuild::isDefensive(const UnitType *building){
if(ai->outputAIBehaviourToConsole()) printf("BUILD isDefensive check for Unit Name[%s] result = %d\n",building->getName().c_str(),building->hasSkillClass(scAttack));
//aiInterface->printLog(4, "BUILD isDefensive check for Unit Name[%s] result = %d",building->getName().c_str(),building->hasSkillClass(scAttack));
return building->hasSkillClass(scAttack);
}
@ -1326,10 +1415,13 @@ bool AiRuleBuild::isResourceProducer(const UnitType *building){
for(int i= 0; i<building->getCostCount(); i++){
if(building->getCost(i)->getAmount()<0){
if(ai->outputAIBehaviourToConsole()) printf("BUILD isResourceProducer check for Unit Name[%s] result = true\n",building->getName().c_str());
//aiInterface->printLog(4, "BUILD isResourceProducer check for Unit Name[%s] result = true",building->getName().c_str());
return true;
}
}
if(ai->outputAIBehaviourToConsole()) printf("BUILD isResourceProducer check for Unit Name[%s] result = false\n",building->getName().c_str());
//aiInterface->printLog(4, "BUILD isResourceProducer check for Unit Name[%s] result = false",building->getName().c_str());
return false;
}
@ -1341,11 +1433,14 @@ bool AiRuleBuild::isWarriorProducer(const UnitType *building){
if(ut->isOfClass(ucWarrior)){
if(ai->outputAIBehaviourToConsole()) printf("BUILD isWarriorProducer check for Unit Name[%s] result = true\n",building->getName().c_str());
//aiInterface->printLog(4, "BUILD isWarriorProducer check for Unit Name[%s] result = true",building->getName().c_str());
return true;
}
}
}
if(ai->outputAIBehaviourToConsole()) printf("BUILD isWarriorProducer check for Unit Name[%s] result = false\n",building->getName().c_str());
//aiInterface->printLog(4, "BUILD isWarriorProducer check for Unit Name[%s] result = false",building->getName().c_str());
return false;
}

View File

@ -33,6 +33,7 @@ namespace Glest{ namespace Game{
FactionType::FactionType() {
music = NULL;
personalityType = fpt_Normal;
aIBehavior_minStaticResourceCount = INT_MAX;
}
//load a faction, given a directory
@ -41,6 +42,8 @@ void FactionType::load(const string &factionName, const TechTree *techTree, Chec
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
aIBehavior_minStaticResourceCount = INT_MAX;
string techTreePath = techTree->getPath();
string techTreeName=techTree->getName();
string currentPath = "";
@ -217,6 +220,10 @@ void FactionType::load(const string &factionName, const TechTree *techTree, Chec
//read ai behavior
if(factionNode->hasChild("ai-behavior") == true) {
const XmlNode *aiNode= factionNode->getChild("ai-behavior");
if(aiNode->hasAttribute("min-static-resource-count") == true) {
aIBehavior_minStaticResourceCount = aiNode->getAttribute("min-static-resource-count")->getIntValue();
//printf("aIBehavior_minStaticResourceCount = %d\n",aIBehavior_minStaticResourceCount);
}
if(aiNode->hasChild("worker-units") == true) {
const XmlNode *aiNodeUnits= aiNode->getChild("worker-units");
for(int i = 0; i < aiNodeUnits->getChildCount(); ++i) {

View File

@ -54,6 +54,7 @@ private:
std::map<AIBehaviorUnitCategory, std::vector<PairPUnitTypeInt> > mapAIBehaviorUnitCategories;
std::vector<const UpgradeType*> vctAIBehaviorUpgrades;
int aIBehavior_minStaticResourceCount;
public:
//init
@ -64,6 +65,7 @@ public:
const std::vector<FactionType::PairPUnitTypeInt> getAIBehaviorUnits(AIBehaviorUnitCategory category) const;
const std::vector<const UpgradeType*> getAIBehaviorUpgrades() const { return vctAIBehaviorUpgrades; };
int getAIBehaviorMinStaticResourceCount() const { return aIBehavior_minStaticResourceCount; }
//get
int getUnitTypeCount() const {return unitTypes.size();}