summaryrefslogtreecommitdiff
path: root/src/road.h
blob: e97600f1a8b8bd9aa06896201df78c61bc4759de (plain)
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/* $Id$ */

/** @file road.h */

#ifndef ROAD_H
#define ROAD_H

#include "helpers.hpp"

/**
 * The different roadtypes we support
 *
 * @note currently only ROADTYPE_ROAD and ROADTYPE_TRAM are supported.
 */
enum RoadType {
	ROADTYPE_ROAD = 0,      ///< Basic road type
	ROADTYPE_TRAM = 1,      ///< Trams
	ROADTYPE_HWAY = 2,      ///< Only a placeholder. Not sure what we are going to do with this road type.
	ROADTYPE_END,           ///< Used for iterations
	INVALID_ROADTYPE = 0xFF ///< flag for invalid roadtype
};
DECLARE_POSTFIX_INCREMENT(RoadType);

/**
 * The different roadtypes we support, but then a bitmask of them
 * @note currently only roadtypes with ROADTYPE_ROAD and ROADTYPE_TRAM are supported.
 */
enum RoadTypes {
	ROADTYPES_NONE     = 0,                                                 ///< No roadtypes
	ROADTYPES_ROAD     = 1 << ROADTYPE_ROAD,                                ///< Road
	ROADTYPES_TRAM     = 1 << ROADTYPE_TRAM,                                ///< Trams
	ROADTYPES_HWAY     = 1 << ROADTYPE_HWAY,                                ///< Highway (or whatever substitute)
	ROADTYPES_ROADTRAM = ROADTYPES_ROAD | ROADTYPES_TRAM,                   ///< Road + trams
	ROADTYPES_ROADHWAY = ROADTYPES_ROAD | ROADTYPES_HWAY,                   ///< Road + highway (or whatever substitute)
	ROADTYPES_TRAMHWAY = ROADTYPES_TRAM | ROADTYPES_HWAY,                   ///< Trams + highway (or whatever substitute)
	ROADTYPES_ALL      = ROADTYPES_ROAD | ROADTYPES_TRAM | ROADTYPES_HWAY,  ///< Road + trams + highway (or whatever substitute)
};
DECLARE_ENUM_AS_BIT_SET(RoadTypes);

/**
 * Whether the given roadtype is valid.
 * @param rt the roadtype to check for validness
 * @return true if and only if valid
 */
static inline bool IsValidRoadType(RoadType rt)
{
	return rt == ROADTYPE_ROAD || rt == ROADTYPE_TRAM;
}

/**
 * Are the given bits pointing to valid roadtypes?
 * @param rts the roadtypes to check for validness
 * @return true if and only if valid
 */
static inline bool AreValidRoadTypes(RoadTypes rts)
{
	return HASBIT(rts, ROADTYPE_ROAD) || HASBIT(rts, ROADTYPE_TRAM);
}

/**
 * Maps a RoadType to the corresponding RoadTypes value
 *
 * @param rt the roadtype to get the roadtypes from
 * @return the roadtypes with the given roadtype
 */
static inline RoadTypes RoadTypeToRoadTypes(RoadType rt)
{
	return (RoadTypes)(1 << rt);
}

/**
 * Returns the RoadTypes which are not present in the given RoadTypes
 *
 * This function returns the complement of a given RoadTypes.
 *
 * @param r The given RoadTypes
 * @return The complement of the given RoadTypes
 * @note The unused value ROADTYPES_HWAY will be used, too.
 */
static inline RoadTypes ComplementRoadTypes(RoadTypes r)
{
	return (RoadTypes)(ROADTYPES_ALL ^ r);
}

/**
 * Enumeration for the road parts on a tile.
 *
 * This enumeration defines the possible road parts which
 * can be build on a tile.
 */
