CGPathNode.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /*
  2. * CGPathNode.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 "../constants/Enumerations.h"
  12. #include "../constants/EntityIdentifiers.h"
  13. #include "../int3.h"
  14. #include <boost/heap/fibonacci_heap.hpp>
  15. VCMI_LIB_NAMESPACE_BEGIN
  16. class CGHeroInstance;
  17. class CGObjectInstance;
  18. class CGameState;
  19. class CPathfinderHelper;
  20. struct TerrainTile;
  21. template<typename N>
  22. struct DLL_LINKAGE NodeComparer
  23. {
  24. STRONG_INLINE
  25. bool operator()(const N * lhs, const N * rhs) const
  26. {
  27. return lhs->getCost() > rhs->getCost();
  28. }
  29. };
  30. enum class EPathAccessibility : ui8
  31. {
  32. NOT_SET,
  33. ACCESSIBLE, //tile can be entered and passed
  34. VISITABLE, //tile can be entered as the last tile in path
  35. GUARDED, //tile can be entered, but is in zone of control of nearby monster (may also contain visitable object, if any)
  36. BLOCKVIS, //visitable from neighboring tile but not passable
  37. FLYABLE, //can only be accessed in air layer
  38. BLOCKED //tile can be neither entered nor visited
  39. };
  40. enum class EPathNodeAction : ui8
  41. {
  42. UNKNOWN,
  43. EMBARK,
  44. DISEMBARK,
  45. NORMAL,
  46. BATTLE,
  47. VISIT,
  48. BLOCKING_VISIT,
  49. TELEPORT_NORMAL,
  50. TELEPORT_BLOCKING_VISIT,
  51. TELEPORT_BATTLE
  52. };
  53. struct DLL_LINKAGE CGPathNode
  54. {
  55. using TFibHeap = boost::heap::fibonacci_heap<CGPathNode *, boost::heap::compare<NodeComparer<CGPathNode>>>;
  56. using ELayer = EPathfindingLayer;
  57. TFibHeap::handle_type pqHandle;
  58. TFibHeap * pq;
  59. CGPathNode * theNodeBefore;
  60. int3 coord; //coordinates
  61. ELayer layer;
  62. float cost; //total cost of the path to this tile measured in turns with fractions
  63. int moveRemains; //remaining movement points after hero reaches the tile
  64. ui8 turns; //how many turns we have to wait before reaching the tile - 0 means current turn
  65. EPathAccessibility accessible;
  66. EPathNodeAction action;
  67. bool locked;
  68. CGPathNode()
  69. : coord(-1),
  70. layer(ELayer::WRONG),
  71. pqHandle(nullptr)
  72. {
  73. reset();
  74. }
  75. STRONG_INLINE
  76. void reset()
  77. {
  78. locked = false;
  79. accessible = EPathAccessibility::NOT_SET;
  80. moveRemains = 0;
  81. cost = std::numeric_limits<float>::max();
  82. turns = 255;
  83. theNodeBefore = nullptr;
  84. pq = nullptr;
  85. action = EPathNodeAction::UNKNOWN;
  86. }
  87. STRONG_INLINE
  88. bool inPQ() const
  89. {
  90. return pq != nullptr;
  91. }
  92. STRONG_INLINE
  93. float getCost() const
  94. {
  95. return cost;
  96. }
  97. STRONG_INLINE
  98. void setCost(float value)
  99. {
  100. if(vstd::isAlmostEqual(value, cost))
  101. return;
  102. bool getUpNode = value < cost;
  103. cost = value;
  104. // If the node is in the heap, update the heap.
  105. if(inPQ())
  106. {
  107. if(getUpNode)
  108. {
  109. pq->increase(this->pqHandle);
  110. }
  111. else
  112. {
  113. pq->decrease(this->pqHandle);
  114. }
  115. }
  116. }
  117. STRONG_INLINE
  118. void update(const int3 & Coord, const ELayer Layer, const EPathAccessibility Accessible)
  119. {
  120. if(layer == ELayer::WRONG)
  121. {
  122. coord = Coord;
  123. layer = Layer;
  124. }
  125. else
  126. {
  127. reset();
  128. }
  129. accessible = Accessible;
  130. }
  131. STRONG_INLINE
  132. bool reachable() const
  133. {
  134. return turns < 255;
  135. }
  136. bool isTeleportAction() const
  137. {
  138. if (action != EPathNodeAction::TELEPORT_NORMAL &&
  139. action != EPathNodeAction::TELEPORT_BLOCKING_VISIT &&
  140. action != EPathNodeAction::TELEPORT_BATTLE)
  141. {
  142. return false;
  143. }
  144. return true;
  145. }
  146. };
  147. struct DLL_LINKAGE CGPath
  148. {
  149. std::vector<CGPathNode> nodes; //just get node by node
  150. /// Starting position of path, matches location of hero
  151. const CGPathNode & currNode() const;
  152. /// First node in path, this is where hero will move next
  153. const CGPathNode & nextNode() const;
  154. /// Last node in path, this is what hero wants to reach in the end
  155. const CGPathNode & lastNode() const;
  156. int3 startPos() const; // start point
  157. int3 endPos() const; //destination point
  158. };
  159. struct DLL_LINKAGE CPathsInfo
  160. {
  161. using ELayer = EPathfindingLayer;
  162. const CGHeroInstance * hero;
  163. int3 hpos;
  164. int3 sizes;
  165. /// Bonus tree version for which this information can be considered to be valid
  166. int heroBonusTreeVersion = 0;
  167. boost::multi_array<CGPathNode, 4> nodes; //[layer][level][w][h]
  168. CPathsInfo(const int3 & Sizes, const CGHeroInstance * hero_);
  169. ~CPathsInfo();
  170. const CGPathNode * getPathInfo(const int3 & tile) const;
  171. bool getPath(CGPath & out, const int3 & dst) const;
  172. const CGPathNode * getNode(const int3 & coord) const;
  173. STRONG_INLINE
  174. CGPathNode * getNode(const int3 & coord, const ELayer layer)
  175. {
  176. return &nodes[layer.getNum()][coord.z][coord.x][coord.y];
  177. }
  178. };
  179. struct DLL_LINKAGE PathNodeInfo
  180. {
  181. CGPathNode * node;
  182. const CGObjectInstance * nodeObject;
  183. const CGHeroInstance * nodeHero;
  184. const TerrainTile * tile;
  185. int3 coord;
  186. bool guarded;
  187. PlayerRelations objectRelations;
  188. PlayerRelations heroRelations;
  189. bool isInitialPosition;
  190. PathNodeInfo();
  191. virtual void setNode(const IGameInfoCallback & gameInfo, CGPathNode * n);
  192. void updateInfo(CPathfinderHelper * hlp, const IGameInfoCallback & gameInfo);
  193. bool isNodeObjectVisitable() const;
  194. };
  195. struct DLL_LINKAGE CDestinationNodeInfo : public PathNodeInfo
  196. {
  197. EPathNodeAction action;
  198. int turn;
  199. int movementLeft;
  200. float cost; //same as CGPathNode::cost
  201. bool blocked;
  202. bool isGuardianTile;
  203. CDestinationNodeInfo();
  204. void setNode(const IGameInfoCallback & gameInfo, CGPathNode * n) override;
  205. virtual bool isBetterWay() const;
  206. };
  207. VCMI_LIB_NAMESPACE_END