From d01dfe44d5550266415c579b460282b43567dbfd Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Fri, 22 Feb 2019 10:13:08 +0000 Subject: [PATCH] Add RideSetSettingAction Use game action for calling Use correct error titles for operation mode changes --- src/openrct2-ui/windows/Ride.cpp | 81 ++--- .../actions/GameActionRegistration.cpp | 2 + src/openrct2/actions/RideSetSetting.hpp | 331 ++++++++++++++++++ src/openrct2/interface/InteractiveConsole.cpp | 3 +- src/openrct2/ride/Ride.cpp | 19 +- src/openrct2/ride/Ride.h | 6 +- src/openrct2/ride/TrackDesign.cpp | 15 +- 7 files changed, 392 insertions(+), 65 deletions(-) create mode 100644 src/openrct2/actions/RideSetSetting.hpp diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index abde237bce..427f4f1d40 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -944,8 +945,6 @@ static bool _collectTrackDesignScenery = false; static int32_t _lastSceneryX = 0; static int32_t _lastSceneryY = 0; -static void set_operating_setting(int32_t rideNumber, uint8_t setting, uint8_t value); - // Cached overall view for each ride // (Re)calculated when the ride window is opened struct ride_overall_view { @@ -2255,8 +2254,9 @@ static void populate_vehicle_type_dropdown(Ride* ride) bool selectionShouldBeExpanded; int32_t rideTypeIterator, rideTypeIteratorMax; if (gCheatsShowVehiclesFromOtherTrackTypes - && !(ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_FLAT_RIDE) || ride->type == RIDE_TYPE_MAZE - || ride->type == RIDE_TYPE_MINI_GOLF)) + && !( + ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_FLAT_RIDE) || ride->type == RIDE_TYPE_MAZE + || ride->type == RIDE_TYPE_MINI_GOLF)) { selectionShouldBeExpanded = true; rideTypeIterator = 0; @@ -2433,7 +2433,7 @@ static void window_ride_main_dropdown(rct_window* w, rct_widgetindex widgetIndex uint8_t rideType = RideDropdownData[rideLabelId].ride_type_id; if (rideType < RIDE_TYPE_COUNT) { - set_operating_setting(w->number, RIDE_SETTING_RIDE_TYPE, rideType); + set_operating_setting(w->number, RideSetSetting::RideType, rideType); } window_invalidate_all(); } @@ -3187,33 +3187,6 @@ static void window_ride_vehicle_scrollpaint(rct_window* w, rct_drawpixelinfo* dp #pragma region Operating -static void set_operating_setting(int32_t rideNumber, uint8_t setting, uint8_t value) -{ - set_operating_setting(rideNumber, setting, value, GAME_COMMAND_FLAG_APPLY); -} - -static void window_ride_mode_tweak_set(rct_window* w, uint8_t value) -{ - Ride* ride = get_ride(w->number); - - gGameCommandErrorTitle = STR_CANT_CHANGE_LAUNCH_SPEED; - if (ride->mode == RIDE_MODE_STATION_TO_STATION) - gGameCommandErrorTitle = STR_CANT_CHANGE_SPEED; - if (ride->mode == RIDE_MODE_RACE) - gGameCommandErrorTitle = STR_CANT_CHANGE_NUMBER_OF_LAPS; - if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_VEHICLES)) - gGameCommandErrorTitle = STR_CANT_CHANGE_THIS; - if (ride->mode == RIDE_MODE_BUMPERCAR) - gGameCommandErrorTitle = STR_CANT_CHANGE_TIME_LIMIT; - if (ride->mode == RIDE_MODE_SWING) - gGameCommandErrorTitle = STR_CANT_CHANGE_NUMBER_OF_SWINGS; - if (ride->mode == RIDE_MODE_ROTATION || ride->mode == RIDE_MODE_FORWARD_ROTATION - || ride->mode == RIDE_MODE_BACKWARD_ROTATION) - gGameCommandErrorTitle = STR_CANT_CHANGE_NUMBER_OF_ROTATIONS; - - set_operating_setting(w->number, RIDE_SETTING_OPERATION_OPTION, value); -} - /** * * rct2: 0x006B11D5 @@ -3232,7 +3205,8 @@ static void window_ride_mode_tweak_increase(rct_window* w) uint8_t increment = ride->mode == RIDE_MODE_BUMPERCAR ? 10 : 1; - window_ride_mode_tweak_set(w, std::clamp(ride->operation_option + increment, minValue, maxValue)); + set_operating_setting( + w->number, RideSetSetting::Operation, std::clamp(ride->operation_option + increment, minValue, maxValue)); } /** @@ -3252,7 +3226,8 @@ static void window_ride_mode_tweak_decrease(rct_window* w) uint8_t decrement = ride->mode == RIDE_MODE_BUMPERCAR ? 10 : 1; - window_ride_mode_tweak_set(w, std::clamp(ride->operation_option - decrement, minValue, maxValue)); + set_operating_setting( + w->number, RideSetSetting::Operation, std::clamp(ride->operation_option - decrement, minValue, maxValue)); } /** @@ -3352,21 +3327,23 @@ static void window_ride_operating_mouseup(rct_window* w, rct_widgetindex widgetI window_ride_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_LOAD_CHECKBOX: - set_operating_setting(w->number, RIDE_SETTING_DEPARTURE, ride->depart_flags ^ RIDE_DEPART_WAIT_FOR_LOAD); + set_operating_setting(w->number, RideSetSetting::Departure, ride->depart_flags ^ RIDE_DEPART_WAIT_FOR_LOAD); break; case WIDX_LEAVE_WHEN_ANOTHER_ARRIVES_CHECKBOX: set_operating_setting( - w->number, RIDE_SETTING_DEPARTURE, ride->depart_flags ^ RIDE_DEPART_LEAVE_WHEN_ANOTHER_ARRIVES); + w->number, RideSetSetting::Departure, ride->depart_flags ^ RIDE_DEPART_LEAVE_WHEN_ANOTHER_ARRIVES); break; case WIDX_MINIMUM_LENGTH_CHECKBOX: - set_operating_setting(w->number, RIDE_SETTING_DEPARTURE, ride->depart_flags ^ RIDE_DEPART_WAIT_FOR_MINIMUM_LENGTH); + set_operating_setting( + w->number, RideSetSetting::Departure, ride->depart_flags ^ RIDE_DEPART_WAIT_FOR_MINIMUM_LENGTH); break; case WIDX_MAXIMUM_LENGTH_CHECKBOX: - set_operating_setting(w->number, RIDE_SETTING_DEPARTURE, ride->depart_flags ^ RIDE_DEPART_WAIT_FOR_MAXIMUM_LENGTH); + set_operating_setting( + w->number, RideSetSetting::Departure, ride->depart_flags ^ RIDE_DEPART_WAIT_FOR_MAXIMUM_LENGTH); break; case WIDX_SYNCHRONISE_WITH_ADJACENT_STATIONS_CHECKBOX: set_operating_setting( - w->number, RIDE_SETTING_DEPARTURE, ride->depart_flags ^ RIDE_DEPART_SYNCHRONISE_WITH_ADJACENT_STATIONS); + w->number, RideSetSetting::Departure, ride->depart_flags ^ RIDE_DEPART_SYNCHRONISE_WITH_ADJACENT_STATIONS); break; } } @@ -3401,42 +3378,42 @@ static void window_ride_operating_mousedown(rct_window* w, rct_widgetindex widge upper_bound = gCheatsFastLiftHill ? 255 : RideLiftData[ride->type].maximum_speed; lower_bound = gCheatsFastLiftHill ? 0 : RideLiftData[ride->type].minimum_speed; set_operating_setting( - w->number, RIDE_SETTING_LIFT_HILL_SPEED, + w->number, RideSetSetting::LiftHillSpeed, std::clamp(ride->lift_hill_speed + 1, lower_bound, upper_bound)); break; case WIDX_LIFT_HILL_SPEED_DECREASE: upper_bound = gCheatsFastLiftHill ? 255 : RideLiftData[ride->type].maximum_speed; lower_bound = gCheatsFastLiftHill ? 0 : RideLiftData[ride->type].minimum_speed; set_operating_setting( - w->number, RIDE_SETTING_LIFT_HILL_SPEED, + w->number, RideSetSetting::LiftHillSpeed, std::clamp(ride->lift_hill_speed - 1, lower_bound, upper_bound)); break; case WIDX_MINIMUM_LENGTH_INCREASE: upper_bound = 250; lower_bound = 0; set_operating_setting( - w->number, RIDE_SETTING_MIN_WAITING_TIME, + w->number, RideSetSetting::MinWaitingTime, std::clamp(ride->min_waiting_time + 1, lower_bound, upper_bound)); break; case WIDX_MINIMUM_LENGTH_DECREASE: upper_bound = 250; lower_bound = 0; set_operating_setting( - w->number, RIDE_SETTING_MIN_WAITING_TIME, + w->number, RideSetSetting::MinWaitingTime, std::clamp(ride->min_waiting_time - 1, lower_bound, upper_bound)); break; case WIDX_MAXIMUM_LENGTH_INCREASE: upper_bound = 250; lower_bound = 0; set_operating_setting( - w->number, RIDE_SETTING_MAX_WAITING_TIME, + w->number, RideSetSetting::MaxWaitingTime, std::clamp(ride->max_waiting_time + 1, lower_bound, upper_bound)); break; case WIDX_MAXIMUM_LENGTH_DECREASE: upper_bound = 250; lower_bound = 0; set_operating_setting( - w->number, RIDE_SETTING_MAX_WAITING_TIME, + w->number, RideSetSetting::MaxWaitingTime, std::clamp(ride->max_waiting_time - 1, lower_bound, upper_bound)); break; case WIDX_MODE_DROPDOWN: @@ -3449,13 +3426,13 @@ static void window_ride_operating_mousedown(rct_window* w, rct_widgetindex widge upper_bound = gCheatsFastLiftHill ? 255 : 20; lower_bound = 1; set_operating_setting( - w->number, RIDE_SETTING_NUM_CIRCUITS, std::clamp(ride->num_circuits + 1, lower_bound, upper_bound)); + w->number, RideSetSetting::NumCircuits, std::clamp(ride->num_circuits + 1, lower_bound, upper_bound)); break; case WIDX_OPERATE_NUMBER_OF_CIRCUITS_DECREASE: upper_bound = gCheatsFastLiftHill ? 255 : 20; lower_bound = 1; set_operating_setting( - w->number, RIDE_SETTING_NUM_CIRCUITS, std::clamp(ride->num_circuits - 1, lower_bound, upper_bound)); + w->number, RideSetSetting::NumCircuits, std::clamp(ride->num_circuits - 1, lower_bound, upper_bound)); break; } } @@ -3480,11 +3457,11 @@ static void window_ride_operating_dropdown(rct_window* w, rct_widgetindex widget // Seek to available modes for this ride availableModes = ride_seek_available_modes(ride); - set_operating_setting(w->number, RIDE_SETTING_MODE, availableModes[dropdownIndex]); + set_operating_setting(w->number, RideSetSetting::Mode, availableModes[dropdownIndex]); break; case WIDX_LOAD_DROPDOWN: set_operating_setting( - w->number, RIDE_SETTING_DEPARTURE, (ride->depart_flags & ~RIDE_DEPART_WAIT_FOR_LOAD_MASK) | dropdownIndex); + w->number, RideSetSetting::Departure, (ride->depart_flags & ~RIDE_DEPART_WAIT_FOR_LOAD_MASK) | dropdownIndex); break; } } @@ -3986,7 +3963,7 @@ static void window_ride_maintenance_dropdown(rct_window* w, rct_widgetindex widg switch (widgetIndex) { case WIDX_INSPECTION_INTERVAL_DROPDOWN: - set_operating_setting(w->number, RIDE_SETTING_INSPECTION_INTERVAL, dropdownIndex, GAME_COMMAND_FLAG_APPLY); + set_operating_setting(w->number, RideSetSetting::InspectionInterval, dropdownIndex); break; case WIDX_FORCE_BREAKDOWN: @@ -5034,7 +5011,7 @@ static void window_ride_toggle_music(rct_window* w) Ride* ride = get_ride(w->number); int32_t activateMusic = (ride->lifecycle_flags & RIDE_LIFECYCLE_MUSIC) ? 0 : 1; - set_operating_setting(w->number, RIDE_SETTING_MUSIC, activateMusic, GAME_COMMAND_FLAG_APPLY); + set_operating_setting(w->number, RideSetSetting::Music, activateMusic); } /** @@ -5138,7 +5115,7 @@ static void window_ride_music_dropdown(rct_window* w, rct_widgetindex widgetInde return; musicStyle = window_ride_current_music_style_order[dropdownIndex]; - set_operating_setting(w->number, RIDE_SETTING_MUSIC_TYPE, musicStyle, GAME_COMMAND_FLAG_APPLY); + set_operating_setting(w->number, RideSetSetting::MusicType, musicStyle); } /** diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index d163ef0fa9..39618dbc20 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -28,6 +28,7 @@ #include "RideDemolishAction.hpp" #include "RideSetAppearanceAction.hpp" #include "RideSetColourScheme.hpp" +#include "RideSetSetting.hpp" #include "RideSetName.hpp" #include "RideSetPriceAction.hpp" #include "RideSetStatus.hpp" @@ -67,6 +68,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/RideSetSetting.hpp b/src/openrct2/actions/RideSetSetting.hpp new file mode 100644 index 0000000000..a8b729377b --- /dev/null +++ b/src/openrct2/actions/RideSetSetting.hpp @@ -0,0 +1,331 @@ +/***************************************************************************** + * Copyright (c) 2014-2018 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#include "../ride/Ride.h" +#include "../ride/RideData.h" +#include "GameAction.h" + +enum class RideSetSetting : uint8_t +{ + Mode, + Departure, + MinWaitingTime, + MaxWaitingTime, + Operation, + InspectionInterval, + Music, + MusicType, + LiftHillSpeed, + NumCircuits, + RideType, +}; + +DEFINE_GAME_ACTION(RideSetSettingAction, GAME_COMMAND_SET_RIDE_SETTING, GameActionResult) +{ +private: + NetworkRideId_t _rideIndex{ -1 }; + uint8_t _setting{ 0 }; + uint8_t _value{ 0 }; + +public: + RideSetSettingAction() + { + } + RideSetSettingAction(ride_id_t rideIndex, RideSetSetting setting, uint8_t value) + : _rideIndex(rideIndex) + , _setting(static_cast(setting)) + , _value(value) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags(); + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + + stream << DS_TAG(_rideIndex) << DS_TAG(_setting) << DS_TAG(_value); + } + + GameActionResult::Ptr Query() const override + { + if (_rideIndex >= MAX_RIDES || _rideIndex < 0) + { + log_warning("Invalid game command for ride %u", uint32_t(_rideIndex)); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_OPERATING_MODE); + } + + Ride* ride = get_ride(_rideIndex); + if (ride == nullptr || ride->type == RIDE_TYPE_NULL) + { + log_warning("Invalid ride: #%u.", _rideIndex); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_OPERATING_MODE); + } + + switch (static_cast(_setting)) + { + case RideSetSetting::Mode: + if (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) + { + return MakeResult( + GA_ERROR::DISALLOWED, STR_CANT_CHANGE_OPERATING_MODE, STR_HAS_BROKEN_DOWN_AND_REQUIRES_FIXING); + } + + if (ride->status != RIDE_STATUS_CLOSED) + { + return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_CHANGE_OPERATING_MODE, STR_MUST_BE_CLOSED_FIRST); + } + + if (!ride_is_mode_valid(ride)) + { + log_warning("Invalid ride mode: %u", _value); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_OPERATING_MODE); + } + break; + case RideSetSetting::Departure: + break; + case RideSetSetting::MinWaitingTime: + if (_value > 250) + { + log_warning("Invalid minimum waiting time: %u", _value); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_OPERATING_MODE); + } + break; + case RideSetSetting::MaxWaitingTime: + if (_value > 250) + { + log_warning("Invalid maximum waiting time: %u", _value); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_OPERATING_MODE); + } + break; + case RideSetSetting::Operation: + if (!ride_is_valid_operation_option(ride)) + { + log_warning("Invalid operation option value: %u", _value); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, GetOperationErrorMessage(ride)); + } + break; + case RideSetSetting::InspectionInterval: + if (_value > RIDE_INSPECTION_NEVER) + { + log_warning("Invalid inspection interval: %u", _value); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_OPERATING_MODE); + } + break; + case RideSetSetting::Music: + break; + case RideSetSetting::MusicType: + if (_value >= MUSIC_STYLE_COUNT) + { + log_warning("Invalid music style: %u", _value); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_OPERATING_MODE); + } + break; + case RideSetSetting::LiftHillSpeed: + if (!ride_is_valid_lift_hill_speed(ride)) + { + log_warning("Invalid lift hill speed: %u", _value); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_OPERATING_MODE); + } + break; + case RideSetSetting::NumCircuits: + if (ride->lifecycle_flags & RIDE_LIFECYCLE_CABLE_LIFT && _value > 1) + { + return MakeResult( + GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_OPERATING_MODE, + STR_MULTICIRCUIT_NOT_POSSIBLE_WITH_CABLE_LIFT_HILL); + } + + if (!ride_is_valid_num_circuits()) + { + log_warning("Invalid number of circuits: %u", _value); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_OPERATING_MODE); + } + break; + case RideSetSetting::RideType: + if (!gCheatsAllowArbitraryRideTypeChanges) + { + log_warning("Arbitary ride type changes not allowed."); + return MakeResult(GA_ERROR::DISALLOWED, STR_CANT_CHANGE_OPERATING_MODE); + } + break; + default: + log_warning("Invalid RideSetSetting: %u", _setting); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_OPERATING_MODE); + break; + } + + return std::make_unique(); + } + + GameActionResult::Ptr Execute() const override + { + Ride* ride = get_ride(_rideIndex); + if (ride == nullptr || ride->type == RIDE_TYPE_NULL) + { + log_warning("Invalid ride: #%u.", _rideIndex); + return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_CANT_CHANGE_OPERATING_MODE); + } + + switch (static_cast(_setting)) + { + case RideSetSetting::Mode: + invalidate_test_results(ride); + ride_clear_for_construction(ride); + ride_remove_peeps(ride); + + ride->mode = _value; + ride_update_max_vehicles(ride); + break; + case RideSetSetting::Departure: + ride->depart_flags = _value; + break; + case RideSetSetting::MinWaitingTime: + ride->min_waiting_time = _value; + ride->max_waiting_time = std::max(_value, ride->max_waiting_time); + break; + case RideSetSetting::MaxWaitingTime: + ride->max_waiting_time = _value; + ride->min_waiting_time = std::min(_value, ride->min_waiting_time); + break; + case RideSetSetting::Operation: + invalidate_test_results(ride); + ride->operation_option = _value; + break; + case RideSetSetting::InspectionInterval: + + if (_value == RIDE_INSPECTION_NEVER) + { + ride->lifecycle_flags &= ~RIDE_LIFECYCLE_DUE_INSPECTION; + } + + ride->inspection_interval = _value; + break; + case RideSetSetting::Music: + ride->lifecycle_flags &= ~RIDE_LIFECYCLE_MUSIC; + if (_value) + { + ride->lifecycle_flags |= RIDE_LIFECYCLE_MUSIC; + } + break; + case RideSetSetting::MusicType: + if (_value != ride->music) + { + ride->music = _value; + ride->music_tune_id = 0xFF; + } + break; + case RideSetSetting::LiftHillSpeed: + if (_value != ride->lift_hill_speed) + { + ride->lift_hill_speed = _value; + invalidate_test_results(ride); + } + break; + case RideSetSetting::NumCircuits: + if (_value != ride->num_circuits) + { + ride->num_circuits = _value; + invalidate_test_results(ride); + } + + break; + case RideSetSetting::RideType: + ride->type = _value; + break; + } + + auto res = std::make_unique(); + if (ride->overall_view.xy != RCT_XY8_UNDEFINED) + { + res->Position.x = ride->overall_view.x * 32 + 16; + res->Position.y = ride->overall_view.y * 32 + 16; + res->Position.z = tile_element_height(res->Position.x, res->Position.y); + } + window_invalidate_by_number(WC_RIDE, _rideIndex); + return res; + } + +private: + bool ride_is_mode_valid(Ride * ride) const + { + const uint8_t* availableModes = ride_seek_available_modes(ride); + + for (; *availableModes != 0xFF; availableModes++) + { + if (*availableModes == _value) + { + return true; + } + } + + return false; + } + + bool ride_is_valid_lift_hill_speed(Ride * ride) const + { + int32_t minSpeed = gCheatsFastLiftHill ? 0 : RideLiftData[ride->type].minimum_speed; + int32_t maxSpeed = gCheatsFastLiftHill ? 255 : RideLiftData[ride->type].maximum_speed; + return _value >= minSpeed && _value <= maxSpeed; + } + + bool ride_is_valid_num_circuits() const + { + int32_t minNumCircuits = 1; + int32_t maxNumCircuits = gCheatsFastLiftHill ? 255 : 20; + return _value >= minNumCircuits && _value <= maxNumCircuits; + } + + bool ride_is_valid_operation_option(Ride * ride) const + { + uint8_t minValue = RideProperties[ride->type].min_value; + uint8_t maxValue = RideProperties[ride->type].max_value; + if (gCheatsFastLiftHill) + { + minValue = 0; + maxValue = 255; + } + + return _value >= minValue && _value <= maxValue; + } + + rct_string_id GetOperationErrorMessage(Ride * ride) const + { + switch (ride->mode) + { + case RIDE_MODE_STATION_TO_STATION: + return STR_CANT_CHANGE_SPEED; + case RIDE_MODE_RACE: + return STR_CANT_CHANGE_NUMBER_OF_LAPS; + case RIDE_MODE_BUMPERCAR: + return STR_CANT_CHANGE_TIME_LIMIT; + case RIDE_MODE_SWING: + return STR_CANT_CHANGE_NUMBER_OF_SWINGS; + case RIDE_MODE_ROTATION: + case RIDE_MODE_FORWARD_ROTATION: + case RIDE_MODE_BACKWARD_ROTATION: + return STR_CANT_CHANGE_NUMBER_OF_ROTATIONS; + default: + if (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_VEHICLES)) + { + return STR_CANT_CHANGE_THIS; + } + else + { + return STR_CANT_CHANGE_LAUNCH_SPEED; + } + break; + } + } +}; diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 7903a22076..2f69e4aaaf 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -15,6 +15,7 @@ #include "../OpenRCT2.h" #include "../ReplayManager.h" #include "../Version.h" +#include "../actions/RideSetSetting.hpp" #include "../actions/ClimateSetAction.hpp" #include "../actions/StaffSetCostumeAction.hpp" #include "../config/Config.h" @@ -186,7 +187,7 @@ static int32_t cc_rides(InteractiveConsole& console, const arguments_t& argv) } else { - int32_t res = set_operating_setting(ride_index, RIDE_SETTING_RIDE_TYPE, type, GAME_COMMAND_FLAG_APPLY); + int32_t res = set_operating_setting(ride_index, RideSetSetting::RideType, type); if (res == MONEY32_UNDEFINED) { console.WriteFormatLine("That didn't work"); diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 64c77f453a..f477f831c6 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -17,6 +17,7 @@ #include "../OpenRCT2.h" #include "../actions/RideSetVehiclesAction.hpp" #include "../actions/TrackRemoveAction.hpp" +#include "../actions/RideSetSetting.hpp" #include "../audio/AudioMixer.h" #include "../audio/audio.h" #include "../common.h" @@ -4260,10 +4261,20 @@ void game_command_set_ride_setting( *ebx = ride_set_setting(rideIndex, setting, newValue, flags); } -money32 set_operating_setting(int32_t rideId, uint8_t setting, uint8_t value, uint8_t flags) +money32 set_operating_setting(ride_id_t rideId, RideSetSetting setting, uint8_t value) { - gGameCommandErrorTitle = STR_CANT_CHANGE_OPERATING_MODE; - return game_do_command(0, (value << 8) | flags, 0, (setting << 8) | rideId, GAME_COMMAND_SET_RIDE_SETTING, 0, 0); + auto rideSetSetting = RideSetSettingAction(rideId, setting, value); + auto res = GameActions::Execute(&rideSetSetting); + return res->Error == GA_ERROR::OK ? 0 : MONEY32_UNDEFINED; +} + +money32 set_operating_setting_nested(ride_id_t rideId, RideSetSetting setting, uint8_t value, uint8_t flags) +{ + auto rideSetSetting = RideSetSettingAction(rideId, setting, value); + rideSetSetting.SetFlags(flags); + auto res = flags & GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&rideSetSetting) + : GameActions::QueryNested(&rideSetSetting); + return res->Error == GA_ERROR::OK ? 0 : MONEY32_UNDEFINED; } /** @@ -7625,7 +7636,7 @@ void ride_set_to_default_inspection_interval(Ride* ride) if (defaultInspectionInterval <= RIDE_INSPECTION_NEVER) { set_operating_setting( - ride->id, RIDE_SETTING_INSPECTION_INTERVAL, defaultInspectionInterval, GAME_COMMAND_FLAG_APPLY); + ride->id, RideSetSetting::InspectionInterval, defaultInspectionInterval); } } } diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 30f12f35fc..3b82b01dfb 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -1136,7 +1136,11 @@ uint64_t ride_entry_get_supported_track_pieces(const rct_ride_entry* rideEntry); void ride_set_ride_entry(Ride* ride, int32_t rideEntry); void ride_set_num_vehicles(Ride* ride, int32_t numVehicles); void ride_set_num_cars_per_vehicle(Ride* ride, int32_t numCarsPerVehicle); -money32 set_operating_setting(int32_t rideId, uint8_t setting, uint8_t value, uint8_t flags); + +enum class RideSetSetting : uint8_t; +money32 set_operating_setting(ride_id_t rideId, RideSetSetting setting, uint8_t value); +money32 set_operating_setting_nested(ride_id_t rideId, RideSetSetting setting, uint8_t value, uint8_t flags); + void game_command_set_ride_vehicles( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 9ada44f441..63ff47d95e 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -18,6 +18,7 @@ #include "../actions/TrackPlaceAction.hpp" #include "../actions/TrackRemoveAction.hpp" #include "../actions/WallRemoveAction.hpp" +#include "../actions/RideSetSetting.hpp" #include "../audio/audio.h" #include "../core/File.h" #include "../core/String.hpp" @@ -1967,7 +1968,7 @@ static money32 place_track_design(int16_t x, int16_t y, int16_t z, uint8_t flags : GameActions::QueryNested(&rideSetVehicleAction); } - set_operating_setting(ride->id, RIDE_SETTING_MODE, td6->ride_mode, flags); + set_operating_setting_nested(ride->id, RideSetSetting::Mode, td6->ride_mode, flags); auto rideSetVehicleAction2 = RideSetVehicleAction(ride->id, RideSetVehicleType::NumTrains, td6->number_of_trains); flags& GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&rideSetVehicleAction2) : GameActions::QueryNested(&rideSetVehicleAction2); @@ -1975,18 +1976,18 @@ static money32 place_track_design(int16_t x, int16_t y, int16_t z, uint8_t flags ride->id, RideSetVehicleType::NumCarsPerTrain, td6->number_of_cars_per_train); flags& GAME_COMMAND_FLAG_APPLY ? GameActions::ExecuteNested(&rideSetVehicleAction3) : GameActions::QueryNested(&rideSetVehicleAction3); - set_operating_setting(ride->id, RIDE_SETTING_DEPARTURE, td6->depart_flags, flags); - set_operating_setting(ride->id, RIDE_SETTING_MIN_WAITING_TIME, td6->min_waiting_time, flags); - set_operating_setting(ride->id, RIDE_SETTING_MAX_WAITING_TIME, td6->max_waiting_time, flags); - set_operating_setting(ride->id, RIDE_SETTING_OPERATION_OPTION, td6->operation_setting, flags); - set_operating_setting(ride->id, RIDE_SETTING_LIFT_HILL_SPEED, td6->lift_hill_speed_num_circuits & 0x1F, flags); + set_operating_setting_nested(ride->id, RideSetSetting::Departure, td6->depart_flags, flags); + set_operating_setting_nested(ride->id, RideSetSetting::MinWaitingTime, td6->min_waiting_time, flags); + set_operating_setting_nested(ride->id, RideSetSetting::MaxWaitingTime, td6->max_waiting_time, flags); + set_operating_setting_nested(ride->id, RideSetSetting::Operation, td6->operation_setting, flags); + set_operating_setting_nested(ride->id, RideSetSetting::LiftHillSpeed, td6->lift_hill_speed_num_circuits & 0x1F, flags); uint8_t num_circuits = td6->lift_hill_speed_num_circuits >> 5; if (num_circuits == 0) { num_circuits = 1; } - set_operating_setting(ride->id, RIDE_SETTING_NUM_CIRCUITS, num_circuits, flags); + set_operating_setting_nested(ride->id, RideSetSetting::NumCircuits, num_circuits, flags); ride_set_to_default_inspection_interval(ride); ride->lifecycle_flags |= RIDE_LIFECYCLE_NOT_CUSTOM_DESIGN; ride->colour_scheme_type = td6->version_and_colour_scheme & 3;