00001
00002
00005 #ifndef WATER_MAP_H
00006 #define WATER_MAP_H
00007
00008 enum WaterTileType {
00009 WATER_TILE_CLEAR,
00010 WATER_TILE_COAST,
00011 WATER_TILE_LOCK,
00012 WATER_TILE_DEPOT,
00013 };
00014
00015 enum WaterClass {
00016 WATER_CLASS_SEA,
00017 WATER_CLASS_CANAL,
00018 WATER_CLASS_RIVER,
00019 WATER_CLASS_INVALID,
00020 };
00021
00022 enum DepotPart {
00023 DEPOT_NORTH = 0x80,
00024 DEPOT_SOUTH = 0x81,
00025 DEPOT_END = 0x84,
00026 };
00027
00028 enum LockPart {
00029 LOCK_MIDDLE = 0x10,
00030 LOCK_LOWER = 0x14,
00031 LOCK_UPPER = 0x18,
00032 LOCK_END = 0x1C
00033 };
00034
00035 static inline WaterTileType GetWaterTileType(TileIndex t)
00036 {
00037 assert(IsTileType(t, MP_WATER));
00038
00039 if (_m[t].m5 == 0) return WATER_TILE_CLEAR;
00040 if (_m[t].m5 == 1) return WATER_TILE_COAST;
00041 if (IsInsideMM(_m[t].m5, LOCK_MIDDLE, LOCK_END)) return WATER_TILE_LOCK;
00042
00043 assert(IsInsideMM(_m[t].m5, DEPOT_NORTH, DEPOT_END));
00044 return WATER_TILE_DEPOT;
00045 }
00046
00047 static inline WaterClass GetWaterClass(TileIndex t)
00048 {
00049 assert(IsTileType(t, MP_WATER) || IsTileType(t, MP_STATION) || IsTileType(t, MP_INDUSTRY));
00050 return (WaterClass)(IsTileType(t, MP_INDUSTRY) ? GB(_m[t].m1, 5, 2) : GB(_m[t].m3, 0, 2));
00051 }
00052
00053 static inline void SetWaterClass(TileIndex t, WaterClass wc)
00054 {
00055 assert(IsTileType(t, MP_WATER) || IsTileType(t, MP_STATION) || IsTileType(t, MP_INDUSTRY));
00056 if (IsTileType(t, MP_INDUSTRY)) {
00057 SB(_m[t].m1, 5, 2, wc);
00058 } else {
00059 SB(_m[t].m3, 0, 2, wc);
00060 }
00061 }
00062
00064 static inline bool IsWater(TileIndex t)
00065 {
00066 return GetWaterTileType(t) == WATER_TILE_CLEAR;
00067 }
00068
00069 static inline bool IsSea(TileIndex t)
00070 {
00071 return IsWater(t) && GetWaterClass(t) == WATER_CLASS_SEA;
00072 }
00073
00074 static inline bool IsCanal(TileIndex t)
00075 {
00076 return IsWater(t) && GetWaterClass(t) == WATER_CLASS_CANAL;
00077 }
00078
00079 static inline bool IsRiver(TileIndex t)
00080 {
00081 return IsWater(t) && GetWaterClass(t) == WATER_CLASS_RIVER;
00082 }
00083
00084 static inline bool IsWaterTile(TileIndex t)
00085 {
00086 return IsTileType(t, MP_WATER) && IsWater(t);
00087 }
00088
00089 static inline bool IsCoast(TileIndex t)
00090 {
00091 return GetWaterTileType(t) == WATER_TILE_COAST;
00092 }
00093
00094 static inline TileIndex GetOtherShipDepotTile(TileIndex t)
00095 {
00096 return t + (HasBit(_m[t].m5, 0) ? -1 : 1) * (HasBit(_m[t].m5, 1) ? TileDiffXY(0, 1) : TileDiffXY(1, 0));
00097 }
00098
00099 static inline bool IsShipDepot(TileIndex t)
00100 {
00101 return IsInsideMM(_m[t].m5, DEPOT_NORTH, DEPOT_END);
00102 }
00103
00104 static inline bool IsShipDepotTile(TileIndex t)
00105 {
00106 return IsTileType(t, MP_WATER) && IsShipDepot(t);
00107 }
00108
00109 static inline Axis GetShipDepotAxis(TileIndex t)
00110 {
00111 return (Axis)GB(_m[t].m5, 1, 1);
00112 }
00113
00114 static inline DiagDirection GetShipDepotDirection(TileIndex t)
00115 {
00116 return XYNSToDiagDir(GetShipDepotAxis(t), GB(_m[t].m5, 0, 1));
00117 }
00118
00119 static inline bool IsLock(TileIndex t)
00120 {
00121 return IsInsideMM(_m[t].m5, LOCK_MIDDLE, LOCK_END);
00122 }
00123
00124 static inline DiagDirection GetLockDirection(TileIndex t)
00125 {
00126 return (DiagDirection)GB(_m[t].m5, 0, 2);
00127 }
00128
00129 static inline byte GetSection(TileIndex t)
00130 {
00131 assert(GetWaterTileType(t) == WATER_TILE_LOCK || GetWaterTileType(t) == WATER_TILE_DEPOT);
00132 return GB(_m[t].m5, 0, 4);
00133 }
00134
00135 static inline byte GetWaterTileRandomBits(TileIndex t)
00136 {
00137 return _m[t].m4;
00138 }
00139
00140
00141 static inline void MakeWater(TileIndex t)
00142 {
00143 SetTileType(t, MP_WATER);
00144 SetTileOwner(t, OWNER_WATER);
00145 _m[t].m2 = 0;
00146 _m[t].m3 = WATER_CLASS_SEA;
00147 _m[t].m4 = 0;
00148 _m[t].m5 = 0;
00149 }
00150
00151 static inline void MakeShore(TileIndex t)
00152 {
00153 SetTileType(t, MP_WATER);
00154 SetTileOwner(t, OWNER_WATER);
00155 _m[t].m2 = 0;
00156 _m[t].m3 = 0;
00157 _m[t].m4 = 0;
00158 _m[t].m5 = 1;
00159 }
00160
00161 static inline void MakeRiver(TileIndex t, uint8 random_bits)
00162 {
00163 SetTileType(t, MP_WATER);
00164 SetTileOwner(t, OWNER_WATER);
00165 _m[t].m2 = 0;
00166 _m[t].m3 = WATER_CLASS_RIVER;
00167 _m[t].m4 = random_bits;
00168 _m[t].m5 = 0;
00169 }
00170
00171 static inline void MakeCanal(TileIndex t, Owner o, uint8 random_bits)
00172 {
00173 assert(o != OWNER_WATER);
00174 SetTileType(t, MP_WATER);
00175 SetTileOwner(t, o);
00176 _m[t].m2 = 0;
00177 _m[t].m3 = WATER_CLASS_CANAL;
00178 _m[t].m4 = random_bits;
00179 _m[t].m5 = 0;
00180 }
00181
00182 static inline void MakeShipDepot(TileIndex t, Owner o, DepotPart base, Axis a, WaterClass original_water_class)
00183 {
00184 SetTileType(t, MP_WATER);
00185 SetTileOwner(t, o);
00186 _m[t].m2 = 0;
00187 _m[t].m3 = original_water_class;
00188 _m[t].m4 = 0;
00189 _m[t].m5 = base + a * 2;
00190 }
00191
00192 static inline void MakeLockTile(TileIndex t, Owner o, byte section, WaterClass original_water_class)
00193 {
00194 SetTileType(t, MP_WATER);
00195 SetTileOwner(t, o);
00196 _m[t].m2 = 0;
00197 _m[t].m3 = original_water_class;
00198 _m[t].m4 = 0;
00199 _m[t].m5 = section;
00200 }
00201
00202 static inline void MakeLock(TileIndex t, Owner o, DiagDirection d, WaterClass wc_lower, WaterClass wc_upper)
00203 {
00204 TileIndexDiff delta = TileOffsByDiagDir(d);
00205
00206 MakeLockTile(t, o, LOCK_MIDDLE + d, WATER_CLASS_CANAL);
00207 MakeLockTile(t - delta, o, LOCK_LOWER + d, wc_lower);
00208 MakeLockTile(t + delta, o, LOCK_UPPER + d, wc_upper);
00209 }
00210
00211 #endif