OpenTTD Source
20240919-master-gdf0233f4c2
|
Go to the documentation of this file.
10 #include "../../stdafx.h"
11 #include "../../ship.h"
15 #include "../water_regions.h"
17 #include "../../safeguards.h"
19 constexpr
int DIRECT_NEIGHBOR_COST = 100;
20 constexpr
int NODES_PER_REGION = 4;
21 constexpr
int MAX_NUMBER_OF_NODES = 65536;
29 m_water_region_patch = water_region_patch;
38 return (
std::abs(a.m_water_region_patch.
x - b.m_water_region_patch.
x) +
std::abs(a.m_water_region_patch.
y - b.m_water_region_patch.
y)) * DIRECT_NEIGHBOR_COST;
42 template <
class Tkey_>
55 m_key.Set(water_region_patch);
56 m_hash_next =
nullptr;
62 inline void Set(
Node *parent,
const Key &key)
64 Set(parent, key.m_water_region_patch);
70 const int dx = m_key.m_water_region_patch.x - m_parent->m_key.m_water_region_patch.x;
71 const int dy = m_key.m_water_region_patch.y - m_parent->m_key.m_water_region_patch.y;
79 inline Node *GetHashNext() {
return m_hash_next; }
80 inline void SetHashNext(
Node *pNext) { m_hash_next = pNext; }
81 inline const Tkey_ &GetKey()
const {
return m_key; }
82 inline int GetCost() {
return m_cost; }
83 inline int GetCostEstimate() {
return m_estimate; }
84 inline bool operator<(
const Node &other)
const {
return m_estimate < other.m_estimate; }
88 template <
class Types>
92 typedef typename Types::Tpf
Tpf;
93 typedef typename Types::NodeList::Titem
Node;
94 typedef typename Node::Key
Key;
97 inline Tpf &Yapf() {
return *
static_cast<Tpf*
>(
this); }
100 std::vector<CYapfRegionPatchNodeKey> m_origin_keys;
105 if (water_region_patch.
label == INVALID_WATER_REGION_PATCH)
return;
111 return std::find(m_origin_keys.begin(), m_origin_keys.end(),
CYapfRegionPatchNodeKey{ water_region_patch }) != m_origin_keys.end();
114 void PfSetStartupNodes()
117 Node &node = Yapf().CreateNewNode();
118 node.Set(
nullptr, origin_key);
119 Yapf().AddStartupNode(node);
125 template <
class Types>
129 typedef typename Types::Tpf
Tpf;
130 typedef typename Types::NodeList::Titem
Node;
131 typedef typename Node::Key
Key;
139 m_dest.Set(water_region_patch);
143 Tpf &Yapf() {
return *
static_cast<Tpf*
>(
this); }
146 inline bool PfDetectDestination(
Node &n)
const
148 return n.m_key == m_dest;
151 inline bool PfCalcEstimate(
Node &n)
153 if (PfDetectDestination(n)) {
154 n.m_estimate = n.m_cost;
158 n.m_estimate = n.m_cost + ManhattanDistance(n.m_key, m_dest);
165 template <
class Types>
169 typedef typename Types::Tpf
Tpf;
170 typedef typename Types::TrackFollower TrackFollower;
171 typedef typename Types::NodeList::Titem
Node;
172 typedef typename Node::Key
Key;
175 inline Tpf &Yapf() {
return *
static_cast<Tpf*
>(
this); }
178 inline void PfFollowNode(
Node &old_node)
182 Node &node = Yapf().CreateNewNode();
183 node.Set(&old_node, water_region_patch);
184 Yapf().AddNewNode(node, TrackFollower{});
189 inline char TransportTypeChar()
const {
return '^'; }
191 static std::vector<WaterRegionPatchDesc> FindWaterRegionPath(
const Ship *v,
TileIndex start_tile,
int max_returned_path_length)
197 Tpf pf(std::min(
static_cast<int>(
Map::Size() * NODES_PER_REGION) / WATER_REGION_NUMBER_OF_TILES, MAX_NUMBER_OF_NODES));
198 pf.SetDestination(start_water_region_patch);
205 for (
const auto &tile : tile_area) {
216 std::vector<WaterRegionPatchDesc> path = { start_water_region_patch };
217 path.reserve(max_returned_path_length);
218 if (pf.HasOrigin(start_water_region_patch))
return path;
221 if (!pf.FindPath(v))
return {};
223 Node *node = pf.GetBestNode();
224 for (
int i = 0; i < max_returned_path_length - 1; ++i) {
225 if (node !=
nullptr) {
226 node = node->m_parent;
227 if (node !=
nullptr) path.push_back(node->m_key.m_water_region_patch);
231 assert(!path.empty());
237 template <
class Types>
241 typedef typename Types::Tpf
Tpf;
242 typedef typename Types::TrackFollower TrackFollower;
243 typedef typename Types::NodeList::Titem
Node;
244 typedef typename Node::Key
Key;
258 n.m_cost = n.m_parent->m_cost + ManhattanDistance(n.m_key, n.m_parent->m_key);
261 Node *grandparent = n.m_parent->m_parent;
262 if (grandparent !=
nullptr) {
278 template <
class Tpf_,
class Tnode_list>
284 typedef Tnode_list NodeList;
300 explicit CYapfRegionWater(
int max_nodes) { m_max_search_nodes = max_nodes; }
312 return CYapfRegionWater::FindWaterRegionPath(v, start_tile, max_returned_path_length);
CYapfFollowRegionT< Types > PfFollow
Node follower.
@ DIAGDIR_NE
Northeast, upper right on your monitor.
bool IsType(OrderType type) const
Check whether this order is of the given type.
static Titem * Get(size_t index)
Returns Titem with given index.
virtual void GetTileArea(TileArea *ta, StationType type) const =0
Get the tile area for a given station type.
Describes a single interconnected patch of water within a particular water region.
Cost Provider of YAPF for water regions.
DestinationID GetDestination() const
Gets the destination of this order.
Config struct of YAPF for route planning.
DiagDirDiff
Enumeration for the difference between to DiagDirection.
CYapfSegmentCostCacheNoneT< Types > PfCache
Segment cost cache provider.
Types::Tpf Tpf
The pathfinder class (derived from THIS class).
Yapf Node for water regions.
Node::Key Key
Key to hash tables.
CYapfDestinationRegionT< Types > PfDestination
Destination/distance provider.
@ DIAGDIRDIFF_90LEFT
90 degrees left
Node::Key Key
Key to hash tables.
int y
The Y coordinate of the water region, i.e. Y=2 is the 3rd water region along the Y-axis.
DiagDirection
Enumeration for diagonal directions.
CYapfCostRegionT< Types > PfCost
Cost provider.
YAPF node following for water region pathfinding.
YAPF template that uses Ttypes template argument to determine all YAPF components (base classes) from...
Types::NodeList::Titem Node
This will be our node type.
Tpf & Yapf()
To access inherited path finder.
CYapfRegion_TypesT< Tpf_, Tnode_list > Types
Shortcut for this struct type.
Types::NodeList::Titem Node
This will be our node type.
WaterRegionPatchDesc GetWaterRegionPatchInfo(TileIndex tile)
Returns basic water region patch information for the provided tile.
TileIndex dest_tile
Heading for this tile.
YAPF origin for water regions.
@ INVALID_DIAGDIR
Flag for an invalid DiagDirection.
Yapf Node Key that represents a single patch of interconnected water within a water region.
DiagDirDiff DiagDirDifference(DiagDirection d0, DiagDirection d1)
Calculate the difference between two DiagDirection values.
Order current_order
The current order (+ status, like: loading)
Types::NodeList::Titem Node
This will be our node type.
Represents the covered area of e.g.
@ DIAGDIRDIFF_90RIGHT
90 degrees right
Hash table based node list multi-container class.
void VisitWaterRegionPatchNeighbors(const WaterRegionPatchDesc &water_region_patch, TVisitWaterRegionPatchCallBack &callback)
Calls the provided callback function on all accessible water region patches in each cardinal directio...
int CalculateWaterRegionPatchHash(const WaterRegionPatchDesc &water_region_patch)
Calculates a number that uniquely identifies the provided water region patch.
YAPF destination provider for water regions.
CYapfSegmentCostCacheNoneT - the formal only yapf cost cache provider that implements PfNodeCacheFetc...
All ships have this type.
Types::Tpf Tpf
The pathfinder class (derived from THIS class).
Types::Tpf Tpf
The pathfinder class (derived from THIS class).
bool IsDockingTile(Tile t)
Checks whether the tile is marked as a dockling tile.
Types::NodeList::Titem Node
This will be our node type.
CYapfOriginRegionT< Types > PfOrigin
Origin provider.
constexpr T abs(const T a)
Returns the absolute value of (scalar) variable.
static debug_inline uint Size()
Get the size of the map.
CYapfBaseT< Types > PfBase
Pathfinder components (modules).
Base class for all station-ish types.
bool PfCalcCost(Node &n, const TrackFollower *)
Called by YAPF to calculate the cost from the origin to the given node.
TWaterRegionPatchLabel label
Unique label identifying the patch within the region.
Node::Key Key
Key to hash tables.
Types::Tpf Tpf
The pathfinder class (derived from THIS class).
DummyFollower TrackFollower
Track follower helper class.
std::vector< WaterRegionPatchDesc > YapfShipFindWaterRegionPath(const Ship *v, TileIndex start_tile, int max_returned_path_length)
Finds a path at the water region level.
bool IsShipDestinationTile(TileIndex tile, StationID station)
Test if a tile is a docking tile for the given station.
CYapfBaseT - A-star type path finder base class.
Node::Key Key
Key to hash tables.
Track follower helper template class (can serve pathfinders and vehicle controllers).
int x
The X coordinate of the water region, i.e. X=2 is the 3rd water region along the X-axis.