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 SB(_m[t].m6, 2, 4, 0);
00150 _me[t].m7 = 0;
00151 }
00152
00153 static inline void MakeShore(TileIndex t)
00154 {
00155 SetTileType(t, MP_WATER);
00156 SetTileOwner(t, OWNER_WATER);
00157 _m[t].m2 = 0;
00158 _m[t].m3 = 0;
00159 _m[t].m4 = 0;
00160 _m[t].m5 = 1;
00161 SB(_m[t].m6, 2, 4, 0);
00162 _me[t].m7 = 0;
00163 }
00164
00165 static inline void MakeRiver(TileIndex t, uint8 random_bits)
00166 {
00167 SetTileType(t, MP_WATER);
00168 SetTileOwner(t, OWNER_WATER);
00169 _m[t].m2 = 0;
00170 _m[t].m3 = WATER_CLASS_RIVER;
00171 _m[t].m4 = random_bits;
00172 _m[t].m5 = 0;
00173 SB(_m[t].m6, 2, 4, 0);
00174 _me[t].m7 = 0;
00175 }
00176
00177 static inline void MakeCanal(TileIndex t, Owner o, uint8 random_bits)
00178 {
00179 assert(o != OWNER_WATER);
00180 SetTileType(t, MP_WATER);
00181 SetTileOwner(t, o);
00182 _m[t].m2 = 0;
00183 _m[t].m3 = WATER_CLASS_CANAL;
00184 _m[t].m4 = random_bits;
00185 _m[t].m5 = 0;
00186 SB(_m[t].m6, 2, 4, 0);
00187 _me[t].m7 = 0;
00188 }
00189
00190 static inline void MakeShipDepot(TileIndex t, Owner o, DepotPart base, Axis a, WaterClass original_water_class)
00191 {
00192 SetTileType(t, MP_WATER);
00193 SetTileOwner(t, o);
00194 _m[t].m2 = 0;
00195 _m[t].m3 = original_water_class;
00196 _m[t].m4 = 0;
00197 _m[t].m5 = base + a * 2;
00198 SB(_m[t].m6, 2, 4, 0);
00199 _me[t].m7 = 0;
00200 }
00201
00202 static inline void MakeLockTile(TileIndex t, Owner o, byte section, WaterClass original_water_class)
00203 {
00204 SetTileType(t, MP_WATER);
00205 SetTileOwner(t, o);
00206 _m[t].m2 = 0;
00207 _m[t].m3 = original_water_class;
00208 _m[t].m4 = 0;
00209 _m[t].m5 = section;
00210 SB(_m[t].m6, 2, 4, 0);
00211 _me[t].m7 = 0;
00212 }
00213
00214 static inline void MakeLock(TileIndex t, Owner o, DiagDirection d, WaterClass wc_lower, WaterClass wc_upper)
00215 {
00216 TileIndexDiff delta = TileOffsByDiagDir(d);
00217
00218 MakeLockTile(t, o, LOCK_MIDDLE + d, WATER_CLASS_CANAL);
00219 MakeLockTile(t - delta, o, LOCK_LOWER + d, wc_lower);
00220 MakeLockTile(t + delta, o, LOCK_UPPER + d, wc_upper);
00221 }
00222
00223 #endif