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
00068 static inline RoadBits GetAllRoadBits(TileIndex tile)
00069 {
00070 return GetRoadBits(tile, ROADTYPE_ROAD) | GetRoadBits(tile, ROADTYPE_TRAM) | GetRoadBits(tile, ROADTYPE_HWAY);
00071 }
00072
00073 static inline void SetRoadBits(TileIndex t, RoadBits r, RoadType rt)
00074 {
00075 assert(IsNormalRoad(t));
00076 switch (rt) {
00077 default: NOT_REACHED();
00078 case ROADTYPE_ROAD: SB(_m[t].m4, 0, 4, r); break;
00079 case ROADTYPE_TRAM: SB(_m[t].m4, 4, 4, r); break;
00080 case ROADTYPE_HWAY: SB(_m[t].m6, 2, 4, r); break;
00081 }
00082 }
00083
00084 static inline RoadTypes GetRoadTypes(TileIndex t)
00085 {
00086 if (IsTileType(t, MP_ROAD)) {
00087 return (RoadTypes)GB(_me[t].m7, 5, 3);
00088 } else {
00089 return (RoadTypes)GB(_m[t].m3, 0, 3);
00090 }
00091 }
00092
00093 static inline void SetRoadTypes(TileIndex t, RoadTypes rt)
00094 {
00095 if (IsTileType(t, MP_ROAD)) {
00096 SB(_me[t].m7, 5, 3, rt);
00097 } else {
00098 assert(IsTileType(t, MP_STATION) || IsTileType(t, MP_TUNNELBRIDGE));
00099 SB(_m[t].m3, 0, 2, rt);
00100 }
00101 }
00102
00103 static inline bool HasTileRoadType(TileIndex t, RoadType rt)
00104 {
00105 return HasBit(GetRoadTypes(t), rt);
00106 }
00107
00108 static inline Owner GetRoadOwner(TileIndex t, RoadType rt)
00109 {
00110 if (!IsTileType(t, MP_ROAD)) return GetTileOwner(t);
00111
00112 switch (GetRoadTileType(t)) {
00113 default: NOT_REACHED();
00114 case ROAD_TILE_NORMAL:
00115 switch (rt) {
00116 default: NOT_REACHED();
00117 case ROADTYPE_ROAD: return (Owner)GB( _m[t].m1, 0, 5);
00118 case ROADTYPE_TRAM: {
00119
00120
00121 Owner o = (Owner)GB( _m[t].m5, 0, 4);
00122 return o == OWNER_TOWN ? OWNER_NONE : o;
00123 }
00124 case ROADTYPE_HWAY: return (Owner)GB(_me[t].m7, 0, 5);
00125 }
00126 case ROAD_TILE_CROSSING:
00127 switch (rt) {
00128 default: NOT_REACHED();
00129 case ROADTYPE_ROAD: return (Owner)GB( _m[t].m4, 0, 5);
00130 case ROADTYPE_TRAM: {
00131
00132
00133 Owner o = (Owner)GB( _m[t].m5, 0, 4);
00134 return o == OWNER_TOWN ? OWNER_NONE : o;
00135 }
00136 case ROADTYPE_HWAY: return (Owner)GB(_me[t].m7, 0, 5);
00137 }
00138 case ROAD_TILE_DEPOT: return GetTileOwner(t);
00139 }
00140 }
00141
00142 static inline void SetRoadOwner(TileIndex t, RoadType rt, Owner o)
00143 {
00144 if (!IsTileType(t, MP_ROAD)) return SetTileOwner(t, o);
00145
00146 switch (GetRoadTileType(t)) {
00147 default: NOT_REACHED();
00148 case ROAD_TILE_NORMAL:
00149 switch (rt) {
00150 default: NOT_REACHED();
00151 case ROADTYPE_ROAD: SB( _m[t].m1, 0, 5, o); break;
00152 case ROADTYPE_TRAM: SB( _m[t].m5, 0, 4, o == OWNER_NONE ? OWNER_TOWN : o); break;
00153 case ROADTYPE_HWAY: SB(_me[t].m7, 0, 5, o); break;
00154 }
00155 break;
00156 case ROAD_TILE_CROSSING:
00157 switch (rt) {
00158 default: NOT_REACHED();
00159 case ROADTYPE_ROAD: SB( _m[t].m4, 0, 5, o); break;
00160
00161
00162 case ROADTYPE_TRAM: SB( _m[t].m5, 0, 4, o == OWNER_NONE ? OWNER_TOWN : o); break;
00163 case ROADTYPE_HWAY: SB(_me[t].m7, 0, 5, o); break;
00164 }
00165 break;
00166 case ROAD_TILE_DEPOT: return SetTileOwner(t, o);
00167 }
00168 }
00169
00171 enum DisallowedRoadDirections {
00172 DRD_NONE,
00173 DRD_SOUTHBOUND,
00174 DRD_NORTHBOUND,
00175 DRD_BOTH,
00176 DRD_END
00177 };
00178 DECLARE_ENUM_AS_BIT_SET(DisallowedRoadDirections);
00179
00185 static inline DisallowedRoadDirections GetDisallowedRoadDirections(TileIndex t)
00186 {
00187 assert(IsNormalRoad(t));
00188 return (DisallowedRoadDirections)GB(_m[t].m5, 4, 2);
00189 }
00190
00196 static inline void SetDisallowedRoadDirections(TileIndex t, DisallowedRoadDirections drd)
00197 {
00198 assert(IsNormalRoad(t));
00199 assert(drd < DRD_END);
00200 SB(_m[t].m5, 4, 2, drd);
00201 }
00202
00203 static inline Axis GetCrossingRoadAxis(TileIndex t)
00204 {
00205 assert(IsLevelCrossing(t));
00206 return (Axis)GB(_m[t].m4, 6, 1);
00207 }
00208
00209 static inline Axis GetCrossingRailAxis(TileIndex t)
00210 {
00211 assert(IsLevelCrossing(t));
00212 return OtherAxis((Axis)GetCrossingRoadAxis(t));
00213 }
00214
00215 static inline RoadBits GetCrossingRoadBits(TileIndex tile)
00216 {
00217 return GetCrossingRoadAxis(tile) == AXIS_X ? ROAD_X : ROAD_Y;
00218 }
00219
00220 static inline Track GetCrossingRailTrack(TileIndex tile)
00221 {
00222 return AxisToTrack(GetCrossingRailAxis(tile));
00223 }
00224
00225 static inline TrackBits GetCrossingRailBits(TileIndex tile)
00226 {
00227 return AxisToTrackBits(GetCrossingRailAxis(tile));
00228 }
00229
00230 static inline bool IsCrossingBarred(TileIndex t)
00231 {
00232 assert(IsLevelCrossing(t));
00233 return HasBit(_m[t].m4, 5);
00234 }
00235
00236 static inline void SetCrossingBarred(TileIndex t, bool barred)
00237 {
00238 assert(IsLevelCrossing(t));
00239 SB(_m[t].m4, 5, 1, barred);
00240 }
00241
00242 static inline void UnbarCrossing(TileIndex t)
00243 {
00244 SetCrossingBarred(t, false);
00245 }
00246
00247 static inline void BarCrossing(TileIndex t)
00248 {
00249 SetCrossingBarred(t, true);
00250 }
00251
00252 #define IsOnDesert IsOnSnow
00253 static inline bool IsOnSnow(TileIndex t)
00254 {
00255 return HasBit(_m[t].m3, 7);
00256 }
00257
00258 #define ToggleDesert ToggleSnow
00259 static inline void ToggleSnow(TileIndex t)
00260 {
00261 ToggleBit(_m[t].m3, 7);
00262 }
00263
00264
00265 enum Roadside {
00266 ROADSIDE_BARREN = 0,
00267 ROADSIDE_GRASS = 1,
00268 ROADSIDE_PAVED = 2,
00269 ROADSIDE_STREET_LIGHTS = 3,
00270 ROADSIDE_TREES = 5,
00271 ROADSIDE_GRASS_ROAD_WORKS = 6,
00272 ROADSIDE_PAVED_ROAD_WORKS = 7
00273 };
00274
00275 static inline Roadside GetRoadside(TileIndex tile)
00276 {
00277 return (Roadside)GB(_m[tile].m3, 4, 3);
00278 }
00279
00280 static inline void SetRoadside(TileIndex tile, Roadside s)
00281 {
00282 SB(_m[tile].m3, 4, 3, s);
00283 }
00284
00285 static inline bool HasRoadWorks(TileIndex t)
00286 {
00287 return GetRoadside(t) >= ROADSIDE_GRASS_ROAD_WORKS;
00288 }
00289
00290 static inline bool IncreaseRoadWorksCounter(TileIndex t)
00291 {
00292 AB(_m[t].m3, 0, 4, 1);
00293
00294 return GB(_m[t].m3, 0, 4) == 15;
00295 }
00296
00297 static inline void StartRoadWorks(TileIndex t)
00298 {
00299 assert(!HasRoadWorks(t));
00300
00301 switch (GetRoadside(t)) {
00302 case ROADSIDE_BARREN:
00303 case ROADSIDE_GRASS: SetRoadside(t, ROADSIDE_GRASS_ROAD_WORKS); break;
00304 default: SetRoadside(t, ROADSIDE_PAVED_ROAD_WORKS); break;
00305 }
00306 }
00307
00308 static inline void TerminateRoadWorks(TileIndex t)
00309 {
00310 assert(HasRoadWorks(t));
00311 SetRoadside(t, (Roadside)(GetRoadside(t) - ROADSIDE_GRASS_ROAD_WORKS + ROADSIDE_GRASS));
00312
00313 SB(_m[t].m3, 0, 4, 0);
00314 }
00315
00316
00317 static inline DiagDirection GetRoadDepotDirection(TileIndex t)
00318 {
00319 assert(IsRoadDepot(t));
00320 return (DiagDirection)GB(_m[t].m5, 0, 2);
00321 }
00322
00323
00340 RoadBits GetAnyRoadBits(TileIndex tile, RoadType rt, bool straight_tunnel_bridge_entrance = false);
00341
00350 TrackBits GetAnyRoadTrackBits(TileIndex tile, RoadType rt);
00351
00360 bool IsPossibleCrossing(const TileIndex tile, Axis ax);
00361
00362
00363 static inline void MakeRoadNormal(TileIndex t, RoadBits bits, RoadTypes rot, TownID town, Owner road, Owner tram, Owner hway)
00364 {
00365 SetTileType(t, MP_ROAD);
00366 SetTileOwner(t, road);
00367 _m[t].m2 = town;
00368 _m[t].m3 = 0;
00369 _m[t].m4 = (HasBit(rot, ROADTYPE_TRAM) ? bits : 0) << 4 | (HasBit(rot, ROADTYPE_ROAD) ? bits : 0);
00370 _m[t].m5 = ROAD_TILE_NORMAL << 6;
00371 SetRoadOwner(t, ROADTYPE_TRAM, tram);
00372 SB(_m[t].m6, 2, 4, HasBit(rot, ROADTYPE_HWAY) ? bits : 0);
00373 _me[t].m7 = rot << 5 | hway;
00374 }
00375
00376
00377 static inline void MakeRoadCrossing(TileIndex t, Owner road, Owner tram, Owner hway, Owner rail, Axis roaddir, RailType rat, RoadTypes rot, uint town)
00378 {
00379 SetTileType(t, MP_ROAD);
00380 SetTileOwner(t, rail);
00381 _m[t].m2 = town;
00382 _m[t].m3 = rat;
00383 _m[t].m4 = roaddir << 6 | road;
00384 _m[t].m5 = ROAD_TILE_CROSSING << 6;
00385 SetRoadOwner(t, ROADTYPE_TRAM, tram);
00386 SB(_m[t].m6, 2, 4, 0);
00387 _me[t].m7 = rot << 5 | hway;
00388 }
00389
00390
00391 static inline void MakeRoadDepot(TileIndex t, Owner owner, DiagDirection dir, RoadType rt)
00392 {
00393 SetTileType(t, MP_ROAD);
00394 SetTileOwner(t, owner);
00395 _m[t].m2 = 0;
00396 _m[t].m3 = 0;
00397 _m[t].m4 = 0;
00398 _m[t].m5 = ROAD_TILE_DEPOT << 6 | dir;
00399 SB(_m[t].m6, 2, 4, 0);
00400 _me[t].m7 = RoadTypeToRoadTypes(rt) << 5;
00401 }
00402
00403 #endif