CPathfinder.h 4.8 KB

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