1
/* $Id: ai_rail.hpp 15519 2009-02-19 07:40:08Z yexo $ */
3
/** @file ai_rail.hpp Everything to query and build rails. */
8
#include "ai_object.hpp"
9
#include "ai_error.hpp"
10
#include "ai_tile.hpp"
13
* Class that handles all rail related functions.
15
class AIRail : public AIObject {
17
static const char *GetClassName() { return "AIRail"; }
20
* All rail related error messages.
23
/** Base for rail building / maintaining errors */
24
ERR_RAIL_BASE = AIError::ERR_CAT_RAIL << AIError::ERR_CAT_BIT_SIZE,
26
/** One-way roads cannot have crossings */
27
ERR_CROSSING_ON_ONEWAY_ROAD, // [STR_ERR_CROSSING_ON_ONEWAY_ROAD]
29
/** Track not suitable for signals */
30
ERR_UNSUITABLE_TRACK, // [STR_1005_NO_SUITABLE_RAILROAD_TRACK]
32
/** Non-uniform stations is diabled */
33
ERR_NONUNIFORM_STATIONS_DISABLED, // [STR_NONUNIFORM_STATIONS_DISALLOWED]
37
* Types of rail known to the game.
40
/* Note: the values _are_ important as they represent an in-game value */
41
RAILTYPE_INVALID = 0xFF, //!< Invalid RailType.
45
* A bitmap with all possible rail tracks on a tile.
48
/* Note: the values _are_ important as they represent an in-game value */
49
RAILTRACK_NE_SW = 1 << 0, //!< Track along the x-axis (north-east to south-west).
50
RAILTRACK_NW_SE = 1 << 1, //!< Track along the y-axis (north-west to south-east).
51
RAILTRACK_NW_NE = 1 << 2, //!< Track in the upper corner of the tile (north).
52
RAILTRACK_SW_SE = 1 << 3, //!< Track in the lower corner of the tile (south).
53
RAILTRACK_NW_SW = 1 << 4, //!< Track in the left corner of the tile (west).
54
RAILTRACK_NE_SE = 1 << 5, //!< Track in the right corner of the tile (east).
55
RAILTRACK_INVALID = 0xFF, //!< Flag for an invalid track.
59
* Types of signal known to the game.
62
/* Note: the values _are_ important as they represent an in-game value */
63
SIGNALTYPE_NORMAL = 0, //!< Normal signal.
64
SIGNALTYPE_ENTRY = 1, //!< Entry presignal.
65
SIGNALTYPE_EXIT = 2, //!< Exit signal.
66
SIGNALTYPE_COMBO = 3, //!< Combo signal.
67
SIGNALTYPE_PBS = 4, //!< Normal PBS signal.
68
SIGNALTYPE_PBS_ONEWAY = 5, //!< No-entry PBS signal.
69
SIGNALTYPE_TWOWAY = 8, //!< Bit mask for twoway signal.
70
SIGNALTYPE_NORMAL_TWOWAY = SIGNALTYPE_NORMAL | SIGNALTYPE_TWOWAY, //!< Normal twoway signal.
71
SIGNALTYPE_ENTRY_TWOWAY = SIGNALTYPE_ENTRY | SIGNALTYPE_TWOWAY, //!< Entry twoway signal.
72
SIGNALTYPE_EXIT_TWOWAY = SIGNALTYPE_EXIT | SIGNALTYPE_TWOWAY, //!< Exit twoway signal.
73
SIGNALTYPE_COMBO_TWOWAY = SIGNALTYPE_COMBO | SIGNALTYPE_TWOWAY, //!< Combo twoway signal.
74
SIGNALTYPE_NONE = 0xFF, //!< No signal.
78
* Checks whether the given tile is actually a tile with rail that can be
79
* used to traverse a tile. This excludes rail depots but includes
80
* stations and waypoints.
81
* @param tile The tile to check.
82
* @pre AIMap::IsValidTile(tile).
83
* @return True if and only if the tile has rail.
85
static bool IsRailTile(TileIndex tile);
88
* Checks whether there is a road / rail crossing on a tile.
89
* @param tile The tile to check.
90
* @return True if and only if there is a road / rail crossing.
92
static bool IsLevelCrossingTile(TileIndex tile);
95
* Checks whether the given tile is actually a tile with a rail depot.
96
* @param tile The tile to check.
97
* @pre AIMap::IsValidTile(tile).
98
* @return True if and only if the tile has a rail depot.
100
static bool IsRailDepotTile(TileIndex tile);
103
* Checks whether the given tile is actually a tile with a rail station.
104
* @param tile The tile to check.
105
* @pre AIMap::IsValidTile(tile).
106
* @return True if and only if the tile has a rail station.
108
static bool IsRailStationTile(TileIndex tile);
111
* Checks whether the given tile is actually a tile with a rail waypoint.
112
* @param tile The tile to check.
113
* @pre AIMap::IsValidTile(tile).
114
* @return True if and only if the tile has a rail waypoint.
116
static bool IsRailWaypointTile(TileIndex tile);
119
* Check if a given RailType is available.
120
* @param rail_type The RailType to check for.
121
* @return True if this RailType can be used.
123
static bool IsRailTypeAvailable(RailType rail_type);
126
* Get the current RailType set for all AIRail functions.
127
* @return The RailType currently set.
129
static RailType GetCurrentRailType();
132
* Set the RailType for all further AIRail functions.
133
* @param rail_type The RailType to set.
135
static void SetCurrentRailType(RailType rail_type);
138
* Check if a train build for a rail type can run on another rail type.
139
* @param engine_rail_type The rail type the train is build for.
140
* @param track_rail_type The type you want to check.
141
* @pre AIRail::IsRailTypeAvailable(engine_rail_type).
142
* @pre AIRail::IsRailTypeAvailable(track_rail_type).
143
* @return Whether a train build for 'engine_rail_type' can run on 'track_rail_type'.
144
* @note Even if a train can run on a RailType that doesn't mean that it'll be
145
* able to power the train. Use TrainHasPowerOnRail for that.
147
static bool TrainCanRunOnRail(AIRail::RailType engine_rail_type, AIRail::RailType track_rail_type);
150
* Check if a train build for a rail type has power on another rail type.
151
* @param engine_rail_type The rail type the train is build for.
152
* @param track_rail_type The type you want to check.
153
* @pre AIRail::IsRailTypeAvailable(engine_rail_type).
154
* @pre AIRail::IsRailTypeAvailable(track_rail_type).
155
* @return Whether a train build for 'engine_rail_type' has power on 'track_rail_type'.
157
static bool TrainHasPowerOnRail(AIRail::RailType engine_rail_type, AIRail::RailType track_rail_type);
160
* Get the RailType that is used on a tile.
161
* @param tile The tile to check.
162
* @pre AITile::HasTransportType(tile, AITile.TRANSPORT_RAIL).
163
* @return The RailType that is used on a tile.
165
static RailType GetRailType(TileIndex tile);
168
* Convert the tracks on all tiles within a rectangle to another RailType.
169
* @param start_tile One corner of the rectangle.
170
* @param end_tile The opposite corner of the rectangle.
171
* @param convert_to The RailType you want to convert the rails to.
172
* @pre AIMap::IsValidTile(start_tile).
173
* @pre AIMap::IsValidTile(end_tile).
174
* @pre IsRailTypeAvailable(convert_to).
175
* @exception AIRail::ERR_UNSUITABLE_TRACK
176
* @return Whether at least some rail has been converted succesfully.
178
static bool ConvertRailType(TileIndex start_tile, TileIndex end_tile, AIRail::RailType convert_to);
181
* Gets the tile in front of a rail depot.
182
* @param depot The rail depot tile.
183
* @pre IsRailDepotTile(depot).
184
* @return The tile in front of the depot.
186
static TileIndex GetRailDepotFrontTile(TileIndex depot);
189
* Gets the direction of a rail station tile.
190
* @param tile The rail station tile.
191
* @pre IsRailStationTile(tile).
192
* @return The direction of the station (either RAILTRACK_NE_SW or RAILTRACK_NW_SE).
194
static RailTrack GetRailStationDirection(TileIndex tile);
197
* Builds a rail depot.
198
* @param tile Place to build the depot.
199
* @param front The tile exactly in front of the depot.
200
* @pre AIMap::IsValidTile(tile).
201
* @pre AIMap::IsValidTile(front).
202
* @pre 'tile' is not equal to 'front', but in a straight line of it.
203
* @pre IsRailTypeAvailable(GetCurrentRailType()).
204
* @exception AIError::ERR_FLAT_LAND_REQUIRED
205
* @exception AIError::ERR_AREA_NOT_CLEAR
206
* @return Whether the rail depot has been/can be build or not.
208
static bool BuildRailDepot(TileIndex tile, TileIndex front);
211
* Build a rail station.
212
* @param tile Place to build the station.
213
* @param direction The direction to build the station.
214
* @param num_platforms The number of platforms to build.
215
* @param platform_length The length of each platform.
216
* @param station_id The station to join, AIStation::STATION_NEW or AIStation::STATION_JOIN_ADJACENT.
217
* @pre IsRailTypeAvailable(GetCurrentRailType()).
218
* @pre AIMap::IsValidTile(tile).
219
* @pre direction == RAILTRACK_NW_SE || direction == RAILTRACK_NE_SW.
220
* @pre num_platforms > 0 && num_platforms <= 255.
221
* @pre platform_length > 0 && platform_length <= 255.
222
* @pre station_id == AIStation::STATION_NEW || station_id == AIStation::STATION_JOIN_ADJACENT || AIStation::IsValidStation(station_id).
223
* @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
224
* @exception AIError::ERR_AREA_NOT_CLEAR
225
* @exception AIError::ERR_FLAT_LAND_REQUIRED
226
* @exception AIStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION
227
* @exception AIStation::ERR_STATION_TOO_MANY_STATIONS
228
* @exception AIStation::ERR_STATION_TOO_MANY_STATIONS_IN_TOWN
229
* @return Whether the station has been/can be build or not.
231
static bool BuildRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id);
234
* Build a NewGRF rail station. This calls callback 18 to let a NewGRF
235
* provide the station class / id to build, so we don't end up with
236
* only the default stations on the map.
237
* @param tile Place to build the station.
238
* @param direction The direction to build the station.
239
* @param num_platforms The number of platforms to build.
240
* @param platform_length The length of each platform.
241
* @param station_id The station to join, AIStation::STATION_NEW or AIStation::STATION_JOIN_ADJACENT.
242
* @param cargo_id The CargoID of the cargo that will be transported from / to this station.
243
* @param source_industry The IndustryType of the industry you'll transport goods from.
244
* @param goal_industry The IndustryType of the industry you'll transport goods to.
245
* @param distance The manhattan distance you'll transport the cargo over.
246
* @param source_station True if this is the source station, false otherwise.
247
* @pre IsRailTypeAvailable(GetCurrentRailType()).
248
* @pre AIMap::IsValidTile(tile).
249
* @pre direction == RAILTRACK_NW_SE || direction == RAILTRACK_NE_SW.
250
* @pre num_platforms > 0 && num_platforms <= 255.
251
* @pre platform_length > 0 && platform_length <= 255.
252
* @pre station_id == AIStation::STATION_NEW || station_id == AIStation::STATION_JOIN_ADJACENT || AIStation::IsValidStation(station_id).
253
* @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
254
* @exception AIError::ERR_AREA_NOT_CLEAR
255
* @exception AIError::ERR_FLAT_LAND_REQUIRED
256
* @exception AIStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION
257
* @exception AIStation::ERR_STATION_TOO_MANY_STATIONS
258
* @exception AIStation::ERR_STATION_TOO_MANY_STATIONS_IN_TOWN
259
* @return Whether the station has been/can be build or not.
261
static bool BuildNewGRFRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id, CargoID cargo_id, IndustryType source_industry, IndustryType goal_industry, int distance, bool source_station);
264
* Build a rail waypoint.
265
* @param tile Place to build the waypoint.
266
* @pre AIMap::IsValidTile(tile).
267
* @pre IsRailTile(tile).
268
* @pre GetRailTracks(tile) == RAILTRACK_NE_SW || GetRailTracks(tile) == RAILTRACK_NW_SE.
269
* @pre IsRailTypeAvailable(GetCurrentRailType()).
270
* @exception AIError::ERR_FLAT_LAND_REQUIRED
271
* @return Whether the rail waypoint has been/can be build or not.
273
static bool BuildRailWaypoint(TileIndex tile);
276
* Remove a rail waypoint.
277
* @param tile Place to remove the waypoint from.
278
* @pre AIMap::IsValidTile(tile).
279
* @pre IsRailWaypointTile(tile).
280
* @return Whether the rail waypoint has been/can be removed or not.
282
static bool RemoveRailWaypoint(TileIndex tile);
285
* Remove a rectangle of platform pieces from a rail station.
286
* @param tile One corner of the rectangle to clear.
287
* @param tile2 The oppposite corner.
288
* @pre IsValidTile(tile).
289
* @pre IsValidTile(tile2).
290
* @return Whether at least one tile has been/can be cleared or not.
292
static bool RemoveRailStationTileRect(TileIndex tile, TileIndex tile2);
295
* Get all RailTracks on the given tile.
296
* @param tile The tile to check.
297
* @pre IsRailTile(tile).
298
* @return A bitmask of RailTrack with all RailTracks on the tile.
300
static uint GetRailTracks(TileIndex tile);
303
* Build rail on the given tile.
304
* @param tile The tile to build on.
305
* @param rail_track The RailTrack to build.
306
* @pre AIMap::IsValidTile(tile).
307
* @pre IsRailTypeAvailable(GetCurrentRailType()).
308
* @exception AIError::ERR_AREA_NOT_CLEAR
309
* @exception AIError::ERR_LAND_SLOPED_WRONG
310
* @exception AIRoad::ERR_ROAD_WORKS_IN_PROGRESS
311
* @exception AIRail::ERR_CROSSING_ON_ONEWAY_ROAD
312
* @exception AIError::ERR_ALREADY_BUILT
313
* @return Whether the rail has been/can be build or not.
314
* @note You can only build a single track with this function so do not
315
* use the values from RailTrack as bitmask.
317
static bool BuildRailTrack(TileIndex tile, RailTrack rail_track);
320
* Remove rail on the given tile.
321
* @param tile The tile to remove rail from.
322
* @param rail_track The RailTrack to remove.
323
* @pre AIMap::IsValidTile(tile).
324
* @pre (GetRailTracks(tile) & rail_track) != 0.
325
* @return Whether the rail has been/can be removed or not.
326
* @note You can only remove a single track with this function so do not
327
* use the values from RailTrack as bitmask.
329
static bool RemoveRailTrack(TileIndex tile, RailTrack rail_track);
332
* Check if a tile connects two adjacent tiles.
333
* @param from The first tile to connect.
334
* @param tile The tile that is checked.
335
* @param to The second tile to connect.
337
* @pre AIMap::DistanceManhattan(from, tile) == 1.
338
* @pre AIMap::DistanceManhattan(to, tile) == 1.
339
* @return True if 'tile' connects 'from' and 'to'.
341
static bool AreTilesConnected(TileIndex from, TileIndex tile, TileIndex to);
344
* Build a rail connection between two tiles.
345
* @param from The tile just before the tile to build on.
346
* @param tile The first tile to build on.
347
* @param to The tile just after the last tile to build on.
349
* @pre AIMap::DistanceManhattan(from, tile) == 1.
350
* @pre AIMap::DistanceManhattan(to, tile) >= 1.
351
* @pre (abs(abs(AIMap::GetTileX(to) - AIMap::GetTileX(tile)) -
352
* abs(AIMap::GetTileY(to) - AIMap::GetTileY(tile))) <= 1) ||
353
* (AIMap::GetTileX(from) == AIMap::GetTileX(tile) && AIMap::GetTileX(tile) == AIMap::GetTileX(to)) ||
354
* (AIMap::GetTileY(from) == AIMap::GetTileY(tile) && AIMap::GetTileY(tile) == AIMap::GetTileY(to)).
355
* @pre IsRailTypeAvailable(GetCurrentRailType()).
356
* @exception AIError::ERR_AREA_NOT_CLEAR
357
* @exception AIError::ERR_LAND_SLOPED_WRONG
358
* @exception AIRail::ERR_CROSSING_ON_ONEWAY_ROAD
359
* @exception AIRoad::ERR_ROAD_WORKS_IN_PROGRESS
360
* @exception AIError::ERR_ALREADY_BUILT
361
* @return Whether the rail has been/can be build or not.
363
static bool BuildRail(TileIndex from, TileIndex tile, TileIndex to);
366
* Remove a rail connection between two tiles.
367
* @param from The tile just before the tile to remove rail from.
368
* @param tile The first tile to remove rail from.
369
* @param to The tile just after the last tile to remove rail from.
371
* @pre AIMap::DistanceManhattan(from, tile) == 1.
372
* @pre AIMap::DistanceManhattan(to, tile) >= 1.
373
* @pre (abs(abs(AIMap::GetTileX(to) - AIMap::GetTileX(tile)) -
374
* abs(AIMap::GetTileY(to) - AIMap::GetTileY(tile))) <= 1) ||
375
* (AIMap::GetTileX(from) == AIMap::GetTileX(tile) && AIMap::GetTileX(tile) == AIMap::GetTileX(to)) ||
376
* (AIMap::GetTileY(from) == AIMap::GetTileY(tile) && AIMap::GetTileY(tile) == AIMap::GetTileY(to)).
377
* @return Whether the rail has been/can be removed or not.
379
static bool RemoveRail(TileIndex from, TileIndex tile, TileIndex to);
382
* Get the SignalType of the signal on a tile or SIGNALTYPE_NONE if there is no signal.
383
* @pre AIMap::DistanceManhattan(tile, front) == 1.
384
* @param tile The tile that might have a signal.
385
* @param front The tile in front of 'tile'.
386
* @return The SignalType of the signal on 'tile' with it's front to 'front'.
388
static SignalType GetSignalType(TileIndex tile, TileIndex front);
391
* Build a signal on a tile.
392
* @param tile The tile to build on.
393
* @param front The tile in front of the signal.
394
* @param signal The SignalType to build.
395
* @pre AIMap::DistanceManhattan(tile, front) == 1.
396
* @pre IsRailTile(tile) && !IsRailStationTile(tile) && !IsRailWaypointTile(tile).
397
* @exception AIRail::ERR_UNSUITABLE_TRACK
398
* @return Whether the signal has been/can be build or not.
400
static bool BuildSignal(TileIndex tile, TileIndex front, SignalType signal);
404
* @param tile The tile to remove the signal from.
405
* @param front The tile in front of the signal.
406
* @pre AIMap::DistanceManhattan(tile, front) == 1.
407
* @pre GetSignalType(tile, front) != SIGNALTYPE_NONE.
408
* @return Whether the signal has been/can be removed or not.
410
static bool RemoveSignal(TileIndex tile, TileIndex front);
413
#endif /* AI_RAIL_HPP */