OpenTTD Source 20251213-master-g1091fa6071
road.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#include "rail_map.h"
12#include "road_map.h"
13#include "water_map.h"
14#include "genworld.h"
15#include "company_func.h"
16#include "company_base.h"
17#include "engine_base.h"
19#include "landscape.h"
20#include "road.h"
21#include "road_func.h"
22#include "roadveh.h"
23
24#include "safeguards.h"
25
31{
32 extern RoadTypeInfo _roadtypes[ROADTYPE_END];
33 size_t index = this - _roadtypes;
34 assert(index < ROADTYPE_END);
35 return static_cast<RoadType>(index);
36}
37
45static bool IsPossibleCrossing(const TileIndex tile, Axis ax)
46{
47 return (IsTileType(tile, MP_RAILWAY) &&
49 GetTrackBits(tile) == (ax == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X) &&
50 std::get<0>(GetFoundationSlope(tile)) == SLOPE_FLAT);
51}
52
60{
61 if (!IsValidTile(tile)) return ROAD_NONE;
62 for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
63 const TileIndex neighbour_tile = TileAddByDiagDir(tile, dir);
64
65 /* Get the Roadbit pointing to the neighbour_tile */
66 const RoadBits target_rb = DiagDirToRoadBits(dir);
67
68 /* If the roadbit is in the current plan */
69 if (org_rb & target_rb) {
70 bool connective = false;
71 const RoadBits mirrored_rb = MirrorRoadBits(target_rb);
72
73 if (IsValidTile(neighbour_tile)) {
74 switch (GetTileType(neighbour_tile)) {
75 /* Always connective ones */
76 case MP_CLEAR: case MP_TREES:
77 connective = true;
78 break;
79
80 /* The conditionally connective ones */
81 case MP_TUNNELBRIDGE:
82 case MP_STATION:
83 case MP_ROAD:
84 if (IsNormalRoadTile(neighbour_tile)) {
85 /* Always connective */
86 connective = true;
87 } else {
88 const RoadBits neighbour_rb = GetAnyRoadBits(neighbour_tile, RTT_ROAD) | GetAnyRoadBits(neighbour_tile, RTT_TRAM);
89
90 /* Accept only connective tiles */
91 connective = (neighbour_rb & mirrored_rb) != ROAD_NONE;
92 }
93 break;
94
95 case MP_RAILWAY:
96 connective = IsPossibleCrossing(neighbour_tile, DiagDirToAxis(dir));
97 break;
98
99 case MP_WATER:
100 /* Check for real water tile */
101 connective = !IsWater(neighbour_tile);
102 break;
103
104 /* The definitely not connective ones */
105 default: break;
106 }
107 }
108
109 /* If the neighbour tile is inconnective, remove the planned road connection to it */
110 if (!connective) org_rb ^= target_rb;
111 }
112 }
113
114 return org_rb;
115}
116
123bool HasRoadTypeAvail(const CompanyID company, RoadType roadtype)
124{
125 if (company == OWNER_DEITY || company == OWNER_TOWN || _game_mode == GM_EDITOR || _generating_world) {
126 const RoadTypeInfo *rti = GetRoadTypeInfo(roadtype);
127 if (rti->label == 0) return false;
128
129 /* Not yet introduced at this date. */
131
132 /*
133 * Do not allow building hidden road types, except when a town may build it.
134 * The GS under deity mode, as well as anybody in the editor builds roads that are
135 * owned by towns. So if a town may build it, it should be buildable by them too.
136 */
138 } else {
139 const Company *c = Company::GetIfValid(company);
140 if (c == nullptr) return false;
141 RoadTypes avail = c->avail_roadtypes;
143 return avail.Test(roadtype);
144 }
145}
146
153{
154 RoadTypes avail = Company::Get(company)->avail_roadtypes;
156 return avail.Any(GetMaskForRoadTramType(rtt));
157}
158
165{
166 return roadtype < ROADTYPE_END && HasRoadTypeAvail(_current_company, roadtype);
167}
168
178{
179 RoadTypes rts = current;
180
181 for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
182 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
183 /* Unused road type. */
184 if (rti->label == 0) continue;
185
186 /* Not date introduced. */
187 if (!IsInsideMM(rti->introduction_date, 0, CalendarTime::MAX_DATE.base())) continue;
188
189 /* Not yet introduced at this date. */
190 if (rti->introduction_date > date) continue;
191
192 /* Have we introduced all required roadtypes? */
194 if (!rts.All(required)) continue;
195
196 rts.Set(rti->introduces_roadtypes);
197 }
198
199 /* When we added roadtypes we need to run this method again; the added
200 * roadtypes might enable more rail types to become introduced. */
201 return rts == current ? rts : AddDateIntroducedRoadTypes(rts, date);
202}
203
210RoadTypes GetCompanyRoadTypes(CompanyID company, bool introduces)
211{
212 RoadTypes rts{};
213
214 for (const Engine *e : Engine::IterateType(VEH_ROAD)) {
215 const EngineInfo *ei = &e->info;
216
218 (e->company_avail.Test(company) || TimerGameCalendar::date >= e->intro_date + CalendarTime::DAYS_IN_YEAR)) {
219 const RoadVehicleInfo *rvi = &e->VehInfo<RoadVehicleInfo>();
220 assert(rvi->roadtype < ROADTYPE_END);
221 if (introduces) {
223 } else {
224 rts.Set(rvi->roadtype);
225 }
226 }
227 }
228
229 if (introduces) return AddDateIntroducedRoadTypes(rts, TimerGameCalendar::date);
230 return rts;
231}
232
238RoadTypes GetRoadTypes(bool introduces)
239{
240 RoadTypes rts{};
241
242 for (const Engine *e : Engine::IterateType(VEH_ROAD)) {
243 const EngineInfo *ei = &e->info;
245
246 const RoadVehicleInfo *rvi = &e->VehInfo<RoadVehicleInfo>();
247 assert(rvi->roadtype < ROADTYPE_END);
248 if (introduces) {
250 } else {
251 rts.Set(rvi->roadtype);
252 }
253 }
254
255 if (introduces) return AddDateIntroducedRoadTypes(rts, CalendarTime::MAX_DATE);
256 return rts;
257}
258
265RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels)
266{
267 extern RoadTypeInfo _roadtypes[ROADTYPE_END];
268 if (label == 0) return INVALID_ROADTYPE;
269
270 auto it = std::ranges::find(_roadtypes, label, &RoadTypeInfo::label);
271 if (it == std::end(_roadtypes) && allow_alternate_labels) {
272 /* Test if any road type defines the label as an alternate. */
273 it = std::ranges::find_if(_roadtypes, [label](const RoadTypeInfo &rti) { return rti.alternate_labels.contains(label); });
274 }
275
276 if (it != std::end(_roadtypes)) return it->Index();
277
278 /* No matching label was found, so it is invalid */
279 return INVALID_ROADTYPE;
280}
constexpr bool All(const Timpl &other) const
Test if all of the values are set.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr Timpl & Reset()
Reset all bits.
constexpr Timpl & Set()
Set all bits.
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
static Pool::IterateWrapperFiltered< Engine, EngineTypeFilter > IterateType(VehicleType vt, size_t from=0)
Returns an iterable ensemble of all valid engines of the given type.
bool contains(const Tkey &key) const
Test if a key exists in the set.
RoadTypeLabel label
Unique 32 bit road type identifier.
Definition road.h:121
RoadTypes introduces_roadtypes
Bitmask of which other roadtypes are introduced when this roadtype is introduced.
Definition road.h:151
RoadType Index() const
Get the RoadType for this RoadTypeInfo.
Definition road.cpp:30
TimerGameCalendar::Date introduction_date
Introduction date.
Definition road.h:140
RoadTypeFlags flags
Bit mask of road type flags.
Definition road.h:101
FlatSet< RoadTypeLabel > alternate_labels
Road type labels this type provides in addition to the main label.
Definition road.h:126
RoadTypes introduction_required_roadtypes
Bitmask of roadtypes that are required for this roadtype to be introduced at a given introduction_dat...
Definition road.h:146
static Date date
Current date in days (day counter).
static constexpr TimerGame< struct Calendar >::Date MAX_DATE
The date of the last day of the max year.
static constexpr int DAYS_IN_YEAR
days per year
Definition of stuff that is very close to a company, like the company struct itself.
CompanyID _current_company
Company currently doing an action.
Functions related to companies.
static constexpr Owner OWNER_DEITY
The object is owned by a superuser / goal script.
static constexpr Owner OWNER_TOWN
A town owns the tile, or a town is expanding.
Axis DiagDirToAxis(DiagDirection d)
Convert a DiagDirection to the axis.
Axis
Allow incrementing of DiagDirDiff variables.
@ AXIS_X
The X axis.
DiagDirection
Enumeration for diagonal directions.
@ DIAGDIR_END
Used for iterations.
@ DIAGDIR_BEGIN
Used for iterations.
Base class for engines.
bool _generating_world
Whether we are generating the map or not.
Definition genworld.cpp:74
Functions related to world/map generation.
std::tuple< Slope, int > GetFoundationSlope(TileIndex tile)
Get slope of a tile on top of a (possible) foundation If a tile does not have a foundation,...
Functions related to OTTD's landscape.
TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
Adds a DiagDir to a tile.
Definition map_func.h:623
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
Hides the direct accesses to the map array with map accessors.
static RailTileType GetRailTileType(Tile t)
Returns the RailTileType (normal with or without signals, waypoint or depot).
Definition rail_map.h:36
TrackBits GetTrackBits(Tile tile)
Gets the track bits of the given tile.
Definition rail_map.h:136
@ Normal
Normal rail tile without signals.
RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb)
Clean up unnecessary RoadBits of a planned tile.
Definition road.cpp:59
RoadTypes GetCompanyRoadTypes(CompanyID company, bool introduces)
Get the road types the given company can build.
Definition road.cpp:210
RoadTypes GetRoadTypes(bool introduces)
Get list of road types, regardless of company availability.
Definition road.cpp:238
bool ValParamRoadType(RoadType roadtype)
Validate functions for rail building.
Definition road.cpp:164
RoadTypes AddDateIntroducedRoadTypes(RoadTypes current, TimerGameCalendar::Date date)
Add the road types that are to be introduced at the given date.
Definition road.cpp:177
bool HasAnyRoadTypesAvail(CompanyID company, RoadTramType rtt)
Test if any buildable RoadType is available for a company.
Definition road.cpp:152
static bool IsPossibleCrossing(const TileIndex tile, Axis ax)
Return if the tile is a valid tile for a crossing.
Definition road.cpp:45
bool HasRoadTypeAvail(const CompanyID company, RoadType roadtype)
Finds out, whether given company has a given RoadType available for construction.
Definition road.cpp:123
RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels)
Get the road type for a given label.
Definition road.cpp:265
Road specific functions.
@ Hidden
Bit number for hidden from construction.
@ TownBuild
Bit number for allowing towns to build this roadtype.
RoadTypes _roadtypes_hidden_mask
Bitset of hidden roadtypes.
Definition road_cmd.cpp:56
RoadTypes GetMaskForRoadTramType(RoadTramType rtt)
Get the mask for road types of the given RoadTramType.
Definition road.h:183
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition road.h:215
Functions related to roads.
RoadBits MirrorRoadBits(RoadBits r)
Calculate the mirrored RoadBits.
Definition road_func.h:51
RoadBits DiagDirToRoadBits(DiagDirection d)
Create the road-part which belongs to the given DiagDirection.
Definition road_func.h:96
RoadBits GetAnyRoadBits(Tile tile, RoadTramType rtt, bool straight_tunnel_bridge_entrance)
Returns the RoadBits on an arbitrary tile Special behaviour:
Definition road_map.cpp:54
Map accessors for roads.
static bool IsNormalRoadTile(Tile t)
Return whether a tile is a normal road tile.
Definition road_map.h:58
RoadBits
Enumeration for the road parts on a tile.
Definition road_type.h:56
@ ROAD_NONE
No road-part is build.
Definition road_type.h:57
RoadTramType
The different types of road type.
Definition road_type.h:37
@ RTT_ROAD
Road road type.
Definition road_type.h:38
@ RTT_TRAM
Tram road type.
Definition road_type.h:39
RoadType
The different roadtypes we support.
Definition road_type.h:23
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:28
@ ROADTYPE_END
Used for iterations.
Definition road_type.h:27
@ ROADTYPE_BEGIN
Used for iterations.
Definition road_type.h:24
Road vehicle states.
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
@ SLOPE_FLAT
a flat tile
Definition slope_type.h:49
Definition of base types and functions in a cross-platform compatible way.
RoadTypes avail_roadtypes
Road types available to this company.
Information about a vehicle.
LandscapeTypes climates
Climates supported by the engine.
LandscapeType landscape
the landscape we're currently in
GameCreationSettings game_creation
settings used during the creation of a game (map)
static Titem * Get(auto index)
Returns Titem with given index.
static Titem * GetIfValid(auto index)
Returns Titem with given index.
Information about a road vehicle.
RoadType roadtype
Road type.
static bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
bool IsValidTile(Tile tile)
Checks if a tile is valid.
Definition tile_map.h:161
static TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
@ MP_TREES
Tile got trees.
Definition tile_type.h:52
@ MP_ROAD
A tile with road (or tram tracks)
Definition tile_type.h:50
@ MP_STATION
A tile of a station.
Definition tile_type.h:53
@ MP_TUNNELBRIDGE
Tunnel entry/exit and bridge heads.
Definition tile_type.h:57
@ MP_CLEAR
A tile without any structures, i.e. grass, rocks, farm fields etc.
Definition tile_type.h:48
@ MP_WATER
Water tile.
Definition tile_type.h:54
@ MP_RAILWAY
A railway.
Definition tile_type.h:49
Definition of the game-calendar-timer.
@ TRACK_BIT_Y
Y-axis track.
Definition track_type.h:38
@ TRACK_BIT_X
X-axis track.
Definition track_type.h:37
@ VEH_ROAD
Road vehicle type.
Map accessors for water tiles.
bool IsWater(Tile t)
Is it a plain water tile?
Definition water_map.h:149