# water_map.h

Go to the documentation of this file.

    00001 /* $Id$ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
    00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    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   /* Keep the current waterclass and owner for the tiles.
    00476    * It allows to restore them after the lock is deleted */
    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 /* WATER_MAP_H */