2021-05-15 18:22:44 +02:00
/*
* Build . cpp , part of VCMI engine
*
* Authors : listed in file AUTHORS in main folder
*
* License : GNU General Public License v2 .0 or later
* Full text of license available in license . txt file , in main folder
*
*/
# include "StdInc.h"
# include "Build.h"
# include "BuildThis.h"
2021-05-16 14:39:38 +02:00
# include "../AIGateway.h"
2021-05-15 18:22:44 +02:00
# include "../AIUtility.h"
# include "../AIhelper.h"
# include "../FuzzyHelper.h"
# include "../ResourceManager.h"
# include "../BuildingManager.h"
# include "../../../lib/mapping/CMap.h" //for victory conditions
# include "../../../lib/CPathfinder.h"
# include "../../../lib/StringConstants.h"
2024-03-29 07:48:52 +02:00
namespace Nullkiller
{
2021-05-15 18:22:44 +02:00
extern boost : : thread_specific_ptr < CCallback > cb ;
2021-05-16 14:39:38 +02:00
extern boost : : thread_specific_ptr < AIGateway > ai ;
2021-05-15 18:22:44 +02:00
extern FuzzyHelper * fh ;
using namespace Goals ;
TGoalVec Build : : getAllPossibleSubgoals ( )
{
TGoalVec ret ;
for ( const CGTownInstance * t : cb - > getTownsInfo ( ) )
{
//start fresh with every town
ai - > ah - > getBuildingOptions ( t ) ;
auto immediateBuilding = ai - > ah - > immediateBuilding ( ) ;
auto expensiveBuilding = ai - > ah - > expensiveBuilding ( ) ;
//handling for early town development to save money and focus on income
2023-04-16 19:42:56 +02:00
if ( ! t - > hasBuilt ( ai - > ah - > getMaxPossibleGoldBuilding ( t ) ) & & expensiveBuilding . has_value ( ) )
2021-05-15 18:22:44 +02:00
{
2023-04-16 19:42:56 +02:00
auto potentialBuilding = expensiveBuilding . value ( ) ;
switch ( expensiveBuilding . value ( ) . bid )
2021-05-15 18:22:44 +02:00
{
case BuildingID : : TOWN_HALL :
case BuildingID : : CITY_HALL :
case BuildingID : : CAPITOL :
case BuildingID : : FORT :
case BuildingID : : CITADEL :
case BuildingID : : CASTLE :
//If above buildings are next to be bought, but no money... do not buy anything else, try to gather resources for these. Simple but has to suffice for now.
auto goal = ai - > ah - > whatToDo ( potentialBuilding . price , sptr ( BuildThis ( potentialBuilding . bid , t ) . setpriority ( 2.25 ) ) ) ;
ret . push_back ( goal ) ;
return ret ;
break ;
}
}
2023-04-16 19:42:56 +02:00
if ( immediateBuilding . has_value ( ) )
2021-05-15 18:22:44 +02:00
{
2023-04-16 19:42:56 +02:00
ret . push_back ( sptr ( BuildThis ( immediateBuilding . value ( ) . bid , t ) . setpriority ( 2 ) ) ) ; //prioritize buildings we can build quick
2021-05-15 18:22:44 +02:00
}
else //try build later
{
2023-04-16 19:42:56 +02:00
if ( expensiveBuilding . has_value ( ) )
2021-05-15 18:22:44 +02:00
{
2023-04-16 19:42:56 +02:00
auto potentialBuilding = expensiveBuilding . value ( ) ; //gather resources for any we can't afford
2021-05-15 18:22:44 +02:00
auto goal = ai - > ah - > whatToDo ( potentialBuilding . price , sptr ( BuildThis ( potentialBuilding . bid , t ) . setpriority ( 0.5 ) ) ) ;
ret . push_back ( goal ) ;
}
}
}
if ( ret . empty ( ) )
throw cannotFulfillGoalException ( " BUILD has been realized as much as possible. " ) ;
else
return ret ;
}
TSubgoal Build : : whatToDoToAchieve ( )
{
return fh - > chooseSolution ( getAllPossibleSubgoals ( ) ) ;
}
bool Build : : fulfillsMe ( TSubgoal goal )
{
if ( goal - > goalType = = BUILD | | goal - > goalType = = BUILD_STRUCTURE )
return ( ! town | | town = = goal - > town ) ; //building anything will do, in this town if set
else
return false ;
}
2022-09-26 20:01:07 +02:00
}