// ============================================================== // 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{ 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->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(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } 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 ==================== void AiInterface::update() { timer++; ai.update(); } // ==================== misc ==================== void AiInterface::printLog(int logLevel, const string &s){ if(this->logLevel >= logLevel) { string logString= "(" + intToStr(factionIndex) + ") " + s; //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); } CommandResult AiInterface::giveCommandSwitchTeamVote(const Faction* faction, SwitchTeamVote *vote) { assert(this->gameSettings != NULL); commander->trySwitchTeamVote(faction,vote); return crSuccess; } CommandResult AiInterface::giveCommand(int unitIndex, CommandClass commandClass, const Vec2i &pos){ assert(this->gameSettings != NULL); if(executeCommandOverNetwork() == true) { const Unit *unit = getMyUnit(unitIndex); CommandResult 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__); CommandResult 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; } } CommandResult AiInterface::giveCommand(const Unit *unit, const CommandType *commandType, const Vec2i &pos, int unitGroupCommandId) { assert(this->gameSettings != NULL); if(unit == NULL) { char szBuf[1024]=""; sprintf(szBuf,"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[1024]=""; sprintf(szBuf,"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[1024]=""; sprintf(szBuf,"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[4096]=""; sprintf(szBuf,"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().c_str(),unit->getDesc().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) { CommandResult 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); CommandResult 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; } } CommandResult AiInterface::giveCommand(int unitIndex, const CommandType *commandType, const Vec2i &pos, int unitGroupCommandId) { assert(this->gameSettings != NULL); const Unit *unit = getMyUnit(unitIndex); if(unit == NULL) { char szBuf[1024]=""; sprintf(szBuf,"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[1024]=""; sprintf(szBuf,"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[4096]=""; sprintf(szBuf,"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().c_str(),unit->getDesc().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); CommandResult 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); CommandResult 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; } } CommandResult AiInterface::giveCommand(int unitIndex, const CommandType *commandType, const Vec2i &pos, const UnitType *ut) { assert(this->gameSettings != NULL); const Unit *unit = getMyUnit(unitIndex); if(unit == NULL) { char szBuf[1024]=""; sprintf(szBuf,"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[1024]=""; sprintf(szBuf,"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[4096]=""; sprintf(szBuf,"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().c_str(),unit->getDesc().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); CommandResult 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__); CommandResult 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; } } CommandResult AiInterface::giveCommand(int unitIndex, const CommandType *commandType, Unit *u){ assert(this->gameSettings != NULL); assert(this->commander != NULL); const Unit *unit = getMyUnit(unitIndex); if(unit == NULL) { char szBuf[1024]=""; sprintf(szBuf,"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[1024]=""; sprintf(szBuf,"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[4096]=""; sprintf(szBuf,"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().c_str(),unit->getDesc().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); CommandResult 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__); CommandResult 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; igetFactionCount(); ++i) { for(int j=0; jgetFaction(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[1024]=""; sprintf(szBuf,"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; igetFactionCount(); ++i) { for(int j=0; jgetFaction(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(); RandomGen random; int xi=1; int xj=1; if(random.randRange(0,1)==1){ xi=-1; } if(random.randRange(0,1)==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); //if(faction != NULL) { // char szBuf[4096]=""; // sprintf(szBuf,"[%s::%s Line: %d] [isresourcenear] pos [%s] resourcePos [%s] fallbackToPeersHarvestingSameResource [%d] rt [%s]", // __FILE__,__FUNCTION__,__LINE__,pos.getString().c_str(),resourcePos.getString().c_str(),fallbackToPeersHarvestingSameResource,rt->getName().c_str()); // SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"----------------------------------- START [%d] ------------------------------------------------\n",faction->getFrameCount()); // SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"%s",szBuf); // SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"------------------------------------ END [%d] -------------------------------------------------\n",faction->getFrameCount()); //} 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; //char szBuf[4096]=""; // sprintf(szBuf,"[%s::%s Line: %d] [isresourcenear] pos [%s] resourcePos [%s] fallbackToPeersHarvestingSameResource [%d] rt [%s]", // __FILE__,__FUNCTION__,__LINE__,pos.getString().c_str(),resourcePos.getString().c_str(),fallbackToPeersHarvestingSameResource,rt->getName().c_str()); //SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"----------------------------------- START [%d] ------------------------------------------------\n",faction->getFrameCount()); //SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"%s",szBuf); //SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"------------------------------------ END [%d] -------------------------------------------------\n",faction->getFrameCount()); if(pos.dist(resourcePos) <= size) { return true; } } } //if(faction != NULL) { // char szBuf[4096]=""; // sprintf(szBuf,"[%s::%s Line: %d] [isresourcenear] pos [%s] resourcePos [%s] fallbackToPeersHarvestingSameResource [%d] rt [%s] getCacheResourceTargetListSize() [%d]", // __FILE__,__FUNCTION__,__LINE__,pos.getString().c_str(),resourcePos.getString().c_str(),fallbackToPeersHarvestingSameResource,rt->getName().c_str(),faction->getCacheResourceTargetListSize()); // SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"----------------------------------- START [%d] ------------------------------------------------\n",faction->getFrameCount()); // SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"%s",szBuf); // SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"------------------------------------ END [%d] -------------------------------------------------\n",faction->getFrameCount()); //} 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::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); //bool isResourceClose = false; // Found a resource if(isResourceClose == true || resultPos.x >= 0) { anyResource= true; } else { const Map *map = world->getMap(); //Faction *faction = world->getFaction(factionIndex); 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; } } //faction->addResourceTargetToCache(resPos,false); } } } } } } 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); } const Unit *AiInterface::getFirstOnSightEnemyUnit(Vec2i &pos, Field &field, int radius) { 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 && 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"); 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 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 cacheUnitHarvestResourceLookup; for(std::map::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 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 cacheUnitHarvestResourceLookup; // for(std::map::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