CPathfinder.h 4.8 KB

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