From f97b6e8cbe39de532ca6d0031685481693a73678 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Thu, 18 Dec 2025 00:25:56 +0100 Subject: [PATCH] Pass inspection interval as a parameter to game actions --- distribution/changelog.txt | 2 ++ src/openrct2-ui/ride/Construction.cpp | 4 +++- src/openrct2-ui/windows/RideConstruction.cpp | 1 - src/openrct2-ui/windows/TrackDesignPlace.cpp | 14 +++++++++---- src/openrct2/actions/RideCreateAction.cpp | 14 ++++++++++--- src/openrct2/actions/RideCreateAction.h | 3 ++- src/openrct2/actions/TrackDesignAction.cpp | 22 +++++++++++++------- src/openrct2/actions/TrackDesignAction.h | 4 +++- src/openrct2/ride/Ride.cpp | 9 -------- src/openrct2/ride/Ride.h | 1 - src/openrct2/ride/TrackDesign.cpp | 4 +++- 11 files changed, 48 insertions(+), 30 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 52447bd4ba..57609070ae 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -24,8 +24,10 @@ - Fix: [#25588] When the master server becomes unreachable the server would not register again until a restart. - Fix: [#25592] Log flume, river rapids, & splash boats can get control failure breakdown instead of brakes failure. - Fix: [#25595] Invisible entrance is added to imported SV4 saves. +- Fix: [#25601] Inspection interval of a ride gets reset when opening the construction window. - Fix: [#25628] Availability of AVX2 and SSE4.1 is not detected correctly. - Fix: [#25639] Scenery window crashes when a no longer present object is still selected. +- Fix: [#25641] Desync because of mismatching inspection intervals. - Fix: [#25642] The selection marker for purchasing land rights is not drawn with the correct colours. - Fix: [#25646] It is possible to remove scenery and paths when setting staff patrol areas and purchasing land. - Fix: [#25660] After saving a track design with scenery, that ride’s entrances and exits are visible in ‘Highlight path issues’ mode. diff --git a/src/openrct2-ui/ride/Construction.cpp b/src/openrct2-ui/ride/Construction.cpp index 978beeb081..b025036747 100644 --- a/src/openrct2-ui/ride/Construction.cpp +++ b/src/openrct2-ui/ride/Construction.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -231,7 +232,8 @@ namespace OpenRCT2 int32_t colour2 = RideGetUnusedPresetVehicleColour(rideEntryIndex); auto gameAction = GameActions::RideCreateAction( - listItem.Type, listItem.EntryIndex, colour1, colour2, getGameState().lastEntranceStyle); + listItem.Type, listItem.EntryIndex, colour1, colour2, getGameState().lastEntranceStyle, + Config::Get().general.defaultInspectionInterval); gameAction.SetCallback([](const GameActions::GameAction* ga, const GameActions::Result* result) { if (result->error != GameActions::Status::ok) diff --git a/src/openrct2-ui/windows/RideConstruction.cpp b/src/openrct2-ui/windows/RideConstruction.cpp index 7efb2573bc..f0757d8eb1 100644 --- a/src/openrct2-ui/windows/RideConstruction.cpp +++ b/src/openrct2-ui/windows/RideConstruction.cpp @@ -326,7 +326,6 @@ namespace OpenRCT2::Ui::Windows } } - currentRide->setToDefaultInspectionInterval(); auto intent = Intent(WindowClass::ride); intent.PutExtra(INTENT_EXTRA_RIDE_ID, currentRide->id.ToUnderlying()); ContextOpenIntent(&intent); diff --git a/src/openrct2-ui/windows/TrackDesignPlace.cpp b/src/openrct2-ui/windows/TrackDesignPlace.cpp index 97d689e63d..777db90bd8 100644 --- a/src/openrct2-ui/windows/TrackDesignPlace.cpp +++ b/src/openrct2-ui/windows/TrackDesignPlace.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -225,7 +226,9 @@ namespace OpenRCT2::Ui::Windows if (res.error == GameActions::Status::ok) { // Valid location found. Place the ghost at the location. - auto tdAction = GameActions::TrackDesignAction(ghostTrackLoc, *_trackDesign, !gTrackDesignSceneryToggle); + auto tdAction = GameActions::TrackDesignAction( + ghostTrackLoc, *_trackDesign, !gTrackDesignSceneryToggle, + Config::Get().general.defaultInspectionInterval); tdAction.SetFlags({ CommandFlag::noSpend, CommandFlag::ghost }); tdAction.SetCallback([&](const GameActions::GameAction*, const GameActions::Result* result) { if (result->error == GameActions::Status::ok) @@ -297,7 +300,8 @@ namespace OpenRCT2::Ui::Windows _placingTrackDesign = true; auto tdAction = GameActions::TrackDesignAction( - { trackLoc, _currentTrackPieceDirection }, *_trackDesign, !gTrackDesignSceneryToggle); + { trackLoc, _currentTrackPieceDirection }, *_trackDesign, !gTrackDesignSceneryToggle, + Config::Get().general.defaultInspectionInterval); tdAction.SetCallback([&, trackLoc](const GameActions::GameAction*, const GameActions::Result* result) { if (result->error != GameActions::Status::ok) { @@ -400,7 +404,8 @@ namespace OpenRCT2::Ui::Windows if (_hasPlacementGhost) { auto tdAction = GameActions::TrackDesignAction( - { _placementGhostLoc }, *_trackDesign, !gTrackDesignSceneryToggle); + { _placementGhostLoc }, *_trackDesign, !gTrackDesignSceneryToggle, + Config::Get().general.defaultInspectionInterval); tdAction.SetFlags({ CommandFlag::noSpend, CommandFlag::ghost }); auto res = GameActions::Execute(&tdAction, getGameState()); if (res.error != GameActions::Status::ok) @@ -747,7 +752,8 @@ namespace OpenRCT2::Ui::Windows for (int32_t i = 0; i < 7; i++, loc.z += kCoordsZStep) { auto tdAction = GameActions::TrackDesignAction( - CoordsXYZD{ loc.x, loc.y, loc.z, _currentTrackPieceDirection }, *_trackDesign, !gTrackDesignSceneryToggle); + CoordsXYZD{ loc.x, loc.y, loc.z, _currentTrackPieceDirection }, *_trackDesign, !gTrackDesignSceneryToggle, + Config::Get().general.defaultInspectionInterval); tdAction.SetFlags(newFlags); res = GameActions::Query(&tdAction, getGameState()); diff --git a/src/openrct2/actions/RideCreateAction.cpp b/src/openrct2/actions/RideCreateAction.cpp index 0b0795fe0b..dcf4f21627 100644 --- a/src/openrct2/actions/RideCreateAction.cpp +++ b/src/openrct2/actions/RideCreateAction.cpp @@ -32,12 +32,13 @@ namespace OpenRCT2::GameActions { RideCreateAction::RideCreateAction( ride_type_t rideType, ObjectEntryIndex subType, uint8_t trackColourPreset, uint8_t vehicleColourPreset, - ObjectEntryIndex entranceObjectIndex) + ObjectEntryIndex entranceObjectIndex, RideInspection inspectionInterval) : _rideType(rideType) , _subType(subType) , _entranceObjectIndex(entranceObjectIndex) , _trackColourPreset(trackColourPreset) , _vehicleColourPreset(vehicleColourPreset) + , _inspectionInterval(inspectionInterval) { } @@ -48,6 +49,7 @@ namespace OpenRCT2::GameActions visitor.Visit("entranceObject", _entranceObjectIndex); visitor.Visit("colour1", _trackColourPreset); visitor.Visit("colour2", _vehicleColourPreset); + visitor.Visit("inspectionInterval", _inspectionInterval); } ride_type_t RideCreateAction::GetRideType() const @@ -70,11 +72,17 @@ namespace OpenRCT2::GameActions GameAction::Serialise(stream); stream << DS_TAG(_rideType) << DS_TAG(_subType) << DS_TAG(_entranceObjectIndex) << DS_TAG(_trackColourPreset) - << DS_TAG(_vehicleColourPreset); + << DS_TAG(_vehicleColourPreset) << DS_TAG(_inspectionInterval); } Result RideCreateAction::Query(GameState_t& gameState) const { + if (_inspectionInterval > RideInspection::never) + { + LOG_ERROR("Invalid inspection interval: %u", EnumValue(_inspectionInterval)); + return Result(Status::invalidParameters, STR_CANT_CHANGE_OPERATING_MODE, STR_ERR_VALUE_OUT_OF_RANGE); + } + auto rideIndex = GetNextFreeRideId(); if (rideIndex.IsNull()) { @@ -274,7 +282,7 @@ namespace OpenRCT2::GameActions ride->upkeepCost = kMoney64Undefined; ride->reliability = kRideInitialReliability; ride->unreliabilityFactor = 1; - ride->inspectionInterval = RideInspection::every30Minutes; + ride->inspectionInterval = _inspectionInterval; ride->lastCrashType = RIDE_CRASH_TYPE_NONE; ride->incomePerHour = kMoney64Undefined; ride->profit = kMoney64Undefined; diff --git a/src/openrct2/actions/RideCreateAction.h b/src/openrct2/actions/RideCreateAction.h index 910bea53d6..b386d45ddb 100644 --- a/src/openrct2/actions/RideCreateAction.h +++ b/src/openrct2/actions/RideCreateAction.h @@ -21,12 +21,13 @@ namespace OpenRCT2::GameActions ObjectEntryIndex _entranceObjectIndex{ kObjectEntryIndexNull }; uint8_t _trackColourPreset{ COLOUR_NULL }; uint8_t _vehicleColourPreset{ COLOUR_NULL }; + RideInspection _inspectionInterval{ RideInspection::every30Minutes }; public: RideCreateAction() = default; RideCreateAction( ride_type_t rideType, ObjectEntryIndex subType, uint8_t trackColourPreset, uint8_t vehicleColourPreset, - ObjectEntryIndex entranceStyleIndex); + ObjectEntryIndex entranceStyleIndex, RideInspection inspectionInterval); void AcceptParameters(GameActionParameterVisitor&) final; diff --git a/src/openrct2/actions/TrackDesignAction.cpp b/src/openrct2/actions/TrackDesignAction.cpp index 9c57bac225..5f6311ad56 100644 --- a/src/openrct2/actions/TrackDesignAction.cpp +++ b/src/openrct2/actions/TrackDesignAction.cpp @@ -27,10 +27,12 @@ namespace OpenRCT2::GameActions { - TrackDesignAction::TrackDesignAction(const CoordsXYZD& location, const TrackDesign& td, bool placeScenery) + TrackDesignAction::TrackDesignAction( + const CoordsXYZD& location, const TrackDesign& td, bool placeScenery, RideInspection inspectionInterval) : _loc(location) , _td(td) , _placeScenery(placeScenery) + , _inspectionInterval(inspectionInterval) { } @@ -52,6 +54,7 @@ namespace OpenRCT2::GameActions stream << DS_TAG(_loc); _td.Serialise(stream); stream << DS_TAG(_placeScenery); + stream << DS_TAG(_inspectionInterval); } Result TrackDesignAction::Query(GameState_t& gameState) const @@ -67,6 +70,12 @@ namespace OpenRCT2::GameActions return Result(Status::invalidParameters, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_OFF_EDGE_OF_MAP); } + if (_inspectionInterval > RideInspection::never) + { + LOG_ERROR("Invalid inspection interval: %u", EnumValue(_inspectionInterval)); + return Result(Status::invalidParameters, STR_CANT_CHANGE_OPERATING_MODE, STR_ERR_VALUE_OUT_OF_RANGE); + } + auto& objManager = GetContext()->GetObjectManager(); auto entryIndex = objManager.GetLoadedObjectEntryIndex(_td.trackAndVehicle.vehicleObject); if (entryIndex == kObjectEntryIndexNull) @@ -80,7 +89,8 @@ namespace OpenRCT2::GameActions } // Colours do not matter as will be overwritten - auto rideCreateAction = RideCreateAction(_td.trackAndVehicle.rtdIndex, entryIndex, 0, 0, gameState.lastEntranceStyle); + auto rideCreateAction = RideCreateAction( + _td.trackAndVehicle.rtdIndex, entryIndex, 0, 0, gameState.lastEntranceStyle, _inspectionInterval); rideCreateAction.SetFlags(GetFlags()); auto r = ExecuteNested(&rideCreateAction, gameState); if (r.error != Status::ok) @@ -150,7 +160,8 @@ namespace OpenRCT2::GameActions } // Colours do not matter as will be overwritten - auto rideCreateAction = RideCreateAction(_td.trackAndVehicle.rtdIndex, entryIndex, 0, 0, gameState.lastEntranceStyle); + auto rideCreateAction = RideCreateAction( + _td.trackAndVehicle.rtdIndex, entryIndex, 0, 0, gameState.lastEntranceStyle, _inspectionInterval); rideCreateAction.SetFlags(GetFlags()); auto r = ExecuteNested(&rideCreateAction, gameState); if (r.error != Status::ok) @@ -236,11 +247,6 @@ namespace OpenRCT2::GameActions auto numCircuits = std::max(1, _td.operation.numCircuits); SetOperatingSettingNested(ride->id, RideSetSetting::NumCircuits, numCircuits, flags); - auto defaultInspectionInterval = Config::Get().general.defaultInspectionInterval; - if (defaultInspectionInterval <= RideInspection::never) - SetOperatingSettingNested( - ride->id, RideSetSetting::InspectionInterval, EnumValue(defaultInspectionInterval), flags); - ride->lifecycleFlags |= RIDE_LIFECYCLE_NOT_CUSTOM_DESIGN; ride->vehicleColourSettings = _td.appearance.vehicleColourSettings; diff --git a/src/openrct2/actions/TrackDesignAction.h b/src/openrct2/actions/TrackDesignAction.h index 1b5acfa888..526a9e8f48 100644 --- a/src/openrct2/actions/TrackDesignAction.h +++ b/src/openrct2/actions/TrackDesignAction.h @@ -20,10 +20,12 @@ namespace OpenRCT2::GameActions CoordsXYZD _loc; TrackDesign _td; bool _placeScenery{ false }; + RideInspection _inspectionInterval{ RideInspection::every30Minutes }; public: TrackDesignAction() = default; - TrackDesignAction(const CoordsXYZD& location, const TrackDesign& td, bool placeScenery); + TrackDesignAction( + const CoordsXYZD& location, const TrackDesign& td, bool placeScenery, RideInspection inspectionInterval); void AcceptParameters(GameActionParameterVisitor&) final; diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 8de005a31a..49406f5715 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -5300,15 +5300,6 @@ void Ride::setReversedTrains(bool reverseTrains) GameActions::Execute(&rideSetVehicleAction, getGameState()); } -void Ride::setToDefaultInspectionInterval() -{ - auto defaultInspectionInterval = Config::Get().general.defaultInspectionInterval; - if (inspectionInterval != defaultInspectionInterval) - { - SetOperatingSetting(id, GameActions::RideSetSetting::InspectionInterval, EnumValue(defaultInspectionInterval)); - } -} - /** * * rct2: 0x006B752C diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 32be193a8e..4175c588bc 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -361,7 +361,6 @@ public: void renew(); void remove(); void crash(uint8_t vehicleIndex); - void setToDefaultInspectionInterval(); void setRideEntry(OpenRCT2::ObjectEntryIndex entryIndex); void setNumTrains(int32_t newNumTrains); diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index d39094f2f2..ded63ee05f 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -31,6 +31,7 @@ #include "../actions/WallPlaceAction.h" #include "../actions/WallRemoveAction.h" #include "../audio/Audio.h" +#include "../config/Config.h" #include "../core/DataSerialiser.h" #include "../core/File.h" #include "../core/Numerics.hpp" @@ -1859,7 +1860,8 @@ int32_t TrackDesignGetZPlacement(const TrackDesign& td, Ride& ride, const Coords static money64 TrackDesignCreateRide(int32_t type, int32_t subType, CommandFlags flags, RideId* outRideIndex) { // Don't set colours as will be set correctly later. - auto gameAction = GameActions::RideCreateAction(type, subType, 0, 0, getGameState().lastEntranceStyle); + auto gameAction = GameActions::RideCreateAction( + type, subType, 0, 0, getGameState().lastEntranceStyle, Config::Get().general.defaultInspectionInterval); gameAction.SetFlags(flags); auto& gameState = getGameState();