OpenTTD

- Main Page
- Related Pages
- Modules
- Namespaces
- Data Structures
- Files

- File List
- Globals

road_map.h
Go to the documentation of this file.
1 /* $Id: road_map.h 26878 2014-09-21 11:23:33Z rubidium $ */
2
3 /*
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/>.
8 */
9
12 #ifndef ROAD_MAP_H
13 #define ROAD_MAP_H
14
15 #include "track_func.h"
16 #include "depot_type.h"
17 #include "rail_type.h"
18 #include "road_func.h"
19 #include "tile_map.h"
20
21
23 enum RoadTileType {
24 ROAD_TILE_NORMAL,
25 ROAD_TILE_CROSSING,
26 ROAD_TILE_DEPOT,
27 };
28
35 static inline RoadTileType GetRoadTileType(TileIndex t)
36 {
37 assert(IsTileType(t, MP_ROAD));
38 return (RoadTileType)GB(_m[t].m5, 6, 2);
39 }
40
47 static inline bool IsNormalRoad(TileIndex t)
48 {
49 return GetRoadTileType(t) == ROAD_TILE_NORMAL;
50 }
51
57 static inline bool IsNormalRoadTile(TileIndex t)
58 {
59 return IsTileType(t, MP_ROAD) && IsNormalRoad(t);
60 }
61
68 static inline bool IsLevelCrossing(TileIndex t)
69 {
70 return GetRoadTileType(t) == ROAD_TILE_CROSSING;
71 }
72
78 static inline bool IsLevelCrossingTile(TileIndex t)
79 {
80 return IsTileType(t, MP_ROAD) && IsLevelCrossing(t);
81 }
82
89 static inline bool IsRoadDepot(TileIndex t)
90 {
91 return GetRoadTileType(t) == ROAD_TILE_DEPOT;
92 }
93
99 static inline bool IsRoadDepotTile(TileIndex t)
100 {
101 return IsTileType(t, MP_ROAD) && IsRoadDepot(t);
102 }
103
111 static inline RoadBits GetRoadBits(TileIndex t, RoadType rt)
112 {
113 assert(IsNormalRoad(t));
114 switch (rt) {
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);
118 }
119 }
120
128 static inline RoadBits GetOtherRoadBits(TileIndex t, RoadType rt)
129 {
130 return GetRoadBits(t, rt == ROADTYPE_ROAD ? ROADTYPE_TRAM : ROADTYPE_ROAD);
131 }
132
139 static inline RoadBits GetAllRoadBits(TileIndex tile)
140 {
141 return GetRoadBits(tile, ROADTYPE_ROAD) | GetRoadBits(tile, ROADTYPE_TRAM);
142 }
143
151 static inline void SetRoadBits(TileIndex t, RoadBits r, RoadType rt)
152 {
153 assert(IsNormalRoad(t)); // XXX incomplete
154 switch (rt) {
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;
158 }
159 }
160
166 static inline RoadTypes GetRoadTypes(TileIndex t)
167 {
168 return (RoadTypes)GB(_me[t].m7, 6, 2);
169 }
170
176 static inline void SetRoadTypes(TileIndex t, RoadTypes rt)
177 {
178 assert(IsTileType(t, MP_ROAD) || IsTileType(t, MP_STATION) || IsTileType(t, MP_TUNNELBRIDGE));
179 SB(_me[t].m7, 6, 2, rt);
180 }
181
188 static inline bool HasTileRoadType(TileIndex t, RoadType rt)
189 {
190 return HasBit(GetRoadTypes(t), rt);
191 }
192
199 static inline Owner GetRoadOwner(TileIndex t, RoadType rt)
200 {
201 assert(IsTileType(t, MP_ROAD) || IsTileType(t, MP_STATION) || IsTileType(t, MP_TUNNELBRIDGE));
202 switch (rt) {
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;
210 }
211 }
212 }
213
220 static inline void SetRoadOwner(TileIndex t, RoadType rt, Owner o)
221 {
222 switch (rt) {
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;
226 }
227 }
228
237 static inline bool IsRoadOwner(TileIndex t, RoadType rt, Owner o)
238 {
239 assert(HasTileRoadType(t, rt));
240 return (GetRoadOwner(t, rt) == o);
241 }
242
249 static inline bool HasTownOwnedRoad(TileIndex t)
250 {
251 return HasTileRoadType(t, ROADTYPE_ROAD) && IsRoadOwner(t, ROADTYPE_ROAD, OWNER_TOWN);
252 }
253
255 enum DisallowedRoadDirections {
256 DRD_NONE,
257 DRD_SOUTHBOUND,
258 DRD_NORTHBOUND,
259 DRD_BOTH,
260 DRD_END,
261 };
262 DECLARE_ENUM_AS_BIT_SET(DisallowedRoadDirections)
264 template <> struct EnumPropsT<DisallowedRoadDirections> : MakeEnumPropsT<DisallowedRoadDirections, byte, DRD_NONE, DRD_END, DRD_END, 2> {};
265
271 static inline DisallowedRoadDirections GetDisallowedRoadDirections(TileIndex t)
272 {
273 assert(IsNormalRoad(t));
274 return (DisallowedRoadDirections)GB(_m[t].m5, 4, 2);
275 }
276
282 static inline void SetDisallowedRoadDirections(TileIndex t, DisallowedRoadDirections drd)
283 {
284 assert(IsNormalRoad(t));
285 assert(drd < DRD_END);
286 SB(_m[t].m5, 4, 2, drd);
287 }
288
295 static inline Axis GetCrossingRoadAxis(TileIndex t)
296 {
297 assert(IsLevelCrossing(t));
298 return (Axis)GB(_m[t].m5, 0, 1);
299 }
300
307 static inline Axis GetCrossingRailAxis(TileIndex t)
308 {
309 assert(IsLevelCrossing(t));
310 return OtherAxis((Axis)GetCrossingRoadAxis(t));
311 }
312
318 static inline RoadBits GetCrossingRoadBits(TileIndex tile)
319 {
320 return GetCrossingRoadAxis(tile) == AXIS_X ? ROAD_X : ROAD_Y;
321 }
322
328 static inline Track GetCrossingRailTrack(TileIndex tile)
329 {
330 return AxisToTrack(GetCrossingRailAxis(tile));
331 }
332
338 static inline TrackBits GetCrossingRailBits(TileIndex tile)
339 {
340 return AxisToTrackBits(GetCrossingRailAxis(tile));
341 }
342
343
350 static inline bool HasCrossingReservation(TileIndex t)
351 {
352 assert(IsLevelCrossingTile(t));
353 return HasBit(_m[t].m5, 4);
354 }
355
363 static inline void SetCrossingReservation(TileIndex t, bool b)
364 {
365 assert(IsLevelCrossingTile(t));
366 SB(_m[t].m5, 4, 1, b ? 1 : 0);
367 }
368
375 static inline TrackBits GetCrossingReservationTrackBits(TileIndex t)
376 {
377 return HasCrossingReservation(t) ? GetCrossingRailBits(t) : TRACK_BIT_NONE;
378 }
379
386 static inline bool IsCrossingBarred(TileIndex t)
387 {
388 assert(IsLevelCrossing(t));
389 return HasBit(_m[t].m5, 5);
390 }
391
398 static inline void SetCrossingBarred(TileIndex t, bool barred)
399 {
400 assert(IsLevelCrossing(t));
401 SB(_m[t].m5, 5, 1, barred ? 1 : 0);
402 }
403
408 static inline void UnbarCrossing(TileIndex t)
409 {
410 SetCrossingBarred(t, false);
411 }
412
417 static inline void BarCrossing(TileIndex t)
418 {
419 SetCrossingBarred(t, true);
420 }
421
423 #define IsOnDesert IsOnSnow
424
429 static inline bool IsOnSnow(TileIndex t)
430 {
431 return HasBit(_me[t].m7, 5);
432 }
433
435 #define ToggleDesert ToggleSnow
436
440 static inline void ToggleSnow(TileIndex t)
441 {
442 ToggleBit(_me[t].m7, 5);
443 }
444
445
447 enum Roadside {
448 ROADSIDE_BARREN = 0,
449 ROADSIDE_GRASS = 1,
450 ROADSIDE_PAVED = 2,
451 ROADSIDE_STREET_LIGHTS = 3,
452 ROADSIDE_TREES = 5,
453 ROADSIDE_GRASS_ROAD_WORKS = 6,
454 ROADSIDE_PAVED_ROAD_WORKS = 7,
455 };
456
462 static inline Roadside GetRoadside(TileIndex tile)
463 {
464 return (Roadside)GB(_me[tile].m6, 3, 3);
465 }
466
472 static inline void SetRoadside(TileIndex tile, Roadside s)
473 {
474 SB(_me[tile].m6, 3, 3, s);
475 }
476
482 static inline bool HasRoadWorks(TileIndex t)
483 {
484 return GetRoadside(t) >= ROADSIDE_GRASS_ROAD_WORKS;
485 }
486
492 static inline bool IncreaseRoadWorksCounter(TileIndex t)
493 {
494 AB(_me[t].m7, 0, 4, 1);
495
496 return GB(_me[t].m7, 0, 4) == 15;
497 }
498
504 static inline void StartRoadWorks(TileIndex t)
505 {
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;
512 }
513 }
514
520 static inline void TerminateRoadWorks(TileIndex t)
521 {
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);
526 }
527
528
534 static inline DiagDirection GetRoadDepotDirection(TileIndex t)
535 {
536 assert(IsRoadDepot(t));
537 return (DiagDirection)GB(_m[t].m5, 0, 2);
538 }
539
540
541 RoadBits GetAnyRoadBits(TileIndex tile, RoadType rt, bool straight_tunnel_bridge_entrance = false);
542
543
553 static inline void MakeRoadNormal(TileIndex t, RoadBits bits, RoadTypes rot, TownID town, Owner road, Owner tram)
554 {
555 SetTileType(t, MP_ROAD);
556 SetTileOwner(t, road);
557 _m[t].m2 = town;
558 _m[t].m3 = (HasBit(rot, ROADTYPE_TRAM) ? bits : 0);
559 _m[t].m4 = 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);
564 }
565
577 static inline void MakeRoadCrossing(TileIndex t, Owner road, Owner tram, Owner rail, Axis roaddir, RailType rat, RoadTypes rot, uint town)
578 {
579 SetTileType(t, MP_ROAD);
580 SetTileOwner(t, rail);
581 _m[t].m2 = town;
582 _m[t].m3 = rat;
583 _m[t].m4 = 0;
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);
588 }
589
598 static inline void MakeRoadDepot(TileIndex t, Owner owner, DepotID did, DiagDirection dir, RoadType rt)
599 {
600 SetTileType(t, MP_ROAD);
601 SetTileOwner(t, owner);
602 _m[t].m2 = did;
603 _m[t].m3 = 0;
604 _m[t].m4 = 0;
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);
609 }
610
611 #endif /* ROAD_MAP_H */