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