VisitObj.cpp 2.8 KB

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