ExecuteHeroChain.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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. ai->nullkiller->setActive(hero);
  68. Goals::VisitTile(node.coord).sethero(hero).accept(ai);
  69. // no exception means we were not able to rich the tile
  70. ai->nullkiller->lockHero(hero);
  71. blockedIndexes.insert(node.parentIndex);
  72. }
  73. catch(goalFulfilledException)
  74. {
  75. if(!hero)
  76. {
  77. logAi->debug("Hero %s was killed while attempting to rich %s", hero.name, node.coord.toString());
  78. return;
  79. }
  80. }
  81. }
  82. }
  83. std::string ExecuteHeroChain::name() const
  84. {
  85. return "ExecuteHeroChain " + targetName;
  86. }
  87. std::string ExecuteHeroChain::completeMessage() const
  88. {
  89. return "Hero chain completed";
  90. }