- bugfix AI, no longer try to build a farm type unit if the faction does not have a unit that is able to build it yet
- new optional feature added to tell each faction some basic info regarding which units should take priority when building,producing and morphing
This commit is contained in:
parent
22e28c323f
commit
8729c32b68
|
@ -537,7 +537,9 @@ bool AiRuleBuildOneFarm::test(){
|
||||||
|
|
||||||
//find a food producer in the farm produced units
|
//find a food producer in the farm produced units
|
||||||
if(r->getAmount() < 0 && r->getType()->getClass() == rcConsumable && ai->getCountOfType(ut) == 0) {
|
if(r->getAmount() < 0 && r->getType()->getClass() == rcConsumable && ai->getCountOfType(ut) == 0) {
|
||||||
|
if(aiInterface->reqsOk(ct) && aiInterface->getMyFaction()->canCreateUnit(ut, true, true, true) == true) {
|
||||||
farm= ut;
|
farm= ut;
|
||||||
|
//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());
|
if(ai->outputAIBehaviourToConsole()) printf("AiRuleBuildOneFarm returning true, RULE Name[%s]\n",this->getName().c_str());
|
||||||
return true;
|
return true;
|
||||||
|
@ -546,6 +548,7 @@ bool AiRuleBuildOneFarm::test(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -657,6 +660,52 @@ void AiRuleProduce::produceGeneric(const ProduceTask *pt){
|
||||||
UnitTypes ableUnits;
|
UnitTypes ableUnits;
|
||||||
AiInterface *aiInterface= ai->getAiInterface();
|
AiInterface *aiInterface= ai->getAiInterface();
|
||||||
|
|
||||||
|
if(pt->getResourceType() != NULL) {
|
||||||
|
if(aiInterface->getMyFactionType()->getAIBehaviorUnits(aibcResourceProducerUnits).size() > 0) {
|
||||||
|
const std::vector<FactionType::PairPUnitTypeInt> &unitList = aiInterface->getMyFactionType()->getAIBehaviorUnits(aibcResourceProducerUnits);
|
||||||
|
for(unsigned int i = 0; i < unitList.size(); ++i) {
|
||||||
|
const FactionType::PairPUnitTypeInt &priorityUnit = unitList[i];
|
||||||
|
if(ai->getCountOfType(priorityUnit.first) < priorityUnit.second &&
|
||||||
|
aiInterface->getMyFaction()->canCreateUnit(priorityUnit.first, false, true, true) == true) {
|
||||||
|
//if(ai->getRandom()->randRange(0, 1)==0) {
|
||||||
|
ai->addTask(new ProduceTask(priorityUnit.first));
|
||||||
|
return;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(pt->getUnitClass() == ucWorker) {
|
||||||
|
if(aiInterface->getMyFactionType()->getAIBehaviorUnits(aibcWorkerUnits).size() > 0) {
|
||||||
|
const std::vector<FactionType::PairPUnitTypeInt> &unitList = aiInterface->getMyFactionType()->getAIBehaviorUnits(aibcWorkerUnits);
|
||||||
|
for(unsigned int i = 0; i < unitList.size(); ++i) {
|
||||||
|
const FactionType::PairPUnitTypeInt &priorityUnit = unitList[i];
|
||||||
|
if(ai->getCountOfType(priorityUnit.first) < priorityUnit.second &&
|
||||||
|
aiInterface->getMyFaction()->canCreateUnit(priorityUnit.first, false, true, true) == true) {
|
||||||
|
//if(ai->getRandom()->randRange(0, 1)==0) {
|
||||||
|
ai->addTask(new ProduceTask(priorityUnit.first));
|
||||||
|
return;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(pt->getUnitClass() == ucWarrior) {
|
||||||
|
if(aiInterface->getMyFactionType()->getAIBehaviorUnits(aibcWarriorUnits).size() > 0) {
|
||||||
|
const std::vector<FactionType::PairPUnitTypeInt> &unitList = aiInterface->getMyFactionType()->getAIBehaviorUnits(aibcWarriorUnits);
|
||||||
|
for(unsigned int i = 0; i < unitList.size(); ++i) {
|
||||||
|
const FactionType::PairPUnitTypeInt &priorityUnit = unitList[i];
|
||||||
|
if(ai->getCountOfType(priorityUnit.first) < priorityUnit.second &&
|
||||||
|
aiInterface->getMyFaction()->canCreateUnit(priorityUnit.first, false, true, true) == true) {
|
||||||
|
//if(ai->getRandom()->randRange(0, 1)==0) {
|
||||||
|
ai->addTask(new ProduceTask(priorityUnit.first));
|
||||||
|
return;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//for each unit, produce it if possible
|
//for each unit, produce it if possible
|
||||||
for(int i = 0; i < aiInterface->getMyUnitCount(); ++i) {
|
for(int i = 0; i < aiInterface->getMyUnitCount(); ++i) {
|
||||||
|
|
||||||
|
@ -708,7 +757,7 @@ void AiRuleProduce::produceGeneric(const ProduceTask *pt){
|
||||||
}
|
}
|
||||||
|
|
||||||
//add specific produce task
|
//add specific produce task
|
||||||
if(!ableUnits.empty()){
|
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());
|
if(ai->outputAIBehaviourToConsole()) printf("produceGeneric !ableUnits.empty(), ableUnits.size() = [%d] Testing AI RULE Name[%s]\n",(int)ableUnits.size(), this->getName().c_str());
|
||||||
|
|
||||||
|
@ -1030,6 +1079,37 @@ void AiRuleBuild::buildGeneric(const BuildTask *bt){
|
||||||
typedef vector<const UnitType*> UnitTypes;
|
typedef vector<const UnitType*> UnitTypes;
|
||||||
UnitTypes buildings;
|
UnitTypes buildings;
|
||||||
|
|
||||||
|
if(bt->getResourceType() != NULL) {
|
||||||
|
if(aiInterface->getMyFactionType()->getAIBehaviorUnits(aibcResourceProducerUnits).size() > 0) {
|
||||||
|
const std::vector<FactionType::PairPUnitTypeInt> &unitList = aiInterface->getMyFactionType()->getAIBehaviorUnits(aibcResourceProducerUnits);
|
||||||
|
for(unsigned int i = 0; i < unitList.size(); ++i) {
|
||||||
|
const FactionType::PairPUnitTypeInt &priorityUnit = unitList[i];
|
||||||
|
if(ai->getCountOfType(priorityUnit.first) < priorityUnit.second &&
|
||||||
|
aiInterface->getMyFaction()->canCreateUnit(priorityUnit.first, true, false, false) == true) {
|
||||||
|
//if(ai->getRandom()->randRange(0, 1)==0) {
|
||||||
|
ai->addTask(new BuildTask(priorityUnit.first));
|
||||||
|
return;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(aiInterface->getMyFactionType()->getAIBehaviorUnits(aibcBuildingUnits).size() > 0) {
|
||||||
|
const std::vector<FactionType::PairPUnitTypeInt> &unitList = aiInterface->getMyFactionType()->getAIBehaviorUnits(aibcBuildingUnits);
|
||||||
|
for(unsigned int i = 0; i < unitList.size(); ++i) {
|
||||||
|
const FactionType::PairPUnitTypeInt &priorityUnit = unitList[i];
|
||||||
|
if(ai->getCountOfType(priorityUnit.first) < priorityUnit.second &&
|
||||||
|
aiInterface->getMyFaction()->canCreateUnit(priorityUnit.first, true, false, false) == true) {
|
||||||
|
//if(ai->getRandom()->randRange(0, 1)==0) {
|
||||||
|
ai->addTask(new BuildTask(priorityUnit.first));
|
||||||
|
return;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//for each unit
|
//for each unit
|
||||||
for(int i=0; i<aiInterface->getMyUnitCount(); ++i){
|
for(int i=0; i<aiInterface->getMyUnitCount(); ++i){
|
||||||
|
|
||||||
|
|
|
@ -1588,6 +1588,62 @@ void Faction::setSwitchTeamVote(SwitchTeamVote &vote) {
|
||||||
switchTeamVotes[vote.factionIndex] = vote;
|
switchTeamVotes[vote.factionIndex] = vote;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Faction::canCreateUnit(const UnitType *ut, bool checkBuild, bool checkProduce, bool checkMorph) const {
|
||||||
|
// Now check that at least 1 other unit can produce, build or morph this unit
|
||||||
|
bool foundUnit = false;
|
||||||
|
for(int l = 0; l < this->getUnitCount() && foundUnit == false; ++l) {
|
||||||
|
const UnitType *unitType2 = this->getUnit(l)->getType();
|
||||||
|
|
||||||
|
for(int j = 0; j < unitType2->getCommandTypeCount() && foundUnit == false; ++j) {
|
||||||
|
const CommandType *cmdType = unitType2->getCommandType(j);
|
||||||
|
if(cmdType != NULL) {
|
||||||
|
// Check if this is a produce command
|
||||||
|
if(checkProduce == true && cmdType->getClass() == ccProduce) {
|
||||||
|
const ProduceCommandType *produce = dynamic_cast<const ProduceCommandType *>(cmdType);
|
||||||
|
if(produce != NULL) {
|
||||||
|
const UnitType *produceUnit = produce->getProducedUnit();
|
||||||
|
|
||||||
|
if( produceUnit != NULL &&
|
||||||
|
ut->getId() != unitType2->getId() &&
|
||||||
|
ut->getName() == produceUnit->getName()) {
|
||||||
|
foundUnit = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check if this is a build command
|
||||||
|
else if(checkBuild == true && cmdType->getClass() == ccBuild) {
|
||||||
|
const BuildCommandType *build = dynamic_cast<const BuildCommandType *>(cmdType);
|
||||||
|
for(int k = 0; k < build->getBuildingCount() && foundUnit == false; ++k) {
|
||||||
|
const UnitType *buildUnit = build->getBuilding(k);
|
||||||
|
|
||||||
|
if( buildUnit != NULL &&
|
||||||
|
ut->getId() != unitType2->getId() &&
|
||||||
|
ut->getName() == buildUnit->getName()) {
|
||||||
|
foundUnit = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Check if this is a morph command
|
||||||
|
else if(checkMorph == true && cmdType->getClass() == ccMorph) {
|
||||||
|
const MorphCommandType *morph = dynamic_cast<const MorphCommandType *>(cmdType);
|
||||||
|
const UnitType *morphUnit = morph->getMorphUnit();
|
||||||
|
|
||||||
|
if( morphUnit != NULL &&
|
||||||
|
ut->getId() != unitType2->getId() &&
|
||||||
|
ut->getName() == morphUnit->getName()) {
|
||||||
|
foundUnit = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return foundUnit;
|
||||||
|
}
|
||||||
|
|
||||||
std::string Faction::toString() const {
|
std::string Faction::toString() const {
|
||||||
std::string result = "";
|
std::string result = "";
|
||||||
|
|
||||||
|
|
|
@ -248,6 +248,8 @@ public:
|
||||||
|
|
||||||
void sortUnitsByCommandGroups();
|
void sortUnitsByCommandGroups();
|
||||||
|
|
||||||
|
bool canCreateUnit(const UnitType *ut, bool checkBuild, bool checkProduce, bool checkMorph) const;
|
||||||
|
|
||||||
std::string toString() const;
|
std::string toString() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -163,10 +163,63 @@ void FactionType::load(const string &dir, const TechTree *techTree, Checksum* ch
|
||||||
music->open(musicNode->getAttribute("path")->getRestrictedValue(currentPath));
|
music->open(musicNode->getAttribute("path")->getRestrictedValue(currentPath));
|
||||||
loadedFileList[musicNode->getAttribute("path")->getRestrictedValue(currentPath)].push_back(make_pair(path,musicNode->getAttribute("path")->getRestrictedValue()));
|
loadedFileList[musicNode->getAttribute("path")->getRestrictedValue(currentPath)].push_back(make_pair(path,musicNode->getAttribute("path")->getRestrictedValue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//read ai behavior
|
||||||
|
if(factionNode->hasChild("ai-behavior") == true) {
|
||||||
|
const XmlNode *aiNode= factionNode->getChild("ai-behavior");
|
||||||
|
if(aiNode->hasChild("worker-units") == true) {
|
||||||
|
const XmlNode *aiNodeUnits= aiNode->getChild("worker-units");
|
||||||
|
for(int i = 0; i < aiNodeUnits->getChildCount(); ++i) {
|
||||||
|
const XmlNode *unitNode= aiNodeUnits->getChild("unit", i);
|
||||||
|
string name= unitNode->getAttribute("name")->getRestrictedValue();
|
||||||
|
int minimum= unitNode->getAttribute("minimum")->getIntValue();
|
||||||
|
|
||||||
|
mapAIBehaviorUnitCategories[aibcWorkerUnits].push_back(PairPUnitTypeInt(getUnitType(name), minimum));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(aiNode->hasChild("warrior-units") == true) {
|
||||||
|
const XmlNode *aiNodeUnits= aiNode->getChild("warrior-units");
|
||||||
|
for(int i = 0; i < aiNodeUnits->getChildCount(); ++i) {
|
||||||
|
const XmlNode *unitNode= aiNodeUnits->getChild("unit", i);
|
||||||
|
string name= unitNode->getAttribute("name")->getRestrictedValue();
|
||||||
|
int minimum= unitNode->getAttribute("minimum")->getIntValue();
|
||||||
|
|
||||||
|
mapAIBehaviorUnitCategories[aibcWarriorUnits].push_back(PairPUnitTypeInt(getUnitType(name), minimum));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(aiNode->hasChild("resource-producer-units") == true) {
|
||||||
|
const XmlNode *aiNodeUnits= aiNode->getChild("resource-producer-units");
|
||||||
|
for(int i = 0; i < aiNodeUnits->getChildCount(); ++i) {
|
||||||
|
const XmlNode *unitNode= aiNodeUnits->getChild("unit", i);
|
||||||
|
string name= unitNode->getAttribute("name")->getRestrictedValue();
|
||||||
|
int minimum= unitNode->getAttribute("minimum")->getIntValue();
|
||||||
|
|
||||||
|
mapAIBehaviorUnitCategories[aibcResourceProducerUnits].push_back(PairPUnitTypeInt(getUnitType(name), minimum));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(aiNode->hasChild("building-units") == true) {
|
||||||
|
const XmlNode *aiNodeUnits= aiNode->getChild("building-units");
|
||||||
|
for(int i = 0; i < aiNodeUnits->getChildCount(); ++i) {
|
||||||
|
const XmlNode *unitNode= aiNodeUnits->getChild("unit", i);
|
||||||
|
string name= unitNode->getAttribute("name")->getRestrictedValue();
|
||||||
|
int minimum= unitNode->getAttribute("minimum")->getIntValue();
|
||||||
|
|
||||||
|
mapAIBehaviorUnitCategories[aibcBuildingUnits].push_back(PairPUnitTypeInt(getUnitType(name), minimum));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<FactionType::PairPUnitTypeInt> FactionType::getAIBehaviorUnits(AIBehaviorUnitCategory category) const {
|
||||||
|
std::map<AIBehaviorUnitCategory, std::vector<PairPUnitTypeInt> >::const_iterator iterFind = mapAIBehaviorUnitCategories.find(category);
|
||||||
|
if(iterFind != mapAIBehaviorUnitCategories.end()) {
|
||||||
|
return iterFind->second;
|
||||||
|
}
|
||||||
|
return std::vector<FactionType::PairPUnitTypeInt>();
|
||||||
|
}
|
||||||
|
|
||||||
FactionType::~FactionType(){
|
FactionType::~FactionType(){
|
||||||
delete music;
|
delete music;
|
||||||
music = NULL;
|
music = NULL;
|
||||||
|
|
|
@ -27,8 +27,16 @@ namespace Glest{ namespace Game{
|
||||||
/// Each of the possible factions the user can select
|
/// Each of the possible factions the user can select
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
|
||||||
|
enum AIBehaviorUnitCategory {
|
||||||
|
aibcWorkerUnits,
|
||||||
|
aibcWarriorUnits,
|
||||||
|
aibcResourceProducerUnits,
|
||||||
|
aibcBuildingUnits
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class FactionType {
|
class FactionType {
|
||||||
private:
|
public:
|
||||||
typedef pair<const UnitType*, int> PairPUnitTypeInt;
|
typedef pair<const UnitType*, int> PairPUnitTypeInt;
|
||||||
typedef vector<UnitType> UnitTypes;
|
typedef vector<UnitType> UnitTypes;
|
||||||
typedef vector<UpgradeType> UpgradeTypes;
|
typedef vector<UpgradeType> UpgradeTypes;
|
||||||
|
@ -44,6 +52,8 @@ private:
|
||||||
StrSound *music;
|
StrSound *music;
|
||||||
FactionPersonalityType personalityType;
|
FactionPersonalityType personalityType;
|
||||||
|
|
||||||
|
std::map<AIBehaviorUnitCategory, std::vector<PairPUnitTypeInt> > mapAIBehaviorUnitCategories;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//init
|
//init
|
||||||
FactionType();
|
FactionType();
|
||||||
|
@ -51,6 +61,8 @@ public:
|
||||||
Checksum *techtreeChecksum, std::map<string,vector<pair<string, string> > > &loadedFileList);
|
Checksum *techtreeChecksum, std::map<string,vector<pair<string, string> > > &loadedFileList);
|
||||||
~FactionType();
|
~FactionType();
|
||||||
|
|
||||||
|
const std::vector<FactionType::PairPUnitTypeInt> getAIBehaviorUnits(AIBehaviorUnitCategory category) const;
|
||||||
|
|
||||||
//get
|
//get
|
||||||
int getUnitTypeCount() const {return unitTypes.size();}
|
int getUnitTypeCount() const {return unitTypes.size();}
|
||||||
int getUpgradeTypeCount() const {return upgradeTypes.size();}
|
int getUpgradeTypeCount() const {return upgradeTypes.size();}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user