enum RoadBits {
	ROAD_NONE = 0U,                  ///< No road-part is build
	ROAD_NW   = 1U,                  ///< North-west part
	ROAD_SW   = 2U,                  ///< South-west part
	ROAD_SE   = 4U,                  ///< South-east part
	ROAD_NE   = 8U,                  ///< North-east part
	ROAD_X    = ROAD_SW | ROAD_NE,   ///< Full road along the x-axis (south-west + north-east)
	ROAD_Y    = ROAD_NW | ROAD_SE,   ///< Full road along the y-axis (north-west + south-east)
	ROAD_ALL  = ROAD_X  | ROAD_Y     ///< Full 4-way crossing
};

DECLARE_ENUM_AS_BIT_SET(RoadBits);

/**
 * Calculate the complement of a RoadBits value
 *
 * Simply flips all bits in the RoadBits value to get the complement
 * of the RoadBits.
 *
 * @param r The given RoadBits value
 * @return the complement
 */
static inline RoadBits ComplementRoadBits(RoadBits r)
{
	return (RoadBits)(ROAD_ALL ^ r);
}

/**
 * Calculate the mirrored RoadBits
 *
 * Simply move the bits to their new position.
 *
 * @param r The given RoadBits value
 * @return the mirrored
 */
static inline RoadBits MirrorRoadBits(RoadBits r)
{
	return (RoadBits)(GB(r, 0, 2) << 2 | GB(r, 2, 2));
}

/**
 * Calculate rotated RoadBits
 *
 * Move the Roadbits clockwise til they are in their final position.
 *
 * @param r The given RoadBits value
 * @param rot The given Rotation angle
 * @return the rotated
 */
static inline RoadBits RotateRoadBits(RoadBits r, DiagDirDiff rot)
{
	for (; rot > (DiagDirDiff)0; rot--){
		r = (RoadBits)(GB(r, 0, 1) << 3 | GB(r, 1, 3));
	}
	return r;
}

/**
 * Create the road-part which belongs to the given DiagDirection
 *
 * This function returns a RoadBits value which belongs to
 * the given DiagDirection.
 *
 * @param d The DiagDirection
 * @return The result RoadBits which the selected road-part set
 */
static inline RoadBits DiagDirToRoadBits(DiagDirection d)
{
	return (RoadBits)(ROAD_NW << (3 ^ d));
}

/**
 * Return if the tile is a valid tile for a crossing.
 *
 * @note function is overloaded
 * @param tile the curent tile
 * @param ax the axis of the road over the rail
 * @return true if it is a valid tile
 */
bool IsPossibleCrossing(const TileIndex tile, Axis ax);

/**
 * Checks whether the trackdir means that we are reversing.
 * @param dir the trackdir to check
 * @return true if it is a reversing road trackdir
 */
static inline bool IsReversingRoadTrackdir(Trackdir dir)
{
	return (dir & 0x07) >= 6;
}

/**
 * Checks whether the given trackdir is a straight road
 * @param dir the trackdir to check
 * @return true if it is a straight road trackdir
 */
static inline bool IsStraightRoadTrackdir(Trackdir dir)
{
	return (dir & 0x06) == 0;
}

/**
 * Clean up unneccesary RoadBits of a planed tile.
 * @param tile current tile
 * @param org_rb planed RoadBits
 * @return optimised RoadBits
 */
RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb);

/**
 * Is it allowed to remove the given road bits from the given tile?
 * @param tile      the tile to remove the road from
 * @param remove    the roadbits that are going to be removed
 * @param owner     the actual owner of the roadbits of the tile
 * @param edge_road are the removed bits from a town?
 * @param rt        the road type to remove the bits from
 * @return true when it is allowed to remove the road bits
 */
bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *edge_road, RoadType rt);

/**
 * Draw the catenary for tram road bits
 * @param ti   information about the tile (position, slope)
 * @param tram the roadbits to draw the catenary for
 */
void DrawTramCatenary(TileInfo *ti, RoadBits tram);

#endif /* ROAD_H */