Build.cpp 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * Build.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "Build.h"
  12. #include "BuildThis.h"
  13. #include "../AIGateway.h"
  14. #include "../AIUtility.h"
  15. #include "../AIhelper.h"
  16. #include "../FuzzyHelper.h"
  17. #include "../ResourceManager.h"
  18. #include "../BuildingManager.h"
  19. #include "../../../lib/mapping/CMap.h" //for victory conditions
  20. #include "../../../lib/CPathfinder.h"
  21. #include "../../../lib/StringConstants.h"
  22. namespace Nullkiller
  23. {
  24. extern boost::thread_specific_ptr<CCallback> cb;
  25. extern boost::thread_specific_ptr<AIGateway> ai;
  26. extern FuzzyHelper * fh;
  27. using namespace Goals;
  28. TGoalVec Build::getAllPossibleSubgoals()
  29. {
  30. TGoalVec ret;
  31. for(const CGTownInstance * t : cb->getTownsInfo())
  32. {
  33. //start fresh with every town
  34. ai->ah->getBuildingOptions(t);
  35. auto immediateBuilding = ai->ah->immediateBuilding();
  36. auto expensiveBuilding = ai->ah->expensiveBuilding();
  37. //handling for early town development to save money and focus on income
  38. if(!t->hasBuilt(ai->ah->getMaxPossibleGoldBuilding(t)) && expensiveBuilding.has_value())
  39. {
  40. auto potentialBuilding = expensiveBuilding.value();
  41. switch(expensiveBuilding.value().bid)
  42. {
  43. case BuildingID::TOWN_HALL:
  44. case BuildingID::CITY_HALL:
  45. case BuildingID::CAPITOL:
  46. case BuildingID::FORT:
  47. case BuildingID::CITADEL:
  48. case BuildingID::CASTLE:
  49. //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.
  50. auto goal = ai->ah->whatToDo(potentialBuilding.price, sptr(BuildThis(potentialBuilding.bid, t).setpriority(2.25)));
  51. ret.push_back(goal);
  52. return ret;
  53. break;
  54. }
  55. }
  56. if(immediateBuilding.has_value())
  57. {
  58. ret.push_back(sptr(BuildThis(immediateBuilding.value().bid, t).setpriority(2))); //prioritize buildings we can build quick
  59. }
  60. else //try build later
  61. {
  62. if(expensiveBuilding.has_value())
  63. {
  64. auto potentialBuilding = expensiveBuilding.value(); //gather resources for any we can't afford
  65. auto goal = ai->ah->whatToDo(potentialBuilding.price, sptr(BuildThis(potentialBuilding.bid, t).setpriority(0.5)));
  66. ret.push_back(goal);
  67. }
  68. }
  69. }
  70. if(ret.empty())
  71. throw cannotFulfillGoalException("BUILD has been realized as much as possible.");
  72. else
  73. return ret;
  74. }
  75. TSubgoal Build::whatToDoToAchieve()
  76. {
  77. return fh->chooseSolution(getAllPossibleSubgoals());
  78. }
  79. bool Build::fulfillsMe(TSubgoal goal)
  80. {
  81. if(goal->goalType == BUILD || goal->goalType == BUILD_STRUCTURE)
  82. return (!town || town == goal->town); //building anything will do, in this town if set
  83. else
  84. return false;
  85. }
  86. }