- more AI fixes.

#1: AI does not try to harvest resources that the unit cannot yet harvest (could be an upgrade required)

#2: AI no longer tries to expand near resources that they are not yet able to harvest. (found using RealtimeFreaks test mod and map). This makes for a more aggresive CPU in scenarios where there are additional resource types since they expand much more quickly.
This commit is contained in:
Mark Vejvoda 2010-10-02 01:11:59 +00:00
parent 468340403f
commit 02e0a1302f
7 changed files with 61 additions and 42 deletions

View File

@ -200,9 +200,9 @@ const ResourceType *Ai::getNeededResource(int unitIndex) {
// Now MAKE SURE the unit has a harvest command for this resource // Now MAKE SURE the unit has a harvest command for this resource
// AND that the resource is within eye-sight to avoid units // AND that the resource is within eye-sight to avoid units
// standing around doing nothing. // standing around doing nothing.
const HarvestCommandType *hct= aiInterface->getMyUnit(unitIndex)->getType()->getFirstHarvestCommand(rt); const HarvestCommandType *hct= aiInterface->getMyUnit(unitIndex)->getType()->getFirstHarvestCommand(rt,aiInterface->getMyUnit(unitIndex)->getFaction());
Vec2i resPos; Vec2i resPos;
if(hct != NULL && aiInterface->getNearestSightedResource(rt, aiInterface->getHomeLocation(), resPos)) { if(hct != NULL && aiInterface->getNearestSightedResource(rt, aiInterface->getHomeLocation(), resPos, false)) {
amount= r->getAmount(); amount= r->getAmount();
neededResource= rt; neededResource= rt;
} }
@ -486,9 +486,9 @@ void Ai::harvest(int unitIndex) {
const ResourceType *rt= getNeededResource(unitIndex); const ResourceType *rt= getNeededResource(unitIndex);
if(rt != NULL) { if(rt != NULL) {
const HarvestCommandType *hct= aiInterface->getMyUnit(unitIndex)->getType()->getFirstHarvestCommand(rt); const HarvestCommandType *hct= aiInterface->getMyUnit(unitIndex)->getType()->getFirstHarvestCommand(rt,aiInterface->getMyUnit(unitIndex)->getFaction());
Vec2i resPos; Vec2i resPos;
if(hct != NULL && aiInterface->getNearestSightedResource(rt, aiInterface->getHomeLocation(), resPos)) { if(hct != NULL && aiInterface->getNearestSightedResource(rt, aiInterface->getHomeLocation(), resPos, false)) {
resPos= resPos+Vec2i(random.randRange(-2, 2), random.randRange(-2, 2)); resPos= resPos+Vec2i(random.randRange(-2, 2), random.randRange(-2, 2));
aiInterface->giveCommand(unitIndex, hct, resPos); aiInterface->giveCommand(unitIndex, hct, resPos);
//aiInterface->printLog(4, "Order harvest pos:" + intToStr(resPos.x)+", "+intToStr(resPos.y)+": "+rrToStr(r)+"\n"); //aiInterface->printLog(4, "Order harvest pos:" + intToStr(resPos.x)+", "+intToStr(resPos.y)+": "+rrToStr(r)+"\n");

View File

@ -371,29 +371,45 @@ const TechTree *AiInterface::getTechTree(){
return world->getTechTree(); return world->getTechTree();
} }
bool AiInterface::getNearestSightedResource(const ResourceType *rt, const Vec2i &pos, Vec2i &resultPos){ bool AiInterface::getNearestSightedResource(const ResourceType *rt, const Vec2i &pos,
float tmpDist; Vec2i &resultPos, bool usableResourceTypeOnly) {
float tmpDist=0;
float nearestDist= infinity; float nearestDist= infinity;
bool anyResource= false; bool anyResource= false;
const Map *map= world->getMap(); bool canUseResourceType = (usableResourceTypeOnly == false);
if(usableResourceTypeOnly == true) {
// can any unit harvest this resource yet?
for(int i = 0; i < getMyUnitCount(); ++i) {
const Unit *unit = getMyUnit(i);
const HarvestCommandType *hct= unit->getType()->getFirstHarvestCommand(rt,unit->getFaction());
if(hct != NULL) {
canUseResourceType = true;
break;
}
}
}
for(int i=0; i<map->getW(); ++i){ if(canUseResourceType == true) {
for(int j=0; j<map->getH(); ++j){ const Map *map= world->getMap();
Vec2i surfPos= Map::toSurfCoords(Vec2i(i, j));
for(int i=0; i<map->getW(); ++i){
//if explored cell for(int j=0; j<map->getH(); ++j){
if(map->getSurfaceCell(surfPos)->isExplored(teamIndex)){ Vec2i surfPos= Map::toSurfCoords(Vec2i(i, j));
Resource *r= map->getSurfaceCell(surfPos)->getResource();
//if resource cell //if explored cell
if(r!=NULL && r->getType()==rt){ if(map->getSurfaceCell(surfPos)->isExplored(teamIndex)){
tmpDist= pos.dist(Vec2i(i, j)); Resource *r= map->getSurfaceCell(surfPos)->getResource();
if(tmpDist<nearestDist){
anyResource= true; //if resource cell
nearestDist= tmpDist; if(r != NULL && r->getType() == rt) {
resultPos= Vec2i(i, j); tmpDist= pos.dist(Vec2i(i, j));
if(tmpDist < nearestDist) {
anyResource= true;
nearestDist= tmpDist;
resultPos= Vec2i(i, j);
}
} }
} }
} }

View File

@ -30,7 +30,7 @@ namespace Glest{ namespace Game{
/// The AI will interact with the game through this interface /// The AI will interact with the game through this interface
// ===================================================== // =====================================================
class AiInterface{ class AiInterface {
private: private:
World *world; World *world;
Commander *commander; Commander *commander;
@ -80,7 +80,7 @@ public:
const Unit *getOnSightUnit(int unitIndex); const Unit *getOnSightUnit(int unitIndex);
const FactionType *getMyFactionType(); const FactionType *getMyFactionType();
const TechTree *getTechTree(); const TechTree *getTechTree();
bool getNearestSightedResource(const ResourceType *rt, const Vec2i &pos, Vec2i &resultPos); bool getNearestSightedResource(const ResourceType *rt, const Vec2i &pos, Vec2i &resultPos, bool usableResourceTypeOnly);
bool isAlly(const Unit *unit) const; bool isAlly(const Unit *unit) const;
bool isAlly(int factionIndex) const; bool isAlly(int factionIndex) const;
bool reqsOk(const RequirableType *rt); bool reqsOk(const RequirableType *rt);

View File

@ -1089,42 +1089,38 @@ AiRuleExpand::AiRuleExpand(Ai *ai):
storeType= NULL; storeType= NULL;
} }
bool AiRuleExpand::test(){ bool AiRuleExpand::test() {
AiInterface *aiInterface = ai->getAiInterface(); AiInterface *aiInterface = ai->getAiInterface();
for(int i= 0; i<aiInterface->getTechTree()->getResourceTypeCount(); ++i){ for(int i= 0; i<aiInterface->getTechTree()->getResourceTypeCount(); ++i){
const ResourceType *rt = aiInterface->getTechTree()->getResourceType(i); const ResourceType *rt = aiInterface->getTechTree()->getResourceType(i);
if(rt->getClass() == rcTech){
if(rt->getClass()==rcTech){
// If any resource sighted // If any resource sighted
if(aiInterface->getNearestSightedResource(rt, aiInterface->getHomeLocation(), expandPos)){ if(aiInterface->getNearestSightedResource(rt, aiInterface->getHomeLocation(), expandPos, true)) {
int minDistance= INT_MAX; int minDistance= INT_MAX;
storeType= NULL; storeType= NULL;
//If there is no close store //If there is no close store
for(int j=0; j<aiInterface->getMyUnitCount(); ++j){ for(int j=0; j < aiInterface->getMyUnitCount(); ++j) {
const Unit *u= aiInterface->getMyUnit(j); const Unit *u= aiInterface->getMyUnit(j);
const UnitType *ut= aiInterface->getMyUnit(j)->getType(); const UnitType *ut= aiInterface->getMyUnit(j)->getType();
// If this building is a store // If this building is a store
if(ut->getStore(rt)>0){ if(ut->getStore(rt) > 0) {
storeType = ut; storeType = ut;
int distance= static_cast<int> (u->getPos().dist(expandPos)); int distance= static_cast<int> (u->getPos().dist(expandPos));
if(distance < minDistance){ if(distance < minDistance) {
minDistance = distance; minDistance = distance;
} }
} }
} }
if(minDistance>expandDistance) if(minDistance > expandDistance) {
{
return true; return true;
} }
} }
else{ else {
// send patrol to look for resource // send patrol to look for resource
ai->sendScoutPatrol(); ai->sendScoutPatrol();
} }

View File

@ -930,7 +930,7 @@ const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *target
//check harvest command //check harvest command
Resource *resource= sc->getResource(); Resource *resource= sc->getResource();
if(resource!=NULL){ if(resource!=NULL){
commandType= type->getFirstHarvestCommand(resource->getType()); commandType= type->getFirstHarvestCommand(resource->getType(),this->getFaction());
} }
} }

View File

@ -24,6 +24,7 @@
#include "renderer.h" #include "renderer.h"
#include "game_util.h" #include "game_util.h"
#include "unit_particle_type.h" #include "unit_particle_type.h"
#include "faction.h"
#include "leak_dumper.h" #include "leak_dumper.h"
using namespace Shared::Xml; using namespace Shared::Xml;
@ -434,11 +435,16 @@ const SkillType *UnitType::getFirstStOfClass(SkillClass skillClass) const{
return firstSkillTypeOfClass[skillClass]; return firstSkillTypeOfClass[skillClass];
} }
const HarvestCommandType *UnitType::getFirstHarvestCommand(const ResourceType *resourceType) const{ const HarvestCommandType *UnitType::getFirstHarvestCommand(const ResourceType *resourceType, const Faction *faction) const {
for(int i=0; i<commandTypes.size(); ++i) { for(int i = 0; i < commandTypes.size(); ++i) {
if(commandTypes[i]->getClass()== ccHarvest){ if(commandTypes[i]->getClass() == ccHarvest) {
const HarvestCommandType *hct= static_cast<const HarvestCommandType*>(commandTypes[i]); const HarvestCommandType *hct = static_cast<const HarvestCommandType*>(commandTypes[i]);
if(hct->canHarvest(resourceType)){
if (faction->reqsOk(hct) == false) {
continue;
}
if(hct->canHarvest(resourceType)) {
return hct; return hct;
} }
} }

View File

@ -31,6 +31,7 @@ class UnitParticleSystemType;
class ResourceType; class ResourceType;
class TechTree; class TechTree;
class FactionType; class FactionType;
class Faction;
// =============================== // ===============================
@ -172,7 +173,7 @@ public:
const SkillType *getSkillType(const string &skillName, SkillClass skillClass) const; const SkillType *getSkillType(const string &skillName, SkillClass skillClass) const;
const SkillType *getFirstStOfClass(SkillClass skillClass) const; const SkillType *getFirstStOfClass(SkillClass skillClass) const;
const CommandType *getFirstCtOfClass(CommandClass commandClass) const; const CommandType *getFirstCtOfClass(CommandClass commandClass) const;
const HarvestCommandType *getFirstHarvestCommand(const ResourceType *resourceType) const; const HarvestCommandType *getFirstHarvestCommand(const ResourceType *resourceType,const Faction *faction) const;
const AttackCommandType *getFirstAttackCommand(Field field) const; const AttackCommandType *getFirstAttackCommand(Field field) const;
const RepairCommandType *getFirstRepairCommand(const UnitType *repaired) const; const RepairCommandType *getFirstRepairCommand(const UnitType *repaired) const;