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.
This commit is contained in:
@@ -726,6 +726,7 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
|
|||||||
SLE_CONDNULL(2, 2, 19),
|
SLE_CONDNULL(2, 2, 19),
|
||||||
SLE_CONDVAR(Train, gv_flags, SLE_UINT16, 139, SL_MAX_VERSION),
|
SLE_CONDVAR(Train, gv_flags, SLE_UINT16, 139, SL_MAX_VERSION),
|
||||||
SLE_CONDNULL(11, 2, 143), // old reserved space
|
SLE_CONDNULL(11, 2, 143), // old reserved space
|
||||||
|
SLE_CONDVAR(Train, critical_breakdown_count, SLE_UINT8, SL_IB, SL_MAX_VERSION),
|
||||||
|
|
||||||
SLE_END()
|
SLE_END()
|
||||||
};
|
};
|
||||||
|
@@ -462,7 +462,7 @@ struct VehicleSettings {
|
|||||||
byte extend_vehicle_life; ///< extend vehicle life by this many years
|
byte extend_vehicle_life; ///< extend vehicle life by this many years
|
||||||
byte road_side; ///< the side of the road vehicles drive on
|
byte road_side; ///< the side of the road vehicles drive on
|
||||||
uint8 plane_crashes; ///< number of plane crashes, 0 = none, 1 = reduced, 2 = normal
|
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. */
|
/** Settings related to the economy. */
|
||||||
|
@@ -106,6 +106,7 @@ struct Train FINAL : public GroundVehicle<Train, VEH_TRAIN> {
|
|||||||
TrackBitsByte track;
|
TrackBitsByte track;
|
||||||
TrainForceProceedingByte force_proceed;
|
TrainForceProceedingByte force_proceed;
|
||||||
RailTypeByte railtype;
|
RailTypeByte railtype;
|
||||||
|
byte critical_breakdown_count; ///< Counter for the number of critical breakdowns since last service
|
||||||
RailTypes compatible_railtypes;
|
RailTypes compatible_railtypes;
|
||||||
|
|
||||||
/** Ticks waiting in front of a signal, ticks being stuck or a counter for forced proceeding through signals. */
|
/** Ticks waiting in front of a signal, ticks being stuck or a counter for forced proceeding through signals. */
|
||||||
|
@@ -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);
|
u->tcache.user_def_data = GetVehicleProperty(u, PROP_TRAIN_USER_DATA, u->tcache.user_def_data);
|
||||||
this->InvalidateNewGRFCache();
|
this->InvalidateNewGRFCache();
|
||||||
u->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()) {
|
for (Train *u = this; u != NULL; u = u->Next()) {
|
||||||
@@ -233,12 +239,12 @@ void Train::ConsistChanged(ConsistChangeFlags allowed_changes)
|
|||||||
/* max speed is the minimum of the speed limits of all vehicles in the consist */
|
/* 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)) {
|
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);
|
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()) {
|
||||||
if (speed != 0) max_speed = min(speed, max_speed);
|
for (uint i = 0; i < u->critical_breakdown_count; i++) {
|
||||||
|
speed = min(speed - (speed / (this->tcache.cached_num_engines + 2)) + 1, speed);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (u->IsEngine() || u-> IsMultiheaded()) {
|
if (speed != 0) max_speed = min(speed, max_speed);
|
||||||
this->tcache.cached_num_engines++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -104,6 +104,7 @@ void VehicleServiceInDepot(Vehicle *v)
|
|||||||
if (v->Next() != NULL) VehicleServiceInDepot(v->Next());
|
if (v->Next() != NULL) VehicleServiceInDepot(v->Next());
|
||||||
if (!(Train::From(v)->IsEngine()) && !(Train::From(v)->IsRearDualheaded())) return;
|
if (!(Train::From(v)->IsEngine()) && !(Train::From(v)->IsRearDualheaded())) return;
|
||||||
ClrBit(Train::From(v)->flags,VRF_NEED_REPAIR);
|
ClrBit(Train::From(v)->flags,VRF_NEED_REPAIR);
|
||||||
|
Train::From(v)->critical_breakdown_count = 0;
|
||||||
const RailVehicleInfo *rvi = &e->u.rail;
|
const RailVehicleInfo *rvi = &e->u.rail;
|
||||||
v->vcache.cached_max_speed = rvi->max_speed;
|
v->vcache.cached_max_speed = rvi->max_speed;
|
||||||
if (Train::From(v)->IsFrontEngine()) {
|
if (Train::From(v)->IsFrontEngine()) {
|
||||||
@@ -1352,17 +1353,12 @@ bool Vehicle::HandleBreakdown()
|
|||||||
}
|
}
|
||||||
/* Max Speed reduction*/
|
/* Max Speed reduction*/
|
||||||
if (_settings_game.vehicle.improved_breakdowns) {
|
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 (!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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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<uint16>(rvi->max_speed / 4, 28));
|
|
||||||
SetBit(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++;
|
||||||
|
}
|
||||||
Train::From(this->First())->ConsistChanged(CCF_TRACK);
|
Train::From(this->First())->ConsistChanged(CCF_TRACK);
|
||||||
}
|
}
|
||||||
/* FALL THROUGH */
|
/* FALL THROUGH */
|
||||||
|
Reference in New Issue
Block a user