mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Add possible income utility function, make capitol building errorproof
This commit is contained in:
		| @@ -48,6 +48,11 @@ bool AIhelper::getBuildingOptions(const CGTownInstance * t) | |||||||
| 	return buildingManager->getBuildingOptions(t); | 	return buildingManager->getBuildingOptions(t); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | BuildingID AIhelper::getMaxPossibleGoldBuilding(const CGTownInstance * t) | ||||||
|  | { | ||||||
|  | 	return buildingManager->getMaxPossibleGoldBuilding(t); | ||||||
|  | } | ||||||
|  |  | ||||||
| boost::optional<PotentialBuilding> AIhelper::immediateBuilding() const | boost::optional<PotentialBuilding> AIhelper::immediateBuilding() const | ||||||
| { | { | ||||||
| 	return buildingManager->immediateBuilding(); | 	return buildingManager->immediateBuilding(); | ||||||
|   | |||||||
| @@ -49,6 +49,7 @@ public: | |||||||
| 	bool hasTasksLeft() const override; | 	bool hasTasksLeft() const override; | ||||||
|  |  | ||||||
| 	bool getBuildingOptions(const CGTownInstance * t) override; | 	bool getBuildingOptions(const CGTownInstance * t) override; | ||||||
|  | 	BuildingID getMaxPossibleGoldBuilding(const CGTownInstance * t); | ||||||
| 	boost::optional<PotentialBuilding> immediateBuilding() const override; | 	boost::optional<PotentialBuilding> immediateBuilding() const override; | ||||||
| 	boost::optional<PotentialBuilding> expensiveBuilding() const override; | 	boost::optional<PotentialBuilding> expensiveBuilding() const override; | ||||||
| 	boost::optional<BuildingID> canBuildAnyStructure(const CGTownInstance * t, const std::vector<BuildingID> & buildList, unsigned int maxDays = 7) const override; | 	boost::optional<BuildingID> canBuildAnyStructure(const CGTownInstance * t, const std::vector<BuildingID> & buildList, unsigned int maxDays = 7) const override; | ||||||
|   | |||||||
| @@ -138,8 +138,8 @@ void BuildingManager::setAI(VCAI * AI) | |||||||
| } | } | ||||||
| //Set of buildings for different goals. Does not include any prerequisites. | //Set of buildings for different goals. Does not include any prerequisites. | ||||||
| static const BuildingID essential[] = { BuildingID::TAVERN, BuildingID::TOWN_HALL }; | static const BuildingID essential[] = { BuildingID::TAVERN, BuildingID::TOWN_HALL }; | ||||||
| static const BuildingID goldSource[] = { BuildingID::TOWN_HALL, BuildingID::CITY_HALL, BuildingID::CAPITOL }; | static const BuildingID basicGoldSource[] = { BuildingID::TOWN_HALL, BuildingID::CITY_HALL }; | ||||||
| static const BuildingID capitolRequirements[] = { BuildingID::FORT, BuildingID::CITADEL }; | 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, | 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 }; | 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, | 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<BuildingID>(essential, essential + ARRAY_COUNT(essential)))) | 	if (tryBuildAnyStructure(t, std::vector<BuildingID>(essential, essential + ARRAY_COUNT(essential)))) | ||||||
| 		return true; | 		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<BuildingID>(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? | 	//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<BuildingID>(goldSource, goldSource + ARRAY_COUNT(goldSource)))) | 	if(tryBuildNextStructure(t, std::vector<BuildingID>(basicGoldSource, basicGoldSource + ARRAY_COUNT(basicGoldSource)))) | ||||||
| 		return true; | 		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<BuildingID>(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(!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)) | 		if(tryBuildThisStructure(t, BuildingID::FORT)) | ||||||
| 			return true; | 			return true; | ||||||
| @@ -201,8 +197,8 @@ bool BuildingManager::getBuildingOptions(const CGTownInstance * t) | |||||||
| 			return true; | 			return true; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// first in-game week or second half of any week: try build dwellings //TODO: this condition looks not optimal, rethink | 	//try building dwellings | ||||||
| 	if (t->hasBuilt(BuildingID::FORT) && (cb->getDate(Date::DAY) < 7 || cb->getDate(Date::DAY_OF_WEEK) > 3)) | 	if (t->hasBuilt(BuildingID::FORT)) | ||||||
| 	{ | 	{ | ||||||
| 		if (tryBuildAnyStructure(t, std::vector<BuildingID>(unitsSource, | 		if (tryBuildAnyStructure(t, std::vector<BuildingID>(unitsSource, | ||||||
| 			unitsSource + ARRAY_COUNT(unitsSource)), 8 - cb->getDate(Date::DAY_OF_WEEK))) | 			unitsSource + ARRAY_COUNT(unitsSource)), 8 - cb->getDate(Date::DAY_OF_WEEK))) | ||||||
| @@ -238,6 +234,18 @@ bool BuildingManager::getBuildingOptions(const CGTownInstance * t) | |||||||
| 	return false; | 	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<PotentialBuilding> BuildingManager::immediateBuilding() const | boost::optional<PotentialBuilding> BuildingManager::immediateBuilding() const | ||||||
| { | { | ||||||
| 	if (immediateBuildings.size()) | 	if (immediateBuildings.size()) | ||||||
|   | |||||||
| @@ -51,6 +51,7 @@ public: | |||||||
|  |  | ||||||
| 	//try build anything in given town, and execute resulting Goal if any | 	//try build anything in given town, and execute resulting Goal if any | ||||||
| 	bool getBuildingOptions(const CGTownInstance * t) override; | 	bool getBuildingOptions(const CGTownInstance * t) override; | ||||||
|  | 	BuildingID getMaxPossibleGoldBuilding(const CGTownInstance * t); | ||||||
| 	boost::optional<PotentialBuilding> immediateBuilding() const override; | 	boost::optional<PotentialBuilding> immediateBuilding() const override; | ||||||
| 	boost::optional<PotentialBuilding> expensiveBuilding() const override; | 	boost::optional<PotentialBuilding> expensiveBuilding() const override; | ||||||
| 	boost::optional<BuildingID> canBuildAnyStructure(const CGTownInstance * t, const std::vector<BuildingID> & buildList, unsigned int maxDays = 7) const override; | 	boost::optional<BuildingID> canBuildAnyStructure(const CGTownInstance * t, const std::vector<BuildingID> & buildList, unsigned int maxDays = 7) const override; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user