00001
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));
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
00140
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
00152
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
00181
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
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
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