TurnInfo.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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 "../IGameSettings.h"
  13. #include "../TerrainHandler.h"
  14. #include "../GameLibrary.h"
  15. #include "../bonuses/BonusList.h"
  16. #include "../callback/IGameInfoCallback.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::getMovementCostBase() const
  59. {
  60. return moveCostBaseValue;
  61. }
  62. int TurnInfo::getMovePointsLimitLand() const
  63. {
  64. return movePointsLimitLand;
  65. }
  66. int TurnInfo::getMovePointsLimitWater() const
  67. {
  68. return movePointsLimitWater;
  69. }
  70. TurnInfo::TurnInfo(TurnInfoCache * sharedCache, const CGHeroInstance * target, int Turn)
  71. : target(target)
  72. , noterrainPenalty(LIBRARY->terrainTypeHandler->size())
  73. {
  74. CSelector daySelector = Selector::days(Turn);
  75. int lowestSpeed;
  76. if (target->getTreeVersion() == sharedCache->heroLowestSpeedVersion)
  77. {
  78. lowestSpeed = sharedCache->heroLowestSpeedValue;
  79. }
  80. else
  81. {
  82. lowestSpeed = target->getLowestCreatureSpeed();
  83. sharedCache->heroLowestSpeedValue = lowestSpeed;
  84. sharedCache->heroLowestSpeedVersion = target->getTreeVersion();
  85. }
  86. {
  87. static const CSelector selector = Selector::type()(BonusType::WATER_WALKING);
  88. const auto & bonuses = sharedCache->waterWalking.getBonusList(target, selector);
  89. waterWalkingTest = bonuses->getFirst(daySelector) != nullptr;
  90. waterWalkingValue = bonuses->valOfBonuses(daySelector);
  91. }
  92. {
  93. static const CSelector selector = Selector::type()(BonusType::FLYING_MOVEMENT);
  94. const auto & bonuses = sharedCache->flyingMovement.getBonusList(target, selector);
  95. flyingMovementTest = bonuses->getFirst(daySelector) != nullptr;
  96. flyingMovementValue = bonuses->valOfBonuses(daySelector);
  97. }
  98. {
  99. static const CSelector selector = Selector::type()(BonusType::FREE_SHIP_BOARDING);
  100. const auto & bonuses = sharedCache->freeShipBoarding.getBonusList(target, selector);
  101. freeShipBoardingTest = bonuses->getFirst(daySelector) != nullptr;
  102. }
  103. {
  104. static const CSelector selector = Selector::type()(BonusType::ROUGH_TERRAIN_DISCOUNT);
  105. const auto & bonuses = sharedCache->roughTerrainDiscount.getBonusList(target, selector);
  106. roughTerrainDiscountValue = bonuses->valOfBonuses(daySelector);
  107. }
  108. {
  109. static const CSelector selector = Selector::type()(BonusType::BASE_TILE_MOVEMENT_COST);
  110. const auto & bonuses = sharedCache->baseTileMovementCost.getBonusList(target, selector);
  111. int baseMovementCost = target->cb->getSettings().getInteger(EGameSettings::HEROES_MOVEMENT_COST_BASE);
  112. moveCostBaseValue = bonuses->valOfBonuses(daySelector, baseMovementCost);
  113. }
  114. {
  115. static const CSelector selector = Selector::typeSubtype(BonusType::MOVEMENT, BonusCustomSubtype::heroMovementSea);
  116. const auto & vectorSea = target->cb->getSettings().getValue(EGameSettings::HEROES_MOVEMENT_POINTS_SEA).Vector();
  117. const auto & bonuses = sharedCache->movementPointsLimitWater.getBonusList(target, selector);
  118. int baseMovementPointsSea;
  119. if (lowestSpeed < vectorSea.size())
  120. baseMovementPointsSea = vectorSea[lowestSpeed].Integer();
  121. else
  122. baseMovementPointsSea = vectorSea.back().Integer();
  123. movePointsLimitWater = bonuses->valOfBonuses(daySelector, baseMovementPointsSea);
  124. }
  125. {
  126. static const CSelector selector = Selector::typeSubtype(BonusType::MOVEMENT, BonusCustomSubtype::heroMovementLand);
  127. const auto & vectorLand = target->cb->getSettings().getValue(EGameSettings::HEROES_MOVEMENT_POINTS_LAND).Vector();
  128. const auto & bonuses = sharedCache->movementPointsLimitLand.getBonusList(target, selector);
  129. int baseMovementPointsLand;
  130. if (lowestSpeed < vectorLand.size())
  131. baseMovementPointsLand = vectorLand[lowestSpeed].Integer();
  132. else
  133. baseMovementPointsLand = vectorLand.back().Integer();
  134. movePointsLimitLand = bonuses->valOfBonuses(daySelector, baseMovementPointsLand);
  135. }
  136. {
  137. static const CSelector selector = Selector::type()(BonusType::NO_TERRAIN_PENALTY);
  138. const auto & bonuses = sharedCache->noTerrainPenalty.getBonusList(target, selector);
  139. for (const auto & bonus : *bonuses)
  140. {
  141. TerrainId affectedTerrain = bonus->subtype.as<TerrainId>();
  142. noterrainPenalty.at(affectedTerrain.num) = true;
  143. }
  144. const auto nativeTerrain = target->getNativeTerrain();
  145. if (nativeTerrain.hasValue())
  146. noterrainPenalty.at(nativeTerrain.num) = true;
  147. if (nativeTerrain == ETerrainId::ANY_TERRAIN)
  148. boost::range::fill(noterrainPenalty, true);
  149. }
  150. }
  151. bool TurnInfo::isLayerAvailable(const EPathfindingLayer & layer) const
  152. {
  153. switch(layer.toEnum())
  154. {
  155. case EPathfindingLayer::AIR:
  156. if(target && target->inBoat() && target->getBoat()->layer == EPathfindingLayer::AIR)
  157. break;
  158. if(!hasFlyingMovement())
  159. return false;
  160. break;
  161. case EPathfindingLayer::WATER:
  162. if(target && target->inBoat() && target->getBoat()->layer == EPathfindingLayer::WATER)
  163. break;
  164. if(!hasWaterWalking())
  165. return false;
  166. break;
  167. }
  168. return true;
  169. }
  170. int TurnInfo::getMaxMovePoints(const EPathfindingLayer & layer) const
  171. {
  172. return layer == EPathfindingLayer::SAIL ? getMovePointsLimitWater() : getMovePointsLimitLand();
  173. }
  174. VCMI_LIB_NAMESPACE_END