CPathfinder.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. * CPathfinder.h, 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. #pragma once
  11. #include "CGPathNode.h"
  12. #include "../IGameCallback.h"
  13. #include "../bonuses/BonusEnum.h"
  14. VCMI_LIB_NAMESPACE_BEGIN
  15. class CGWhirlpool;
  16. class TurnInfo;
  17. struct PathfinderOptions;
  18. // Optimized storage - tile can have 0-8 neighbour tiles
  19. // static_vector uses fixed, preallocated storage (capacity) and dynamic size
  20. // this avoid dynamic allocations on huge number of neighbour list queries
  21. using NeighbourTilesVector = boost::container::static_vector<int3, 8>;
  22. // Optimized storage to minimize dynamic allocations - most of teleporters have only one exit, but some may have more (premade maps, castle gates)
  23. using TeleporterTilesVector = boost::container::small_vector<int3, 4>;
  24. class DLL_LINKAGE CPathfinder
  25. {
  26. public:
  27. friend class CPathfinderHelper;
  28. CPathfinder(
  29. CGameState * _gs,
  30. std::shared_ptr<PathfinderConfig> config);
  31. void calculatePaths(); //calculates possible paths for hero, uses current hero position and movement left; returns pointer to newly allocated CPath or nullptr if path does not exists
  32. private:
  33. CGameState * gamestate;
  34. using ELayer = EPathfindingLayer;
  35. std::shared_ptr<PathfinderConfig> config;
  36. boost::heap::fibonacci_heap<CGPathNode *, boost::heap::compare<NodeComparer<CGPathNode>> > pq;
  37. PathNodeInfo source; //current (source) path node -> we took it from the queue
  38. CDestinationNodeInfo destination; //destination node -> it's a neighbour of source that we consider
  39. bool isLayerTransitionPossible() const;
  40. EPathNodeAction getTeleportDestAction() const;
  41. bool isDestinationGuardian() const;
  42. void initializeGraph();
  43. STRONG_INLINE
  44. void push(CGPathNode * node);
  45. STRONG_INLINE
  46. CGPathNode * topAndPop();
  47. };
  48. class DLL_LINKAGE CPathfinderHelper : private CGameInfoCallback
  49. {
  50. public:
  51. enum EPatrolState
  52. {
  53. PATROL_NONE = 0,
  54. PATROL_LOCKED = 1,
  55. PATROL_RADIUS
  56. } patrolState;
  57. std::unordered_set<int3> patrolTiles;
  58. int turn;
  59. PlayerColor owner;
  60. const CGHeroInstance * hero;
  61. std::vector<std::unique_ptr<TurnInfo>> turnsInfo;
  62. const PathfinderOptions & options;
  63. bool canCastFly;
  64. bool canCastWaterWalk;
  65. bool whirlpoolProtection;
  66. CPathfinderHelper(CGameState * gs, const CGHeroInstance * Hero, const PathfinderOptions & Options);
  67. virtual ~CPathfinderHelper();
  68. void initializePatrol();
  69. bool isHeroPatrolLocked() const;
  70. bool canMoveFromNode(const PathNodeInfo & source) const;
  71. bool isPatrolMovementAllowed(const int3 & dst) const;
  72. void updateTurnInfo(const int turn = 0);
  73. bool isLayerAvailable(const EPathfindingLayer & layer) const;
  74. const TurnInfo * getTurnInfo() const;
  75. //bool hasBonusOfType(BonusType type) const;
  76. int getMaxMovePoints(const EPathfindingLayer & layer) const;
  77. TeleporterTilesVector getCastleGates(const PathNodeInfo & source) const;
  78. bool isAllowedTeleportEntrance(const CGTeleport * obj) const;
  79. TeleporterTilesVector getAllowedTeleportChannelExits(const TeleportChannelID & channelID) const;
  80. bool addTeleportTwoWay(const CGTeleport * obj) const;
  81. bool addTeleportOneWay(const CGTeleport * obj) const;
  82. bool addTeleportOneWayRandom(const CGTeleport * obj) const;
  83. bool addTeleportWhirlpool(const CGWhirlpool * obj) const;
  84. bool canMoveBetween(const int3 & a, const int3 & b) const; //checks only for visitable objects that may make moving between tiles impossible, not other conditions (like tiles itself accessibility)
  85. void calculateNeighbourTiles(NeighbourTilesVector & result, const PathNodeInfo & source) const;
  86. TeleporterTilesVector getTeleportExits(const PathNodeInfo & source) const;
  87. void getNeighbours(
  88. const TerrainTile & srcTile,
  89. const int3 & srcCoord,
  90. NeighbourTilesVector & vec,
  91. const boost::logic::tribool & onLand,
  92. const bool limitCoastSailing) const;
  93. int getMovementCost(
  94. const int3 & src,
  95. const int3 & dst,
  96. const TerrainTile * ct,
  97. const TerrainTile * dt,
  98. const int remainingMovePoints = -1,
  99. const bool checkLast = true,
  100. boost::logic::tribool isDstSailLayer = boost::logic::indeterminate,
  101. boost::logic::tribool isDstWaterLayer = boost::logic::indeterminate) const;
  102. int getMovementCost(
  103. const PathNodeInfo & src,
  104. const PathNodeInfo & dst,
  105. const int remainingMovePoints = -1,
  106. const bool checkLast = true) const;
  107. int movementPointsAfterEmbark(int movement, int basicCost, bool disembark) const;
  108. bool passOneTurnLimitCheck(const PathNodeInfo & source) const;
  109. int getGuardiansCount(int3 tile) const;
  110. };
  111. VCMI_LIB_NAMESPACE_END