summaryrefslogtreecommitdiff
path: root/src/ai/api/ai_bridge.hpp
blob: 819242e79b5d832fbba5f87e507de7bab01a95ac (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
/* $Id$ */

/** @file ai_bridge.hpp Everything to query and build bridges. */

#ifndef AI_BRIDGE_HPP
#define AI_BRIDGE_HPP

#include "ai_object.hpp"
#include "ai_vehicle.hpp"
#include "ai_error.hpp"

/**
 * Class that handles all bridge related functions.
 */
class AIBridge : public AIObject {
public:
	/**
	 * All bridge related error messages.
	 */
	enum ErrorMessages {
		/** Base for bridge related errors */
		ERR_BRIDGE_BASE = AIError::ERR_CAT_BRIDGE << AIError::ERR_CAT_BIT_SIZE,

		/**
		 * The bridge you want to build is not available yet,
		 * or it is not available for the requested length.
		 */
		ERR_BRIDGE_TYPE_UNAVAILABLE,         // [STR_5015_CAN_T_BUILD_BRIDGE_HERE]

		/** One (or more) of the bridge head(s) ends in water. */
		ERR_BRIDGE_CANNOT_END_IN_WATER,      // [STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH]

		/** The bride heads need to be on the same height */
		ERR_BRIDGE_HEADS_NOT_ON_SAME_HEIGHT, // [STR_BRIDGEHEADS_NOT_SAME_HEIGHT]
	};

	static const char *GetClassName() { return "AIBridge"; }

	/**
	 * Checks whether the given bridge type is valid.
	 * @param bridge_id The bridge to check.
	 * @return True if and only if the bridge type is valid.
	 */
	static bool IsValidBridge(BridgeID bridge_id);

	/**
	 * Checks whether the given tile is actually a bridge start or end tile.
	 * @param tile The tile to check.
	 * @pre AIMap::IsValidTile(tile).
	 * @return True if and only if the tile is the beginning or end of a bridge.
	 */
	static bool IsBridgeTile(TileIndex tile);

	/**
	 * Get the name of a bridge.
	 * @param bridge_id The bridge to get the name of.
	 * @pre IsValidBridge(bridge_id).
	 * @return The name the bridge has.
	 */
	static char *GetName(BridgeID bridge_id);

	/**
	 * Get the maximum speed of a bridge (in km/h).
	 * @param bridge_id The bridge to get the maximum speed of.
	 * @pre IsValidBridge(bridge_id).
	 * @return The maximum speed the bridge has.
	 */
	static int32 GetMaxSpeed(BridgeID bridge_id);

	/**
	 * Get the new cost of a bridge.
	 * @param bridge_id The bridge to get the new cost of.
	 * @param length The length of the bridge.
	 * @pre IsValidBridge(bridge_id).
	 * @return The new cost the bridge has.
	 */
	static Money GetPrice(BridgeID bridge_id, uint length);

	/**
	 * Get the maximum length of a bridge.
	 * @param bridge_id The bridge to get the maximum length of.
	 * @pre IsValidBridge(bridge_id).
	 * @returns The maximum length the bridge has.
	 */
	static int32 GetMaxLength(BridgeID bridge_id);

	/**
	 * Get the minimum length of a bridge.
	 * @param bridge_id The bridge to get the minimum length of.
	 * @pre IsValidBridge(bridge_id).
	 * @returns The minimum length the bridge has.
	 */
	static int32 GetMinLength(BridgeID bridge_id);

	/**
	 * Get the year in which a bridge becomes available.
	 * @param bridge_id The bridge to get the year of availability of.
	 * @pre IsValidBridge(bridge_id).
	 * @returns The year of availability the bridge has.
	 * @note Years are like 2010, -10 (10 B.C.), 1950, ..
	 */
	static int32 GetYearAvailable(BridgeID bridge_id);

#ifndef DOXYGEN_SKIP
	/**
	 * Internal function to help BuildBridge in case of road.
	 */
	static bool _BuildBridgeRoad1();

	/**
	 * Internal function to help BuildBridge in case of road.
	 */
	static bool _BuildBridgeRoad2();
#endif

	/**
	 * Build a bridge from one tile to the other.
	 * As an extra for road, this functions builds two half-pieces of road on
	 *  each end of the bridge, making it easier for you to connect it to your
	 *  network.
	 * @param vehicle_type The vehicle-type of bridge to build.
	 * @param bridge_id The bridge-type to build.
	 * @param start Where to start the bridge.
	 * @param end Where to end the bridge.
	 * @pre AIMap::IsValidTile(start).
	 * @pre AIMap::IsValidTile(end).
	 * @pre 'start' and 'end' are in a straight line, i.e.
	 *  AIMap::GetTileX(start) == AIMap::GetTileX(end) or
	 *  AIMap::GetTileY(start) == AIMap::GetTileY(end).
	 * @pre vehicle_type == AIVehicle::VEHICLE_ROAD || (vehicle_type == AIVehicle::VEHICLE_RAIL &&
	 *   AIRail::IsRailTypeAvailable(AIRail::GetCurrentRailType())) || vehicle_type == AIVehicle::VEHICLE_WATER.
	 * @exception AIError::ERR_ALREADY_BUILT
	 * @exception AIError::ERR_AREA_NOT_CLEAR
	 * @exception AIError::ERR_LAND_SLOPED_WRONG
	 * @exception AIError::ERR_VEHICLE_IN_THE_WAY
	 * @exception AIBridge::ERR_BRIDGE_TYPE_UNAVAILABLE
	 * @exception AIBridge::ERR_BRIDGE_CANNOT_END_IN_WATER
	 * @exception AIBridge::ERR_BRIDGE_HEADS_NOT_ON_SAME_HEIGHT
	 * @return Whether the bridge has been/can be build or not.
	 * @note No matter if the road pieces were build or not, if building the
	 *  bridge succeeded, this function returns true.
	 */
	static bool BuildBridge(AIVehicle::VehicleType vehicle_type, BridgeID bridge_id, TileIndex start, TileIndex end);

	/**
	 * Removes a bridge, by executing it on either the start or end tile.
	 * @param tile An end or start tile of the bridge.
	 * @pre AIMap::IsValidTile(tile).
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
	 * @return Whether the bridge has been/can be removed or not.
	 */
	static bool RemoveBridge(TileIndex tile);

	/**
	 * Get the tile that is on the other end of a bridge starting at tile.
	 * @param tile The tile that is an end of a bridge.
	 * @pre AIMap::IsValidTile(tile).
	 * @pre IsBridgeTile(tile).
	 * @return The TileIndex that is the other end of the bridge.
	 */
	static TileIndex GetOtherBridgeEnd(TileIndex tile);
};

#endif /* AI_BRIDGE_HPP */