Add train cache flag for whether train using realistic braking physics
This commit is contained in:
@@ -225,7 +225,7 @@ GroundVehicleAcceleration GroundVehicle<T, Type>::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<T, Type>::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. */
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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();
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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.
|
||||
|
@@ -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<int>(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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user