VisitObj.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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()->name + " captured Object ID = " + boost::lexical_cast<std::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(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(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) : CGoal(VISIT_OBJ)
  81. {
  82. objid = Objid;
  83. tile = ai->myCb->getObjInstance(ObjectInstanceID(objid))->visitablePos();
  84. priority = 3;
  85. }
  86. bool VisitObj::fulfillsMe(TSubgoal goal)
  87. {
  88. if(goal->goalType == VISIT_TILE)
  89. {
  90. if (!hero || hero == goal->hero)
  91. {
  92. auto obj = cb->getObjInstance(ObjectInstanceID(objid));
  93. if (obj && obj->visitablePos() == goal->tile) //object could be removed
  94. return true;
  95. }
  96. }
  97. return false;
  98. }