Build.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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 "../VCAI.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. extern boost::thread_specific_ptr<CCallback> cb;
  23. extern boost::thread_specific_ptr<VCAI> ai;
  24. extern FuzzyHelper * fh;
  25. using namespace Goals;
  26. TGoalVec Build::getAllPossibleSubgoals()
  27. {
  28. TGoalVec ret;
  29. for(const CGTownInstance * t : cb->getTownsInfo())
  30. {
  31. //start fresh with every town
  32. ai->ah->getBuildingOptions(t);
  33. auto immediateBuilding = ai->ah->immediateBuilding();
  34. auto expensiveBuilding = ai->ah->expensiveBuilding();
  35. //handling for early town development to save money and focus on income
  36. if(!t->hasBuilt(ai->ah->getMaxPossibleGoldBuilding(t)) && expensiveBuilding.has_value())
  37. {
  38. auto potentialBuilding = expensiveBuilding.value();
  39. switch(expensiveBuilding.value().bid)
  40. {
  41. case BuildingID::TOWN_HALL:
  42. case BuildingID::CITY_HALL:
  43. case BuildingID::CAPITOL:
  44. case BuildingID::FORT:
  45. case BuildingID::CITADEL:
  46. case BuildingID::CASTLE:
  47. //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.
  48. auto goal = ai->ah->whatToDo(potentialBuilding.price, sptr(BuildThis(potentialBuilding.bid, t).setpriority(2.25)));
  49. ret.push_back(goal);
  50. return ret;
  51. break;
  52. }
  53. }
  54. if(immediateBuilding.has_value())
  55. {
  56. ret.push_back(sptr(BuildThis(immediateBuilding.value().bid, t).setpriority(2))); //prioritize buildings we can build quick
  57. }
  58. else //try build later
  59. {
  60. if(expensiveBuilding.has_value())
  61. {
  62. auto potentialBuilding = expensiveBuilding.value(); //gather resources for any we can't afford
  63. auto goal = ai->ah->whatToDo(potentialBuilding.price, sptr(BuildThis(potentialBuilding.bid, t).setpriority(0.5)));
  64. ret.push_back(goal);
  65. }
  66. }
  67. }
  68. if(ret.empty())
  69. throw cannotFulfillGoalException("BUILD has been realized as much as possible.");
  70. else
  71. return ret;
  72. }
  73. TSubgoal Build::whatToDoToAchieve()
  74. {
  75. return fh->chooseSolution(getAllPossibleSubgoals());
  76. }
  77. bool Build::fulfillsMe(TSubgoal goal)
  78. {
  79. if(goal->goalType == BUILD || goal->goalType == BUILD_STRUCTURE)
  80. return (!town || town == goal->town); //building anything will do, in this town if set
  81. else
  82. return false;
  83. }