OpenTTD Source: src/road.cpp Source File

OpenTTD Source 15.3

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"
18#include "timer/timer_game_calendar.h"
19#include "landscape.h"
20#include "road.h"
21#include "road_func.h"
22#include "roadveh.h"
23
24#include "safeguards.h"
25
30 RoadType RoadTypeInfo::Index() const
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
45 static bool IsPossibleCrossing(const TileIndex tile, Axis ax)
46{
47 return (IsTileType(tile, MP_RAILWAY) &&
48 GetRailTileType(tile) == RailTileType::Normal &&
49 GetTrackBits(tile) == (ax == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X) &&
50 std::get<0>(GetFoundationSlope(tile)) == SLOPE_FLAT);
51}
52
59 RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb)
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
123 bool 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. */
130 if (IsInsideMM(rti->introduction_date, 0, CalendarTime::MAX_DATE.base()) && rti->introduction_date > TimerGameCalendar::date) return false;
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 */
137 return !rti->flags.Test( RoadTypeFlag::Hidden) || rti->flags.Test( RoadTypeFlag::TownBuild);
138 } else {
139 const Company *c = Company::GetIfValid(company);
140 if (c == nullptr) return false;
141 RoadTypes avail = c->avail_roadtypes;
142 avail.Reset(_roadtypes_hidden_mask);
143 return avail.Test(roadtype);
144 }
145}
146
152 bool HasAnyRoadTypesAvail(CompanyID company, RoadTramType rtt)
153{
154 RoadTypes avail = Company::Get(company)->avail_roadtypes;
155 avail.Reset(_roadtypes_hidden_mask);
156 return avail.Any(GetMaskForRoadTramType(rtt));
157}
158
164 bool ValParamRoadType(RoadType roadtype)
165{
166 return roadtype < ROADTYPE_END && HasRoadTypeAvail(_current_company, roadtype);
167}
168
177 RoadTypes AddDateIntroducedRoadTypes(RoadTypes current, TimerGameCalendar::Date date)
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? */
193 RoadTypes required = rti->introduction_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
210 RoadTypes 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
217 if (ei->climates.Test(_settings_game.game_creation.landscape) &&
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) {
222 rts.Set(GetRoadTypeInfo(rvi->roadtype)->introduces_roadtypes);
223 } else {
224 rts.Set(rvi->roadtype);
225 }
226 }
227 }
228
229 if (introduces) return AddDateIntroducedRoadTypes(rts, TimerGameCalendar::date);
230 return rts;
231}
232
238 RoadTypes GetRoadTypes(bool introduces)
239{
240 RoadTypes rts{};
241
242 for (const Engine *e : Engine::IterateType(VEH_ROAD)) {
243 const EngineInfo *ei = &e->info;
244 if (!ei->climates.Test(_settings_game.game_creation.landscape)) continue;
245
246 const RoadVehicleInfo *rvi = &e->VehInfo<RoadVehicleInfo>();
247 assert(rvi->roadtype < ROADTYPE_END);
248 if (introduces) {
249 rts.Set(GetRoadTypeInfo(rvi->roadtype)->introduces_roadtypes);
250 } else {
251 rts.Set(rvi->roadtype);
252 }
253 }
254
255 if (introduces) return AddDateIntroducedRoadTypes(rts, CalendarTime::MAX_DATE);
256 return rts;
257}
258
265 RoadType 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}
BaseBitSet::All
constexpr bool All(const Timpl &other) const
Test if all of the values are set.
Definition base_bitset_type.hpp:151
BaseBitSet::Test
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Definition base_bitset_type.hpp:141
BaseBitSet::Reset
constexpr Timpl & Reset()
Reset all bits.
Definition base_bitset_type.hpp:83
BaseBitSet::Set
constexpr Timpl & Set()
Set all bits.
Definition base_bitset_type.hpp:40
BaseBitSet::Any
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
Definition base_bitset_type.hpp:170
Engine
Definition engine_base.h:38
Engine::IterateType
static Pool::IterateWrapperFiltered< Engine, EngineTypeFilter > IterateType(VehicleType vt, size_t from=0)
Returns an iterable ensemble of all valid engines of the given type.
Definition engine_base.h:197
EnumBitSet< RoadType, uint64_t >
FlatSet::contains
bool contains(const Tkey &key) const
Test if a key exists in the set.
Definition flatset_type.hpp:57
RoadTypeInfo
Definition road.h:52
RoadTypeInfo::label
RoadTypeLabel label
Unique 32 bit road type identifier.
Definition road.h:121
RoadTypeInfo::introduces_roadtypes
RoadTypes introduces_roadtypes
Bitmask of which other roadtypes are introduced when this roadtype is introduced.
Definition road.h:151
RoadTypeInfo::Index
RoadType Index() const
Get the RoadType for this RoadTypeInfo.
Definition road.cpp:30
RoadTypeInfo::introduction_date
TimerGameCalendar::Date introduction_date
Introduction date.
Definition road.h:140
RoadTypeInfo::flags
RoadTypeFlags flags
Bit mask of road type flags.
Definition road.h:101
RoadTypeInfo::alternate_labels
FlatSet< RoadTypeLabel > alternate_labels
Road type labels this type provides in addition to the main label.
Definition road.h:126
RoadTypeInfo::introduction_required_roadtypes
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
TimerGameCalendar::date
static Date date
Current date in days (day counter).
Definition timer_game_calendar.h:33
TimerGameConst< struct Calendar >::MAX_DATE
static constexpr TimerGame< struct Calendar >::Date MAX_DATE
The date of the last day of the max year.
Definition timer_game_common.h:187
TimerGameConst< struct Calendar >::DAYS_IN_YEAR
static constexpr int DAYS_IN_YEAR
days per year
Definition timer_game_common.h:149
company_base.h
Definition of stuff that is very close to a company, like the company struct itself.
_current_company
CompanyID _current_company
Company currently doing an action.
Definition company_cmd.cpp:56
company_func.h
Functions related to companies.
OWNER_DEITY
static constexpr Owner OWNER_DEITY
The object is owned by a superuser / goal script.
Definition company_type.h:28
OWNER_TOWN
static constexpr Owner OWNER_TOWN
A town owns the tile, or a town is expanding.
Definition company_type.h:25
DiagDirToAxis
Axis DiagDirToAxis(DiagDirection d)
Convert a DiagDirection to the axis.
Definition direction_func.h:214
Axis
Axis
Allow incrementing of DiagDirDiff variables.
Definition direction_type.h:123
AXIS_X
@ AXIS_X
The X axis.
Definition direction_type.h:124
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
engine_base.h
Base class for engines.
_generating_world
bool _generating_world
Whether we are generating the map or not.
Definition genworld.cpp:74
genworld.h
Functions related to world/map generation.
GetFoundationSlope
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,...
Definition landscape.cpp:386
landscape.h
Functions related to OTTD's landscape.
TileAddByDiagDir
TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
Adds a DiagDir to a tile.
Definition map_func.h:624
IsInsideMM
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
Definition math_func.hpp:267
rail_map.h
Hides the direct accesses to the map array with map accessors.
GetRailTileType
static RailTileType GetRailTileType(Tile t)
Returns the RailTileType (normal with or without signals, waypoint or depot).
Definition rail_map.h:36
GetTrackBits
TrackBits GetTrackBits(Tile tile)
Gets the track bits of the given tile.
Definition rail_map.h:136
RailTileType::Normal
@ Normal
Normal rail tile without signals.
CleanUpRoadBits
RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb)
Clean up unnecessary RoadBits of a planned tile.
Definition road.cpp:59
GetCompanyRoadTypes
RoadTypes GetCompanyRoadTypes(CompanyID company, bool introduces)
Get the road types the given company can build.
Definition road.cpp:210
GetRoadTypes
RoadTypes GetRoadTypes(bool introduces)
Get list of road types, regardless of company availability.
Definition road.cpp:238
ValParamRoadType
bool ValParamRoadType(RoadType roadtype)
Validate functions for rail building.
Definition road.cpp:164
AddDateIntroducedRoadTypes
RoadTypes AddDateIntroducedRoadTypes(RoadTypes current, TimerGameCalendar::Date date)
Add the road types that are to be introduced at the given date.
Definition road.cpp:177
HasAnyRoadTypesAvail
bool HasAnyRoadTypesAvail(CompanyID company, RoadTramType rtt)
Test if any buildable RoadType is available for a company.
Definition road.cpp:152
IsPossibleCrossing
static bool IsPossibleCrossing(const TileIndex tile, Axis ax)
Return if the tile is a valid tile for a crossing.
Definition road.cpp:45
HasRoadTypeAvail
bool HasRoadTypeAvail(const CompanyID company, RoadType roadtype)
Finds out, whether given company has a given RoadType available for construction.
Definition road.cpp:123
GetRoadTypeByLabel
RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels)
Get the road type for a given label.
Definition road.cpp:265
road.h
Road specific functions.
RoadTypeFlag::Hidden
@ Hidden
Bit number for hidden from construction.
RoadTypeFlag::TownBuild
@ TownBuild
Bit number for allowing towns to build this roadtype.
_roadtypes_hidden_mask
RoadTypes _roadtypes_hidden_mask
Bitset of hidden roadtypes.
Definition road_cmd.cpp:56
GetMaskForRoadTramType
RoadTypes GetMaskForRoadTramType(RoadTramType rtt)
Get the mask for road types of the given RoadTramType.
Definition road.h:183
GetRoadTypeInfo
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition road.h:215
road_func.h
Functions related to roads.
MirrorRoadBits
RoadBits MirrorRoadBits(RoadBits r)
Calculate the mirrored RoadBits.
Definition road_func.h:51
DiagDirToRoadBits
RoadBits DiagDirToRoadBits(DiagDirection d)
Create the road-part which belongs to the given DiagDirection.
Definition road_func.h:96
GetAnyRoadBits
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
road_map.h
Map accessors for roads.
IsNormalRoadTile
static bool IsNormalRoadTile(Tile t)
Return whether a tile is a normal road tile.
Definition road_map.h:58
RoadBits
RoadBits
Enumeration for the road parts on a tile.
Definition road_type.h:56
ROAD_NONE
@ ROAD_NONE
No road-part is build.
Definition road_type.h:57
RoadTramType
RoadTramType
The different types of road type.
Definition road_type.h:37
RTT_ROAD
@ RTT_ROAD
Road road type.
Definition road_type.h:38
RTT_TRAM
@ RTT_TRAM
Tram road type.
Definition road_type.h:39
RoadType
RoadType
The different roadtypes we support.
Definition road_type.h:23
INVALID_ROADTYPE
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:28
ROADTYPE_END
@ ROADTYPE_END
Used for iterations.
Definition road_type.h:27
ROADTYPE_BEGIN
@ ROADTYPE_BEGIN
Used for iterations.
Definition road_type.h:24
roadveh.h
Road vehicle states.
safeguards.h
A number of safeguards to prevent using unsafe methods.
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
SLOPE_FLAT
@ SLOPE_FLAT
a flat tile
Definition slope_type.h:49
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
Company
Definition company_base.h:127
Company::avail_roadtypes
RoadTypes avail_roadtypes
Road types available to this company.
Definition company_base.h:132
EngineInfo
Information about a vehicle.
Definition engine_type.h:198
EngineInfo::climates
LandscapeTypes climates
Climates supported by the engine.
Definition engine_type.h:204
GameCreationSettings::landscape
LandscapeType landscape
the landscape we're currently in
Definition settings_type.h:395
GameSettings::game_creation
GameCreationSettings game_creation
settings used during the creation of a game (map)
Definition settings_type.h:634
PoolID< uint8_t, struct CompanyIDTag, 0xF, 0xFF >
Pool::PoolItem<&_company_pool >::Get
static Titem * Get(auto index)
Returns Titem with given index.
Definition pool_type.hpp:387
Pool::PoolItem<&_company_pool >::GetIfValid
static Titem * GetIfValid(auto index)
Returns Titem with given index.
Definition pool_type.hpp:398
RoadVehicleInfo
Information about a road vehicle.
Definition engine_type.h:146
RoadVehicleInfo::roadtype
RoadType roadtype
Road type.
Definition engine_type.h:160
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >
IsTileType
static bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
IsValidTile
bool IsValidTile(Tile tile)
Checks if a tile is valid.
Definition tile_map.h:161
GetTileType
static TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
MP_TREES
@ MP_TREES
Tile got trees.
Definition tile_type.h:52
MP_ROAD
@ MP_ROAD
A tile with road (or tram tracks)
Definition tile_type.h:50
MP_STATION
@ MP_STATION
A tile of a station.
Definition tile_type.h:53
MP_TUNNELBRIDGE
@ MP_TUNNELBRIDGE
Tunnel entry/exit and bridge heads.
Definition tile_type.h:57
MP_CLEAR
@ MP_CLEAR
A tile without any structures, i.e. grass, rocks, farm fields etc.
Definition tile_type.h:48
MP_WATER
@ MP_WATER
Water tile.
Definition tile_type.h:54
MP_RAILWAY
@ MP_RAILWAY
A railway.
Definition tile_type.h:49
timer_game_calendar.h
Definition of the game-calendar-timer.
TRACK_BIT_Y
@ TRACK_BIT_Y
Y-axis track.
Definition track_type.h:38
TRACK_BIT_X
@ TRACK_BIT_X
X-axis track.
Definition track_type.h:37
VEH_ROAD
@ VEH_ROAD
Road vehicle type.
Definition vehicle_type.h:26
water_map.h
Map accessors for water tiles.
IsWater
bool IsWater(Tile t)
Is it a plain water tile?
Definition water_map.h:149