diff --git a/AI/VCAI/AIhelper.cpp b/AI/VCAI/AIhelper.cpp index e65d28b05..9e2045b93 100644 --- a/AI/VCAI/AIhelper.cpp +++ b/AI/VCAI/AIhelper.cpp @@ -48,6 +48,11 @@ bool AIhelper::getBuildingOptions(const CGTownInstance * t) return buildingManager->getBuildingOptions(t); } +BuildingID AIhelper::getMaxPossibleGoldBuilding(const CGTownInstance * t) +{ + return buildingManager->getMaxPossibleGoldBuilding(t); +} + boost::optional AIhelper::immediateBuilding() const { return buildingManager->immediateBuilding(); diff --git a/AI/VCAI/AIhelper.h b/AI/VCAI/AIhelper.h index 35b9ad942..7c6b9cb88 100644 --- a/AI/VCAI/AIhelper.h +++ b/AI/VCAI/AIhelper.h @@ -49,6 +49,7 @@ public: bool hasTasksLeft() const override; bool getBuildingOptions(const CGTownInstance * t) override; + BuildingID getMaxPossibleGoldBuilding(const CGTownInstance * t); boost::optional immediateBuilding() const override; boost::optional expensiveBuilding() const override; boost::optional canBuildAnyStructure(const CGTownInstance * t, const std::vector & buildList, unsigned int maxDays = 7) const override; diff --git a/AI/VCAI/BuildingManager.cpp b/AI/VCAI/BuildingManager.cpp index a83715ad0..70b7c71ee 100644 --- a/AI/VCAI/BuildingManager.cpp +++ b/AI/VCAI/BuildingManager.cpp @@ -138,8 +138,8 @@ void BuildingManager::setAI(VCAI * AI) } //Set of buildings for different goals. Does not include any prerequisites. static const BuildingID essential[] = { BuildingID::TAVERN, BuildingID::TOWN_HALL }; -static const BuildingID goldSource[] = { BuildingID::TOWN_HALL, BuildingID::CITY_HALL, BuildingID::CAPITOL }; -static const BuildingID capitolRequirements[] = { BuildingID::FORT, BuildingID::CITADEL }; +static const BuildingID basicGoldSource[] = { BuildingID::TOWN_HALL, BuildingID::CITY_HALL }; +static const BuildingID capitolAndRequirements[] = { BuildingID::FORT, BuildingID::CITADEL, BuildingID::CASTLE, BuildingID::CAPITOL }; static const BuildingID unitsSource[] = { BuildingID::DWELL_LVL_1, BuildingID::DWELL_LVL_2, BuildingID::DWELL_LVL_3, BuildingID::DWELL_LVL_4, BuildingID::DWELL_LVL_5, BuildingID::DWELL_LVL_6, BuildingID::DWELL_LVL_7 }; static const BuildingID unitsUpgrade[] = { BuildingID::DWELL_LVL_1_UP, BuildingID::DWELL_LVL_2_UP, BuildingID::DWELL_LVL_3_UP, @@ -171,22 +171,18 @@ bool BuildingManager::getBuildingOptions(const CGTownInstance * t) if (tryBuildAnyStructure(t, std::vector(essential, essential + ARRAY_COUNT(essential)))) return true; - //workaround for mantis #2696 - build fort and citadel - building castle prerequisite when trying to build capitol will be then handled without bug - if(vstd::contains(t->builtBuildings, BuildingID::CITY_HALL) && - cb->canBuildStructure(t, BuildingID::CAPITOL) != EBuildingState::HAVE_CAPITAL) - { - if(cb->canBuildStructure(t, BuildingID::CAPITOL) != EBuildingState::FORBIDDEN) - { - if(tryBuildNextStructure(t, std::vector(capitolRequirements, - capitolRequirements + ARRAY_COUNT(capitolRequirements)))) - return true; - } - } - //the more gold the better and less problems later //TODO: what about building mage guild / marketplace etc. with city hall disabled in editor? - if (tryBuildNextStructure(t, std::vector(goldSource, goldSource + ARRAY_COUNT(goldSource)))) + if(tryBuildNextStructure(t, std::vector(basicGoldSource, basicGoldSource + ARRAY_COUNT(basicGoldSource)))) return true; + //workaround for mantis #2696 - build capitol with separate algorithm if it is available + if(vstd::contains(t->builtBuildings, BuildingID::CITY_HALL) && getMaxPossibleGoldBuilding(t) == BuildingID::CAPITOL) + { + if(tryBuildNextStructure(t, std::vector(capitolAndRequirements, + capitolAndRequirements + ARRAY_COUNT(capitolAndRequirements)))) + return true; + } + if(!t->hasBuilt(BuildingID::FORT)) //in vast majority of situations fort is top priority building if we already have city hall, TODO: unite with unitGrowth building chain if(tryBuildThisStructure(t, BuildingID::FORT)) return true; @@ -201,8 +197,8 @@ bool BuildingManager::getBuildingOptions(const CGTownInstance * t) return true; } - // first in-game week or second half of any week: try build dwellings //TODO: this condition looks not optimal, rethink - if (t->hasBuilt(BuildingID::FORT) && (cb->getDate(Date::DAY) < 7 || cb->getDate(Date::DAY_OF_WEEK) > 3)) + //try building dwellings + if (t->hasBuilt(BuildingID::FORT)) { if (tryBuildAnyStructure(t, std::vector(unitsSource, unitsSource + ARRAY_COUNT(unitsSource)), 8 - cb->getDate(Date::DAY_OF_WEEK))) @@ -238,6 +234,18 @@ bool BuildingManager::getBuildingOptions(const CGTownInstance * t) return false; } +BuildingID BuildingManager::getMaxPossibleGoldBuilding(const CGTownInstance * t) +{ + if(cb->canBuildStructure(t, BuildingID::CAPITOL) != EBuildingState::HAVE_CAPITAL && cb->canBuildStructure(t, BuildingID::CAPITOL) != EBuildingState::FORBIDDEN) + return BuildingID::CAPITOL; + else if(cb->canBuildStructure(t, BuildingID::CITY_HALL) != EBuildingState::FORBIDDEN) + return BuildingID::CITY_HALL; + else if(cb->canBuildStructure(t, BuildingID::TOWN_HALL) != EBuildingState::FORBIDDEN) + return BuildingID::TOWN_HALL; + else + return BuildingID::VILLAGE_HALL; +} + boost::optional BuildingManager::immediateBuilding() const { if (immediateBuildings.size()) diff --git a/AI/VCAI/BuildingManager.h b/AI/VCAI/BuildingManager.h index 0df8ed8ef..cc6fd64e2 100644 --- a/AI/VCAI/BuildingManager.h +++ b/AI/VCAI/BuildingManager.h @@ -51,6 +51,7 @@ public: //try build anything in given town, and execute resulting Goal if any bool getBuildingOptions(const CGTownInstance * t) override; + BuildingID getMaxPossibleGoldBuilding(const CGTownInstance * t); boost::optional immediateBuilding() const override; boost::optional expensiveBuilding() const override; boost::optional canBuildAnyStructure(const CGTownInstance * t, const std::vector & buildList, unsigned int maxDays = 7) const override;