ExchangeSwapTownHeroes.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. /*
  2. * ExchangeSwapTownHeroes.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 "ExchangeSwapTownHeroes.h"
  12. #include "ExecuteHeroChain.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. ExchangeSwapTownHeroes::ExchangeSwapTownHeroes(
  24. const CGTownInstance * town,
  25. const CGHeroInstance * garrisonHero,
  26. HeroLockedReason lockingReason)
  27. :CGoal(Goals::EXCHANGE_SWAP_TOWN_HEROES), town(town), garrisonHero(garrisonHero), lockingReason(lockingReason)
  28. {
  29. }
  30. std::string ExchangeSwapTownHeroes::name() const
  31. {
  32. return "Exchange and swap heroes of " + town->name;
  33. }
  34. bool ExchangeSwapTownHeroes::operator==(const ExchangeSwapTownHeroes & other) const
  35. {
  36. return town == other.town;
  37. }
  38. TSubgoal ExchangeSwapTownHeroes::whatToDoToAchieve()
  39. {
  40. return iAmElementar();
  41. }
  42. void ExchangeSwapTownHeroes::accept(VCAI * ai)
  43. {
  44. if(!garrisonHero)
  45. {
  46. if(!town->garrisonHero)
  47. throw cannotFulfillGoalException("Invalid configuration. There is no hero in town garrison.");
  48. cb->swapGarrisonHero(town);
  49. ai->buildArmyIn(town);
  50. ai->nullkiller->unlockHero(town->visitingHero.get());
  51. logAi->debug("Extracted hero %s from garrison of %s", town->visitingHero->name, town->name);
  52. return;
  53. }
  54. if(town->visitingHero && town->visitingHero.get() != garrisonHero)
  55. cb->swapGarrisonHero(town);
  56. ai->makePossibleUpgrades(town);
  57. ai->moveHeroToTile(town->visitablePos(), garrisonHero);
  58. auto upperArmy = town->getUpperArmy();
  59. if(!town->garrisonHero && upperArmy->stacksCount() != 0)
  60. {
  61. // dismiss creatures we are not able to pick to be able to hide in garrison
  62. if(upperArmy->getArmyStrength() < 500
  63. && town->fortLevel() >= CGTownInstance::CITADEL)
  64. {
  65. for(auto slot : upperArmy->Slots())
  66. {
  67. cb->dismissCreature(upperArmy, slot.first);
  68. }
  69. cb->swapGarrisonHero(town);
  70. }
  71. }
  72. else
  73. {
  74. cb->swapGarrisonHero(town); // selected hero left in garrison with strongest army
  75. }
  76. ai->nullkiller->lockHero(garrisonHero, lockingReason);
  77. if(town->visitingHero && town->visitingHero != garrisonHero)
  78. {
  79. ai->nullkiller->unlockHero(town->visitingHero.get());
  80. ai->makePossibleUpgrades(town->visitingHero);
  81. }
  82. logAi->debug("Put hero %s to garrison of %s", garrisonHero->name, town->name);
  83. }