ExecuteHeroChain.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /*
  2. * ExecuteHeroChain.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 "ExecuteHeroChain.h"
  12. #include "VisitTile.h"
  13. #include "../VCAI.h"
  14. #include "../FuzzyHelper.h"
  15. #include "../AIhelper.h"
  16. #include "../../../lib/mapping/CMap.h" //for victory conditions
  17. #include "../../../lib/CPathfinder.h"
  18. #include "../Engine/Nullkiller.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. ExecuteHeroChain::ExecuteHeroChain(const AIPath & path, const CGObjectInstance * obj)
  24. :CGoal(Goals::EXECUTE_HERO_CHAIN), chainPath(path)
  25. {
  26. evaluationContext.danger = path.getTotalDanger(hero);
  27. evaluationContext.movementCost = path.movementCost();
  28. evaluationContext.armyLoss = path.armyLoss;
  29. evaluationContext.heroStrength = path.getHeroStrength();
  30. hero = path.targetHero;
  31. tile = path.targetTile();
  32. if(obj)
  33. {
  34. objid = obj->id.getNum();
  35. targetName = obj->getObjectName() + tile.toString();
  36. }
  37. else
  38. {
  39. targetName = "tile" + tile.toString();
  40. }
  41. }
  42. bool ExecuteHeroChain::operator==(const ExecuteHeroChain & other) const
  43. {
  44. return false;
  45. }
  46. TSubgoal ExecuteHeroChain::whatToDoToAchieve()
  47. {
  48. return iAmElementar();
  49. }
  50. void ExecuteHeroChain::accept(VCAI * ai)
  51. {
  52. logAi->debug("Executing hero chain towards %s. Path %s", targetName, chainPath.toString());
  53. std::set<int> blockedIndexes;
  54. for(int i = chainPath.nodes.size() - 1; i >= 0; i--)
  55. {
  56. auto & node = chainPath.nodes[i];
  57. HeroPtr hero = node.targetHero;
  58. if(vstd::contains(blockedIndexes, i))
  59. {
  60. blockedIndexes.insert(node.parentIndex);
  61. ai->nullkiller->lockHero(hero);
  62. continue;
  63. }
  64. logAi->debug("Executing chain node %d. Moving hero %s to %s", i, hero.name, node.coord.toString());
  65. try
  66. {
  67. if(hero->movement)
  68. {
  69. ai->nullkiller->setActive(hero);
  70. if(node.specialAction)
  71. {
  72. auto specialGoal = node.specialAction->whatToDo(hero);
  73. if(specialGoal->isElementar)
  74. specialGoal->accept(ai);
  75. }
  76. Goals::VisitTile(node.coord).sethero(hero).accept(ai);
  77. }
  78. // no exception means we were not able to rich the tile
  79. ai->nullkiller->lockHero(hero);
  80. blockedIndexes.insert(node.parentIndex);
  81. }
  82. catch(goalFulfilledException)
  83. {
  84. if(!hero)
  85. {
  86. logAi->debug("Hero %s was killed while attempting to rich %s", hero.name, node.coord.toString());
  87. return;
  88. }
  89. }
  90. }
  91. }
  92. std::string ExecuteHeroChain::name() const
  93. {
  94. return "ExecuteHeroChain " + targetName;
  95. }
  96. std::string ExecuteHeroChain::completeMessage() const
  97. {
  98. return "Hero chain completed";
  99. }