1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
/* $Id$ */
/** @file water_map.h */
#ifndef WATER_MAP_H
#define WATER_MAP_H
enum WaterTileType {
WATER_TILE_CLEAR,
WATER_TILE_COAST,
WATER_TILE_LOCK,
WATER_TILE_DEPOT,
};
enum DepotPart {
DEPOT_NORTH = 0x80,
DEPOT_SOUTH = 0x81,
DEPOT_END = 0x84,
};
enum LockPart {
LOCK_MIDDLE = 0x10,
LOCK_LOWER = 0x14,
LOCK_UPPER = 0x18,
LOCK_END = 0x1C
};
static inline WaterTileType GetWaterTileType(TileIndex t)
{
assert(IsTileType(t, MP_WATER));
if (_m[t].m5 == 0) return WATER_TILE_CLEAR;
if (_m[t].m5 == 1) return WATER_TILE_COAST;
if (IsInsideMM(_m[t].m5, LOCK_MIDDLE, LOCK_END)) return WATER_TILE_LOCK;
assert(IsInsideMM(_m[t].m5, DEPOT_NORTH, DEPOT_END));
return WATER_TILE_DEPOT;
}
/** IsWater return true if any type of clear water like ocean, river, canal */
static inline bool IsWater(TileIndex t)
{
return GetWaterTileType(t) == WATER_TILE_CLEAR;
}
static inline bool IsSea(TileIndex t)
{
if (GetWaterTileType(t) != WATER_TILE_CLEAR) return false;
if (!IsTileOwner(t, OWNER_WATER)) return false; // 'Human' built water = canal, not sea
return true;
}
static inline bool IsCoast(TileIndex t)
{
return GetWaterTileType(t) == WATER_TILE_COAST;
}
static inline bool IsCanal(TileIndex t)
{
return GetWaterTileType(t) == WATER_TILE_CLEAR && GetTileOwner(t) != OWNER_WATER;
}
static inline bool IsWaterTile(TileIndex t)
{
return IsTileType(t, MP_WATER) && IsWater(t);
}
static inline TileIndex GetOtherShipDepotTile(TileIndex t)
{
return t + (HasBit(_m[t].m5, 0) ? -1 : 1) * (HasBit(_m[t].m5, 1) ? TileDiffXY(0, 1) : TileDiffXY(1, 0));
}
static inline TileIndex IsShipDepot(TileIndex t)
{
return IsInsideMM(_m[t].m5, DEPOT_NORTH, DEPOT_END);
}
static inline Axis GetShipDepotAxis(TileIndex t)
{
return (Axis)GB(_m[t].m5, 1, 1);
}
static inline DiagDirection GetShipDepotDirection(TileIndex t)
{
return XYNSToDiagDir(GetShipDepotAxis(t), GB(_m[t].m5, 0, 1));
}
static inline DiagDirection GetLockDirection(TileIndex t)
{
return (DiagDirection)GB(_m[t].m5, 0, 2);
}
static inline byte GetSection(TileIndex t)
{
assert(GetWaterTileType(t) == WATER_TILE_LOCK || GetWaterTileType(t) == WATER_TILE_DEPOT);
return GB(_m[t].m5, 0, 4);
}
static inline void MakeWater(TileIndex t)
{
SetTileType(t, MP_WATER);
SetTileOwner(t, OWNER_WATER);
_m[t].m2 = 0;
_m[t].m3 = 0;
_m[t].m4 = 0;
_m[t].m5 = 0;
}
static inline void MakeShore(TileIndex t)
{
SetTileType(t, MP_WATER);
SetTileOwner(t, OWNER_WATER);
_m[t].m2 = 0;
_m[t].m3 = 0;
_m[t].m4 = 0;
_m[t].m5 = 1;
}
static inline void MakeCanal(TileIndex t, Owner o)
{
assert(o != OWNER_WATER);
SetTileType(t, MP_WATER);
SetTileOwner(t, o);
_m[t].m2 = 0;
_m[t].m3 = 0;
_m[t].m4 = 0;
_m[t].m5 = 0;
}
static inline void MakeShipDepot(TileIndex t, Owner o, DepotPart base, Axis a)
{
SetTileType(t, MP_WATER);
SetTileOwner(t, o);
_m[t].m2 = 0;
_m[t].m3 = 0;
_m[t].m4 = 0;
_m[t].m5 = base + a * 2;
}
static inline void MakeLockTile(TileIndex t, Owner o, byte section)
{
SetTileType(t, MP_WATER);
SetTileOwner(t, o);
_m[t].m2 = 0;
_m[t].m3 = 0;
_m[t].m4 = 0;
_m[t].m5 = section;
}
static inline void MakeLock(TileIndex t, Owner o, DiagDirection d)
{
TileIndexDiff delta = TileOffsByDiagDir(d);
MakeLockTile(t, o, LOCK_MIDDLE + d);
MakeLockTile(t - delta, o, LOCK_LOWER + d);
MakeLockTile(t + delta, o, LOCK_UPPER + d);
}
#endif /* WATER_MAP_H */
|