diff --git a/src/ground_vehicle.cpp b/src/ground_vehicle.cpp index f090e8827c..107112d938 100644 --- a/src/ground_vehicle.cpp +++ b/src/ground_vehicle.cpp @@ -225,7 +225,7 @@ GroundVehicleAcceleration GroundVehicle::GetAcceleration() braking_force = force; } - if (Type == VEH_TRAIN && _settings_game.vehicle.train_braking_model == TBM_REALISTIC) { + if (Type == VEH_TRAIN && Train::From(this)->UsingRealisticBraking()) { braking_power += (Train::From(this)->gcache.cached_total_length * (int64)RBC_BRAKE_POWER_PER_LENGTH); } @@ -265,7 +265,7 @@ GroundVehicleAcceleration GroundVehicle::GetAcceleration() } int braking_accel; - if (Type == VEH_TRAIN && _settings_game.vehicle.train_braking_model == TBM_REALISTIC) { + if (Type == VEH_TRAIN && Train::From(this)->UsingRealisticBraking()) { /* Assume that every part of a train is braked, not just the engine. * Exceptionally heavy freight trains should still have a sensible braking distance. * The total braking force is generally larger than the total tractive force. */ diff --git a/src/ground_vehicle.hpp b/src/ground_vehicle.hpp index ee1c83f24a..4bc6b982ea 100644 --- a/src/ground_vehicle.hpp +++ b/src/ground_vehicle.hpp @@ -438,13 +438,13 @@ protected: * @param advisory_max_speed The advisory maximum speed here, in vehicle specific units. * @return Distance to drive. */ - inline uint DoUpdateSpeed(GroundVehicleAcceleration accel, int min_speed, int max_speed, int advisory_max_speed) + inline uint DoUpdateSpeed(GroundVehicleAcceleration accel, int min_speed, int max_speed, int advisory_max_speed, bool use_realistic_braking) { const byte initial_subspeed = this->subspeed; uint spd = this->subspeed + accel.acceleration; this->subspeed = (byte)spd; - if (!(Type == VEH_TRAIN && _settings_game.vehicle.train_braking_model == TBM_REALISTIC)) { + if (!use_realistic_braking) { max_speed = std::min(max_speed, advisory_max_speed); } @@ -469,7 +469,7 @@ protected: } if (this->cur_speed > max_speed) { - if (Type == VEH_TRAIN && _settings_game.vehicle.train_braking_model == TBM_REALISTIC && accel.braking >= 0) { + if (use_realistic_braking && accel.braking >= 0) { extern void TrainBrakesOverheatedBreakdown(Vehicle *v); TrainBrakesOverheatedBreakdown(this); } @@ -478,12 +478,12 @@ protected: int tempspeed = this->cur_speed + ((int)spd >> 8); - if (Type == VEH_TRAIN && _settings_game.vehicle.train_braking_model == TBM_REALISTIC && tempspeed > advisory_max_speed && accel.braking != accel.acceleration) { + if (use_realistic_braking && tempspeed > advisory_max_speed && accel.braking != accel.acceleration) { spd = initial_subspeed + accel.braking; int braking_speed = this->cur_speed + ((int)spd >> 8); if (braking_speed >= advisory_max_speed) { if (braking_speed > tempmax) { - if (Type == VEH_TRAIN && _settings_game.vehicle.train_braking_model == TBM_REALISTIC && accel.braking >= 0) { + if (use_realistic_braking && accel.braking >= 0) { extern void TrainBrakesOverheatedBreakdown(Vehicle *v); TrainBrakesOverheatedBreakdown(this); } diff --git a/src/pbs.cpp b/src/pbs.cpp index 588808a8b8..f6f9b6e79b 100644 --- a/src/pbs.cpp +++ b/src/pbs.cpp @@ -1033,7 +1033,7 @@ CommandCost CheckTrainReservationPreventsTrackModification(TileIndex tile, Track CommandCost CheckTrainReservationPreventsTrackModification(const Train *v) { - if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC && v != nullptr && (v->cur_speed > 0 || !(v->vehstatus & (VS_STOPPED | VS_CRASHED)))) { + if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC && v != nullptr && v->UsingRealisticBraking() && (v->cur_speed > 0 || !(v->vehstatus & (VS_STOPPED | VS_CRASHED)))) { return_cmd_error(STR_ERROR_CANNOT_MODIFY_TRACK_TRAIN_APPROACHING); } return CommandCost(); diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 4944cdba2a..04653dde52 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -795,13 +795,13 @@ int RoadVehicle::UpdateSpeed() default: NOT_REACHED(); case AM_ORIGINAL: { int acceleration = this->overtaking != 0 ? 512 : 256; - return this->DoUpdateSpeed({ acceleration, acceleration }, 0, max_speed, max_speed); + return this->DoUpdateSpeed({ acceleration, acceleration }, 0, max_speed, max_speed, false); } case AM_REALISTIC: { GroundVehicleAcceleration acceleration = this->GetAcceleration(); if (this->overtaking != 0) acceleration.acceleration += 256; - return this->DoUpdateSpeed(acceleration, this->GetAccelerationStatus() == AS_BRAKE ? 0 : 4, max_speed, max_speed); + return this->DoUpdateSpeed(acceleration, this->GetAccelerationStatus() == AS_BRAKE ? 0 : 4, max_speed, max_speed, false); } } } diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 76e091050e..9fda946fcf 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -3647,7 +3647,7 @@ static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, i stop &= TILE_SIZE - 1; if (x == stop) { - if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC && front->cur_speed > 15 && !(front->lookahead != nullptr && HasBit(front->lookahead->flags, TRLF_APPLY_ADVISORY))) { + if (front->UsingRealisticBraking() && front->cur_speed > 15 && !(front->lookahead != nullptr && HasBit(front->lookahead->flags, TRLF_APPLY_ADVISORY))) { /* Travelling too fast, do not stop and report overshoot to player */ if (front->owner == _local_company) { SetDParam(0, front->index); @@ -3664,7 +3664,7 @@ static VehicleEnterTileStatus VehicleEnter_Station(Vehicle *v, TileIndex tile, i } return VETSB_ENTERED_STATION | (VehicleEnterTileStatus)(station_id << VETS_STATION_ID_OFFSET); // enter station } else if (x < stop) { - if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC && front->cur_speed > 30) { + if (front->UsingRealisticBraking()&& front->cur_speed > 30) { /* Travelling too fast, take no action */ return VETSB_CONTINUE; } diff --git a/src/table/newgrf_debug_data.h b/src/table/newgrf_debug_data.h index ca7f725dee..40e0b2e879 100644 --- a/src/table/newgrf_debug_data.h +++ b/src/table/newgrf_debug_data.h @@ -151,8 +151,11 @@ class NIHVehicle : public NIHelper { } if (v->type == VEH_TRAIN) { const Train *t = Train::From(v); - seprintf(buffer, lastof(buffer), " T cache: tilt: %d, engines: %u, decel: %u, uncapped decel: %u, centre mass: %u", - (t->tcache.cached_tflags & TCF_TILT) ? 1 : 0, t->tcache.cached_num_engines, t->tcache.cached_deceleration, t->tcache.cached_uncapped_decel, t->tcache.cached_centre_mass); + seprintf(buffer, lastof(buffer), " T cache: tilt: %d, engines: %u", + (t->tcache.cached_tflags & TCF_TILT) ? 1 : 0, t->tcache.cached_num_engines); + print(buffer); + seprintf(buffer, lastof(buffer), " T cache: RL braking: %d, decel: %u, uncapped decel: %u, centre mass: %u", + (t->UsingRealisticBraking()) ? 1 : 0, t->tcache.cached_deceleration, t->tcache.cached_uncapped_decel, t->tcache.cached_centre_mass); print(buffer); seprintf(buffer, lastof(buffer), " T cache: veh weight: %u, user data: %u, curve speed: %u", t->tcache.cached_veh_weight, t->tcache.user_def_data, t->tcache.cached_max_curve_speed); diff --git a/src/train.h b/src/train.h index 5bc82a47dc..6fd5186dd6 100644 --- a/src/train.h +++ b/src/train.h @@ -97,6 +97,7 @@ inline int GetTrainRealisticBrakingTargetDecelerationLimit(int acceleration_type enum TrainCacheFlags : byte { TCF_NONE = 0, ///< No flags TCF_TILT = 0x01, ///< Train can tilt; feature provides a bonus in curves. + TCF_RL_BRAKING = 0x02, ///< Train realistic braking (movement physics) in effect for this vehicle }; DECLARE_ENUM_AS_BIT_SET(TrainCacheFlags) @@ -204,6 +205,8 @@ public: int GetCurrentMaxSpeed() const; + bool UsingRealisticBraking() const { return this->tcache.cached_tflags & TCF_RL_BRAKING; } + /** * Get the next real (non-articulated part and non rear part of dualheaded engine) vehicle in the consist. * @return Next vehicle in the consist. diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 1c5327a8fd..f40dd69523 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -980,7 +980,7 @@ Train::MaxSpeedInfo Train::GetCurrentMaxSpeedInfoInternal(bool update_state) con int distance_to_go = station_ahead / TILE_SIZE - (station_length - stop_at) / TILE_SIZE; if (distance_to_go > 0) { - if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC) { + if (this->UsingRealisticBraking()) { advisory_max_speed = std::min(advisory_max_speed, 15 * distance_to_go); } else { int st_max_speed = 120; @@ -1028,7 +1028,7 @@ Train::MaxSpeedInfo Train::GetCurrentMaxSpeedInfoInternal(bool update_state) con advisory_max_speed = std::min(advisory_max_speed, ReversingDistanceTargetSpeed(this)); } - if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC) { + if (this->UsingRealisticBraking()) { if (this->lookahead != nullptr) { TrainDecelerationStats stats(this); if (HasBit(this->lookahead->flags, TRLF_DEPOT_END)) { @@ -1074,6 +1074,7 @@ void Train::UpdateAcceleration() this->acceleration = Clamp(power / weight * 4, 1, 255); if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC) { + this->tcache.cached_tflags |= TCF_RL_BRAKING; switch (_settings_game.vehicle.train_acceleration_model) { default: NOT_REACHED(); case AM_ORIGINAL: @@ -1130,6 +1131,7 @@ void Train::UpdateAcceleration() } } } else { + this->tcache.cached_tflags &= ~TCF_RL_BRAKING; this->tcache.cached_deceleration = 0; this->tcache.cached_uncapped_decel = 0; } @@ -3796,7 +3798,7 @@ public: static bool IsReservationLookAheadLongEnough(const Train *v, const ChooseTrainTrackLookAheadState &lookahead_state) { - if (_settings_game.vehicle.train_braking_model != TBM_REALISTIC || v->lookahead == nullptr) return true; + if (!v->UsingRealisticBraking() || v->lookahead == nullptr) return true; if (v->current_order.IsAnyLoadingType()) return true; @@ -4391,10 +4393,12 @@ int Train::UpdateSpeed() switch (_settings_game.vehicle.train_acceleration_model) { default: NOT_REACHED(); case AM_ORIGINAL: - return this->DoUpdateSpeed({ this->acceleration * (this->GetAccelerationStatus() == AS_BRAKE ? -4 : 2), this->acceleration * -4 }, 0, max_speed_info.strict_max_speed, max_speed_info.advisory_max_speed); + return this->DoUpdateSpeed({ this->acceleration * (this->GetAccelerationStatus() == AS_BRAKE ? -4 : 2), this->acceleration * -4 }, 0, + max_speed_info.strict_max_speed, max_speed_info.advisory_max_speed, this->UsingRealisticBraking()); case AM_REALISTIC: - return this->DoUpdateSpeed(this->GetAcceleration(), accel_status == AS_BRAKE ? 0 : 2, max_speed_info.strict_max_speed, max_speed_info.advisory_max_speed); + return this->DoUpdateSpeed(this->GetAcceleration(), accel_status == AS_BRAKE ? 0 : 2, + max_speed_info.strict_max_speed, max_speed_info.advisory_max_speed, this->UsingRealisticBraking()); } } /** @@ -4983,7 +4987,7 @@ inline void DecreaseReverseDistance(Train *v) int ReversingDistanceTargetSpeed(const Train *v) { - if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC) { + if (v->UsingRealisticBraking()) { TrainDecelerationStats stats(v); return GetRealisticBrakingSpeedForDistance(stats, v->reverse_distance - 1, 0, 0); }