OpenTTD Source: src/pathfinder/yapf/yapf_river_builder.cpp Source File

OpenTTD Source 15.3

yapf_river_builder.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
10#include "../../stdafx.h"
11
12#include "../../water.h"
13#include "../../genworld.h"
14#include "yapf.hpp"
15
16#include "../../safeguards.h"
17
18/* River builder pathfinder node. */
19 struct YapfRiverBuilderNode : CYapfNodeT<CYapfNodeKeyTrackDir, YapfRiverBuilderNode> {};
20
21/* River builder pathfinder node list. */
22using RiverBuilderNodeList = NodeList<YapfRiverBuilderNode, 8, 10>;
23
24/* We don't need a follower but YAPF requires one. */
25 struct RiverBuilderFollower {};
26
27/* We don't need a vehicle but YAPF requires one. */
28 struct DummyVehicle : Vehicle {};
29
30class YapfRiverBuilder;
31
32/* Types struct required for YAPF components. */
33 struct RiverBuilderTypes {
34 using Tpf = YapfRiverBuilder;
35 using TrackFollower = RiverBuilderFollower;
36 using NodeList = RiverBuilderNodeList;
37 using VehicleType = DummyVehicle;
38};
39
40/* River builder pathfinder implementation. */
41 class YapfRiverBuilder
42 : public CYapfBaseT<RiverBuilderTypes>
43 , public CYapfSegmentCostCacheNoneT<RiverBuilderTypes>
44{
45public:
46 using Node = RiverBuilderTypes::NodeList::Item;
47 using Key = Node::Key;
48
49protected:
50 TileIndex end_tile;
51
52 inline YapfRiverBuilder &Yapf()
53 {
54 return *static_cast<YapfRiverBuilder *>(this);
55 }
56
57public:
58 YapfRiverBuilder(TileIndex start_tile, TileIndex end_tile)
59 {
60 this->end_tile = end_tile;
61
62 Node &node = Yapf().CreateNewNode();
63 node.Set(nullptr, start_tile, INVALID_TRACKDIR, false);
64 Yapf().AddStartupNode(node);
65 }
66
67 inline bool PfDetectDestination(Node &n) const
68 {
69 return n.GetTile() == this->end_tile;
70 }
71
72 inline bool PfCalcCost(Node &n, const RiverBuilderFollower *)
73 {
74 n.cost = n.parent->cost + 1 + RandomRange(_settings_game.game_creation.river_route_random);
75 return true;
76 }
77
78 inline bool PfCalcEstimate(Node &n)
79 {
80 n.estimate = n.cost + DistanceManhattan(this->end_tile, n.GetTile());
81 assert(n.estimate >= n.parent->estimate);
82 return true;
83 }
84
85 inline void PfFollowNode(Node &old_node)
86 {
87 for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; ++d) {
88 const TileIndex t = old_node.GetTile() + TileOffsByDiagDir(d);
89 if (IsValidTile(t) && RiverFlowsDown(old_node.GetTile(), t)) {
90 Node &node = Yapf().CreateNewNode();
91 node.Set(&old_node, t, INVALID_TRACKDIR, true);
92 Yapf().AddNewNode(node, RiverBuilderFollower{});
93 }
94 }
95 }
96
97 inline char TransportTypeChar() const
98 {
99 return '~';
100 }
101
102 static void BuildRiver(TileIndex start_tile, TileIndex end_tile, TileIndex spring_tile, bool main_river)
103 {
104 YapfRiverBuilder pf(start_tile, end_tile);
105 if (pf.FindPath(nullptr) == false) return; // No path found
106
107 /* First, build the river without worrying about its width. */
108 for (Node *node = pf.GetBestNode(); node != nullptr; node = node->parent) {
109 TileIndex tile = node->GetTile();
110 if (!IsWaterTile(tile)) {
111 MakeRiverAndModifyDesertZoneAround(tile);
112 }
113 }
114
115 /* If the river is a main river, go back along the path to widen it.
116 * Don't make wide rivers if we're using the original landscape generator.
117 */
118 if (_settings_game.game_creation.land_generator != LG_ORIGINAL && main_river) {
119 const uint long_river_length = _settings_game.game_creation.min_river_length * 4;
120
121 for (Node *node = pf.GetBestNode(); node != nullptr; node = node->parent) {
122 const TileIndex center_tile = node->GetTile();
123
124 /* Check if we should widen river depending on how far we are away from the source. */
125 uint current_river_length = DistanceManhattan(spring_tile, center_tile);
126 uint diameter = std::min(3u, (current_river_length / (long_river_length / 3u)) + 1u);
127 if (diameter <= 1) continue;
128
129 for (auto tile : SpiralTileSequence(center_tile, diameter)) {
130 RiverMakeWider(tile, center_tile);
131 }
132 }
133 }
134 }
135};
136
144 void YapfBuildRiver(TileIndex start_tile, TileIndex end_tile, TileIndex spring_tile, bool main_river)
145{
146 YapfRiverBuilder::BuildRiver(start_tile, end_tile, spring_tile, main_river);
147}
CYapfBaseT
CYapfBaseT - A-star type path finder base class.
Definition yapf_base.hpp:48
CYapfBaseT::AddNewNode
void AddNewNode(Node &n, const TrackFollower &follower)
AddNewNode() - called by Tderived::PfFollowNode() for each child node.
Definition yapf_base.hpp:188
CYapfBaseT::CreateNewNode
Node & CreateNewNode()
Calls NodeList::CreateNewNode() - allocates new node that can be filled and used as argument for AddS...
Definition yapf_base.hpp:153
CYapfBaseT::AddStartupNode
void AddStartupNode(Node &n)
Add new node (created by CreateNewNode and filled with data) into open list.
Definition yapf_base.hpp:160
CYapfSegmentCostCacheNoneT
CYapfSegmentCostCacheNoneT - the formal only yapf cost cache provider that implements PfNodeCacheFetc...
Definition yapf_costcache.hpp:23
NodeList
Hash table based node list multi-container class.
Definition nodelist.hpp:21
SpiralTileSequence
Generate TileIndices around a center tile or tile area, with increasing distance.
Definition tilearea_type.h:316
YapfRiverBuilder
Definition yapf_river_builder.cpp:44
YapfRiverBuilder::end_tile
TileIndex end_tile
End tile of the river.
Definition yapf_river_builder.cpp:50
DiagDirection
DiagDirection
Enumeration for diagonal directions.
Definition direction_type.h:78
DIAGDIR_END
@ DIAGDIR_END
Used for iterations.
Definition direction_type.h:84
DIAGDIR_BEGIN
@ DIAGDIR_BEGIN
Used for iterations.
Definition direction_type.h:79
LG_ORIGINAL
@ LG_ORIGINAL
The original landscape generator.
Definition genworld.h:21
RiverFlowsDown
bool RiverFlowsDown(TileIndex begin, TileIndex end)
Check whether a river at begin could (logically) flow down to end.
Definition landscape.cpp:1312
RiverMakeWider
void RiverMakeWider(TileIndex tile, TileIndex origin_tile)
Widen a river by expanding into adjacent tiles via circular tile search.
Definition landscape.cpp:1169
DistanceManhattan
uint DistanceManhattan(TileIndex t0, TileIndex t1)
Gets the Manhattan distance between the two given tiles.
Definition map.cpp:169
TileOffsByDiagDir
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:583
RandomRange
uint32_t RandomRange(uint32_t limit, const std::source_location location=std::source_location::current())
Pick a random number between 0 and limit - 1, inclusive.
Definition random_func.hpp:88
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
CYapfNodeT
Yapf Node base.
Definition yapf_node.hpp:61
DummyVehicle
Definition yapf_river_builder.cpp:28
GameCreationSettings::min_river_length
uint8_t min_river_length
the minimum river length
Definition settings_type.h:403
GameCreationSettings::land_generator
uint8_t land_generator
the landscape generator
Definition settings_type.h:384
GameCreationSettings::river_route_random
uint8_t river_route_random
the amount of randomicity for the route finding
Definition settings_type.h:404
GameSettings::game_creation
GameCreationSettings game_creation
settings used during the creation of a game (map)
Definition settings_type.h:634
LinkGraph::BaseNode
Node of the link graph.
Definition linkgraph.h:90
RiverBuilderFollower
Definition yapf_river_builder.cpp:25
RiverBuilderTypes
Definition yapf_river_builder.cpp:33
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >
Vehicle
Vehicle data structure.
Definition vehicle_base.h:205
YapfRiverBuilderNode
Definition yapf_river_builder.cpp:19
IsValidTile
bool IsValidTile(Tile tile)
Checks if a tile is valid.
Definition tile_map.h:161
INVALID_TRACKDIR
@ INVALID_TRACKDIR
Flag for an invalid trackdir.
Definition track_type.h:85
MakeRiverAndModifyDesertZoneAround
void MakeRiverAndModifyDesertZoneAround(TileIndex tile)
Make a river tile and remove desert directly around it.
Definition water_cmd.cpp:472
IsWaterTile
bool IsWaterTile(Tile t)
Is it a water tile with plain water?
Definition water_map.h:192
yapf.hpp
Base includes/functions for YAPF.
YapfBuildRiver
void YapfBuildRiver(TileIndex start_tile, TileIndex end_tile, TileIndex spring_tile, bool main_river)
Builds a river from the start tile to the end tile.
Definition yapf_river_builder.cpp:144