# road_map.h

Go to the documentation of this file.

    00001 /* $Id: road_map.h 14591 2008-11-18 22:43:59Z smatz $ */
    00002
    00005 #ifndef ROAD_MAP_H
    00006 #define ROAD_MAP_H
    00007
    00008 #include "track_func.h"
    00009 #include "rail_type.h"
    00010 #include "town_type.h"
    00011 #include "road_func.h"
    00012 #include "tile_map.h"
    00013
    00014
    00015 enum RoadTileType {
    00016   ROAD_TILE_NORMAL,
    00017   ROAD_TILE_CROSSING,
    00018   ROAD_TILE_DEPOT
    00019 };
    00020
    00021 static inline RoadTileType GetRoadTileType(TileIndex t)
    00022 {
    00023   assert(IsTileType(t, MP_ROAD));
    00024   return (RoadTileType)GB(_m[t].m5, 6, 2);
    00025 }
    00026
    00027 static inline bool IsNormalRoad(TileIndex t)
    00028 {
    00029   return GetRoadTileType(t) == ROAD_TILE_NORMAL;
    00030 }
    00031
    00032 static inline bool IsNormalRoadTile(TileIndex t)
    00033 {
    00034   return IsTileType(t, MP_ROAD) && IsNormalRoad(t);
    00035 }
    00036
    00037 static inline bool IsLevelCrossing(TileIndex t)
    00038 {
    00039   return GetRoadTileType(t) == ROAD_TILE_CROSSING;
    00040 }
    00041
    00042 static inline bool IsLevelCrossingTile(TileIndex t)
    00043 {
    00044   return IsTileType(t, MP_ROAD) && IsLevelCrossing(t);
    00045 }
    00046
    00047 static inline bool IsRoadDepot(TileIndex t)
    00048 {
    00049   return GetRoadTileType(t) == ROAD_TILE_DEPOT;
    00050 }
    00051
    00052 static inline bool IsRoadDepotTile(TileIndex t)
    00053 {
    00054   return IsTileType(t, MP_ROAD) && IsRoadDepot(t);
    00055 }
    00056
    00057 static inline RoadBits GetRoadBits(TileIndex t, RoadType rt)
    00058 {
    00059   assert(IsNormalRoad(t));
    00060   switch (rt) {
    00061     default: NOT_REACHED();
    00062     case ROADTYPE_ROAD: return (RoadBits)GB(_m[t].m4, 0, 4);
    00063     case ROADTYPE_TRAM: return (RoadBits)GB(_m[t].m4, 4, 4);
    00064     case ROADTYPE_HWAY: return (RoadBits)GB(_m[t].m6, 2, 4);
    00065   }
    00066 }
    00067
    00075 static inline RoadBits GetOtherRoadBits(TileIndex t, RoadType rt)
    00076 {
    00077   return ((rt == ROADTYPE_ROAD) ? ROAD_NONE : GetRoadBits(t, ROADTYPE_ROAD)) |
    00078     ((rt == ROADTYPE_TRAM) ? ROAD_NONE : GetRoadBits(t, ROADTYPE_TRAM)) |
    00079     ((rt == ROADTYPE_HWAY) ? ROAD_NONE : GetRoadBits(t, ROADTYPE_HWAY));
    00080 }
    00081
    00088 static inline RoadBits GetAllRoadBits(TileIndex tile)
    00089 {
    00090   return GetRoadBits(tile, ROADTYPE_ROAD) | GetRoadBits(tile, ROADTYPE_TRAM) | GetRoadBits(tile, ROADTYPE_HWAY);
    00091 }
    00092
    00093 static inline void SetRoadBits(TileIndex t, RoadBits r, RoadType rt)
    00094 {
    00095   assert(IsNormalRoad(t)); // XXX incomplete
    00096   switch (rt) {
    00097     default: NOT_REACHED();
    00098     case ROADTYPE_ROAD: SB(_m[t].m4, 0, 4, r); break;
    00099     case ROADTYPE_TRAM: SB(_m[t].m4, 4, 4, r); break;
    00100     case ROADTYPE_HWAY: SB(_m[t].m6, 2, 4, r); break;
    00101   }
    00102 }
    00103
    00104 static inline RoadTypes GetRoadTypes(TileIndex t)
    00105 {
    00106   if (IsTileType(t, MP_ROAD)) {
    00107     return (RoadTypes)GB(_me[t].m7, 5, 3);
    00108   } else {
    00109     return (RoadTypes)GB(_m[t].m3, 0, 3);
    00110   }
    00111 }
    00112
    00113 static inline void SetRoadTypes(TileIndex t, RoadTypes rt)
    00114 {
    00115   if (IsTileType(t, MP_ROAD)) {
    00116     SB(_me[t].m7, 5, 3, rt);
    00117   } else {
    00118     assert(IsTileType(t, MP_STATION) || IsTileType(t, MP_TUNNELBRIDGE));
    00119     SB(_m[t].m3, 0, 2, rt);
    00120   }
    00121 }
    00122
    00123 static inline bool HasTileRoadType(TileIndex t, RoadType rt)
    00124 {
    00125   return HasBit(GetRoadTypes(t), rt);
    00126 }
    00127
    00128 static inline Owner GetRoadOwner(TileIndex t, RoadType rt)
    00129 {
    00130   if (!IsTileType(t, MP_ROAD)) return GetTileOwner(t);
    00131
    00132   switch (GetRoadTileType(t)) {
    00133     default: NOT_REACHED();
    00134     case ROAD_TILE_NORMAL:
    00135       switch (rt) {
    00136         default: NOT_REACHED();
    00137         case ROADTYPE_ROAD: return (Owner)GB( _m[t].m1, 0, 5);
    00138         case ROADTYPE_TRAM: {
    00139           /* Trams don't need OWNER_TOWN, and remapping OWNER_NONE
    00140            * to OWNER_TOWN makes it use one bit less */
    00141           Owner o = (Owner)GB( _m[t].m5, 0, 4);
    00142           return o == OWNER_TOWN ? OWNER_NONE : o;
    00143         }
    00144         case ROADTYPE_HWAY: return (Owner)GB(_me[t].m7, 0, 5);
    00145       }
    00146     case ROAD_TILE_CROSSING:
    00147       switch (rt) {
    00148         default: NOT_REACHED();
    00149         case ROADTYPE_ROAD: return (Owner)GB( _m[t].m4, 0, 5);
    00150         case ROADTYPE_TRAM: {
    00151           /* Trams don't need OWNER_TOWN, and remapping OWNER_NONE
    00152            * to OWNER_TOWN makes it use one bit less */
    00153           Owner o = (Owner)GB( _m[t].m5, 0, 4);
    00154           return o == OWNER_TOWN ? OWNER_NONE : o;
    00155         }
    00156         case ROADTYPE_HWAY: return (Owner)GB(_me[t].m7, 0, 5);
    00157       }
    00158     case ROAD_TILE_DEPOT: return GetTileOwner(t);
    00159   }
    00160 }
    00161
    00162 static inline void SetRoadOwner(TileIndex t, RoadType rt, Owner o)
    00163 {
    00164   if (!IsTileType(t, MP_ROAD)) return SetTileOwner(t, o);
    00165
    00166   switch (GetRoadTileType(t)) {
    00167     default: NOT_REACHED();
    00168     case ROAD_TILE_NORMAL:
    00169       switch (rt) {
    00170         default: NOT_REACHED();
    00171         case ROADTYPE_ROAD: SB( _m[t].m1, 0, 5, o); break;
    00172         case ROADTYPE_TRAM: SB( _m[t].m5, 0, 4, o == OWNER_NONE ? OWNER_TOWN : o); break;
    00173         case ROADTYPE_HWAY: SB(_me[t].m7, 0, 5, o); break;
    00174       }
    00175       break;
    00176     case ROAD_TILE_CROSSING:
    00177       switch (rt) {
    00178         default: NOT_REACHED();
    00179         case ROADTYPE_ROAD: SB( _m[t].m4, 0, 5, o); break;
    00180         /* Trams don't need OWNER_TOWN, and remapping OWNER_NONE
    00181          * to OWNER_TOWN makes it use one bit less */
    00182         case ROADTYPE_TRAM: SB( _m[t].m5, 0, 4, o == OWNER_NONE ? OWNER_TOWN : o); break;
    00183         case ROADTYPE_HWAY: SB(_me[t].m7, 0, 5, o); break;
    00184       }
    00185       break;
    00186     case ROAD_TILE_DEPOT: return SetTileOwner(t, o);
    00187   }
    00188 }
    00189
    00190 static inline bool IsRoadOwner(TileIndex t, RoadType rt, Owner o)
    00191 {
    00192   assert(HasTileRoadType(t, rt));
    00193   return (GetRoadOwner(t, rt) == o);
    00194 }
    00195
    00201 static inline bool HasTownOwnedRoad(TileIndex t)
    00202 {
    00203   assert(IsTileType(t, MP_ROAD));
    00204   return HasTileRoadType(t, ROADTYPE_ROAD) && IsRoadOwner(t, ROADTYPE_ROAD, OWNER_TOWN);
    00205 }
    00206
    00208 enum DisallowedRoadDirections {
    00209   DRD_NONE,
    00210   DRD_SOUTHBOUND,
    00211   DRD_NORTHBOUND,
    00212   DRD_BOTH,
    00213   DRD_END
    00214 };
    00215 DECLARE_ENUM_AS_BIT_SET(DisallowedRoadDirections);
    00216
    00222 static inline DisallowedRoadDirections GetDisallowedRoadDirections(TileIndex t)
    00223 {
    00224   assert(IsNormalRoad(t));
    00225   return (DisallowedRoadDirections)GB(_m[t].m5, 4, 2);
    00226 }
    00227
    00233 static inline void SetDisallowedRoadDirections(TileIndex t, DisallowedRoadDirections drd)
    00234 {
    00235   assert(IsNormalRoad(t));
    00236   assert(drd < DRD_END);
    00237   SB(_m[t].m5, 4, 2, drd);
    00238 }
    00239
    00240 static inline Axis GetCrossingRoadAxis(TileIndex t)
    00241 {
    00242   assert(IsLevelCrossing(t));
    00243   return (Axis)GB(_m[t].m4, 6, 1);
    00244 }
    00245
    00246 static inline Axis GetCrossingRailAxis(TileIndex t)
    00247 {
    00248   assert(IsLevelCrossing(t));
    00249   return OtherAxis((Axis)GetCrossingRoadAxis(t));
    00250 }
    00251
    00252 static inline RoadBits GetCrossingRoadBits(TileIndex tile)
    00253 {
    00254   return GetCrossingRoadAxis(tile) == AXIS_X ? ROAD_X : ROAD_Y;
    00255 }
    00256
    00257 static inline Track GetCrossingRailTrack(TileIndex tile)
    00258 {
    00259   return AxisToTrack(GetCrossingRailAxis(tile));
    00260 }
    00261
    00262 static inline TrackBits GetCrossingRailBits(TileIndex tile)
    00263 {
    00264   return AxisToTrackBits(GetCrossingRailAxis(tile));
    00265 }
    00266
    00267
    00274 static inline bool GetCrossingReservation(TileIndex t)
    00275 {
    00276   assert(IsLevelCrossingTile(t));
    00277   return HasBit(_m[t].m5, 4);
    00278 }
    00279
    00287 static inline void SetCrossingReservation(TileIndex t, bool b)
    00288 {
    00289   assert(IsLevelCrossingTile(t));
    00290   SB(_m[t].m5, 4, 1, b ? 1 : 0);
    00291 }
    00292
    00299 static inline TrackBits GetRailCrossingReservation(TileIndex t)
    00300 {
    00301   return GetCrossingReservation(t) ? GetCrossingRailBits(t) : TRACK_BIT_NONE;
    00302 }
    00303
    00304 static inline bool IsCrossingBarred(TileIndex t)
    00305 {
    00306   assert(IsLevelCrossing(t));
    00307   return HasBit(_m[t].m4, 5);
    00308 }
    00309
    00310 static inline void SetCrossingBarred(TileIndex t, bool barred)
    00311 {
    00312   assert(IsLevelCrossing(t));
    00313   SB(_m[t].m4, 5, 1, barred);
    00314 }
    00315
    00316 static inline void UnbarCrossing(TileIndex t)
    00317 {
    00318   SetCrossingBarred(t, false);
    00319 }
    00320
    00321 static inline void BarCrossing(TileIndex t)
    00322 {
    00323   SetCrossingBarred(t, true);
    00324 }
    00325
    00326 #define IsOnDesert IsOnSnow
    00327 static inline bool IsOnSnow(TileIndex t)
    00328 {
    00329   return HasBit(_m[t].m3, 7);
    00330 }
    00331
    00332 #define ToggleDesert ToggleSnow
    00333 static inline void ToggleSnow(TileIndex t)
    00334 {
    00335   ToggleBit(_m[t].m3, 7);
    00336 }
    00337
    00338
    00339 enum Roadside {
    00340   ROADSIDE_BARREN           = 0,
    00341   ROADSIDE_GRASS            = 1,
    00342   ROADSIDE_PAVED            = 2,
    00343   ROADSIDE_STREET_LIGHTS    = 3,
    00344   ROADSIDE_TREES            = 5,
    00345   ROADSIDE_GRASS_ROAD_WORKS = 6,
    00346   ROADSIDE_PAVED_ROAD_WORKS = 7
    00347 };
    00348
    00349 static inline Roadside GetRoadside(TileIndex tile)
    00350 {
    00351   return (Roadside)GB(_m[tile].m3, 4, 3);
    00352 }
    00353
    00354 static inline void SetRoadside(TileIndex tile, Roadside s)
    00355 {
    00356   SB(_m[tile].m3, 4, 3, s);
    00357 }
    00358
    00359 static inline bool HasRoadWorks(TileIndex t)
    00360 {
    00361   return GetRoadside(t) >= ROADSIDE_GRASS_ROAD_WORKS;
    00362 }
    00363
    00364 static inline bool IncreaseRoadWorksCounter(TileIndex t)
    00365 {
    00366   AB(_m[t].m3, 0, 4, 1);
    00367
    00368   return GB(_m[t].m3, 0, 4) == 15;
    00369 }
    00370
    00371 static inline void StartRoadWorks(TileIndex t)
    00372 {
    00373   assert(!HasRoadWorks(t));
    00374   /* Remove any trees or lamps in case or roadwork */
    00375   switch (GetRoadside(t)) {
    00376     case ROADSIDE_BARREN:
    00377     case ROADSIDE_GRASS:  SetRoadside(t, ROADSIDE_GRASS_ROAD_WORKS); break;
    00378     default:              SetRoadside(t, ROADSIDE_PAVED_ROAD_WORKS); break;
    00379   }
    00380 }
    00381
    00382 static inline void TerminateRoadWorks(TileIndex t)
    00383 {
    00384   assert(HasRoadWorks(t));
    00385   SetRoadside(t, (Roadside)(GetRoadside(t) - ROADSIDE_GRASS_ROAD_WORKS + ROADSIDE_GRASS));
    00386   /* Stop the counter */
    00387   SB(_m[t].m3, 0, 4, 0);
    00388 }
    00389
    00390
    00391 static inline DiagDirection GetRoadDepotDirection(TileIndex t)
    00392 {
    00393   assert(IsRoadDepot(t));
    00394   return (DiagDirection)GB(_m[t].m5, 0, 2);
    00395 }
    00396
    00397
    00414 RoadBits GetAnyRoadBits(TileIndex tile, RoadType rt, bool straight_tunnel_bridge_entrance = false);
    00415
    00424 TrackBits GetAnyRoadTrackBits(TileIndex tile, RoadType rt);
    00425
    00434 bool IsPossibleCrossing(const TileIndex tile, Axis ax);
    00435
    00436
    00437 static inline void MakeRoadNormal(TileIndex t, RoadBits bits, RoadTypes rot, TownID town, Owner road, Owner tram, Owner hway)
    00438 {
    00439   SetTileType(t, MP_ROAD);
    00440   SetTileOwner(t, road);
    00441   _m[t].m2 = town;
    00442   _m[t].m3 = 0;
    00443   _m[t].m4 = (HasBit(rot, ROADTYPE_TRAM) ? bits : 0) << 4 | (HasBit(rot, ROADTYPE_ROAD) ? bits : 0);
    00444   _m[t].m5 = ROAD_TILE_NORMAL << 6;
    00445   SetRoadOwner(t, ROADTYPE_TRAM, tram);
    00446   SB(_m[t].m6, 2, 4, HasBit(rot, ROADTYPE_HWAY) ? bits : 0);
    00447   _me[t].m7 = rot << 5 | hway;
    00448 }
    00449
    00450
    00451 static inline void MakeRoadCrossing(TileIndex t, Owner road, Owner tram, Owner hway, Owner rail, Axis roaddir, RailType rat, RoadTypes rot, uint town)
    00452 {
    00453   SetTileType(t, MP_ROAD);
    00454   SetTileOwner(t, rail);
    00455   _m[t].m2 = town;
    00456   _m[t].m3 = rat;
    00457   _m[t].m4 = roaddir << 6 | road;
    00458   _m[t].m5 = ROAD_TILE_CROSSING << 6;
    00459   SetRoadOwner(t, ROADTYPE_TRAM, tram);
    00460   SB(_m[t].m6, 2, 4, 0);
    00461   _me[t].m7 = rot << 5 | hway;
    00462 }
    00463
    00464
    00465 static inline void MakeRoadDepot(TileIndex t, Owner owner, DiagDirection dir, RoadType rt, TownID town)
    00466 {
    00467   SetTileType(t, MP_ROAD);
    00468   SetTileOwner(t, owner);
    00469   _m[t].m2 = town;
    00470   _m[t].m3 = 0;
    00471   _m[t].m4 = 0;
    00472   _m[t].m5 = ROAD_TILE_DEPOT << 6 | dir;
    00473   SB(_m[t].m6, 2, 4, 0);
    00474   _me[t].m7 = RoadTypeToRoadTypes(rt) << 5;
    00475 }
    00476
    00477 #endif /* ROAD_MAP_H */