- 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:
parent
91dce63aac
commit
e6028a0555
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -47,6 +47,9 @@ private:
|
|||
//config
|
||||
bool redir;
|
||||
int logLevel;
|
||||
std::string aiLogFile;
|
||||
FILE *fp;
|
||||
|
||||
std::map<const ResourceType *,int> cacheUnitHarvestResourceLookup;
|
||||
|
||||
public:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();}
|
||||
|
|
Loading…
Reference in New Issue