4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
10 /** @file road.cpp Generic road related functions. */
13 #include "map/ground.h"
14 #include "map/water.h"
18 #include "company_func.h"
19 #include "company_base.h"
20 #include "engine_base.h"
21 #include "date_func.h"
22 #include "landscape.h"
25 * Return if the tile is a valid tile for a crossing.
27 * @param tile the current tile
28 * @param ax the axis of the road over the rail
29 * @return true if it is a valid tile
31 static bool IsPossibleCrossing(const TileIndex tile
, Axis ax
)
33 return (IsNormalRailTile(tile
) && !HasSignalOnTrack(tile
, TRACK_UPPER
) &&
34 GetTrackBits(tile
) == (ax
== AXIS_X
? TRACK_BIT_Y
: TRACK_BIT_X
) &&
35 GetFoundationSlope(tile
) == SLOPE_FLAT
);
39 * Clean up unnecessary RoadBits of a planed tile.
40 * @param tile current tile
41 * @param org_rb planed RoadBits
42 * @return optimised RoadBits
44 RoadBits
CleanUpRoadBits(const TileIndex tile
, RoadBits org_rb
)
46 if (!IsValidTile(tile
)) return ROAD_NONE
;
47 for (DiagDirection dir
= DIAGDIR_BEGIN
; dir
< DIAGDIR_END
; dir
++) {
48 const TileIndex neighbor_tile
= TileAddByDiagDir(tile
, dir
);
50 /* Get the Roadbit pointing to the neighbor_tile */
51 const RoadBits target_rb
= DiagDirToRoadBits(dir
);
53 /* If the roadbit is in the current plan */
54 if (org_rb
& target_rb
) {
55 bool connective
= false;
56 const RoadBits mirrored_rb
= MirrorRoadBits(target_rb
);
58 switch (GetTileType(neighbor_tile
)) {
59 /* Always connective ones */
61 connective
= IsGroundTile(neighbor_tile
);
64 /* The conditionally connective ones */
68 const RoadBits neighbor_rb
= GetAnyRoadBits(neighbor_tile
, ROADTYPE_ROAD
) | GetAnyRoadBits(neighbor_tile
, ROADTYPE_TRAM
);
70 /* Accept only connective tiles */
71 connective
= (neighbor_rb
& mirrored_rb
) || // Neighbor has got the fitting RoadBit
72 HasExactlyOneBit(neighbor_rb
); // Neighbor has got only one Roadbit
78 connective
= IsTileSubtype(neighbor_tile
, TT_TRACK
) && IsPossibleCrossing(neighbor_tile
, DiagDirToAxis(dir
));
82 /* Check for real water tile */
83 connective
= !IsPlainWater(neighbor_tile
);
86 /* The definitely not connective ones */
90 /* If the neighbor tile is inconnective, remove the planed road connection to it */
91 if (!connective
) org_rb
^= target_rb
;
100 * Finds out, whether given company has all given RoadTypes available
101 * @param company ID of company
102 * @param rts RoadTypes to test
103 * @return true if company has all requested RoadTypes available
105 bool HasRoadTypesAvail(const CompanyID company
, const RoadTypes rts
)
107 RoadTypes avail_roadtypes
;
109 if (company
== OWNER_DEITY
|| company
== OWNER_TOWN
|| _game_mode
== GM_EDITOR
|| _generating_world
) {
110 avail_roadtypes
= ROADTYPES_ROAD
;
112 Company
*c
= Company::GetIfValid(company
);
113 if (c
== NULL
) return false;
114 avail_roadtypes
= (RoadTypes
)c
->avail_roadtypes
| ROADTYPES_ROAD
; // road is available for always for everybody
116 return (rts
& ~avail_roadtypes
) == 0;
120 * Validate functions for rail building.
121 * @param rt road type to check.
122 * @return true if the current company may build the road.
124 bool ValParamRoadType(const RoadType rt
)
126 return HasRoadTypesAvail(_current_company
, RoadTypeToRoadTypes(rt
));
130 * Get the road types the given company can build.
131 * @param company the company to get the roadtypes for.
132 * @return the road types.
134 RoadTypes
GetCompanyRoadtypes(CompanyID company
)
136 RoadTypes rt
= ROADTYPES_NONE
;
139 FOR_ALL_ENGINES_OF_TYPE(e
, VEH_ROAD
) {
140 const EngineInfo
*ei
= &e
->info
;
142 if (HasBit(ei
->climates
, _settings_game
.game_creation
.landscape
) &&
143 (HasBit(e
->company_avail
, company
) || _date
>= e
->intro_date
+ DAYS_IN_YEAR
)) {
144 SetBit(rt
, HasBit(ei
->misc_flags
, EF_ROAD_TRAM
) ? ROADTYPE_TRAM
: ROADTYPE_ROAD
);