diff --git a/src/roadveh.h b/src/roadveh.h index e5bc0f3c5d..5ae519423b 100644 --- a/src/roadveh.h +++ b/src/roadveh.h @@ -150,7 +150,7 @@ struct RoadVehicle FINAL : public GroundVehicle { int GetCurrentMaxSpeed() const; int GetEffectiveMaxSpeed() const; int GetDisplayEffectiveMaxSpeed() const { return this->GetEffectiveMaxSpeed() / 2; } - int UpdateSpeed(); + int UpdateSpeed(int max_speed); void SetDestTile(TileIndex tile); inline bool IsRoadVehicleOnLevelCrossing() const diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index fdeab17d4d..444097a83a 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -795,11 +795,11 @@ static void RoadVehArrivesAt(const RoadVehicle *v, Station *st) * and subspeed) variables. Furthermore, it returns the distance that * the vehicle can drive this tick. #Vehicle::GetAdvanceDistance() determines * the distance to drive before moving a step on the map. + * @param max_speed maximum speed as from GetCurrentMaxSpeed() * @return distance to drive. */ -int RoadVehicle::UpdateSpeed() +int RoadVehicle::UpdateSpeed(int max_speed) { - int max_speed = this->GetCurrentMaxSpeed(); switch (_settings_game.vehicle.roadveh_acceleration_model) { default: NOT_REACHED(); case AM_ORIGINAL: { @@ -2126,10 +2126,14 @@ static bool RoadVehController(RoadVehicle *v) if (v->IsInDepot() && RoadVehLeaveDepot(v, true)) return true; - v->ShowVisualEffect(); + int j; + { + int max_speed = v->GetCurrentMaxSpeed(); + v->ShowVisualEffect(max_speed); - /* Check how far the vehicle needs to proceed */ - int j = v->UpdateSpeed(); + /* Check how far the vehicle needs to proceed */ + j = v->UpdateSpeed(max_speed); + } int adv_spd = v->GetAdvanceDistance(); bool blocked = false; diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index f6723b555a..f404195798 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -885,7 +885,7 @@ static void ShipController(Ship *v) if (CheckShipLeaveDepot(v)) return; - v->ShowVisualEffect(); + v->ShowVisualEffect(UINT_MAX); /* Rotating on spot */ if (v->direction != v->rotation) { diff --git a/src/train.h b/src/train.h index 20556a92a5..77d7935ced 100644 --- a/src/train.h +++ b/src/train.h @@ -185,15 +185,15 @@ struct Train FINAL : public GroundVehicle { void ConsistChanged(ConsistChangeFlags allowed_changes); - int UpdateSpeed(); - - void UpdateAcceleration(); - struct MaxSpeedInfo { int strict_max_speed; int advisory_max_speed; }; + int UpdateSpeed(MaxSpeedInfo max_speed_info); + + void UpdateAcceleration(); + bool ConsistNeedsRepair() const; private: diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index c2c0c6d3d5..e85b261263 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -4582,17 +4582,16 @@ void Train::MarkDirty() * the distance to drive before moving a step on the map. * @return distance to drive. */ -int Train::UpdateSpeed() +int Train::UpdateSpeed(MaxSpeedInfo max_speed_info) { AccelStatus accel_status = this->GetAccelerationStatus(); - MaxSpeedInfo max_speed_info = this->GetCurrentMaxSpeedInfoAndUpdate(); if (this->lookahead != nullptr && HasBit(this->lookahead->flags, TRLF_APPLY_ADVISORY) && this->cur_speed <= max_speed_info.strict_max_speed) { ClrBit(this->lookahead->flags, TRLF_APPLY_ADVISORY); } 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, + return this->DoUpdateSpeed({ this->acceleration * (accel_status == 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: @@ -6397,8 +6396,6 @@ static bool TrainLocoHandler(Train *v, bool mode) } } - if (!mode) v->ShowVisualEffect(); - /* We had no order but have an order now, do look ahead. */ if (!valid_order && !v->current_order.IsType(OT_NOTHING)) { CheckNextTrainTile(v); @@ -6461,7 +6458,13 @@ static bool TrainLocoHandler(Train *v, bool mode) return true; } - int j = v->UpdateSpeed(); + int j; + { + Train::MaxSpeedInfo max_speed_info = v->GetCurrentMaxSpeedInfoAndUpdate(); + + if (!mode) v->ShowVisualEffect(std::min(max_speed_info.strict_max_speed, max_speed_info.advisory_max_speed)); + j = v->UpdateSpeed(max_speed_info); + } /* we need to invalidate the widget if we are stopping from 'Stopping 0 km/h' to 'Stopped' */ if (v->cur_speed == 0 && (v->vehstatus & VS_STOPPED)) { diff --git a/src/vehicle.cpp b/src/vehicle.cpp index a6446748b0..ca0f107793 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -3865,9 +3865,10 @@ int ReversingDistanceTargetSpeed(const Train *v); /** * Draw visual effects (smoke and/or sparks) for a vehicle chain. + * @param max_speed The speed as limited by underground and orders, UINT_MAX if not already known * @pre this->IsPrimaryVehicle() */ -void Vehicle::ShowVisualEffect() const +void Vehicle::ShowVisualEffect(uint max_speed) const { assert(this->IsPrimaryVehicle()); bool sound = false; @@ -3883,8 +3884,7 @@ void Vehicle::ShowVisualEffect() const return; } - /* Use the speed as limited by underground and orders. */ - uint max_speed = this->GetCurrentMaxSpeed(); + if (max_speed == UINT_MAX) max_speed = this->GetCurrentMaxSpeed(); if (this->type == VEH_TRAIN) { const Train *t = Train::From(this); diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 0cc59bf63d..4558eed572 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -884,7 +884,7 @@ public: CommandCost SendToDepot(DoCommandFlag flags, DepotCommand command, TileIndex specific_depot = 0); void UpdateVisualEffect(bool allow_power_change = true); - void ShowVisualEffect() const; + void ShowVisualEffect(uint max_speed) const; /** * Update the position of the vehicle. This will update the hash that tells