From 5e924262f48df6f655b2184b9ed82781ed80c6b7 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Mon, 18 Jan 2016 18:27:51 +0000 Subject: [PATCH] Fix speed reduction after critical breakdowns. Previous code set vcache.cached_max_speed directly (and incorrectly), which did not survive across save/load or network joins. Instead add a struct Train field to store the number of critical breakdowns since last service and do the speed reduction properly in Train::ConsistChanged. Slightly tweak algorithm for speed reduction. --- src/saveload/vehicle_sl.cpp | 1 + src/settings_type.h | 2 +- src/train.h | 1 + src/train_cmd.cpp | 16 +++++++++++----- src/vehicle.cpp | 16 ++++++---------- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 6aab04102c..def7ada99d 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -726,6 +726,7 @@ const SaveLoad *GetVehicleDescription(VehicleType vt) SLE_CONDNULL(2, 2, 19), SLE_CONDVAR(Train, gv_flags, SLE_UINT16, 139, SL_MAX_VERSION), SLE_CONDNULL(11, 2, 143), // old reserved space + SLE_CONDVAR(Train, critical_breakdown_count, SLE_UINT8, SL_IB, SL_MAX_VERSION), SLE_END() }; diff --git a/src/settings_type.h b/src/settings_type.h index 035bef31a8..2aef7f3cc9 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -462,7 +462,7 @@ struct VehicleSettings { byte extend_vehicle_life; ///< extend vehicle life by this many years byte road_side; ///< the side of the road vehicles drive on uint8 plane_crashes; ///< number of plane crashes, 0 = none, 1 = reduced, 2 = normal - bool improved_breakdowns; ///< different types, chances and serverities of breakdowns + bool improved_breakdowns; ///< different types, chances and severities of breakdowns }; /** Settings related to the economy. */ diff --git a/src/train.h b/src/train.h index 9c745676b4..e6acea7981 100644 --- a/src/train.h +++ b/src/train.h @@ -106,6 +106,7 @@ struct Train FINAL : public GroundVehicle { TrackBitsByte track; TrainForceProceedingByte force_proceed; RailTypeByte railtype; + byte critical_breakdown_count; ///< Counter for the number of critical breakdowns since last service RailTypes compatible_railtypes; /** Ticks waiting in front of a signal, ticks being stuck or a counter for forced proceeding through signals. */ diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index d8873654a4..4c83477fd5 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -191,6 +191,12 @@ void Train::ConsistChanged(ConsistChangeFlags allowed_changes) u->tcache.user_def_data = GetVehicleProperty(u, PROP_TRAIN_USER_DATA, u->tcache.user_def_data); this->InvalidateNewGRFCache(); u->InvalidateNewGRFCache(); + + if (!u->IsArticulatedPart()) { + if (u->IsEngine() || u->IsMultiheaded()) { + this->tcache.cached_num_engines++; + } + } } for (Train *u = this; u != NULL; u = u->Next()) { @@ -233,13 +239,13 @@ void Train::ConsistChanged(ConsistChangeFlags allowed_changes) /* max speed is the minimum of the speed limits of all vehicles in the consist */ if ((rvi_u->railveh_type != RAILVEH_WAGON || _settings_game.vehicle.wagon_speed_limits) && !UsesWagonOverride(u)) { uint16 speed = GetVehicleProperty(u, PROP_TRAIN_SPEED, rvi_u->max_speed); - if (HasBit(u->flags, VRF_NEED_REPAIR)) speed = u->vcache.cached_max_speed; + if (HasBit(u->flags, VRF_NEED_REPAIR) && this->IsFrontEngine()) { + for (uint i = 0; i < u->critical_breakdown_count; i++) { + speed = min(speed - (speed / (this->tcache.cached_num_engines + 2)) + 1, speed); + } + } if (speed != 0) max_speed = min(speed, max_speed); } - - if (u->IsEngine() || u-> IsMultiheaded()) { - this->tcache.cached_num_engines++; - } } uint16 new_cap = e_u->DetermineCapacity(u); diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 8aebcf9594..398c61bdae 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -104,6 +104,7 @@ void VehicleServiceInDepot(Vehicle *v) if (v->Next() != NULL) VehicleServiceInDepot(v->Next()); if (!(Train::From(v)->IsEngine()) && !(Train::From(v)->IsRearDualheaded())) return; ClrBit(Train::From(v)->flags,VRF_NEED_REPAIR); + Train::From(v)->critical_breakdown_count = 0; const RailVehicleInfo *rvi = &e->u.rail; v->vcache.cached_max_speed = rvi->max_speed; if (Train::From(v)->IsFrontEngine()) { @@ -1352,17 +1353,12 @@ bool Vehicle::HandleBreakdown() } /* Max Speed reduction*/ if (_settings_game.vehicle.improved_breakdowns) { - const Engine *e = Engine::Get(this->engine_type); - const RailVehicleInfo *rvi = &e->u.rail; - if (!HasBit(Train::From(this)->flags,VRF_NEED_REPAIR)) { - if (rvi->max_speed > this->vcache.cached_max_speed) { - this->vcache.cached_max_speed = rvi->max_speed; - } + if (!HasBit(Train::From(this)->flags, VRF_NEED_REPAIR)) { + SetBit(Train::From(this)->flags, VRF_NEED_REPAIR); + Train::From(this)->critical_breakdown_count = 1; + } else if (Train::From(this)->critical_breakdown_count != 255) { + Train::From(this)->critical_breakdown_count++; } - uint16 target_max_speed = min(this->vcache.cached_max_speed - - (this->vcache.cached_max_speed >> 1) / Train::From(this->First())->tcache.cached_num_engines + 1, this->vcache.cached_max_speed); - this->vcache.cached_max_speed = max(target_max_speed, min(rvi->max_speed / 4, 28)); - SetBit(Train::From(this)->flags, VRF_NEED_REPAIR); Train::From(this->First())->ConsistChanged(CCF_TRACK); } /* FALL THROUGH */