TurnInfo.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. * TurnInfo.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 "TurnInfo.h"
  12. #include "../IGameCallback.h"
  13. #include "../IGameSettings.h"
  14. #include "../TerrainHandler.h"
  15. #include "../VCMI_Lib.h"
  16. #include "../bonuses/BonusList.h"
  17. #include "../json/JsonNode.h"
  18. #include "../mapObjects/CGHeroInstance.h"
  19. #include "../mapObjects/MiscObjects.h"
  20. VCMI_LIB_NAMESPACE_BEGIN
  21. TConstBonusListPtr TurnInfoBonusList::getBonusList(const CGHeroInstance * target, const CSelector & bonusSelector)
  22. {
  23. std::lock_guard guard(bonusListMutex);
  24. if (target->getTreeVersion() == bonusListVersion)
  25. return bonusList;
  26. bonusList = target->getBonuses(bonusSelector);
  27. bonusListVersion = target->getTreeVersion();
  28. return bonusList;
  29. }
  30. int TurnInfo::hasWaterWalking() const
  31. {
  32. return waterWalkingTest;
  33. }
  34. int TurnInfo::hasFlyingMovement() const
  35. {
  36. return flyingMovementTest;
  37. }
  38. int TurnInfo::hasNoTerrainPenalty(const TerrainId &terrain) const
  39. {
  40. return noterrainPenalty[terrain.num];
  41. }
  42. int TurnInfo::hasFreeShipBoarding() const
  43. {
  44. return freeShipBoardingTest;
  45. }
  46. int TurnInfo::getFlyingMovementValue() const
  47. {
  48. return flyingMovementValue;
  49. }
  50. int TurnInfo::getWaterWalkingValue() const
  51. {
  52. return waterWalkingValue;
  53. }
  54. int TurnInfo::getRoughTerrainDiscountValue() const
  55. {
  56. return roughTerrainDiscountValue;
  57. }
  58. int TurnInfo::getMovePointsLimitLand() const
  59. {
  60. return movePointsLimitLand;
  61. }
  62. int TurnInfo::getMovePointsLimitWater() const
  63. {
  64. return movePointsLimitWater;
  65. }
  66. TurnInfo::TurnInfo(TurnInfoCache * sharedCache, const CGHeroInstance * target, int Turn)
  67. : target(target)
  68. , noterrainPenalty(VLC->terrainTypeHandler->size())
  69. {
  70. CSelector daySelector = Selector::days(Turn);
  71. int lowestSpeed;
  72. if (target->getTreeVersion() == sharedCache->heroLowestSpeedVersion)
  73. {
  74. lowestSpeed = sharedCache->heroLowestSpeedValue;
  75. }
  76. else
  77. {
  78. lowestSpeed = target->getLowestCreatureSpeed();
  79. sharedCache->heroLowestSpeedValue = lowestSpeed;
  80. sharedCache->heroLowestSpeedVersion = target->getTreeVersion();
  81. }
  82. {
  83. static const CSelector selector = Selector::type()(BonusType::WATER_WALKING);
  84. const auto & bonuses = sharedCache->waterWalking.getBonusList(target, selector);
  85. waterWalkingTest = bonuses->getFirst(daySelector) != nullptr;
  86. waterWalkingValue = bonuses->valOfBonuses(daySelector);
  87. }
  88. {
  89. static const CSelector selector = Selector::type()(BonusType::FLYING_MOVEMENT);
  90. const auto & bonuses = sharedCache->flyingMovement.getBonusList(target, selector);
  91. flyingMovementTest = bonuses->getFirst(daySelector) != nullptr;
  92. flyingMovementValue = bonuses->valOfBonuses(daySelector);
  93. }
  94. {
  95. static const CSelector selector = Selector::type()(BonusType::FREE_SHIP_BOARDING);
  96. const auto & bonuses = sharedCache->freeShipBoarding.getBonusList(target, selector);
  97. freeShipBoardingTest = bonuses->getFirst(daySelector) != nullptr;
  98. }
  99. {
  100. static const CSelector selector = Selector::type()(BonusType::ROUGH_TERRAIN_DISCOUNT);
  101. const auto & bonuses = sharedCache->roughTerrainDiscount.getBonusList(target, selector);
  102. roughTerrainDiscountValue = bonuses->valOfBonuses(daySelector);
  103. }
  104. {
  105. static const CSelector selector = Selector::typeSubtype(BonusType::MOVEMENT, BonusCustomSubtype::heroMovementSea);
  106. const auto & vectorSea = target->cb->getSettings().getValue(EGameSettings::HEROES_MOVEMENT_POINTS_SEA).Vector();
  107. const auto & bonuses = sharedCache->movementPointsLimitWater.getBonusList(target, selector);
  108. int baseMovementPointsSea;
  109. if (lowestSpeed < vectorSea.size())
  110. baseMovementPointsSea = vectorSea[lowestSpeed].Integer();
  111. else
  112. baseMovementPointsSea = vectorSea.back().Integer();
  113. movePointsLimitWater = bonuses->valOfBonuses(daySelector, baseMovementPointsSea);
  114. }
  115. {
  116. static const CSelector selector = Selector::typeSubtype(BonusType::MOVEMENT, BonusCustomSubtype::heroMovementLand);
  117. const auto & vectorLand = target->cb->getSettings().getValue(EGameSettings::HEROES_MOVEMENT_POINTS_LAND).Vector();
  118. const auto & bonuses = sharedCache->movementPointsLimitLand.getBonusList(target, selector);
  119. int baseMovementPointsLand;
  120. if (lowestSpeed < vectorLand.size())
  121. baseMovementPointsLand = vectorLand[lowestSpeed].Integer();
  122. else
  123. baseMovementPointsLand = vectorLand.back().Integer();
  124. movePointsLimitLand = bonuses->valOfBonuses(daySelector, baseMovementPointsLand);
  125. }
  126. {
  127. static const CSelector selector = Selector::type()(BonusType::NO_TERRAIN_PENALTY);
  128. const auto & bonuses = sharedCache->noTerrainPenalty.getBonusList(target, selector);
  129. for (const auto & bonus : *bonuses)
  130. {
  131. TerrainId affectedTerrain = bonus->subtype.as<TerrainId>();
  132. noterrainPenalty.at(affectedTerrain.num) = true;
  133. }
  134. const auto nativeTerrain = target->getNativeTerrain();
  135. if (nativeTerrain.hasValue())
  136. noterrainPenalty.at(nativeTerrain.num) = true;
  137. if (nativeTerrain == ETerrainId::ANY_TERRAIN)
  138. boost::range::fill(noterrainPenalty, true);
  139. }
  140. }
  141. bool TurnInfo::isLayerAvailable(const EPathfindingLayer & layer) const
  142. {
  143. switch(layer.toEnum())
  144. {
  145. case EPathfindingLayer::AIR:
  146. if(target && target->boat && target->boat->layer == EPathfindingLayer::AIR)
  147. break;
  148. if(!hasFlyingMovement())
  149. return false;
  150. break;
  151. case EPathfindingLayer::WATER:
  152. if(target && target->boat && target->boat->layer == EPathfindingLayer::WATER)
  153. break;
  154. if(!hasWaterWalking())
  155. return false;
  156. break;
  157. }
  158. return true;
  159. }
  160. int TurnInfo::getMaxMovePoints(const EPathfindingLayer & layer) const
  161. {
  162. return layer == EPathfindingLayer::SAIL ? getMovePointsLimitWater() : getMovePointsLimitLand();
  163. }
  164. VCMI_LIB_NAMESPACE_END