00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef WATER_MAP_H
00013 #define WATER_MAP_H
00014
00015 #include "depot_type.h"
00016 #include "tile_map.h"
00017
00021 enum WaterTileTypeBitLayout {
00022 WBL_TYPE_BEGIN = 4,
00023 WBL_TYPE_COUNT = 4,
00024
00025 WBL_TYPE_NORMAL = 0x0,
00026 WBL_TYPE_LOCK = 0x1,
00027 WBL_TYPE_DEPOT = 0x8,
00028
00029 WBL_COAST_FLAG = 0,
00030
00031 WBL_LOCK_ORIENT_BEGIN = 0,
00032 WBL_LOCK_ORIENT_COUNT = 2,
00033 WBL_LOCK_PART_BEGIN = 2,
00034 WBL_LOCK_PART_COUNT = 2,
00035
00036 WBL_DEPOT_PART = 0,
00037 WBL_DEPOT_AXIS = 1,
00038 };
00039
00041 enum WaterTileType {
00042 WATER_TILE_CLEAR,
00043 WATER_TILE_COAST,
00044 WATER_TILE_LOCK,
00045 WATER_TILE_DEPOT,
00046 };
00047
00049 enum WaterClass {
00050 WATER_CLASS_SEA,
00051 WATER_CLASS_CANAL,
00052 WATER_CLASS_RIVER,
00053 WATER_CLASS_INVALID,
00054 };
00056 template <> struct EnumPropsT<WaterClass> : MakeEnumPropsT<WaterClass, byte, WATER_CLASS_SEA, WATER_CLASS_INVALID, WATER_CLASS_INVALID, 2> {};
00057
00059 enum DepotPart {
00060 DEPOT_PART_NORTH = 0,
00061 DEPOT_PART_SOUTH = 1,
00062 DEPOT_PART_END
00063 };
00064
00066 enum LockPart {
00067 LOCK_PART_MIDDLE = 0,
00068 LOCK_PART_LOWER = 1,
00069 LOCK_PART_UPPER = 2,
00070 };
00071
00077 static inline WaterTileType GetWaterTileType(TileIndex t)
00078 {
00079 assert(IsTileType(t, MP_WATER));
00080
00081 switch (GB(_m[t].m5, WBL_TYPE_BEGIN, WBL_TYPE_COUNT)) {
00082 case WBL_TYPE_NORMAL: return HasBit(_m[t].m5, WBL_COAST_FLAG) ? WATER_TILE_COAST : WATER_TILE_CLEAR;
00083 case WBL_TYPE_LOCK: return WATER_TILE_LOCK;
00084 case WBL_TYPE_DEPOT: return WATER_TILE_DEPOT;
00085 default: NOT_REACHED();
00086 }
00087 }
00088
00095 static inline bool HasTileWaterClass(TileIndex t)
00096 {
00097 return IsTileType(t, MP_WATER) || IsTileType(t, MP_STATION) || IsTileType(t, MP_INDUSTRY) || IsTileType(t, MP_OBJECT);
00098 }
00099
00106 static inline WaterClass GetWaterClass(TileIndex t)
00107 {
00108 assert(HasTileWaterClass(t));
00109 return (WaterClass)GB(_m[t].m1, 5, 2);
00110 }
00111
00118 static inline void SetWaterClass(TileIndex t, WaterClass wc)
00119 {
00120 assert(HasTileWaterClass(t));
00121 SB(_m[t].m1, 5, 2, wc);
00122 }
00123
00130 static inline bool IsTileOnWater(TileIndex t)
00131 {
00132 return (GetWaterClass(t) != WATER_CLASS_INVALID);
00133 }
00134
00141 static inline bool IsWater(TileIndex t)
00142 {
00143 return GetWaterTileType(t) == WATER_TILE_CLEAR;
00144 }
00145
00152 static inline bool IsSea(TileIndex t)
00153 {
00154 return IsWater(t) && GetWaterClass(t) == WATER_CLASS_SEA;
00155 }
00156
00163 static inline bool IsCanal(TileIndex t)
00164 {
00165 return IsWater(t) && GetWaterClass(t) == WATER_CLASS_CANAL;
00166 }
00167
00174 static inline bool IsRiver(TileIndex t)
00175 {
00176 return IsWater(t) && GetWaterClass(t) == WATER_CLASS_RIVER;
00177 }
00178
00184 static inline bool IsWaterTile(TileIndex t)
00185 {
00186 return IsTileType(t, MP_WATER) && IsWater(t);
00187 }
00188
00195 static inline bool IsCoast(TileIndex t)
00196 {
00197 return GetWaterTileType(t) == WATER_TILE_COAST;
00198 }
00199
00205 static inline bool IsCoastTile(TileIndex t)
00206 {
00207 return IsTileType(t, MP_WATER) && IsCoast(t);
00208 }
00209
00216 static inline bool IsShipDepot(TileIndex t)
00217 {
00218 return GetWaterTileType(t) == WATER_TILE_DEPOT;
00219 }
00220
00226 static inline bool IsShipDepotTile(TileIndex t)
00227 {
00228 return IsTileType(t, MP_WATER) && IsShipDepot(t);
00229 }
00230
00237 static inline Axis GetShipDepotAxis(TileIndex t)
00238 {
00239 assert(IsShipDepotTile(t));
00240 return (Axis)GB(_m[t].m5, WBL_DEPOT_AXIS, 1);
00241 }
00242
00249 static inline DepotPart GetShipDepotPart(TileIndex t)
00250 {
00251 assert(IsShipDepotTile(t));
00252 return (DepotPart)GB(_m[t].m5, WBL_DEPOT_PART, 1);
00253 }
00254
00261 static inline DiagDirection GetShipDepotDirection(TileIndex t)
00262 {
00263 return XYNSToDiagDir(GetShipDepotAxis(t), GetShipDepotPart(t));
00264 }
00265
00272 static inline TileIndex GetOtherShipDepotTile(TileIndex t)
00273 {
00274 return t + (GetShipDepotPart(t) != DEPOT_PART_NORTH ? -1 : 1) * (GetShipDepotAxis(t) != AXIS_X ? TileDiffXY(0, 1) : TileDiffXY(1, 0));
00275 }
00276
00283 static inline TileIndex GetShipDepotNorthTile(TileIndex t)
00284 {
00285 assert(IsShipDepot(t));
00286 TileIndex tile2 = GetOtherShipDepotTile(t);
00287
00288 return t < tile2 ? t : tile2;
00289 }
00290
00297 static inline bool IsLock(TileIndex t)
00298 {
00299 return GetWaterTileType(t) == WATER_TILE_LOCK;
00300 }
00301
00308 static inline DiagDirection GetLockDirection(TileIndex t)
00309 {
00310 assert(IsLock(t));
00311 return (DiagDirection)GB(_m[t].m5, WBL_LOCK_ORIENT_BEGIN, WBL_LOCK_ORIENT_COUNT);
00312 }
00313
00320 static inline byte GetLockPart(TileIndex t)
00321 {
00322 assert(IsLock(t));
00323 return GB(_m[t].m5, WBL_LOCK_PART_BEGIN, WBL_LOCK_PART_COUNT);
00324 }
00325
00332 static inline byte GetWaterTileRandomBits(TileIndex t)
00333 {
00334 assert(IsTileType(t, MP_WATER));
00335 return _m[t].m4;
00336 }
00337
00344 static inline bool HasTileWaterGround(TileIndex t)
00345 {
00346 return HasTileWaterClass(t) && IsTileOnWater(t) && !IsCoastTile(t);
00347 }
00348
00349
00354 static inline void MakeShore(TileIndex t)
00355 {
00356 SetTileType(t, MP_WATER);
00357 SetTileOwner(t, OWNER_WATER);
00358 SetWaterClass(t, WATER_CLASS_SEA);
00359 _m[t].m2 = 0;
00360 _m[t].m3 = 0;
00361 _m[t].m4 = 0;
00362 _m[t].m5 = WBL_TYPE_NORMAL << WBL_TYPE_BEGIN | 1 << WBL_COAST_FLAG;
00363 SB(_m[t].m6, 2, 4, 0);
00364 _me[t].m7 = 0;
00365 }
00366
00374 static inline void MakeWater(TileIndex t, Owner o, WaterClass wc, uint8 random_bits)
00375 {
00376 SetTileType(t, MP_WATER);
00377 SetTileOwner(t, o);
00378 SetWaterClass(t, wc);
00379 _m[t].m2 = 0;
00380 _m[t].m3 = 0;
00381 _m[t].m4 = random_bits;
00382 _m[t].m5 = WBL_TYPE_NORMAL << WBL_TYPE_BEGIN;
00383 SB(_m[t].m6, 2, 4, 0);
00384 _me[t].m7 = 0;
00385 }
00386
00391 static inline void MakeSea(TileIndex t)
00392 {
00393 MakeWater(t, OWNER_WATER, WATER_CLASS_SEA, 0);
00394 }
00395
00401 static inline void MakeRiver(TileIndex t, uint8 random_bits)
00402 {
00403 MakeWater(t, OWNER_WATER, WATER_CLASS_RIVER, random_bits);
00404 }
00405
00412 static inline void MakeCanal(TileIndex t, Owner o, uint8 random_bits)
00413 {
00414 assert(o != OWNER_WATER);
00415 MakeWater(t, o, WATER_CLASS_CANAL, random_bits);
00416 }
00417
00427 static inline void MakeShipDepot(TileIndex t, Owner o, DepotID did, DepotPart part, Axis a, WaterClass original_water_class)
00428 {
00429 SetTileType(t, MP_WATER);
00430 SetTileOwner(t, o);
00431 SetWaterClass(t, original_water_class);
00432 _m[t].m2 = did;
00433 _m[t].m3 = 0;
00434 _m[t].m4 = 0;
00435 _m[t].m5 = WBL_TYPE_DEPOT << WBL_TYPE_BEGIN | part << WBL_DEPOT_PART | a << WBL_DEPOT_AXIS;
00436 SB(_m[t].m6, 2, 4, 0);
00437 _me[t].m7 = 0;
00438 }
00439
00449 static inline void MakeLockTile(TileIndex t, Owner o, LockPart part, DiagDirection dir, WaterClass original_water_class)
00450 {
00451 SetTileType(t, MP_WATER);
00452 SetTileOwner(t, o);
00453 SetWaterClass(t, original_water_class);
00454 _m[t].m2 = 0;
00455 _m[t].m3 = 0;
00456 _m[t].m4 = 0;
00457 _m[t].m5 = WBL_TYPE_LOCK << WBL_TYPE_BEGIN | part << WBL_LOCK_PART_BEGIN | dir << WBL_LOCK_ORIENT_BEGIN;
00458 SB(_m[t].m6, 2, 4, 0);
00459 _me[t].m7 = 0;
00460 }
00461
00471 static inline void MakeLock(TileIndex t, Owner o, DiagDirection d, WaterClass wc_lower, WaterClass wc_upper, WaterClass wc_middle)
00472 {
00473 TileIndexDiff delta = TileOffsByDiagDir(d);
00474
00475
00476
00477 MakeLockTile(t, o, LOCK_PART_MIDDLE, d, wc_middle);
00478 MakeLockTile(t - delta, IsWaterTile(t - delta) ? GetTileOwner(t - delta) : o, LOCK_PART_LOWER, d, wc_lower);
00479 MakeLockTile(t + delta, IsWaterTile(t + delta) ? GetTileOwner(t + delta) : o, LOCK_PART_UPPER, d, wc_upper);
00480 }
00481
00482 #endif