MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / GetAcceleration

Method GetAcceleration

src/ground_vehicle.cpp:105–183  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

103 */
104template <class T, VehicleType Type>
105int GroundVehicle<T, Type>::GetAcceleration() const
106{
107 /* Templated class used for function calls for performance reasons. */
108 const T *v = T::From(this);
109 /* Speed is used squared later on, so U16 * U16, and then multiplied by other values. */
110 int64_t speed = v->GetCurrentSpeed(); // [km/h-ish]
111
112 /* Weight is stored in tonnes. */
113 int64_t mass = this->gcache.cached_weight;
114
115 /* Power is stored in HP, we need it in watts.
116 * Each vehicle can have U16 power, 128 vehicles, HP -> watt
117 * and km/h to m/s conversion below result in a maximum of
118 * about 1.1E11, way more than 4.3E9 of int32. */
119 int64_t power = this->gcache.cached_power * 746ll;
120
121 /* This is constructed from:
122 * - axle resistance: U16 power * 10 for 128 vehicles.
123 * * 8.3E7
124 * - rolling friction: U16 power * 144 for 128 vehicles.
125 * * 1.2E9
126 * - slope resistance: U16 weight * 100 * 10 (steepness) for 128 vehicles.
127 * * 8.4E9
128 * - air drag: 28 * (U8 drag + 3 * U8 drag * 128 vehicles / 20) * U16 speed * U16 speed
129 * * 6.2E14 before dividing by 1000
130 * Sum is 6.3E11, more than 4.3E9 of int32_t, so int64_t is needed.
131 */
132 int64_t resistance = 0;
133
134 bool maglev = v->GetAccelerationType() == VehicleAccelerationModel::Maglev;
135
136 const int area = v->GetAirDragArea();
137 if (!maglev) {
138 /* Static resistance plus rolling friction. */
139 resistance = this->gcache.cached_axle_resistance;
140 resistance += mass * v->GetRollingFriction();
141 }
142 /* Air drag; the air drag coefficient is in an arbitrary NewGRF-unit,
143 * so we need some magic conversion factor. */
144 resistance += static_cast<int64_t>(area) * this->gcache.cached_air_drag * speed * speed / 1000;
145
146 resistance += this->GetSlopeResistance();
147
148 /* This value allows to know if the vehicle is accelerating or braking. */
149 AccelStatus mode = v->GetAccelerationStatus();
150
151 const int max_te = this->gcache.cached_max_te; // [N]
152 /* Constructed from power, with need to multiply by 18 and assuming
153 * low speed, it needs to be a 64 bit integer too. */
154 int64_t force;
155 if (speed > 0) {
156 if (!maglev) {
157 /* Conversion factor from km/h to m/s is 5/18 to get [N] in the end. */
158 force = power * 18 / (speed * 5);
159 if (mode == AS_ACCEL && force > max_te) force = max_te;
160 } else {
161 force = power / 25;
162 }

Callers 3

UpdateSpeedMethod · 0.80
UpdateSpeedMethod · 0.80
RoadVehCheckOvertakeFunction · 0.80

Calls 6

GetSlopeResistanceMethod · 0.95
GetCurrentSpeedMethod · 0.45
GetAccelerationTypeMethod · 0.45
GetAirDragAreaMethod · 0.45
GetRollingFrictionMethod · 0.45
GetAccelerationStatusMethod · 0.45

Tested by

no test coverage detected