diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/settings.cpp | 5 | ||||
-rw-r--r-- | src/train.h | 6 | ||||
-rw-r--r-- | src/train_cmd.cpp | 61 |
3 files changed, 47 insertions, 25 deletions
diff --git a/src/settings.cpp b/src/settings.cpp index c842ff5fa..73606af18 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -735,7 +735,10 @@ static bool TrainAccelerationModelChanged(int32 p1) { Train *t; FOR_ALL_TRAINS(t) { - if (IsFrontEngine(t)) UpdateTrainAcceleration(t); + if (IsFrontEngine(t)) { + t->tcache.cached_max_curve_speed = GetTrainCurveSpeedLimit(t); + UpdateTrainAcceleration(t); + } } return true; diff --git a/src/train.h b/src/train.h index c1f9f120d..bcf005472 100644 --- a/src/train.h +++ b/src/train.h @@ -257,6 +257,7 @@ int GetTrainStopLocation(StationID station_id, TileIndex tile, const Train *v, i void TrainConsistChanged(Train *v, bool same_length); void TrainPowerChanged(Train *v); +int GetTrainCurveSpeedLimit(Train *v); Money GetTrainRunningCost(const Train *v); /** Variables that are cached to improve performance and such */ @@ -268,7 +269,6 @@ struct TrainCache { /* cached values, recalculated on load and each time a vehicle is added to/removed from the consist. */ uint32 cached_power; ///< total power of the consist. - uint16 cached_max_speed; ///< max speed of the consist. (minimum of the max speed of all vehicles in the consist) uint16 cached_total_length; ///< Length of the whole train, valid only for first engine. uint8 cached_veh_length; ///< length of this vehicle in units of 1/8 of normal length, cached because this can be set by a callback bool cached_tilt; ///< train can tilt; feature provides a bonus in curves @@ -278,6 +278,10 @@ struct TrainCache { uint32 cached_veh_weight; ///< weight of the vehicle. uint32 cached_max_te; ///< max tractive effort of consist + /* cached max. speed / acceleration data */ + uint16 cached_max_speed; ///< max speed of the consist. (minimum of the max speed of all vehicles in the consist) + int cached_max_curve_speed; ///< max consist speed limited by curves + /** * Position/type of visual effect. * bit 0 - 3 = position of effect relative to vehicle. (0 = front, 8 = centre, 15 = rear) diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index eb75b2388..6ad8707c6 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -342,6 +342,7 @@ void TrainConsistChanged(Train *v, bool same_length) /* store consist weight/max speed in cache */ v->tcache.cached_max_speed = max_speed; v->tcache.cached_tilt = train_can_tilt; + v->tcache.cached_max_curve_speed = GetTrainCurveSpeedLimit(v); /* recalculate cached weights and power too (we do this *after* the rest, so it is known which wagons are powered and need extra weight added) */ TrainCargoChanged(v); @@ -406,12 +407,19 @@ int GetTrainStopLocation(StationID station_id, TileIndex tile, const Train *v, i return stop - (v->tcache.cached_veh_length + 1) / 2; } -/** new acceleration*/ -static int GetTrainAcceleration(Train *v, bool mode) + +/** + * Computes train speed limit caused by curves + * @param v first vehicle of consist + * @return imposed speed limit + */ +int GetTrainCurveSpeedLimit(Train *v) { static const int absolute_max_speed = UINT16_MAX; int max_speed = absolute_max_speed; - int speed = v->cur_speed * 10 / 16; // km-ish/h -> mp/h + + if (_settings_game.vehicle.train_acceleration_model == TAM_ORIGINAL) return max_speed; + int curvecount[2] = {0, 0}; /* first find the curve speed limit */ @@ -445,13 +453,11 @@ static int GetTrainAcceleration(Train *v, bool mode) } } - if ((curvecount[0] != 0 || curvecount[1] != 0) && max_speed > 88) { - int total = curvecount[0] + curvecount[1]; - + if (numcurve > 0 && max_speed > 88) { if (curvecount[0] == 1 && curvecount[1] == 1) { max_speed = absolute_max_speed; - } else if (total > 1) { - if (numcurve > 0) sum /= numcurve; + } else { + sum /= numcurve; max_speed = 232 - (13 - Clamp(sum, 1, 12)) * (13 - Clamp(sum, 1, 12)); } } @@ -467,6 +473,16 @@ static int GetTrainAcceleration(Train *v, bool mode) } } + return max_speed; +} + +/** new acceleration*/ +static int GetTrainAcceleration(Train *v, bool mode) +{ + int max_speed = v->tcache.cached_max_curve_speed; + assert(max_speed == GetTrainCurveSpeedLimit(v)); // safety check, will be removed later + int speed = v->cur_speed * 10 / 16; // km-ish/h -> mp/h + if (IsTileType(v->tile, MP_STATION) && IsFrontEngine(v)) { StationID sid = GetStationIndex(v->tile); if (v->current_order.ShouldStopAtStation(v, sid)) { @@ -3425,18 +3441,6 @@ static const RailtypeSlowdownParams _railtype_slowdown[] = { {0, 256 / 2, 256 / 4, 2}, ///< maglev }; -/** Modify the speed of the vehicle due to a turn */ -static inline void AffectSpeedByDirChange(Train *v, Direction new_dir) -{ - if (_settings_game.vehicle.train_acceleration_model != TAM_ORIGINAL) return; - - DirDiff diff = DirDifference(v->direction, new_dir); - if (diff == DIRDIFF_SAME) return; - - const RailtypeSlowdownParams *rsp = &_railtype_slowdown[v->railtype]; - v->cur_speed -= (diff == DIRDIFF_45RIGHT || diff == DIRDIFF_45LEFT ? rsp->small_turn : rsp->large_turn) * v->cur_speed >> 8; -} - /** Modify the speed of the vehicle due to a change in altitude */ static inline void AffectSpeedByZChange(Train *v, byte old_z) { @@ -3637,7 +3641,9 @@ static Vehicle *CheckVehicleAtSignal(Vehicle *v, void *data) static void TrainController(Train *v, Vehicle *nomove) { + Train *first = v->First(); Train *prev; + bool direction_changed = false; // has direction of any part changed? /* For every vehicle after and including the given vehicle */ for (prev = v->Previous(); v != nomove; prev = v, v = v->Next()) { @@ -3817,9 +3823,15 @@ static void TrainController(Train *v, Vehicle *nomove) * has been updated by AfterSetTrainPos() */ update_signals_crossing = true; - if (prev == NULL) AffectSpeedByDirChange(v, chosen_dir); - - v->direction = chosen_dir; + if (chosen_dir != v->direction) { + if (prev == NULL && _settings_game.vehicle.train_acceleration_model == TAM_ORIGINAL) { + const RailtypeSlowdownParams *rsp = &_railtype_slowdown[v->railtype]; + DirDiff diff = DirDifference(v->direction, chosen_dir); + v->cur_speed -= (diff == DIRDIFF_45RIGHT || diff == DIRDIFF_45LEFT ? rsp->small_turn : rsp->large_turn) * v->cur_speed >> 8; + } + direction_changed = true; + v->direction = chosen_dir; + } if (IsFrontEngine(v)) { v->load_unload_time_rem = 0; @@ -3904,6 +3916,9 @@ static void TrainController(Train *v, Vehicle *nomove) /* Do not check on every tick to save some computing time. */ if (IsFrontEngine(v) && v->tick_counter % _settings_game.pf.path_backoff_interval == 0) CheckNextTrainTile(v); } + + if (direction_changed) first->tcache.cached_max_curve_speed = GetTrainCurveSpeedLimit(first); + return; invalid_rail: |