summaryrefslogtreecommitdiff
path: root/src/script/api/script_station.hpp
blob: 8561cd9bdd4fe65d06a2d4c244cee0be23fdf06f (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
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
/* $Id$ */

/*
 * This file is part of OpenTTD.
 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 */

/** @file script_station.hpp Everything to query and build stations. */

#ifndef SCRIPT_STATION_HPP
#define SCRIPT_STATION_HPP

#include "script_road.hpp"
#include "script_basestation.hpp"
#include "../../station_type.h"

/**
 * Class that handles all station related functions.
 * @api ai game
 */
class ScriptStation : public ScriptBaseStation {
public:
	/**
	 * All station related error messages.
	 */
	enum ErrorMessages {
		/** Base for station related errors */
		ERR_STATION_BASE = ScriptError::ERR_CAT_STATION << ScriptError::ERR_CAT_BIT_SIZE,

		/** The station is build too close to another station, airport or dock */
		ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION, // [STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT, STR_ERROR_TOO_CLOSE_TO_ANOTHER_STATION, STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK]

		/** There are too many stations, airports and docks in the game */
		ERR_STATION_TOO_MANY_STATIONS,            // [STR_ERROR_TOO_MANY_STATIONS_LOADING, STR_ERROR_TOO_MANY_TRUCK_STOPS, STR_ERROR_TOO_MANY_BUS_STOPS]

		/** There are too many stations, airports of docks in a town */
		ERR_STATION_TOO_MANY_STATIONS_IN_TOWN,    // [STR_ERROR_LOCAL_AUTHORITY_REFUSES_AIRPORT]
	};

	/**
	 * Type of stations known in the game.
	 */
	enum StationType {
		/* Note: these values represent part of the in-game StationFacility enum */
		STATION_TRAIN      = (int)::FACIL_TRAIN,      ///< Train station
		STATION_TRUCK_STOP = (int)::FACIL_TRUCK_STOP, ///< Truck station
		STATION_BUS_STOP   = (int)::FACIL_BUS_STOP,   ///< Bus station
		STATION_AIRPORT    = (int)::FACIL_AIRPORT,    ///< Airport
		STATION_DOCK       = (int)::FACIL_DOCK,       ///< Dock
		STATION_ANY        = STATION_TRAIN | STATION_TRUCK_STOP | STATION_BUS_STOP | STATION_AIRPORT | STATION_DOCK, ///< All station types
	};

	/**
	 * Checks whether the given station is valid and owned by you.
	 * @param station_id The station to check.
	 * @return True if and only if the station is valid.
	 */
	static bool IsValidStation(StationID station_id);

	/**
	 * Get the owner of a station.
	 * @param station_id The station to get the owner of.
	 * @pre IsValidStation(station_id).
	 * @return The owner the station has.
	 * @api -ai
	 */
	static ScriptCompany::CompanyID GetOwner(StationID station_id);

	/**
	 * Get the StationID of a tile, if there is a station.
	 * @param tile The tile to find the stationID of
	 * @return StationID of the station.
	 * @post Use IsValidStation() to see if the station is valid.
	 */
	static StationID GetStationID(TileIndex tile);

	/**
	 * See how much cargo there is waiting on a station.
	 * @param station_id The station to get the cargo-waiting of.
	 * @param cargo_id The cargo to get the cargo-waiting of.
	 * @pre IsValidStation(station_id).
	 * @pre IsValidCargo(cargo_id).
	 * @return The amount of units waiting at the station.
	 */
	static int32 GetCargoWaiting(StationID station_id, CargoID cargo_id);

	/**
	 * See how much cargo with a specific source station there is waiting on a station.
	 * @param station_id The station to get the cargo-waiting of.
	 * @param from_station_id The source station of the cargo. Pass STATION_INVALID to get cargo of which the source has been deleted.
	 * @param cargo_id The cargo to get the cargo-waiting of.
	 * @pre IsValidStation(station_id).
	 * @pre IsValidStation(from_station_id) || from_station_id == STATION_INVALID.
	 * @pre IsValidCargo(cargo_id).
	 * @return The amount of units waiting at the station originating from from_station_id.
	 * @note source station means, the station where cargo was first loaded.
	 */
	static int32 GetCargoWaitingFrom(StationID station_id, StationID from_station_id, CargoID cargo_id);

	/**
	 * See how much cargo with a specific via-station there is waiting on a station.
	 * @param station_id The station to get the cargo-waiting of.
	 * @param via_station_id The next station the cargo is going to. Pass STATION_INVALID to get waiting cargo for "via any station".
	 * @param cargo_id The cargo to get the cargo-waiting of.
	 * @pre IsValidStation(station_id).
	 * @pre IsValidStation(via_station_id) || via_station_id == STATION_INVALID.
	 * @pre IsValidCargo(cargo_id).
	 * @return The amount of units waiting at the station with via_station_id as next hop.
	 * @note if ScriptCargo.GetCargoDistributionType(cargo_id) == ScriptCargo.DT_MANUAL, then all waiting cargo will have STATION_INVALID as next hop.
	 */
	static int32 GetCargoWaitingVia(StationID station_id, StationID via_station_id, CargoID cargo_id);

	/**
	 * See how much cargo with a specific via-station and source station there is waiting on a station.
	 * @param station_id The station to get the cargo-waiting of.
	 * @param from_station_id The source station of the cargo. Pass STATION_INVALID to get cargo of which the source has been deleted.
	 * @param via_station_id The next station the cargo is going to. Pass STATION_INVALID to get waiting cargo for "via any station".
	 * @param cargo_id The cargo to get the cargo-waiting of.
	 * @pre IsValidStation(station_id).
	 * @pre IsValidStation(from_station_id) || from_station_id == STATION_INVALID.
	 * @pre IsValidStation(via_station_id) || via_station_id == STATION_INVALID.
	 * @pre IsValidCargo(cargo_id).
	 * @return The amount of units waiting at the station with from_station_id as source and via_station_id as next hop.
	 * @note if ScriptCargo.GetCargoDistributionType(cargo_id) == ScriptCargo.DT_MANUAL, then all waiting cargo will have STATION_INVALID as next hop.
	 */
	static int32 GetCargoWaitingFromVia(StationID station_id, StationID from_station_id, StationID via_station_id, CargoID cargo_id);

	/**
	 * See how much cargo was planned to pass (including production and consumption) this station per month.
	 * @param station_id The station to get the planned flow for.
	 * @param cargo_id The cargo type to get the planned flow for.
	 * @pre IsValidStation(station_id).
	 * @pre IsValidCargo(cargo_id).
	 * @return The amount of cargo units planned to pass the station per month.
	 */
	static int32 GetCargoPlanned(StationID station_id, CargoID cargo_id);

	/**
	 * See how much cargo from the specified origin was planned to pass (including production and consumption) this station per month.
	 * @param station_id The station to get the planned flow for.
	 * @param from_station_id The station the cargo originates at.
	 * @param cargo_id The cargo type to get the planned flow for.
	 * @pre IsValidStation(station_id).
	 * @pre IsValidStation(from_station_id) || from_station_id == STATION_INVALID.
	 * @pre IsValidCargo(cargo_id).
	 * @return The amount of cargo units from the specified origin planned to pass the station per month.
	 */
	static int32 GetCargoPlannedFrom(StationID station_id, StationID from_station_id, CargoID cargo_id);

	/**
	 * See how much cargo was planned to pass (including production and consumption) this station per month, heading for the specified next hop.
	 * @param station_id The station to get the planned flow for.
	 * @param via_station_id The next station the cargo will go on to.
	 * @param cargo_id The cargo type to get the planned flow for.
	 * @pre IsValidStation(station_id).
	 * @pre IsValidStation(via_station_id) || via_station_id == STATION_INVALID.
	 * @pre IsValidCargo(cargo_id).
	 * @return The amount of cargo units planned to pass the station per month, going via the specified next hop.
	 * @note Cargo planned to go "via" the same station that's being queried is actually planned to be consumed there.
	 */
	static int32 GetCargoPlannedVia(StationID station_id, StationID via_station_id, CargoID cargo_id);

	/**
	 * See how much cargo from the specified origin was planned to pass this station per month,
	 * heading for the specified next hop.
	 * @param station_id The station to get the planned flow for.
	 * @param from_station_id The station the cargo originates at.
	 * @param via_station_id The next station the cargo will go on to.
	 * @param cargo_id The cargo type to get the planned flow for.
	 * @pre IsValidStation(station_id).
	 * @pre IsValidStation(from_station_id) || from_station_id == STATION_INVALID.
	 * @pre IsValidStation(via_station_id) || via_station_id == STATION_INVALID.
	 * @pre IsValidCargo(cargo_id).
	 * @return The amount of cargo units from the specified origin planned to pass the station per month, going via the specified next hop.
	 * @note Cargo planned to go "via" the same station that's being queried is actually planned to be consumed there.
	 * @note Cargo planned to pass "from" the same station that's being queried is actually produced there.
	 */
	static int32 GetCargoPlannedFromVia(StationID station_id, StationID from_station_id, StationID via_station_id, CargoID cargo_id);

	/**
	 * Check whether the given cargo at the given station a rating.
	 * @param station_id The station to get the cargo-rating state of.
	 * @param cargo_id The cargo to get the cargo-rating state of.
	 * @pre IsValidStation(station_id).
	 * @pre IsValidCargo(cargo_id).
	 * @return True if the cargo has a rating, otherwise false.
	 */
	static bool HasCargoRating(StationID station_id, CargoID cargo_id);

	/**
	 * See how high the rating is of a cargo on a station.
	 * @param station_id The station to get the cargo-rating of.
	 * @param cargo_id The cargo to get the cargo-rating of.
	 * @pre IsValidStation(station_id).
	 * @pre IsValidCargo(cargo_id).
	 * @pre HasCargoRating(station_id, cargo_id).
	 * @return The rating in percent of the cargo on the station.
	 */
	static int32 GetCargoRating(StationID station_id, CargoID cargo_id);

	/**
	 * Get the coverage radius of this type of station.
	 * @param station_type The type of station.
	 * @pre station_type != STATION_AIRPORT.
	 * @return The radius in tiles.
	 * @note Coverage radius of airports needs to be requested via ScriptAirport::GetAirportCoverageRadius(), as it requires AirportType.
	 */
	static int32 GetCoverageRadius(ScriptStation::StationType station_type);

	/**
	 * Get the coverage radius of this station.
	 * @param station_id The station to get the coverage radius of.
	 * @pre IsValidStation(station_id).
	 * @return The radius in tiles.
	 */
	static int32 GetStationCoverageRadius(StationID station_id);

	/**
	 * Get the manhattan distance from the tile to the ScriptStation::GetLocation()
	 *  of the station.
	 * @param station_id The station to get the distance to.
	 * @param tile The tile to get the distance to.
	 * @pre IsValidStation(station_id).
	 * @return The distance between station and tile.
	 */
	static int32 GetDistanceManhattanToTile(StationID station_id, TileIndex tile);

	/**
	 * Get the square distance from the tile to the ScriptStation::GetLocation()
	 *  of the station.
	 * @param station_id The station to get the distance to.
	 * @param tile The tile to get the distance to.
	 * @pre IsValidStation(station_id).
	 * @return The distance between station and tile.
	 */
	static int32 GetDistanceSquareToTile(StationID station_id, TileIndex tile);

	/**
	 * Find out if this station is within the rating influence of a town.
	 *  The service quality of stations with signs within this radius
	 *  influences the rating of the town.
	 * @param station_id The station to check.
	 * @param town_id The town to check.
	 * @return True if the tile is within the rating influence of the town.
	 */
	static bool IsWithinTownInfluence(StationID station_id, TownID town_id);

	/**
	 * Check if any part of the station contains a station of the type
	 *  StationType
	 * @param station_id The station to look at.
	 * @param station_type The StationType to look for.
	 * @return True if the station has a station part of the type StationType.
	 */
	static bool HasStationType(StationID station_id, StationType station_type);

	/**
	 * Check if any part of the station contains a station of the type
	 *  RoadType.
	 * @param station_id The station to look at.
	 * @param road_type The RoadType to look for.
	 * @return True if the station has a station part of the type RoadType.
	 */
	static bool HasRoadType(StationID station_id, ScriptRoad::RoadType road_type);

	/**
	 * Get the town that was nearest to the given station when the station was built.
	 * @param station_id The station to look at.
	 * @return The TownID of the town whose center tile was closest to the station
	 *  at the time the station was built.
	 * @note There is no guarantee that the station is even near the returned town
	 *  nor that the returns town is closest to the station now. A station that was
	 *  'walked' to the other end of the map will still return the same town. Also,
	 *  towns grow, towns change. So don't depend on this value too much.
	 */
	static TownID GetNearestTown(StationID station_id);

	/**
	 * Get the open/closed state of an airport.
	 * @param station_id The airport to look at.
	 * @pre IsValidStation(station_id).
	 * @pre HasStationType(station_id, STATION_AIRPORT).
	 * @return True if the airport is currently closed to incoming traffic.
	 */
	static bool IsAirportClosed(StationID station_id);

	/**
	 * Toggle the open/closed state of an airport.
	 * @param station_id The airport to modify.
	 * @pre IsValidStation(station_id).
	 * @pre HasStationType(station_id, STATION_AIRPORT).
	 * @return True if the state was toggled successfully.
	 */
	static bool OpenCloseAirport(StationID station_id);

private:
	template<bool Tfrom, bool Tvia>
	static bool IsCargoRequestValid(StationID station_id, StationID from_station_id,
			StationID via_station_id, CargoID cargo_id);

	template<bool Tfrom, bool Tvia>
	static int32 CountCargoWaiting(StationID station_id, StationID from_station_id,
			StationID via_station_id, CargoID cargo_id);

	template<bool Tfrom, bool Tvia>
	static int32 CountCargoPlanned(StationID station_id, StationID from_station_id,
			StationID via_station_id, CargoID cargo_id);

};

DECLARE_ENUM_AS_BIT_SET(ScriptStation::StationType)

#endif /* SCRIPT_STATION_HPP */