OpenTTD Source 20250312-master-gcdcc6b491d
train.h
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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/>.
6 */
7
10#ifndef TRAIN_H
11#define TRAIN_H
12
13#include "core/enum_type.hpp"
14
15#include "newgrf_engine.h"
16#include "cargotype.h"
17#include "rail.h"
18#include "engine_base.h"
19#include "rail_map.h"
20#include "ground_vehicle.hpp"
21
22struct Train;
23
35
37enum TrainForceProceeding : uint8_t {
41};
42
44enum class ConsistChangeFlag : uint8_t {
45 Length,
46 Capacity,
47};
48
50
51static constexpr ConsistChangeFlags CCF_TRACK{};
57
59
61
62void FreeTrainTrackReservation(const Train *v);
63bool TryPathReserve(Train *v, bool mark_as_stuck = false, bool first_tile_okay = false);
64
65int GetTrainStopLocation(StationID station_id, TileIndex tile, const Train *v, int *station_ahead, int *station_length);
66
67void GetTrainSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type);
68
70void NormalizeTrainVehInDepot(const Train *u);
71
73struct TrainCache {
74 /* Cached wagon override spritegroup */
75 const struct SpriteGroup *cached_override = nullptr;
76
77 /* cached values, recalculated on load and each time a vehicle is added to/removed from the consist. */
78 bool cached_tilt = false;
79 uint8_t user_def_data = 0;
80
83
84 auto operator<=>(const TrainCache &) const = default;
85};
86
90struct Train final : public GroundVehicle<Train, VEH_TRAIN> {
91 uint16_t flags = 0;
92 uint16_t crash_anim_pos = 0;
93 uint16_t wait_counter = 0;
94
95 TrainCache tcache{};
96
97 /* Link between the two ends of a multiheaded engine */
98 Train *other_multiheaded_part = nullptr;
99
100 RailTypes compatible_railtypes{};
101 RailType railtype = INVALID_RAILTYPE;
102
103 TrackBits track{};
104 TrainForceProceeding force_proceed{};
105
109 virtual ~Train() { this->PreDestructor(); }
110
111 friend struct GroundVehicle<Train, VEH_TRAIN>; // GroundVehicle needs to use the acceleration functions defined at Train.
112
113 void MarkDirty() override;
114 void UpdateDeltaXY() override;
115 ExpensesType GetExpenseType(bool income) const override { return income ? EXPENSES_TRAIN_REVENUE : EXPENSES_TRAIN_RUN; }
116 void PlayLeaveStationSound(bool force = false) const override;
117 bool IsPrimaryVehicle() const override { return this->IsFrontEngine(); }
118 void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const override;
119 int GetDisplaySpeed() const override { return this->gcache.last_speed; }
120 int GetDisplayMaxSpeed() const override { return this->vcache.cached_max_speed; }
121 Money GetRunningCost() const override;
122 int GetCursorImageOffset() const;
123 int GetDisplayImageWidth(Point *offset = nullptr) const;
124 bool IsInDepot() const override { return this->track == TRACK_BIT_DEPOT; }
125 bool Tick() override;
126 void OnNewCalendarDay() override;
127 void OnNewEconomyDay() override;
128 uint Crash(bool flooded = false) override;
129 Trackdir GetVehicleTrackdir() const override;
132
133 void ReserveTrackUnderConsist() const;
134
135 uint16_t GetCurveSpeedLimit() const;
136
137 void ConsistChanged(ConsistChangeFlags allowed_changes);
138
139 int UpdateSpeed();
140
141 void UpdateAcceleration();
142
143 int GetCurrentMaxSpeed() const override;
144
149 inline Train *GetNextUnit() const
150 {
151 Train *v = this->GetNextVehicle();
152 if (v != nullptr && v->IsRearDualheaded()) v = v->GetNextVehicle();
153
154 return v;
155 }
156
162 {
163 Train *v = this->GetPrevVehicle();
164 if (v != nullptr && v->IsRearDualheaded()) v = v->GetPrevVehicle();
165
166 return v;
167 }
168
174 {
175 /* For vehicles with odd lengths the part before the center will be one unit
176 * longer than the part after the center. This means we have to round up the
177 * length of the next vehicle but may not round the length of the current
178 * vehicle. */
179 return this->gcache.cached_veh_length / 2 + (this->Next() != nullptr ? this->Next()->gcache.cached_veh_length + 1 : 0) / 2;
180 }
181
182protected: // These functions should not be called outside acceleration code.
183
188 inline uint16_t GetPower() const
189 {
190 /* Power is not added for articulated parts */
191 if (!this->IsArticulatedPart() && HasPowerOnRail(this->railtype, GetRailType(this->tile))) {
192 uint16_t power = GetVehicleProperty(this, PROP_TRAIN_POWER, RailVehInfo(this->engine_type)->power);
193 /* Halve power for multiheaded parts */
194 if (this->IsMultiheaded()) power /= 2;
195 return power;
196 }
197
198 return 0;
199 }
200
205 inline uint16_t GetPoweredPartPower(const Train *head) const
206 {
207 /* For powered wagons the engine defines the type of engine (i.e. railtype) */
208 if (HasBit(this->flags, VRF_POWEREDWAGON) && HasPowerOnRail(head->railtype, GetRailType(this->tile))) {
209 return RailVehInfo(this->gcache.first_engine)->pow_wag_power;
210 }
211
212 return 0;
213 }
214
219 inline uint16_t GetWeight() const
220 {
221 uint16_t weight = CargoSpec::Get(this->cargo_type)->WeightOfNUnitsInTrain(this->cargo.StoredCount());
222
223 /* Vehicle weight is not added for articulated parts. */
224 if (!this->IsArticulatedPart()) {
225 weight += GetVehicleProperty(this, PROP_TRAIN_WEIGHT, RailVehInfo(this->engine_type)->weight);
226 }
227
228 /* Powered wagons have extra weight added. */
229 if (HasBit(this->flags, VRF_POWEREDWAGON)) {
230 weight += RailVehInfo(this->gcache.first_engine)->pow_wag_weight;
231 }
232
233 return weight;
234 }
235
240 uint16_t GetMaxWeight() const override;
241
246 inline uint8_t GetTractiveEffort() const
247 {
248 return GetVehicleProperty(this, PROP_TRAIN_TRACTIVE_EFFORT, RailVehInfo(this->engine_type)->tractive_effort);
249 }
250
255 inline uint8_t GetAirDragArea() const
256 {
257 /* Air drag is higher in tunnels due to the limited cross-section. */
258 return (this->track == TRACK_BIT_WORMHOLE && this->vehstatus.Test(VehState::Hidden)) ? 28 : 14;
259 }
260
265 inline uint8_t GetAirDrag() const
266 {
267 return RailVehInfo(this->engine_type)->air_drag;
268 }
269
275 {
276 return this->vehstatus.Test(VehState::Stopped) || HasBit(this->flags, VRF_REVERSING) || HasBit(this->flags, VRF_TRAIN_STUCK) ? AS_BRAKE : AS_ACCEL;
277 }
278
283 inline uint16_t GetCurrentSpeed() const
284 {
285 return this->cur_speed;
286 }
287
292 inline uint32_t GetRollingFriction() const
293 {
294 /* Rolling friction for steel on steel is between 0.1% and 0.2%.
295 * The friction coefficient increases with speed in a way that
296 * it doubles at 512 km/h, triples at 1024 km/h and so on. */
297 return 15 * (512 + this->GetCurrentSpeed()) / 512;
298 }
299
304 inline int GetAccelerationType() const
305 {
306 return GetRailTypeInfo(this->railtype)->acceleration_type;
307 }
308
313 inline uint32_t GetSlopeSteepness() const
314 {
316 }
317
322 inline uint16_t GetMaxTrackSpeed() const
323 {
325 }
326
331 inline int16_t GetCurveSpeedModifier() const
332 {
333 return GetVehicleProperty(this, PROP_TRAIN_CURVE_SPEED_MOD, RailVehInfo(this->engine_type)->curve_speed_mod, true);
334 }
335
340 inline bool TileMayHaveSlopedTrack() const
341 {
342 /* Any track that isn't TRACK_BIT_X or TRACK_BIT_Y cannot be sloped. */
343 return this->track == TRACK_BIT_X || this->track == TRACK_BIT_Y;
344 }
345
352 {
353 return false;
354 }
355};
356
357#endif /* TRAIN_H */
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:23
Types/functions related to cargoes.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Enum-as-bit-set wrapper.
uint16_t max_speed
Maximum speed for vehicles travelling on this rail type.
Definition rail.h:222
uint8_t acceleration_type
Acceleration type of this rail type.
Definition rail.h:217
uint StoredCount() const
Returns sum of cargo on board the vehicle (ie not only reserved).
Direction
Defines the 8 directions on the map.
ExpensesType
Types of expenses.
@ EXPENSES_TRAIN_RUN
Running costs trains.
@ EXPENSES_TRAIN_REVENUE
Revenue from trains.
Base class for engines.
Type (helpers) for enums.
Base class and functions for all vehicles that move through ground.
AccelStatus
What is the status of our acceleration?
@ AS_BRAKE
We want to stop.
@ AS_ACCEL
We want to go faster, if possible of course.
Functions for NewGRF engines.
@ PROP_TRAIN_CURVE_SPEED_MOD
Modifier to maximum speed in curves.
@ PROP_TRAIN_WEIGHT
Weight in t (if dualheaded: for each single vehicle)
@ PROP_TRAIN_TRACTIVE_EFFORT
Tractive effort coefficient in 1/256.
@ PROP_TRAIN_POWER
Power in hp (if dualheaded: sum of both vehicles)
Rail specific functions.
bool HasPowerOnRail(RailType enginetype, RailType tiletype)
Checks if an engine of the given RailType got power on a tile with a given RailType.
Definition rail.h:328
const RailTypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
Definition rail.h:300
Hides the direct accesses to the map array with map accessors.
RailType GetRailType(Tile t)
Gets the rail type of the given tile.
Definition rail_map.h:115
RailTypes
Allow incrementing of Track variables.
Definition rail_type.h:44
RailType
Enumeration for all possible railtypes.
Definition rail_type.h:27
@ INVALID_RAILTYPE
Flag for invalid railtype.
Definition rail_type.h:34
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:58
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo type.
Definition cargotype.h:137
Structure to return information about the closest depot location, and whether it could be found.
VehicleSettings vehicle
options for vehicles
EngineID first_engine
Cached EngineID of the front vehicle. EngineID::Invalid() for the front vehicle itself.
uint16_t last_speed
The last speed we did display, so we only have to redraw when this changes.
uint8_t cached_veh_length
Length of this vehicle in units of 1/VEHICLE_LENGTH of normal length. It is cached because this can b...
Base class for all vehicles that move through ground.
GroundVehicleCache gcache
Cache of often calculated values.
bool IsRearDualheaded() const
Tell if we are dealing with the rear end of a multiheaded engine.
bool IsMultiheaded() const
Check if the vehicle is a multiheaded engine.
Coordinates of a point in 2D.
uint16_t pow_wag_power
Extra power applied to consist if wagon should be powered.
Definition engine_type.h:60
uint8_t air_drag
Coefficient of air drag.
Definition engine_type.h:65
uint8_t pow_wag_weight
Extra weight applied to consist if wagon should be powered.
Definition engine_type.h:61
T * Next() const
Get next vehicle in the chain.
T * GetPrevVehicle() const
Get the previous real (non-articulated part) vehicle in the consist.
T * GetNextVehicle() const
Get the next real (non-articulated part) vehicle in the consist.
Variables that are cached to improve performance and such.
Definition train.h:73
uint16_t cached_max_curve_speed
max consist speed limited by curves
Definition train.h:82
int16_t cached_curve_speed_mod
curve speed modifier of the entire train
Definition train.h:81
uint8_t user_def_data
Cached property 0x25. Can be set by Callback 0x36.
Definition train.h:79
bool cached_tilt
train can tilt; feature provides a bonus in curves
Definition train.h:78
'Train' is either a loco or a wagon.
Definition train.h:90
void PlayLeaveStationSound(bool force=false) const override
Play a sound for a train leaving the station.
int GetAccelerationType() const
Allows to know the acceleration type of a vehicle.
Definition train.h:304
bool IsInDepot() const override
Check whether the vehicle is in the depot.
Definition train.h:124
void UpdateAcceleration()
Update acceleration of the train from the cached power and weight.
void OnNewCalendarDay() override
Calendar day handler.
Train * GetNextUnit() const
Get the next real (non-articulated part and non rear part of dualheaded engine) vehicle in the consis...
Definition train.h:149
Trackdir GetVehicleTrackdir() const override
Get the tracks of the train vehicle.
void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const override
Get the sprite to display the train.
int GetDisplayMaxSpeed() const override
Gets the maximum speed in km-ish/h that can be sent into string parameters for string processing.
Definition train.h:120
uint16_t crash_anim_pos
Crash animation counter.
Definition train.h:92
uint8_t GetTractiveEffort() const
Allows to know the tractive effort value that this vehicle will use.
Definition train.h:246
bool Tick() override
Update train vehicle data for a tick.
bool HasToUseGetSlopePixelZ()
Trains can always use the faster algorithm because they have always the same direction as the track u...
Definition train.h:351
uint16_t GetCurrentSpeed() const
Calculates the current speed of this vehicle.
Definition train.h:283
void ReserveTrackUnderConsist() const
Tries to reserve track under whole train consist.
TileIndex GetOrderStationLocation(StationID station) override
Get the location of the next station to visit.
Train * GetPrevUnit()
Get the previous real (non-articulated part and non rear part of dualheaded engine) vehicle in the co...
Definition train.h:161
uint16_t GetPoweredPartPower(const Train *head) const
Returns a value if this articulated part is powered.
Definition train.h:205
uint32_t GetRollingFriction() const
Returns the rolling friction coefficient of this vehicle.
Definition train.h:292
int GetDisplayImageWidth(Point *offset=nullptr) const
Get the width of a train vehicle image in the GUI.
ClosestDepot FindClosestDepot() override
Find the closest depot for this vehicle and tell us the location, DestinationID and whether we should...
void UpdateDeltaXY() override
Updates the x and y offsets and the size of the sprite used for this vehicle.
uint16_t GetMaxTrackSpeed() const
Gets the maximum speed allowed by the track for this vehicle.
Definition train.h:322
int CalcNextVehicleOffset() const
Calculate the offset from this vehicle's center to the following center taking the vehicle lengths in...
Definition train.h:173
uint16_t GetMaxWeight() const override
Calculates the weight value that this vehicle will have when fully loaded with its current cargo.
uint16_t GetCurveSpeedLimit() const
Computes train speed limit caused by curves.
uint8_t GetAirDrag() const
Gets the air drag coefficient of this vehicle.
Definition train.h:265
bool IsPrimaryVehicle() const override
Whether this is the primary vehicle in the chain.
Definition train.h:117
void MarkDirty() override
Goods at the consist have changed, update the graphics, cargo, and acceleration.
int GetDisplaySpeed() const override
Gets the speed in km-ish/h that can be sent into string parameters for string processing.
Definition train.h:119
int UpdateSpeed()
This function looks at the vehicle and updates its speed (cur_speed and subspeed) variables.
uint Crash(bool flooded=false) override
The train vehicle crashed! Update its status and other parts around it.
Train()
We don't want GCC to zero our struct! It already is zeroed and has an index!
Definition train.h:107
AccelStatus GetAccelerationStatus() const
Checks the current acceleration status of this vehicle.
Definition train.h:274
virtual ~Train()
We want to 'destruct' the right class.
Definition train.h:109
void OnNewEconomyDay() override
Economy day handler.
int16_t GetCurveSpeedModifier() const
Returns the curve speed modifier of this vehicle.
Definition train.h:331
bool TileMayHaveSlopedTrack() const
Checks if the vehicle is at a tile that can be sloped.
Definition train.h:340
uint16_t GetWeight() const
Allows to know the weight value that this vehicle will use.
Definition train.h:219
void ConsistChanged(ConsistChangeFlags allowed_changes)
Recalculates the cached stuff of a train.
ExpensesType GetExpenseType(bool income) const override
Sets the expense type associated to this vehicle type.
Definition train.h:115
Money GetRunningCost() const override
Get running cost for the train consist.
uint8_t GetAirDragArea() const
Gets the area used for calculating air drag.
Definition train.h:255
uint16_t GetPower() const
Allows to know the power value that this vehicle will use.
Definition train.h:188
uint16_t wait_counter
Ticks waiting in front of a signal, ticks being stuck or a counter for forced proceeding through sign...
Definition train.h:93
uint32_t GetSlopeSteepness() const
Returns the slope steepness used by this vehicle.
Definition train.h:313
int GetCurrentMaxSpeed() const override
Calculates the maximum speed of the vehicle under its current conditions.
uint16_t cached_max_speed
Maximum speed of the consist (minimum of the max speed of all vehicles in the consist).
uint8_t train_slope_steepness
Steepness of hills for trains when using realistic acceleration.
Sprite sequence for a vehicle part.
EngineID engine_type
The type of engine used for this vehicle.
Direction direction
facing
VehicleCargoList cargo
The cargo this vehicle is carrying.
VehStates vehstatus
Status.
bool IsArticulatedPart() const
Check if the vehicle is an articulated part of an engine.
CargoType cargo_type
type of cargo this vehicle is carrying
debug_inline bool IsFrontEngine() const
Check if the vehicle is a front engine.
void PreDestructor()
Destroy all stuff that (still) needs the virtual functions to work properly.
Definition vehicle.cpp:822
VehicleCache vcache
Cache of often used vehicle values.
uint16_t cur_speed
current speed
TileIndex tile
Current tile index.
TrackBits
Allow incrementing of Track variables.
Definition track_type.h:35
@ TRACK_BIT_WORMHOLE
Bitflag for a wormhole (used for tunnels)
Definition track_type.h:52
@ TRACK_BIT_DEPOT
Bitflag for a depot.
Definition track_type.h:53
@ TRACK_BIT_Y
Y-axis track.
Definition track_type.h:38
@ TRACK_BIT_X
X-axis track.
Definition track_type.h:37
Trackdir
Enumeration for tracks and directions.
Definition track_type.h:67
ConsistChangeFlag
Flags for Train::ConsistChanged.
Definition train.h:44
@ Capacity
Allow vehicles to change capacity.
@ Length
Allow vehicles to change length.
static constexpr ConsistChangeFlags CCF_TRACK
Valid changes while vehicle is driving, and possibly changing tracks.
Definition train.h:51
bool TryPathReserve(Train *v, bool mark_as_stuck=false, bool first_tile_okay=false)
Try to reserve a path to a safe position.
static constexpr ConsistChangeFlags CCF_SAVELOAD
Valid changes when loading a savegame. (Everything that is not stored in the save....
Definition train.h:56
VehicleRailFlags
Rail vehicle flags.
Definition train.h:25
@ VRF_POWEREDWAGON
Wagon is powered.
Definition train.h:27
@ VRF_LEAVING_STATION
Train is just leaving a station.
Definition train.h:33
@ VRF_TOGGLE_REVERSE
Used for vehicle var 0xFE bit 8 (toggled each time the train is reversed, accurate for first vehicle ...
Definition train.h:31
@ VRF_REVERSE_DIRECTION
Reverse the visible direction of the vehicle.
Definition train.h:28
@ VRF_EL_ENGINE_ALLOWED_NORMAL_RAIL
Electric train engine is allowed to run on normal rail. *‍/.
Definition train.h:30
@ VRF_TRAIN_STUCK
Train can't get a path reservation.
Definition train.h:32
void NormalizeTrainVehInDepot(const Train *u)
Move all free vehicles in the depot to the train.
uint8_t FreightWagonMult(CargoType cargo)
Return the cargo weight multiplier to use for a rail vehicle.
Definition train_cmd.cpp:69
void FreeTrainTrackReservation(const Train *v)
Free the reserved path in front of a vehicle.
static constexpr ConsistChangeFlags CCF_LOADUNLOAD
Valid changes while vehicle is loading/unloading.
Definition train.h:52
void CheckTrainsLengths()
Checks if lengths of all rail vehicles are valid.
Definition train_cmd.cpp:76
bool TrainOnCrossing(TileIndex tile)
Check if a level crossing tile has a train on it.
int GetTrainStopLocation(StationID station_id, TileIndex tile, const Train *v, int *station_ahead, int *station_length)
Get the stop location of (the center) of the front vehicle of a train at a platform of a station.
TrainForceProceeding
Modes for ignoring signals.
Definition train.h:37
@ TFP_SIGNAL
Ignore next signal, after the signal ignore being stuck.
Definition train.h:40
@ TFP_NONE
Normal operation.
Definition train.h:38
@ TFP_STUCK
Proceed till next signal, but ignore being stuck till then. This includes force leaving depots.
Definition train.h:39
static constexpr ConsistChangeFlags CCF_REFIT
Valid changes for refitting in a depot.
Definition train.h:54
static constexpr ConsistChangeFlags CCF_AUTOREFIT
Valid changes for autorefitting in stations.
Definition train.h:53
void GetTrainSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type)
Get the size of the sprite of a train sprite heading west, or both heads (used for lists).
static constexpr ConsistChangeFlags CCF_ARRANGE
Valid changes for arranging the consist in a depot.
Definition train.h:55
@ Hidden
Vehicle is not visible.
@ Stopped
Vehicle is stopped by the player.
EngineImageType
Visualisation contexts of vehicles and engines.
@ VEH_TRAIN
Train vehicle type.