#### Paste #p4ykc3h3j

1. /**
2.  * Sets the new speed for an aircraft
3.  * @param v The vehicle for which the speed should be obtained
4.  * @param speed_limit The maximum speed the vehicle may have.
5.  * @param hard_limit If true, the limit is directly enforced, otherwise the plane is slowed down gradually
6.  * @return The number of position updates needed within the tick
7.  */
8. static int UpdateAircraftSpeed(Aircraft *v, uint speed_limit = SPEED_LIMIT_NONE, bool hard_limit = true)
9. {
10.     /**
11.      * 'acceleration' has the unit 3/8 mph/tick. This function is called twice per tick.
12.      * So the speed amount we need to accelerate is:
13.      *     acceleration * 3 / 16 mph = acceleration * 3 / 16 * 16 / 10 km-ish/h
14.      *                               = acceleration * 3 / 10 * 256 * (km-ish/h / 256)
15.      *                               ~ acceleration * 77 (km-ish/h / 256)
16.      */
17.     uint spd = v->acceleration * 77;
18.     byte t;
19.
20.     /* Adjust speed limits by plane speed factor to prevent taxiing
21.      * and take-off speeds being too low. */
22.     speed_limit *= _settings_game.vehicle.plane_speed;
23.
24.     /* adjust speed for broken vehicles */
25.     if (v->vehstatus & VS_AIRCRAFT_BROKEN) {
26.         if (speed_limit > SPEED_LIMIT_BROKEN) hard_limit = false;
27.         speed_limit = min(speed_limit, SPEED_LIMIT_BROKEN);
28.     }
29.
30.     if (v->vcache.cached_max_speed < speed_limit) {
31.         if (v->cur_speed < speed_limit) hard_limit = false;
32.         speed_limit = v->vcache.cached_max_speed;
33.     }
34.
35.     v->subspeed = (t = v->subspeed) + (byte)spd;
36.
37.     /* Aircraft's current speed is used twice so that very fast planes are
38.      * forced to slow down rapidly in the short distance needed. The magic
39.      * value 16384 was determined to give similar results to the old speed/48
40.      * method at slower speeds. This also results in less reduction at slow
41.      * speeds to that aircraft do not get to taxi speed straight after
42.      * touchdown. */
43.     if (!hard_limit && v->cur_speed > speed_limit) {
44.         speed_limit = v->cur_speed - max(1, ((v->cur_speed * v->cur_speed) / 16384) / _settings_game.vehicle.plane_speed);
45.     }
46.
47.     spd = min(v->cur_speed + (spd >> 8) + (v->subspeed < t), speed_limit);
48.
49.     /* updates statusbar only if speed have changed to save CPU time */
50.     if (spd != v->cur_speed) {
51.         v->cur_speed = spd;
52.         SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
53.     }
54.
55.     /* Adjust distance moved by plane speed setting */
56.     if (_settings_game.vehicle.plane_speed > 1) spd /= _settings_game.vehicle.plane_speed;
57.
58.     /* Convert direction-independent speed into direction-dependent speed. (old movement method) */