mirror of
https://github.com/glest/glest-source.git
synced 2025-02-25 04:02:30 +01:00
- 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
@ -536,11 +536,14 @@ bool AiRuleBuildOneFarm::test(){
|
||||
const Resource *r= producedType->getCost(k);
|
||||
|
||||
//find a food producer in the farm produced units
|
||||
if(r->getAmount()<0 && r->getType()->getClass()==rcConsumable && ai->getCountOfType(ut)==0){
|
||||
farm= ut;
|
||||
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;
|
||||
//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());
|
||||
return true;
|
||||
if(ai->outputAIBehaviourToConsole()) printf("AiRuleBuildOneFarm returning true, RULE Name[%s]\n",this->getName().c_str());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -652,21 +655,67 @@ void AiRuleProduce::execute(){
|
||||
}
|
||||
}
|
||||
|
||||
void AiRuleProduce::produceGeneric(const ProduceTask *pt){
|
||||
void AiRuleProduce::produceGeneric(const ProduceTask *pt) {
|
||||
typedef vector<const UnitType*> UnitTypes;
|
||||
UnitTypes ableUnits;
|
||||
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(int i=0; i<aiInterface->getMyUnitCount(); ++i){
|
||||
for(int i = 0; i < aiInterface->getMyUnitCount(); ++i) {
|
||||
|
||||
//for each command
|
||||
const UnitType *ut= aiInterface->getMyUnit(i)->getType();
|
||||
for(int j=0; j<ut->getCommandTypeCount(); ++j){
|
||||
for(int j = 0; j < ut->getCommandTypeCount(); ++j) {
|
||||
const CommandType *ct= ut->getCommandType(j);
|
||||
|
||||
//if the command is produce
|
||||
if(ct->getClass()==ccProduce || ct->getClass()==ccMorph){
|
||||
if(ct->getClass() == ccProduce || ct->getClass()==ccMorph) {
|
||||
|
||||
const UnitType *producedUnit= static_cast<const UnitType*>(ct->getProduced());
|
||||
bool produceIt= false;
|
||||
@ -674,19 +723,19 @@ void AiRuleProduce::produceGeneric(const ProduceTask *pt){
|
||||
if(ai->outputAIBehaviourToConsole()) printf("produceGeneric [%p] Testing AI RULE Name[%s]\n",pt->getResourceType(), this->getName().c_str());
|
||||
|
||||
//if the unit produces the resource
|
||||
if(pt->getResourceType()!=NULL){
|
||||
if(pt->getResourceType() != NULL) {
|
||||
const Resource *r= producedUnit->getCost(pt->getResourceType());
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
if(r!=NULL && r->getAmount()<0){
|
||||
if(r != NULL && r->getAmount() < 0) {
|
||||
produceIt= true;
|
||||
}
|
||||
}
|
||||
|
||||
else{
|
||||
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());
|
||||
|
||||
@ -697,7 +746,7 @@ void AiRuleProduce::produceGeneric(const ProduceTask *pt){
|
||||
}
|
||||
}
|
||||
|
||||
if(produceIt){
|
||||
if(produceIt) {
|
||||
//if the unit is not already on the list
|
||||
if(find(ableUnits.begin(), ableUnits.end(), producedUnit)==ableUnits.end()){
|
||||
ableUnits.push_back(producedUnit);
|
||||
@ -708,13 +757,13 @@ void AiRuleProduce::produceGeneric(const ProduceTask *pt){
|
||||
}
|
||||
|
||||
//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());
|
||||
|
||||
//priority for non produced units
|
||||
for(unsigned int i=0; i<ableUnits.size(); ++i){
|
||||
if(ai->getCountOfType(ableUnits[i])==0){
|
||||
for(unsigned int i=0; i < ableUnits.size(); ++i) {
|
||||
if(ai->getCountOfType(ableUnits[i]) == 0) {
|
||||
if(ai->getRandom()->randRange(0, 1)==0){
|
||||
ai->addTask(new ProduceTask(ableUnits[i]));
|
||||
return;
|
||||
@ -1023,13 +1072,44 @@ void AiRuleBuild::execute() {
|
||||
}
|
||||
}
|
||||
|
||||
void AiRuleBuild::buildGeneric(const BuildTask *bt){
|
||||
void AiRuleBuild::buildGeneric(const BuildTask *bt) {
|
||||
|
||||
//find buildings that can be built
|
||||
AiInterface *aiInterface= ai->getAiInterface();
|
||||
typedef vector<const UnitType*> UnitTypes;
|
||||
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(int i=0; i<aiInterface->getMyUnitCount(); ++i){
|
||||
|
||||
|
@ -1588,6 +1588,62 @@ void Faction::setSwitchTeamVote(SwitchTeamVote &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 result = "";
|
||||
|
||||
|
@ -248,6 +248,8 @@ public:
|
||||
|
||||
void sortUnitsByCommandGroups();
|
||||
|
||||
bool canCreateUnit(const UnitType *ut, bool checkBuild, bool checkProduce, bool checkMorph) const;
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
private:
|
||||
|
@ -163,10 +163,63 @@ void FactionType::load(const string &dir, const TechTree *techTree, Checksum* ch
|
||||
music->open(musicNode->getAttribute("path")->getRestrictedValue(currentPath));
|
||||
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__);
|
||||
}
|
||||
|
||||
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(){
|
||||
delete music;
|
||||
music = NULL;
|
||||
|
@ -27,8 +27,16 @@ namespace Glest{ namespace Game{
|
||||
/// Each of the possible factions the user can select
|
||||
// =====================================================
|
||||
|
||||
enum AIBehaviorUnitCategory {
|
||||
aibcWorkerUnits,
|
||||
aibcWarriorUnits,
|
||||
aibcResourceProducerUnits,
|
||||
aibcBuildingUnits
|
||||
};
|
||||
|
||||
|
||||
class FactionType {
|
||||
private:
|
||||
public:
|
||||
typedef pair<const UnitType*, int> PairPUnitTypeInt;
|
||||
typedef vector<UnitType> UnitTypes;
|
||||
typedef vector<UpgradeType> UpgradeTypes;
|
||||
@ -44,6 +52,8 @@ private:
|
||||
StrSound *music;
|
||||
FactionPersonalityType personalityType;
|
||||
|
||||
std::map<AIBehaviorUnitCategory, std::vector<PairPUnitTypeInt> > mapAIBehaviorUnitCategories;
|
||||
|
||||
public:
|
||||
//init
|
||||
FactionType();
|
||||
@ -51,6 +61,8 @@ public:
|
||||
Checksum *techtreeChecksum, std::map<string,vector<pair<string, string> > > &loadedFileList);
|
||||
~FactionType();
|
||||
|
||||
const std::vector<FactionType::PairPUnitTypeInt> getAIBehaviorUnits(AIBehaviorUnitCategory category) const;
|
||||
|
||||
//get
|
||||
int getUnitTypeCount() const {return unitTypes.size();}
|
||||
int getUpgradeTypeCount() const {return upgradeTypes.size();}
|
||||
|
Loading…
x
Reference in New Issue
Block a user