VisitObj.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * VisitObj.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 "Goals.h"
  12. #include "../VCAI.h"
  13. #include "../AIUtility.h"
  14. #include "../AIhelper.h"
  15. #include "../FuzzyHelper.h"
  16. #include "../ResourceManager.h"
  17. #include "../BuildingManager.h"
  18. #include "../../../lib/mapping/CMap.h" //for victory conditions
  19. #include "../../../lib/CPathfinder.h"
  20. #include "../../../lib/StringConstants.h"
  21. extern boost::thread_specific_ptr<CCallback> cb;
  22. extern boost::thread_specific_ptr<VCAI> ai;
  23. extern FuzzyHelper * fh;
  24. using namespace Goals;
  25. bool VisitObj::operator==(const VisitObj & other) const
  26. {
  27. return other.hero.h == hero.h && other.objid == objid;
  28. }
  29. std::string VisitObj::completeMessage() const
  30. {
  31. return "hero " + hero.get()->getNameTranslated() + " captured Object ID = " + std::to_string(objid);
  32. }
  33. TGoalVec VisitObj::getAllPossibleSubgoals()
  34. {
  35. TGoalVec goalList;
  36. const CGObjectInstance * obj = cb->getObjInstance(ObjectInstanceID(objid));
  37. if(!obj)
  38. {
  39. throw cannotFulfillGoalException("Object is missing - goal is invalid now!");
  40. }
  41. int3 pos = obj->visitablePos();
  42. if(hero)
  43. {
  44. if(ai->isAccessibleForHero(pos, hero))
  45. {
  46. if(isSafeToVisit(hero, pos))
  47. goalList.push_back(sptr(VisitObj(obj->id.getNum()).sethero(hero)));
  48. else
  49. goalList.push_back(sptr(GatherArmy((int)(fh->evaluateDanger(pos, hero.h) * SAFE_ATTACK_CONSTANT)).sethero(hero).setisAbstract(true)));
  50. return goalList;
  51. }
  52. }
  53. else
  54. {
  55. for(auto potentialVisitor : cb->getHeroesInfo())
  56. {
  57. if(ai->isAccessibleForHero(pos, potentialVisitor))
  58. {
  59. if(isSafeToVisit(potentialVisitor, pos))
  60. goalList.push_back(sptr(VisitObj(obj->id.getNum()).sethero(potentialVisitor)));
  61. else
  62. goalList.push_back(sptr(GatherArmy((int)(fh->evaluateDanger(pos, potentialVisitor) * SAFE_ATTACK_CONSTANT)).sethero(potentialVisitor).setisAbstract(true)));
  63. }
  64. }
  65. if(!goalList.empty())
  66. {
  67. return goalList;
  68. }
  69. }
  70. goalList.push_back(sptr(ClearWayTo(pos)));
  71. return goalList;
  72. }
  73. TSubgoal VisitObj::whatToDoToAchieve()
  74. {
  75. auto bestGoal = fh->chooseSolution(getAllPossibleSubgoals());
  76. if(bestGoal->goalType == VISIT_OBJ && bestGoal->hero)
  77. bestGoal->setisElementar(true);
  78. return bestGoal;
  79. }
  80. VisitObj::VisitObj(int Objid)
  81. : CGoal(VISIT_OBJ)
  82. {
  83. objid = Objid;
  84. auto obj = ai->myCb->getObjInstance(ObjectInstanceID(objid));
  85. if(obj)
  86. tile = obj->visitablePos();
  87. else
  88. logAi->error("VisitObj constructed with invalid object instance %d", Objid);
  89. priority = 3;
  90. }
  91. bool VisitObj::fulfillsMe(TSubgoal goal)
  92. {
  93. if(goal->goalType == VISIT_TILE)
  94. {
  95. if (!hero || hero == goal->hero)
  96. {
  97. auto obj = cb->getObjInstance(ObjectInstanceID(objid));
  98. if (obj && obj->visitablePos() == goal->tile) //object could be removed
  99. return true;
  100. }
  101. }
  102. return false;
  103. }