ExecuteHeroChain.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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 %" PRId32 ". 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. Goals::VisitTile(node.coord).sethero(hero).accept(ai);
  71. }
  72. // no exception means we were not able to rich the tile
  73. ai->nullkiller->lockHero(hero);
  74. blockedIndexes.insert(node.parentIndex);
  75. }
  76. catch(goalFulfilledException)
  77. {
  78. if(!hero)
  79. {
  80. logAi->debug("Hero %s was killed while attempting to rich %s", hero.name, node.coord.toString());
  81. return;
  82. }
  83. }
  84. }
  85. }
  86. std::string ExecuteHeroChain::name() const
  87. {
  88. return "ExecuteHeroChain " + targetName;
  89. }
  90. std::string ExecuteHeroChain::completeMessage() const
  91. {
  92. return "Hero chain completed";
  93. }
  94. ExchangeSwapTownHeroes::ExchangeSwapTownHeroes(const CGTownInstance * town, const CGHeroInstance * garrisonHero)
  95. :CGoal(Goals::EXCHANGE_SWAP_TOWN_HEROES), town(town), garrisonHero(garrisonHero)
  96. {
  97. }
  98. std::string ExchangeSwapTownHeroes::name() const
  99. {
  100. return "Exchange and swap heroes of " + town->name;
  101. }
  102. std::string ExchangeSwapTownHeroes::completeMessage() const
  103. {
  104. return "Exchange and swap heroes of " + town->name + " compelete";
  105. }
  106. bool ExchangeSwapTownHeroes::operator==(const ExchangeSwapTownHeroes & other) const
  107. {
  108. return town == other.town;
  109. }
  110. TSubgoal ExchangeSwapTownHeroes::whatToDoToAchieve()
  111. {
  112. return iAmElementar();
  113. }
  114. void ExchangeSwapTownHeroes::accept(VCAI * ai)
  115. {
  116. if(!garrisonHero && town->garrisonHero && town->visitingHero)
  117. throw cannotFulfillGoalException("Invalid configuration. Garrison hero is null.");
  118. if(!garrisonHero)
  119. {
  120. if(!town->garrisonHero)
  121. throw cannotFulfillGoalException("Invalid configuration. There is no hero in town garrison.");
  122. cb->swapGarrisonHero(town);
  123. ai->nullkiller->unlockHero(town->visitingHero.get());
  124. logAi->debug("Extracted hero %s from garrison of %s", town->visitingHero->name, town->name);
  125. return;
  126. }
  127. if(town->visitingHero && town->visitingHero.get() != garrisonHero)
  128. cb->swapGarrisonHero(town);
  129. ai->moveHeroToTile(town->visitablePos(), garrisonHero);
  130. cb->swapGarrisonHero(town); // selected hero left in garrison with strongest army
  131. ai->nullkiller->lockHero(town->garrisonHero.get());
  132. if(town->visitingHero)
  133. ai->nullkiller->unlockHero(town->visitingHero.get());
  134. logAi->debug("Put hero %s to garrison of %s", town->garrisonHero->name, town->name);
  135. }