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_map.h Map accessors for roads. */
15 #include "track_func.h"
16 #include "depot_type.h"
17 #include "rail_type.h"
18 #include "road_func.h"
22 /** The different types of road tiles. */
24 ROAD_TILE_NORMAL
, ///< Normal road
25 ROAD_TILE_CROSSING
, ///< Level crossing
26 ROAD_TILE_DEPOT
, ///< Depot (one entrance)
30 * Get the type of the road tile.
31 * @param t Tile to query.
32 * @pre IsTileType(t, MP_ROAD)
33 * @return The road tile type.
35 static inline RoadTileType
GetRoadTileType(TileIndex t
)
37 assert(IsTileType(t
, MP_ROAD
));
38 return (RoadTileType
)GB(_m
[t
].m5
, 6, 2);
42 * Return whether a tile is a normal road.
43 * @param t Tile to query.
44 * @pre IsTileType(t, MP_ROAD)
45 * @return True if normal road.
47 static inline bool IsNormalRoad(TileIndex t
)
49 return GetRoadTileType(t
) == ROAD_TILE_NORMAL
;
53 * Return whether a tile is a normal road tile.
54 * @param t Tile to query.
55 * @return True if normal road tile.
57 static inline bool IsNormalRoadTile(TileIndex t
)
59 return IsTileType(t
, MP_ROAD
) && IsNormalRoad(t
);
63 * Return whether a tile is a level crossing.
64 * @param t Tile to query.
65 * @pre IsTileType(t, MP_ROAD)
66 * @return True if level crossing.
68 static inline bool IsLevelCrossing(TileIndex t
)
70 return GetRoadTileType(t
) == ROAD_TILE_CROSSING
;
74 * Return whether a tile is a level crossing tile.
75 * @param t Tile to query.
76 * @return True if level crossing tile.
78 static inline bool IsLevelCrossingTile(TileIndex t
)
80 return IsTileType(t
, MP_ROAD
) && IsLevelCrossing(t
);
84 * Return whether a tile is a road depot.
85 * @param t Tile to query.
86 * @pre IsTileType(t, MP_ROAD)
87 * @return True if road depot.
89 static inline bool IsRoadDepot(TileIndex t
)
91 return GetRoadTileType(t
) == ROAD_TILE_DEPOT
;
95 * Return whether a tile is a road depot tile.
96 * @param t Tile to query.
97 * @return True if road depot tile.
99 static inline bool IsRoadDepotTile(TileIndex t
)
101 return IsTileType(t
, MP_ROAD
) && IsRoadDepot(t
);
105 * Get the present road bits for a specific road type.
106 * @param t The tile to query.
107 * @param rt Road type.
108 * @pre IsNormalRoad(t)
109 * @return The present road bits for the road type.
111 static inline RoadBits
GetRoadBits(TileIndex t
, RoadType rt
)
113 assert(IsNormalRoad(t
));
115 default: NOT_REACHED();
116 case ROADTYPE_ROAD
: return (RoadBits
)GB(_m
[t
].m5
, 0, 4);
117 case ROADTYPE_TRAM
: return (RoadBits
)GB(_m
[t
].m3
, 0, 4);
122 * Get all RoadBits set on a tile except from the given RoadType
124 * @param t The tile from which we want to get the RoadBits
125 * @param rt The RoadType which we exclude from the querry
126 * @return all set RoadBits of the tile which are not from the given RoadType
128 static inline RoadBits
GetOtherRoadBits(TileIndex t
, RoadType rt
)
130 return GetRoadBits(t
, rt
== ROADTYPE_ROAD
? ROADTYPE_TRAM
: ROADTYPE_ROAD
);
134 * Get all set RoadBits on the given tile
136 * @param tile The tile from which we want to get the RoadBits
137 * @return all set RoadBits of the tile
139 static inline RoadBits
GetAllRoadBits(TileIndex tile
)
141 return GetRoadBits(tile
, ROADTYPE_ROAD
) | GetRoadBits(tile
, ROADTYPE_TRAM
);
145 * Set the present road bits for a specific road type.
146 * @param t The tile to change.
147 * @param r The new road bits.
148 * @param rt Road type.
149 * @pre IsNormalRoad(t)
151 static inline void SetRoadBits(TileIndex t
, RoadBits r
, RoadType rt
)
153 assert(IsNormalRoad(t
)); // XXX incomplete
155 default: NOT_REACHED();
156 case ROADTYPE_ROAD
: SB(_m
[t
].m5
, 0, 4, r
); break;
157 case ROADTYPE_TRAM
: SB(_m
[t
].m3
, 0, 4, r
); break;
162 * Get the present road types of a tile.
163 * @param t The tile to query.
164 * @return Present road types.
166 static inline RoadTypes
GetRoadTypes(TileIndex t
)
168 return (RoadTypes
)GB(_me
[t
].m7
, 6, 2);
172 * Set the present road types of a tile.
173 * @param t The tile to change.
174 * @param rt The new road types.
176 static inline void SetRoadTypes(TileIndex t
, RoadTypes rt
)
178 assert(IsTileType(t
, MP_ROAD
) || IsTileType(t
, MP_STATION
) || IsTileType(t
, MP_TUNNELBRIDGE
));
179 SB(_me
[t
].m7
, 6, 2, rt
);
183 * Check if a tile has a specific road type.
184 * @param t The tile to check.
185 * @param rt Road type to check.
186 * @return True if the tile has the specified road type.
188 static inline bool HasTileRoadType(TileIndex t
, RoadType rt
)
190 return HasBit(GetRoadTypes(t
), rt
);
194 * Get the owner of a specific road type.
195 * @param t The tile to query.
196 * @param rt The road type to get the owner of.
197 * @return Owner of the given road type.
199 static inline Owner
GetRoadOwner(TileIndex t
, RoadType rt
)
201 assert(IsTileType(t
, MP_ROAD
) || IsTileType(t
, MP_STATION
) || IsTileType(t
, MP_TUNNELBRIDGE
));
203 default: NOT_REACHED();
204 case ROADTYPE_ROAD
: return (Owner
)GB(IsNormalRoadTile(t
) ? _m
[t
].m1
: _me
[t
].m7
, 0, 5);
205 case ROADTYPE_TRAM
: {
206 /* Trams don't need OWNER_TOWN, and remapping OWNER_NONE
207 * to OWNER_TOWN makes it use one bit less */
208 Owner o
= (Owner
)GB(_m
[t
].m3
, 4, 4);
209 return o
== OWNER_TOWN
? OWNER_NONE
: o
;
215 * Set the owner of a specific road type.
216 * @param t The tile to change.
217 * @param rt The road type to change the owner of.
218 * @param o New owner of the given road type.
220 static inline void SetRoadOwner(TileIndex t
, RoadType rt
, Owner o
)
223 default: NOT_REACHED();
224 case ROADTYPE_ROAD
: SB(IsNormalRoadTile(t
) ? _m
[t
].m1
: _me
[t
].m7
, 0, 5, o
); break;
225 case ROADTYPE_TRAM
: SB(_m
[t
].m3
, 4, 4, o
== OWNER_NONE
? OWNER_TOWN
: o
); break;
230 * Check if a specific road type is owned by an owner.
231 * @param t The tile to query.
232 * @param rt The road type to compare the owner of.
233 * @param o Owner to compare with.
234 * @pre HasTileRoadType(t, rt)
235 * @return True if the road type is owned by the given owner.
237 static inline bool IsRoadOwner(TileIndex t
, RoadType rt
, Owner o
)
239 assert(HasTileRoadType(t
, rt
));
240 return (GetRoadOwner(t
, rt
) == o
);
244 * Checks if given tile has town owned road
245 * @param t tile to check
246 * @pre IsTileType(t, MP_ROAD)
247 * @return true iff tile has road and the road is owned by a town
249 static inline bool HasTownOwnedRoad(TileIndex t
)
251 return HasTileRoadType(t
, ROADTYPE_ROAD
) && IsRoadOwner(t
, ROADTYPE_ROAD
, OWNER_TOWN
);
254 /** Which directions are disallowed ? */
255 enum DisallowedRoadDirections
{
256 DRD_NONE
, ///< None of the directions are disallowed
257 DRD_SOUTHBOUND
, ///< All southbound traffic is disallowed
258 DRD_NORTHBOUND
, ///< All northbound traffic is disallowed
259 DRD_BOTH
, ///< All directions are disallowed
260 DRD_END
, ///< Sentinel
262 DECLARE_ENUM_AS_BIT_SET(DisallowedRoadDirections
)
263 /** Helper information for extract tool. */
264 template <> struct EnumPropsT
<DisallowedRoadDirections
> : MakeEnumPropsT
<DisallowedRoadDirections
, byte
, DRD_NONE
, DRD_END
, DRD_END
, 2> {};
267 * Gets the disallowed directions
268 * @param t the tile to get the directions from
269 * @return the disallowed directions
271 static inline DisallowedRoadDirections
GetDisallowedRoadDirections(TileIndex t
)
273 assert(IsNormalRoad(t
));
274 return (DisallowedRoadDirections
)GB(_m
[t
].m5
, 4, 2);
278 * Sets the disallowed directions
279 * @param t the tile to set the directions for
280 * @param drd the disallowed directions
282 static inline void SetDisallowedRoadDirections(TileIndex t
, DisallowedRoadDirections drd
)
284 assert(IsNormalRoad(t
));
285 assert(drd
< DRD_END
);
286 SB(_m
[t
].m5
, 4, 2, drd
);
290 * Get the road axis of a level crossing.
291 * @param t The tile to query.
292 * @pre IsLevelCrossing(t)
293 * @return The axis of the road.
295 static inline Axis
GetCrossingRoadAxis(TileIndex t
)
297 assert(IsLevelCrossing(t
));
298 return (Axis
)GB(_m
[t
].m5
, 0, 1);
302 * Get the rail axis of a level crossing.
303 * @param t The tile to query.
304 * @pre IsLevelCrossing(t)
305 * @return The axis of the rail.
307 static inline Axis
GetCrossingRailAxis(TileIndex t
)
309 assert(IsLevelCrossing(t
));
310 return OtherAxis((Axis
)GetCrossingRoadAxis(t
));
314 * Get the road bits of a level crossing.
315 * @param tile The tile to query.
316 * @return The present road bits.
318 static inline RoadBits
GetCrossingRoadBits(TileIndex tile
)
320 return GetCrossingRoadAxis(tile
) == AXIS_X
? ROAD_X
: ROAD_Y
;
324 * Get the rail track of a level crossing.
325 * @param tile The tile to query.
326 * @return The rail track.
328 static inline Track
GetCrossingRailTrack(TileIndex tile
)
330 return AxisToTrack(GetCrossingRailAxis(tile
));
334 * Get the rail track bits of a level crossing.
335 * @param tile The tile to query.
336 * @return The rail track bits.
338 static inline TrackBits
GetCrossingRailBits(TileIndex tile
)
340 return AxisToTrackBits(GetCrossingRailAxis(tile
));
345 * Get the reservation state of the rail crossing
346 * @param t the crossing tile
347 * @return reservation state
348 * @pre IsLevelCrossingTile(t)
350 static inline bool HasCrossingReservation(TileIndex t
)
352 assert(IsLevelCrossingTile(t
));
353 return HasBit(_m
[t
].m5
, 4);
357 * Set the reservation state of the rail crossing
358 * @note Works for both waypoints and rail depots
359 * @param t the crossing tile
360 * @param b the reservation state
361 * @pre IsLevelCrossingTile(t)
363 static inline void SetCrossingReservation(TileIndex t
, bool b
)
365 assert(IsLevelCrossingTile(t
));
366 SB(_m
[t
].m5
, 4, 1, b
? 1 : 0);
370 * Get the reserved track bits for a rail crossing
372 * @pre IsLevelCrossingTile(t)
373 * @return reserved track bits
375 static inline TrackBits
GetCrossingReservationTrackBits(TileIndex t
)
377 return HasCrossingReservation(t
) ? GetCrossingRailBits(t
) : TRACK_BIT_NONE
;
381 * Check if the level crossing is barred.
382 * @param t The tile to query.
383 * @pre IsLevelCrossing(t)
384 * @return True if the level crossing is barred.
386 static inline bool IsCrossingBarred(TileIndex t
)
388 assert(IsLevelCrossing(t
));
389 return HasBit(_m
[t
].m5
, 5);
393 * Set the bar state of a level crossing.
394 * @param t The tile to modify.
395 * @param barred True if the crossing should be barred, false otherwise.
396 * @pre IsLevelCrossing(t)
398 static inline void SetCrossingBarred(TileIndex t
, bool barred
)
400 assert(IsLevelCrossing(t
));
401 SB(_m
[t
].m5
, 5, 1, barred
? 1 : 0);
405 * Unbar a level crossing.
406 * @param t The tile to change.
408 static inline void UnbarCrossing(TileIndex t
)
410 SetCrossingBarred(t
, false);
414 * Bar a level crossing.
415 * @param t The tile to change.
417 static inline void BarCrossing(TileIndex t
)
419 SetCrossingBarred(t
, true);
422 /** Check if a road tile has snow/desert. */
423 #define IsOnDesert IsOnSnow
425 * Check if a road tile has snow/desert.
426 * @param t The tile to query.
427 * @return True if the tile has snow/desert.
429 static inline bool IsOnSnow(TileIndex t
)
431 return HasBit(_me
[t
].m7
, 5);
434 /** Toggle the snow/desert state of a road tile. */
435 #define ToggleDesert ToggleSnow
437 * Toggle the snow/desert state of a road tile.
438 * @param t The tile to change.
440 static inline void ToggleSnow(TileIndex t
)
442 ToggleBit(_me
[t
].m7
, 5);
446 /** The possible road side decorations. */
448 ROADSIDE_BARREN
= 0, ///< Road on barren land
449 ROADSIDE_GRASS
= 1, ///< Road on grass
450 ROADSIDE_PAVED
= 2, ///< Road with paved sidewalks
451 ROADSIDE_STREET_LIGHTS
= 3, ///< Road with street lights on paved sidewalks
452 ROADSIDE_TREES
= 5, ///< Road with trees on paved sidewalks
453 ROADSIDE_GRASS_ROAD_WORKS
= 6, ///< Road on grass with road works
454 ROADSIDE_PAVED_ROAD_WORKS
= 7, ///< Road with sidewalks and road works
458 * Get the decorations of a road.
459 * @param tile The tile to query.
460 * @return The road decoration of the tile.
462 static inline Roadside
GetRoadside(TileIndex tile
)
464 return (Roadside
)GB(_me
[tile
].m6
, 3, 3);
468 * Set the decorations of a road.
469 * @param tile The tile to change.
470 * @param s The new road decoration of the tile.
472 static inline void SetRoadside(TileIndex tile
, Roadside s
)
474 SB(_me
[tile
].m6
, 3, 3, s
);
478 * Check if a tile has road works.
479 * @param t The tile to check.
480 * @return True if the tile has road works in progress.
482 static inline bool HasRoadWorks(TileIndex t
)
484 return GetRoadside(t
) >= ROADSIDE_GRASS_ROAD_WORKS
;
488 * Increase the progress counter of road works.
489 * @param t The tile to modify.
490 * @return True if the road works are in the last stage.
492 static inline bool IncreaseRoadWorksCounter(TileIndex t
)
494 AB(_me
[t
].m7
, 0, 4, 1);
496 return GB(_me
[t
].m7
, 0, 4) == 15;
500 * Start road works on a tile.
501 * @param t The tile to start the work on.
502 * @pre !HasRoadWorks(t)
504 static inline void StartRoadWorks(TileIndex t
)
506 assert(!HasRoadWorks(t
));
507 /* Remove any trees or lamps in case or roadwork */
508 switch (GetRoadside(t
)) {
509 case ROADSIDE_BARREN
:
510 case ROADSIDE_GRASS
: SetRoadside(t
, ROADSIDE_GRASS_ROAD_WORKS
); break;
511 default: SetRoadside(t
, ROADSIDE_PAVED_ROAD_WORKS
); break;
516 * Terminate road works on a tile.
517 * @param t Tile to stop the road works on.
518 * @pre HasRoadWorks(t)
520 static inline void TerminateRoadWorks(TileIndex t
)
522 assert(HasRoadWorks(t
));
523 SetRoadside(t
, (Roadside
)(GetRoadside(t
) - ROADSIDE_GRASS_ROAD_WORKS
+ ROADSIDE_GRASS
));
524 /* Stop the counter */
525 SB(_me
[t
].m7
, 0, 4, 0);
530 * Get the direction of the exit of a road depot.
531 * @param t The tile to query.
532 * @return Diagonal direction of the depot exit.
534 static inline DiagDirection
GetRoadDepotDirection(TileIndex t
)
536 assert(IsRoadDepot(t
));
537 return (DiagDirection
)GB(_m
[t
].m5
, 0, 2);
541 RoadBits
GetAnyRoadBits(TileIndex tile
, RoadType rt
, bool straight_tunnel_bridge_entrance
= false);
545 * Make a normal road tile.
546 * @param t Tile to make a normal road.
547 * @param bits Road bits to set for all present road types.
548 * @param rot New present road types.
549 * @param town Town ID if the road is a town-owned road.
550 * @param road New owner of road.
551 * @param tram New owner of tram tracks.
553 static inline void MakeRoadNormal(TileIndex t
, RoadBits bits
, RoadTypes rot
, TownID town
, Owner road
, Owner tram
)
555 SetTileType(t
, MP_ROAD
);
556 SetTileOwner(t
, road
);
558 _m
[t
].m3
= (HasBit(rot
, ROADTYPE_TRAM
) ? bits
: 0);
560 _m
[t
].m5
= (HasBit(rot
, ROADTYPE_ROAD
) ? bits
: 0) | ROAD_TILE_NORMAL
<< 6;
561 SB(_me
[t
].m6
, 2, 4, 0);
562 _me
[t
].m7
= rot
<< 6;
563 SetRoadOwner(t
, ROADTYPE_TRAM
, tram
);
567 * Make a level crossing.
568 * @param t Tile to make a level crossing.
569 * @param road New owner of road.
570 * @param tram New owner of tram tracks.
571 * @param rail New owner of the rail track.
572 * @param roaddir Axis of the road.
573 * @param rat New rail type.
574 * @param rot New present road types.
575 * @param town Town ID if the road is a town-owned road.
577 static inline void MakeRoadCrossing(TileIndex t
, Owner road
, Owner tram
, Owner rail
, Axis roaddir
, RailType rat
, RoadTypes rot
, uint town
)
579 SetTileType(t
, MP_ROAD
);
580 SetTileOwner(t
, rail
);
584 _m
[t
].m5
= ROAD_TILE_CROSSING
<< 6 | roaddir
;
585 SB(_me
[t
].m6
, 2, 4, 0);
586 _me
[t
].m7
= rot
<< 6 | road
;
587 SetRoadOwner(t
, ROADTYPE_TRAM
, tram
);
592 * @param t Tile to make a level crossing.
593 * @param owner New owner of the depot.
594 * @param did New depot ID.
595 * @param dir Direction of the depot exit.
596 * @param rt Road type of the depot.
598 static inline void MakeRoadDepot(TileIndex t
, Owner owner
, DepotID did
, DiagDirection dir
, RoadType rt
)
600 SetTileType(t
, MP_ROAD
);
601 SetTileOwner(t
, owner
);
605 _m
[t
].m5
= ROAD_TILE_DEPOT
<< 6 | dir
;
606 SB(_me
[t
].m6
, 2, 4, 0);
607 _me
[t
].m7
= RoadTypeToRoadTypes(rt
) << 6 | owner
;
608 SetRoadOwner(t
, ROADTYPE_TRAM
, owner
);
611 #endif /* ROAD_MAP_H */