# road_map.h

Go to the documentation of this file.

    00001 /* $Id: road_map.h 23595 2011-12-19 17:48:04Z rubidium $ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * 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.
    00006  * 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.
    00007  * 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/>.
    00008  */
    00009
    00012 #ifndef ROAD_MAP_H
    00013 #define ROAD_MAP_H
    00014
    00015 #include "track_func.h"
    00016 #include "depot_type.h"
    00017 #include "rail_type.h"
    00018 #include "road_func.h"
    00019 #include "tile_map.h"
    00020
    00021
    00023 enum RoadTileType {
    00024   ROAD_TILE_NORMAL,
    00025   ROAD_TILE_CROSSING,
    00026   ROAD_TILE_DEPOT,
    00027 };
    00028
    00035 static inline RoadTileType GetRoadTileType(TileIndex t)
    00036 {
    00037   assert(IsTileType(t, MP_ROAD));
    00038   return (RoadTileType)GB(_m[t].m5, 6, 2);
    00039 }
    00040
    00047 static inline bool IsNormalRoad(TileIndex t)
    00048 {
    00049   return GetRoadTileType(t) == ROAD_TILE_NORMAL;
    00050 }
    00051
    00057 static inline bool IsNormalRoadTile(TileIndex t)
    00058 {
    00059   return IsTileType(t, MP_ROAD) && IsNormalRoad(t);
    00060 }
    00061
    00068 static inline bool IsLevelCrossing(TileIndex t)
    00069 {
    00070   return GetRoadTileType(t) == ROAD_TILE_CROSSING;
    00071 }
    00072
    00078 static inline bool IsLevelCrossingTile(TileIndex t)
    00079 {
    00080   return IsTileType(t, MP_ROAD) && IsLevelCrossing(t);
    00081 }
    00082
    00089 static inline bool IsRoadDepot(TileIndex t)
    00090 {
    00091   return GetRoadTileType(t) == ROAD_TILE_DEPOT;
    00092 }
    00093
    00099 static inline bool IsRoadDepotTile(TileIndex t)
    00100 {
    00101   return IsTileType(t, MP_ROAD) && IsRoadDepot(t);
    00102 }
    00103
    00111 static inline RoadBits GetRoadBits(TileIndex t, RoadType rt)
    00112 {
    00113   assert(IsNormalRoad(t));
    00114   switch (rt) {
    00115     default: NOT_REACHED();
    00116     case ROADTYPE_ROAD: return (RoadBits)GB(_m[t].m5, 0, 4);
    00117     case ROADTYPE_TRAM: return (RoadBits)GB(_m[t].m3, 0, 4);
    00118   }
    00119 }
    00120
    00128 static inline RoadBits GetOtherRoadBits(TileIndex t, RoadType rt)
    00129 {
    00130   return GetRoadBits(t, rt == ROADTYPE_ROAD ? ROADTYPE_TRAM : ROADTYPE_ROAD);
    00131 }
    00132
    00139 static inline RoadBits GetAllRoadBits(TileIndex tile)
    00140 {
    00141   return GetRoadBits(tile, ROADTYPE_ROAD) | GetRoadBits(tile, ROADTYPE_TRAM);
    00142 }
    00143
    00151 static inline void SetRoadBits(TileIndex t, RoadBits r, RoadType rt)
    00152 {
    00153   assert(IsNormalRoad(t)); // XXX incomplete
    00154   switch (rt) {
    00155     default: NOT_REACHED();
    00156     case ROADTYPE_ROAD: SB(_m[t].m5, 0, 4, r); break;
    00157     case ROADTYPE_TRAM: SB(_m[t].m3, 0, 4, r); break;
    00158   }
    00159 }
    00160
    00166 static inline RoadTypes GetRoadTypes(TileIndex t)
    00167 {
    00168   return (RoadTypes)GB(_me[t].m7, 6, 2);
    00169 }
    00170
    00176 static inline void SetRoadTypes(TileIndex t, RoadTypes rt)
    00177 {
    00178   assert(IsTileType(t, MP_ROAD) || IsTileType(t, MP_STATION) || IsTileType(t, MP_TUNNELBRIDGE));
    00179   SB(_me[t].m7, 6, 2, rt);
    00180 }
    00181
    00188 static inline bool HasTileRoadType(TileIndex t, RoadType rt)
    00189 {
    00190   return HasBit(GetRoadTypes(t), rt);
    00191 }
    00192
    00199 static inline Owner GetRoadOwner(TileIndex t, RoadType rt)
    00200 {
    00201   assert(IsTileType(t, MP_ROAD) || IsTileType(t, MP_STATION) || IsTileType(t, MP_TUNNELBRIDGE));
    00202   switch (rt) {
    00203     default: NOT_REACHED();
    00204     case ROADTYPE_ROAD: return (Owner)GB(IsNormalRoadTile(t) ? _m[t].m1 : _me[t].m7, 0, 5);
    00205     case ROADTYPE_TRAM: {
    00206       /* Trams don't need OWNER_TOWN, and remapping OWNER_NONE
    00207        * to OWNER_TOWN makes it use one bit less */
    00208       Owner o = (Owner)GB(_m[t].m3, 4, 4);
    00209       return o == OWNER_TOWN ? OWNER_NONE : o;
    00210     }
    00211   }
    00212 }
    00213
    00220 static inline void SetRoadOwner(TileIndex t, RoadType rt, Owner o)
    00221 {
    00222   switch (rt) {
    00223     default: NOT_REACHED();
    00224     case ROADTYPE_ROAD: SB(IsNormalRoadTile(t) ? _m[t].m1 : _me[t].m7, 0, 5, o); break;
    00225     case ROADTYPE_TRAM: SB(_m[t].m3, 4, 4, o == OWNER_NONE ? OWNER_TOWN : o); break;
    00226   }
    00227 }
    00228
    00237 static inline bool IsRoadOwner(TileIndex t, RoadType rt, Owner o)
    00238 {
    00239   assert(HasTileRoadType(t, rt));
    00240   return (GetRoadOwner(t, rt) == o);
    00241 }
    00242
    00249 static inline bool HasTownOwnedRoad(TileIndex t)
    00250 {
    00251   return HasTileRoadType(t, ROADTYPE_ROAD) && IsRoadOwner(t, ROADTYPE_ROAD, OWNER_TOWN);
    00252 }
    00253
    00255 enum DisallowedRoadDirections {
    00256   DRD_NONE,
    00257   DRD_SOUTHBOUND,
    00258   DRD_NORTHBOUND,
    00259   DRD_BOTH,
    00260   DRD_END,
    00261 };
    00262 DECLARE_ENUM_AS_BIT_SET(DisallowedRoadDirections)
    00264 template <> struct EnumPropsT<DisallowedRoadDirections> : MakeEnumPropsT<DisallowedRoadDirections, byte, DRD_NONE, DRD_END, DRD_END, 2> {};
    00265
    00271 static inline DisallowedRoadDirections GetDisallowedRoadDirections(TileIndex t)
    00272 {
    00273   assert(IsNormalRoad(t));
    00274   return (DisallowedRoadDirections)GB(_m[t].m5, 4, 2);
    00275 }
    00276
    00282 static inline void SetDisallowedRoadDirections(TileIndex t, DisallowedRoadDirections drd)
    00283 {
    00284   assert(IsNormalRoad(t));
    00285   assert(drd < DRD_END);
    00286   SB(_m[t].m5, 4, 2, drd);
    00287 }
    00288
    00295 static inline Axis GetCrossingRoadAxis(TileIndex t)
    00296 {
    00297   assert(IsLevelCrossing(t));
    00298   return (Axis)GB(_m[t].m5, 0, 1);
    00299 }
    00300
    00307 static inline Axis GetCrossingRailAxis(TileIndex t)
    00308 {
    00309   assert(IsLevelCrossing(t));
    00310   return OtherAxis((Axis)GetCrossingRoadAxis(t));
    00311 }
    00312
    00318 static inline RoadBits GetCrossingRoadBits(TileIndex tile)
    00319 {
    00320   return GetCrossingRoadAxis(tile) == AXIS_X ? ROAD_X : ROAD_Y;
    00321 }
    00322
    00328 static inline Track GetCrossingRailTrack(TileIndex tile)
    00329 {
    00330   return AxisToTrack(GetCrossingRailAxis(tile));
    00331 }
    00332
    00338 static inline TrackBits GetCrossingRailBits(TileIndex tile)
    00339 {
    00340   return AxisToTrackBits(GetCrossingRailAxis(tile));
    00341 }
    00342
    00343
    00350 static inline bool HasCrossingReservation(TileIndex t)
    00351 {
    00352   assert(IsLevelCrossingTile(t));
    00353   return HasBit(_m[t].m5, 4);
    00354 }
    00355
    00363 static inline void SetCrossingReservation(TileIndex t, bool b)
    00364 {
    00365   assert(IsLevelCrossingTile(t));
    00366   SB(_m[t].m5, 4, 1, b ? 1 : 0);
    00367 }
    00368
    00375 static inline TrackBits GetCrossingReservationTrackBits(TileIndex t)
    00376 {
    00377   return HasCrossingReservation(t) ? GetCrossingRailBits(t) : TRACK_BIT_NONE;
    00378 }
    00379
    00386 static inline bool IsCrossingBarred(TileIndex t)
    00387 {
    00388   assert(IsLevelCrossing(t));
    00389   return HasBit(_m[t].m5, 5);
    00390 }
    00391
    00398 static inline void SetCrossingBarred(TileIndex t, bool barred)
    00399 {
    00400   assert(IsLevelCrossing(t));
    00401   SB(_m[t].m5, 5, 1, barred ? 1 : 0);
    00402 }
    00403
    00408 static inline void UnbarCrossing(TileIndex t)
    00409 {
    00410   SetCrossingBarred(t, false);
    00411 }
    00412
    00417 static inline void BarCrossing(TileIndex t)
    00418 {
    00419   SetCrossingBarred(t, true);
    00420 }
    00421
    00423 #define IsOnDesert IsOnSnow
    00424
    00429 static inline bool IsOnSnow(TileIndex t)
    00430 {
    00431   return HasBit(_me[t].m7, 5);
    00432 }
    00433
    00435 #define ToggleDesert ToggleSnow
    00436
    00440 static inline void ToggleSnow(TileIndex t)
    00441 {
    00442   ToggleBit(_me[t].m7, 5);
    00443 }
    00444
    00445
    00447 enum Roadside {
    00448   ROADSIDE_BARREN           = 0,
    00449   ROADSIDE_GRASS            = 1,
    00450   ROADSIDE_PAVED            = 2,
    00451   ROADSIDE_STREET_LIGHTS    = 3,
    00452   ROADSIDE_TREES            = 5,
    00453   ROADSIDE_GRASS_ROAD_WORKS = 6,
    00454   ROADSIDE_PAVED_ROAD_WORKS = 7,
    00455 };
    00456
    00462 static inline Roadside GetRoadside(TileIndex tile)
    00463 {
    00464   return (Roadside)GB(_m[tile].m6, 3, 3);
    00465 }
    00466
    00472 static inline void SetRoadside(TileIndex tile, Roadside s)
    00473 {
    00474   SB(_m[tile].m6, 3, 3, s);
    00475 }
    00476
    00482 static inline bool HasRoadWorks(TileIndex t)
    00483 {
    00484   return GetRoadside(t) >= ROADSIDE_GRASS_ROAD_WORKS;
    00485 }
    00486
    00492 static inline bool IncreaseRoadWorksCounter(TileIndex t)
    00493 {
    00494   AB(_me[t].m7, 0, 4, 1);
    00495
    00496   return GB(_me[t].m7, 0, 4) == 15;
    00497 }
    00498
    00504 static inline void StartRoadWorks(TileIndex t)
    00505 {
    00506   assert(!HasRoadWorks(t));
    00507   /* Remove any trees or lamps in case or roadwork */
    00508   switch (GetRoadside(t)) {
    00509     case ROADSIDE_BARREN:
    00510     case ROADSIDE_GRASS:  SetRoadside(t, ROADSIDE_GRASS_ROAD_WORKS); break;
    00511     default:              SetRoadside(t, ROADSIDE_PAVED_ROAD_WORKS); break;
    00512   }
    00513 }
    00514
    00520 static inline void TerminateRoadWorks(TileIndex t)
    00521 {
    00522   assert(HasRoadWorks(t));
    00523   SetRoadside(t, (Roadside)(GetRoadside(t) - ROADSIDE_GRASS_ROAD_WORKS + ROADSIDE_GRASS));
    00524   /* Stop the counter */
    00525   SB(_me[t].m7, 0, 4, 0);
    00526 }
    00527
    00528
    00534 static inline DiagDirection GetRoadDepotDirection(TileIndex t)
    00535 {
    00536   assert(IsRoadDepot(t));
    00537   return (DiagDirection)GB(_m[t].m5, 0, 2);
    00538 }
    00539
    00540
    00541 RoadBits GetAnyRoadBits(TileIndex tile, RoadType rt, bool straight_tunnel_bridge_entrance = false);
    00542
    00543
    00553 static inline void MakeRoadNormal(TileIndex t, RoadBits bits, RoadTypes rot, TownID town, Owner road, Owner tram)
    00554 {
    00555   SetTileType(t, MP_ROAD);
    00556   SetTileOwner(t, road);
    00557   _m[t].m2 = town;
    00558   _m[t].m3 = (HasBit(rot, ROADTYPE_TRAM) ? bits : 0);
    00559   _m[t].m4 = 0;
    00560   _m[t].m5 = (HasBit(rot, ROADTYPE_ROAD) ? bits : 0) | ROAD_TILE_NORMAL << 6;
    00561   SB(_m[t].m6, 2, 4, 0);
    00562   _me[t].m7 = rot << 6;
    00563   SetRoadOwner(t, ROADTYPE_TRAM, tram);
    00564 }
    00565
    00577 static inline void MakeRoadCrossing(TileIndex t, Owner road, Owner tram, Owner rail, Axis roaddir, RailType rat, RoadTypes rot, uint town)
    00578 {
    00579   SetTileType(t, MP_ROAD);
    00580   SetTileOwner(t, rail);
    00581   _m[t].m2 = town;
    00582   _m[t].m3 = rat;
    00583   _m[t].m4 = 0;
    00584   _m[t].m5 = ROAD_TILE_CROSSING << 6 | roaddir;
    00585   SB(_m[t].m6, 2, 4, 0);
    00586   _me[t].m7 = rot << 6 | road;
    00587   SetRoadOwner(t, ROADTYPE_TRAM, tram);
    00588 }
    00589
    00598 static inline void MakeRoadDepot(TileIndex t, Owner owner, DepotID did, DiagDirection dir, RoadType rt)
    00599 {
    00600   SetTileType(t, MP_ROAD);
    00601   SetTileOwner(t, owner);
    00602   _m[t].m2 = did;
    00603   _m[t].m3 = 0;
    00604   _m[t].m4 = 0;
    00605   _m[t].m5 = ROAD_TILE_DEPOT << 6 | dir;
    00606   SB(_m[t].m6, 2, 4, 0);
    00607   _me[t].m7 = RoadTypeToRoadTypes(rt) << 6 | owner;
    00608   SetRoadOwner(t, ROADTYPE_TRAM, owner);
    00609 }
    00610
    00611 #endif /* ROAD_MAP_H */