OpenTTD Source 20251019-master-g9f7f314f81
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 <http://www.gnu.org/licenses/>.
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
152bool HasAnyRoadTypesAvail(CompanyID company, RoadTramType rtt)
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:136
RoadTypes introduces_roadtypes
Bitmask of which other roadtypes are introduced when this roadtype is introduced.
Definition road.h:166
RoadType Index() const
Get the RoadType for this RoadTypeInfo.
Definition road.cpp:30
TimerGameCalendar::Date introduction_date
Introduction date.
Definition road.h:155
RoadTypeFlags flags
Bit mask of road type flags.
Definition road.h:116
FlatSet< RoadTypeLabel > alternate_labels
Road type labels this type provides in addition to the main label.
Definition road.h:141
RoadTypes introduction_required_roadtypes
Bitmask of roadtypes that are required for this roadtype to be introduced at a given introduction_dat...
Definition road.h:161
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:610
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 debug_inline 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
@ RAIL_TILE_NORMAL
Normal rail tile without signals.
Definition rail_map.h:24
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:198
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition road.h:230
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 debug_inline 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:40
@ ROAD_NONE
No road-part is build.
Definition road_type.h:41
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 debug_inline TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
bool IsValidTile(Tile tile)
Checks if a tile is valid.
Definition tile_map.h:161
static debug_inline bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
@ 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