| | 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 |
|
---|
15 | } | 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) */
|
---|
| | 59 | spd = v->GetOldAdvanceSpeed(spd);
|
---|
| | 60 |
|
---|
| | 61 | spd += v->progress;
|
---|
| | 62 | v->progress = (byte)spd;
|
---|
| | 63 | return spd >> 8;
|
---|
| | 64 | } |
---|