tron@3111: /* $Id$ */ tron@3111: rubidium@9111: /** @file water_map.h Map accessors for water tiles. */ belugas@6432: tron@3111: #ifndef WATER_MAP_H tron@3111: #define WATER_MAP_H tron@3111: rubidium@6248: enum WaterTileType { rubidium@6181: WATER_TILE_CLEAR, rubidium@6181: WATER_TILE_COAST, rubidium@6181: WATER_TILE_LOCK, rubidium@6181: WATER_TILE_DEPOT, peter1138@8471: }; peter1138@8471: peter1138@8471: enum WaterClass { peter1138@8471: WATER_CLASS_SEA, peter1138@8471: WATER_CLASS_CANAL, peter1138@8471: WATER_CLASS_RIVER, frosch@9718: WATER_CLASS_INVALID, ///< Used for industry tiles on land (also for oilrig if newgrf says so) rubidium@6248: }; celestar@3402: rubidium@6248: enum DepotPart { celestar@3372: DEPOT_NORTH = 0x80, celestar@3373: DEPOT_SOUTH = 0x81, celestar@3373: DEPOT_END = 0x84, rubidium@6248: }; celestar@3372: rubidium@6248: enum LockPart { celestar@3372: LOCK_MIDDLE = 0x10, celestar@3372: LOCK_LOWER = 0x14, celestar@3402: LOCK_UPPER = 0x18, celestar@3402: LOCK_END = 0x1C rubidium@6248: }; celestar@3372: celestar@3402: static inline WaterTileType GetWaterTileType(TileIndex t) celestar@3373: { rubidium@7739: assert(IsTileType(t, MP_WATER)); rubidium@7739: rubidium@6181: if (_m[t].m5 == 0) return WATER_TILE_CLEAR; rubidium@6181: if (_m[t].m5 == 1) return WATER_TILE_COAST; skidd13@7954: if (IsInsideMM(_m[t].m5, LOCK_MIDDLE, LOCK_END)) return WATER_TILE_LOCK; celestar@3402: skidd13@7954: assert(IsInsideMM(_m[t].m5, DEPOT_NORTH, DEPOT_END)); rubidium@6181: return WATER_TILE_DEPOT; celestar@3402: } celestar@3402: peter1138@8471: static inline WaterClass GetWaterClass(TileIndex t) peter1138@8471: { frosch@9718: assert(IsTileType(t, MP_WATER) || IsTileType(t, MP_STATION) || IsTileType(t, MP_INDUSTRY)); frosch@9718: return (WaterClass)(IsTileType(t, MP_INDUSTRY) ? GB(_m[t].m1, 5, 2) : GB(_m[t].m3, 0, 2)); peter1138@8471: } peter1138@8471: peter1138@8471: static inline void SetWaterClass(TileIndex t, WaterClass wc) peter1138@8471: { frosch@9718: assert(IsTileType(t, MP_WATER) || IsTileType(t, MP_STATION) || IsTileType(t, MP_INDUSTRY)); frosch@9718: if (IsTileType(t, MP_INDUSTRY)) { frosch@9718: SB(_m[t].m1, 5, 2, wc); frosch@9718: } else { frosch@9718: SB(_m[t].m3, 0, 2, wc); frosch@9718: } peter1138@8471: } peter1138@8471: rubidium@7739: /** IsWater return true if any type of clear water like ocean, river, canal */ celestar@3402: static inline bool IsWater(TileIndex t) celestar@3402: { rubidium@6181: return GetWaterTileType(t) == WATER_TILE_CLEAR; celestar@3402: } celestar@3402: rubidium@7739: static inline bool IsSea(TileIndex t) rubidium@7739: { peter1138@8471: return IsWater(t) && GetWaterClass(t) == WATER_CLASS_SEA; celestar@3423: } celestar@3423: rubidium@6974: static inline bool IsCanal(TileIndex t) rubidium@6974: { peter1138@8471: return IsWater(t) && GetWaterClass(t) == WATER_CLASS_CANAL; rubidium@6974: } rubidium@6974: peter1138@8360: static inline bool IsRiver(TileIndex t) peter1138@8360: { peter1138@8471: return IsWater(t) && GetWaterClass(t) == WATER_CLASS_RIVER; peter1138@8360: } peter1138@8360: rubidium@7739: static inline bool IsWaterTile(TileIndex t) celestar@3402: { rubidium@7739: return IsTileType(t, MP_WATER) && IsWater(t); celestar@3373: } celestar@3373: peter1138@8471: static inline bool IsCoast(TileIndex t) peter1138@8383: { peter1138@8471: return GetWaterTileType(t) == WATER_TILE_COAST; peter1138@8383: } peter1138@8383: celestar@3373: static inline TileIndex GetOtherShipDepotTile(TileIndex t) celestar@3373: { skidd13@7928: return t + (HasBit(_m[t].m5, 0) ? -1 : 1) * (HasBit(_m[t].m5, 1) ? TileDiffXY(0, 1) : TileDiffXY(1, 0)); celestar@3373: } celestar@3373: belugas@8966: static inline bool IsShipDepot(TileIndex t) celestar@3373: { skidd13@7954: return IsInsideMM(_m[t].m5, DEPOT_NORTH, DEPOT_END); celestar@3373: } celestar@3373: belugas@8966: static inline bool IsShipDepotTile(TileIndex t) smatz@8954: { smatz@8954: return IsTileType(t, MP_WATER) && IsShipDepot(t); smatz@8954: } smatz@8954: celestar@3423: static inline Axis GetShipDepotAxis(TileIndex t) celestar@3423: { celestar@3423: return (Axis)GB(_m[t].m5, 1, 1); celestar@3423: } celestar@3423: tron@3953: static inline DiagDirection GetShipDepotDirection(TileIndex t) tron@3953: { tron@3953: return XYNSToDiagDir(GetShipDepotAxis(t), GB(_m[t].m5, 0, 1)); tron@3953: } tron@3953: frosch@8495: static inline bool IsLock(TileIndex t) rubidium@8029: { frosch@8495: return IsInsideMM(_m[t].m5, LOCK_MIDDLE, LOCK_END); rubidium@8029: } rubidium@8029: celestar@3373: static inline DiagDirection GetLockDirection(TileIndex t) celestar@3373: { celestar@3373: return (DiagDirection)GB(_m[t].m5, 0, 2); celestar@3373: } celestar@3373: celestar@3425: static inline byte GetSection(TileIndex t) celestar@3425: { rubidium@6181: assert(GetWaterTileType(t) == WATER_TILE_LOCK || GetWaterTileType(t) == WATER_TILE_DEPOT); celestar@3425: return GB(_m[t].m5, 0, 4); celestar@3425: } celestar@3425: peter1138@8368: static inline byte GetWaterTileRandomBits(TileIndex t) peter1138@8368: { peter1138@8368: return _m[t].m4; peter1138@8368: } peter1138@8368: celestar@3373: tron@3111: static inline void MakeWater(TileIndex t) tron@3111: { tron@3111: SetTileType(t, MP_WATER); tron@3111: SetTileOwner(t, OWNER_WATER); tron@3111: _m[t].m2 = 0; peter1138@8471: _m[t].m3 = WATER_CLASS_SEA; tron@3111: _m[t].m4 = 0; tron@3111: _m[t].m5 = 0; tron@3111: } tron@3111: tron@3111: static inline void MakeShore(TileIndex t) tron@3111: { tron@3111: SetTileType(t, MP_WATER); tron@3111: SetTileOwner(t, OWNER_WATER); tron@3111: _m[t].m2 = 0; tron@3111: _m[t].m3 = 0; tron@3111: _m[t].m4 = 0; tron@3111: _m[t].m5 = 1; tron@3111: } tron@3111: peter1138@8368: static inline void MakeRiver(TileIndex t, uint8 random_bits) peter1138@8360: { peter1138@8360: SetTileType(t, MP_WATER); peter1138@8360: SetTileOwner(t, OWNER_WATER); peter1138@8360: _m[t].m2 = 0; peter1138@8471: _m[t].m3 = WATER_CLASS_RIVER; peter1138@8368: _m[t].m4 = random_bits; peter1138@8471: _m[t].m5 = 0; peter1138@8360: } peter1138@8360: peter1138@8368: static inline void MakeCanal(TileIndex t, Owner o, uint8 random_bits) peter1138@3940: { rubidium@7739: assert(o != OWNER_WATER); peter1138@3940: SetTileType(t, MP_WATER); peter1138@3940: SetTileOwner(t, o); peter1138@3940: _m[t].m2 = 0; peter1138@8471: _m[t].m3 = WATER_CLASS_CANAL; peter1138@8368: _m[t].m4 = random_bits; peter1138@3940: _m[t].m5 = 0; peter1138@3940: } peter1138@3940: frosch@8495: static inline void MakeShipDepot(TileIndex t, Owner o, DepotPart base, Axis a, WaterClass original_water_class) celestar@3372: { celestar@3372: SetTileType(t, MP_WATER); celestar@3372: SetTileOwner(t, o); celestar@3372: _m[t].m2 = 0; peter1138@8471: _m[t].m3 = original_water_class; frosch@8495: _m[t].m4 = 0; celestar@3372: _m[t].m5 = base + a * 2; celestar@3372: } celestar@3372: peter1138@8471: static inline void MakeLockTile(TileIndex t, Owner o, byte section, WaterClass original_water_class) celestar@3372: { celestar@3372: SetTileType(t, MP_WATER); peter1138@3940: SetTileOwner(t, o); celestar@3372: _m[t].m2 = 0; peter1138@8471: _m[t].m3 = original_water_class; celestar@3372: _m[t].m4 = 0; celestar@3372: _m[t].m5 = section; celestar@3372: } celestar@3372: peter1138@8471: static inline void MakeLock(TileIndex t, Owner o, DiagDirection d, WaterClass wc_lower, WaterClass wc_upper) celestar@3372: { Darkvater@4559: TileIndexDiff delta = TileOffsByDiagDir(d); celestar@3372: peter1138@8471: MakeLockTile(t, o, LOCK_MIDDLE + d, WATER_CLASS_CANAL); peter1138@8471: MakeLockTile(t - delta, o, LOCK_LOWER + d, wc_lower); peter1138@8471: MakeLockTile(t + delta, o, LOCK_UPPER + d, wc_upper); celestar@3372: } celestar@3372: peter1138@4666: #endif /* WATER_MAP_H */