From c1546a92b7be8d29e214c19975f8bbb8bd47c91f Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Thu, 21 Feb 2019 15:56:23 +0000 Subject: [PATCH] Implement RideSetVehicleAction Move all callees to the new action. Required rework on how the ride type change worked. --- src/openrct2/Game.cpp | 10 +- src/openrct2/Game.h | 4 +- src/openrct2/actions/GameAction.h | 3 + .../actions/GameActionRegistration.cpp | 2 + .../actions/RideSetVehiclesAction.hpp | 276 ++++++++++++++++++ src/openrct2/ride/Ride.cpp | 213 +------------- src/openrct2/ride/TrackDesign.cpp | 13 +- 7 files changed, 302 insertions(+), 219 deletions(-) create mode 100644 src/openrct2/actions/RideSetVehiclesAction.hpp diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 6c51562849..2334f9b745 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -611,7 +611,7 @@ void game_log_multiplayer_command(int command, const int* eax, const int* ebx, c format_string(log_msg, 256, STR_LOG_DEMOLISH_RIDE, args); network_append_server_log(log_msg); } - else if (command == GAME_COMMAND_SET_RIDE_VEHICLES || command == GAME_COMMAND_SET_RIDE_SETTING) + else if (command == GAME_COMMAND_SET_RIDE_SETTING) { // Get ride name int ride_index = *edx & 0xFF; @@ -626,12 +626,6 @@ void game_log_multiplayer_command(int command, const int* eax, const int* ebx, c switch (command) { - case GAME_COMMAND_SET_RIDE_APPEARANCE: - format_string(log_msg, 256, STR_LOG_RIDE_APPEARANCE, args); - break; - case GAME_COMMAND_SET_RIDE_VEHICLES: - format_string(log_msg, 256, STR_LOG_RIDE_VEHICLES, args); - break; case GAME_COMMAND_SET_RIDE_SETTING: format_string(log_msg, 256, STR_LOG_RIDE_SETTINGS, args); break; @@ -1297,7 +1291,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { game_command_create_ride, game_command_demolish_ride, game_command_set_ride_status, - game_command_set_ride_vehicles, + nullptr, game_command_set_ride_name, game_command_set_ride_setting, game_command_place_ride_entrance_or_exit, diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 38dd427d2b..9e82f7b08f 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -27,8 +27,8 @@ enum GAME_COMMAND GAME_COMMAND_CREATE_RIDE, // GA GAME_COMMAND_DEMOLISH_RIDE, // GA GAME_COMMAND_SET_RIDE_STATUS, // GA - GAME_COMMAND_SET_RIDE_VEHICLES, - GAME_COMMAND_SET_RIDE_NAME, // GA + GAME_COMMAND_SET_RIDE_VEHICLES, // GA + GAME_COMMAND_SET_RIDE_NAME, // GA GAME_COMMAND_SET_RIDE_SETTING, GAME_COMMAND_PLACE_RIDE_ENTRANCE_OR_EXIT, GAME_COMMAND_REMOVE_RIDE_ENTRANCE_OR_EXIT, diff --git a/src/openrct2/actions/GameAction.h b/src/openrct2/actions/GameAction.h index aebc20f36a..f98f78b98f 100644 --- a/src/openrct2/actions/GameAction.h +++ b/src/openrct2/actions/GameAction.h @@ -39,6 +39,9 @@ enum class GA_ERROR : uint16_t NO_CLEARANCE, ITEM_ALREADY_PLACED, + NOT_CLOSED, + BROKEN, + NO_FREE_ELEMENTS, UNKNOWN = UINT16_MAX, diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index c1e08d744a..fecd1bcd1e 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -42,6 +42,7 @@ #include "TrackPlaceAction.hpp" #include "TrackRemoveAction.hpp" #include "WallRemoveAction.hpp" +#include "RideSetVehiclesAction.hpp" namespace GameActions { @@ -65,6 +66,7 @@ namespace GameActions Register(); Register(); Register(); + Register(); Register(); Register(); Register(); diff --git a/src/openrct2/actions/RideSetVehiclesAction.hpp b/src/openrct2/actions/RideSetVehiclesAction.hpp new file mode 100644 index 0000000000..5148ceb5a9 --- /dev/null +++ b/src/openrct2/actions/RideSetVehiclesAction.hpp @@ -0,0 +1,276 @@ +/***************************************************************************** + * 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 "../Cheats.h" +#include "../Context.h" +#include "../core/MemoryStream.h" +#include "../drawing/Drawing.h" +#include "../interface/Window.h" +#include "../localisation/Localisation.h" +#include "../localisation/StringIds.h" +#include "../management/Research.h" +#include "../ride/Ride.h" +#include "../ui/UiContext.h" +#include "../ui/WindowManager.h" +#include "../world/Park.h" +#include "GameAction.h" + +enum class RideSetVehicleType : uint8_t +{ + NumTrains, + NumCarsPerTrain, + RideEntry +}; + +DEFINE_GAME_ACTION(RideSetVehicleAction, GAME_COMMAND_SET_RIDE_VEHICLES, GameActionResult) +{ +private: + NetworkRideId_t _rideIndex{ -1 }; + uint8_t _type; + uint8_t _value; + uint8_t _colour; + + constexpr static rct_string_id SetVehicleTypeErrorTitle[] = { STR_RIDE_SET_VEHICLE_SET_NUM_TRAINS_FAIL, + STR_RIDE_SET_VEHICLE_SET_NUM_CARS_PER_TRAIN_FAIL, + STR_RIDE_SET_VEHICLE_TYPE_FAIL }; + +public: + RideSetVehicleAction() + { + } + + RideSetVehicleAction(ride_id_t rideIndex, RideSetVehicleType type, uint8_t value, uint8_t colour = 0) + : _rideIndex(rideIndex) + , _type(static_cast(type)) + , _value(value) + , _colour(colour) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags(); + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + stream << DS_TAG(_rideIndex) << DS_TAG(_type) << DS_TAG(_value) << DS_TAG(_colour); + } + + GameActionResult::Ptr Query() const override + { + if (_type > sizeof(SetVehicleTypeErrorTitle)) + { + log_warning("Invalid type. type = %d", _type); + } + auto errTitle = SetVehicleTypeErrorTitle[_type]; + + if (_rideIndex >= MAX_RIDES || _rideIndex == RIDE_ID_NULL) + { + log_warning("Invalid game command for ride %u", uint32_t(_rideIndex)); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, errTitle); + } + + Ride* ride = get_ride(_rideIndex); + if (ride == nullptr || ride->type == RIDE_TYPE_NULL) + { + log_warning("Invalid game command, ride_id = %u", uint32_t(_rideIndex)); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, errTitle); + } + + if (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) + { + return std::make_unique(GA_ERROR::BROKEN, errTitle, STR_HAS_BROKEN_DOWN_AND_REQUIRES_FIXING); + } + + if (ride->status != RIDE_STATUS_CLOSED) + { + return std::make_unique(GA_ERROR::NOT_CLOSED, errTitle, STR_MUST_BE_CLOSED_FIRST); + } + + switch (static_cast(_type)) + { + case RideSetVehicleType::NumTrains: + case RideSetVehicleType::NumCarsPerTrain: + break; + case RideSetVehicleType::RideEntry: + { + if (!ride_is_vehicle_type_valid(ride)) + { + log_error("Invalid vehicle type. type = %d", _value); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, errTitle); + } + auto rideEntry = get_ride_entry(_value); + if (rideEntry == nullptr) + { + log_warning("Invalid ride entry, ride->subtype = %d", ride->subtype); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, errTitle); + } + + // Validate preset + vehicle_colour_preset_list* presetList = rideEntry->vehicle_preset_list; + if (_colour >= presetList->count) + { + log_error("Unknown vehicle colour preset. colour = %d", _colour); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, errTitle); + } + break; + } + + default: + log_error("Unknown vehicle command. type = %d", _type); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, errTitle); + } + + return std::make_unique(); + } + + GameActionResult::Ptr Execute() const override + { + auto errTitle = SetVehicleTypeErrorTitle[_type]; + Ride* ride = get_ride(_rideIndex); + if (ride == nullptr || ride->type == RIDE_TYPE_NULL) + { + log_warning("Invalid game command, ride_id = %u", uint32_t(_rideIndex)); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, errTitle); + } + + switch (static_cast(_type)) + { + case RideSetVehicleType::NumTrains: + ride_clear_for_construction(ride); + ride_remove_peeps(ride); + ride->vehicle_change_timeout = 100; + + ride->proposed_num_vehicles = _value; + break; + case RideSetVehicleType::NumCarsPerTrain: + { + ride_clear_for_construction(ride); + ride_remove_peeps(ride); + ride->vehicle_change_timeout = 100; + + invalidate_test_results(ride); + auto rideEntry = get_ride_entry(ride->subtype); + if (rideEntry == nullptr) + { + log_warning("Invalid ride entry, ride->subtype = %d", ride->subtype); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, errTitle); + } + auto clampValue = _value; + if (!gCheatsDisableTrainLengthLimit) + { + clampValue = std::clamp(clampValue, rideEntry->min_cars_in_train, rideEntry->max_cars_in_train); + } + ride->proposed_num_cars_per_train = clampValue; + break; + } + case RideSetVehicleType::RideEntry: + { + ride_clear_for_construction(ride); + ride_remove_peeps(ride); + ride->vehicle_change_timeout = 100; + + invalidate_test_results(ride); + ride->subtype = _value; + auto rideEntry = get_ride_entry(ride->subtype); + if (rideEntry == nullptr) + { + log_warning("Invalid ride entry, ride->subtype = %d", ride->subtype); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, errTitle); + } + + ride_set_vehicle_colours_to_random_preset(ride, _colour); + if (!gCheatsDisableTrainLengthLimit) + { + ride->proposed_num_cars_per_train = std::clamp( + ride->proposed_num_cars_per_train, rideEntry->min_cars_in_train, rideEntry->max_cars_in_train); + } + break; + } + + default: + log_error("Unknown vehicle command. type = %d", _type); + return std::make_unique(GA_ERROR::INVALID_PARAMETERS, errTitle); + } + + ride->num_circuits = 1; + ride_update_max_vehicles(ride); + + 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); + } + + auto intent = Intent(INTENT_ACTION_RIDE_PAINT_RESET_VEHICLE); + intent.putExtra(INTENT_EXTRA_RIDE_ID, _rideIndex); + context_broadcast_intent(&intent); + + gfx_invalidate_screen(); + return res; + } + +private: + bool ride_is_vehicle_type_valid(Ride * ride) const + { + 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)) + { + selectionShouldBeExpanded = true; + rideTypeIterator = 0; + rideTypeIteratorMax = RIDE_TYPE_COUNT - 1; + } + else + { + selectionShouldBeExpanded = false; + rideTypeIterator = ride->type; + rideTypeIteratorMax = ride->type; + } + + for (; rideTypeIterator <= rideTypeIteratorMax; rideTypeIterator++) + { + if (selectionShouldBeExpanded) + { + if (ride_type_has_flag(rideTypeIterator, RIDE_TYPE_FLAG_FLAT_RIDE)) + continue; + if (rideTypeIterator == RIDE_TYPE_MAZE || rideTypeIterator == RIDE_TYPE_MINI_GOLF) + continue; + } + + uint8_t* rideEntryIndexPtr = get_ride_entry_indices_for_ride_type(rideTypeIterator); + for (uint8_t* currentRideEntryIndex = rideEntryIndexPtr; *currentRideEntryIndex != RIDE_ENTRY_INDEX_NULL; + currentRideEntryIndex++) + { + uint8_t rideEntryIndex = *currentRideEntryIndex; + if (rideEntryIndex == _value) + { + if (!ride_entry_is_invented(rideEntryIndex) && !gCheatsIgnoreResearchStatus) + { + return false; + } + + return true; + } + } + } + + return false; + } +}; diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 735fa85145..a9207aa2b8 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -16,6 +16,7 @@ #include "../Input.h" #include "../OpenRCT2.h" #include "../actions/TrackRemoveAction.hpp" +#include "../actions/RideSetVehiclesAction.hpp" #include "../audio/AudioMixer.h" #include "../audio/audio.h" #include "../common.h" @@ -7365,219 +7366,21 @@ void ride_update_max_vehicles(Ride* ride) void ride_set_ride_entry(Ride* ride, int32_t rideEntry) { - gGameCommandErrorTitle = STR_RIDE_SET_VEHICLE_TYPE_FAIL; - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY | (RIDE_SET_VEHICLES_COMMAND_TYPE_RIDE_ENTRY << 8), 0, (rideEntry << 8) | ride->id, - GAME_COMMAND_SET_RIDE_VEHICLES, 0, 0); + auto colour = ride_get_unused_preset_vehicle_colour(rideEntry); + auto rideSetVehicleAction = RideSetVehicleAction(ride->id, RideSetVehicleType::RideEntry, rideEntry, colour); + GameActions::Execute(&rideSetVehicleAction); } void ride_set_num_vehicles(Ride* ride, int32_t numVehicles) { - gGameCommandErrorTitle = STR_RIDE_SET_VEHICLE_SET_NUM_TRAINS_FAIL; - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY | (RIDE_SET_VEHICLES_COMMAND_TYPE_NUM_TRAINS << 8), 0, (numVehicles << 8) | ride->id, - GAME_COMMAND_SET_RIDE_VEHICLES, 0, 0); + auto rideSetVehicleAction = RideSetVehicleAction(ride->id, RideSetVehicleType::NumTrains, numVehicles); + GameActions::Execute(&rideSetVehicleAction); } void ride_set_num_cars_per_vehicle(Ride* ride, int32_t numCarsPerVehicle) { - gGameCommandErrorTitle = STR_RIDE_SET_VEHICLE_SET_NUM_CARS_PER_TRAIN_FAIL; - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY | (RIDE_SET_VEHICLES_COMMAND_TYPE_NUM_CARS_PER_TRAIN << 8), 0, - (numCarsPerVehicle << 8) | ride->id, GAME_COMMAND_SET_RIDE_VEHICLES, 0, 0); -} - -static bool ride_is_vehicle_type_valid(Ride* ride, uint8_t inputRideEntryIndex) -{ - 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)) - { - selectionShouldBeExpanded = true; - rideTypeIterator = 0; - rideTypeIteratorMax = RIDE_TYPE_COUNT - 1; - } - else - { - selectionShouldBeExpanded = false; - rideTypeIterator = ride->type; - rideTypeIteratorMax = ride->type; - } - - for (; rideTypeIterator <= rideTypeIteratorMax; rideTypeIterator++) - { - if (selectionShouldBeExpanded) - { - if (ride_type_has_flag(rideTypeIterator, RIDE_TYPE_FLAG_FLAT_RIDE)) - continue; - if (rideTypeIterator == RIDE_TYPE_MAZE || rideTypeIterator == RIDE_TYPE_MINI_GOLF) - continue; - } - - uint8_t* rideEntryIndexPtr = get_ride_entry_indices_for_ride_type(rideTypeIterator); - for (uint8_t* currentRideEntryIndex = rideEntryIndexPtr; *currentRideEntryIndex != RIDE_ENTRY_INDEX_NULL; - currentRideEntryIndex++) - { - uint8_t rideEntryIndex = *currentRideEntryIndex; - if (rideEntryIndex == inputRideEntryIndex) - { - if (!ride_entry_is_invented(rideEntryIndex) && !gCheatsIgnoreResearchStatus) - { - return false; - } - - return true; - } - } - } - - return false; -} - -static money32 ride_set_vehicles(ride_id_t rideIndex, uint8_t setting, uint8_t value, uint32_t flags, uint8_t ex) -{ - rct_ride_entry* rideEntry; - - Ride* ride = get_ride(rideIndex); - if (ride == nullptr || ride->type == RIDE_TYPE_NULL) - { - log_warning("Invalid game command for ride #%u", rideIndex); - return MONEY32_UNDEFINED; - } - - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS; - - if (ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN) - { - gGameCommandErrorText = STR_HAS_BROKEN_DOWN_AND_REQUIRES_FIXING; - return MONEY32_UNDEFINED; - } - - if (ride->status != RIDE_STATUS_CLOSED) - { - gGameCommandErrorText = STR_MUST_BE_CLOSED_FIRST; - return MONEY32_UNDEFINED; - } - - switch (setting) - { - case RIDE_SET_VEHICLES_COMMAND_TYPE_NUM_TRAINS: - if (!(flags & GAME_COMMAND_FLAG_APPLY)) - { - return 0; - } - - ride_clear_for_construction(ride); - ride_remove_peeps(ride); - ride->vehicle_change_timeout = 100; - - ride->proposed_num_vehicles = value; - break; - case RIDE_SET_VEHICLES_COMMAND_TYPE_NUM_CARS_PER_TRAIN: - if (!(flags & GAME_COMMAND_FLAG_APPLY)) - { - return 0; - } - - ride_clear_for_construction(ride); - ride_remove_peeps(ride); - ride->vehicle_change_timeout = 100; - - invalidate_test_results(ride); - rideEntry = get_ride_entry(ride->subtype); - if (!gCheatsDisableTrainLengthLimit) - { - value = std::clamp(value, rideEntry->min_cars_in_train, rideEntry->max_cars_in_train); - } - ride->proposed_num_cars_per_train = value; - break; - case RIDE_SET_VEHICLES_COMMAND_TYPE_RIDE_ENTRY: - { - if (!ride_is_vehicle_type_valid(ride, value)) - { - log_error("Invalid vehicle type."); - return MONEY32_UNDEFINED; - } - - if (!(flags & GAME_COMMAND_FLAG_APPLY)) - { - return 0; - } - - ride_clear_for_construction(ride); - ride_remove_peeps(ride); - ride->vehicle_change_timeout = 100; - - invalidate_test_results(ride); - ride->subtype = value; - rideEntry = get_ride_entry(ride->subtype); - - uint8_t preset = ex; - if (!(flags & GAME_COMMAND_FLAG_NETWORKED)) - { - preset = ride_get_unused_preset_vehicle_colour(ride->subtype); - } - - // Validate preset - vehicle_colour_preset_list* presetList = rideEntry->vehicle_preset_list; - if (preset >= presetList->count) - { - log_error("Unknown vehicle colour preset."); - return MONEY32_UNDEFINED; - } - - ride_set_vehicle_colours_to_random_preset(ride, preset); - if (!gCheatsDisableTrainLengthLimit) - { - ride->proposed_num_cars_per_train = std::clamp( - ride->proposed_num_cars_per_train, rideEntry->min_cars_in_train, rideEntry->max_cars_in_train); - } - break; - } - - default: - log_error("Unknown vehicle command."); - return MONEY32_UNDEFINED; - } - - ride->num_circuits = 1; - ride_update_max_vehicles(ride); - - if (ride->overall_view.xy != RCT_XY8_UNDEFINED) - { - LocationXYZ16 coord; - coord.x = ride->overall_view.x * 32 + 16; - coord.y = ride->overall_view.y * 32 + 16; - coord.z = tile_element_height(coord.x, coord.y); - network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); - } - - auto windowManager = GetContext()->GetUiContext()->GetWindowManager(); - auto intent = Intent(INTENT_ACTION_RIDE_PAINT_RESET_VEHICLE); - intent.putExtra(INTENT_EXTRA_RIDE_ID, rideIndex); - windowManager->BroadcastIntent(intent); - - gfx_invalidate_screen(); - return 0; -} - -/** - * - * rct2: 0x006B52D4 - */ -void game_command_set_ride_vehicles( - int32_t* eax, int32_t* ebx, [[maybe_unused]] int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, - [[maybe_unused]] int32_t* edi, [[maybe_unused]] int32_t* ebp) -{ - ride_id_t rideIndex = *edx & 0xFF; - uint8_t setting = (*ebx >> 8) & 0xFF; - uint8_t value = (*edx >> 8) & 0xFF; - uint32_t flags = *ebx; - uint8_t ex = *eax & 0xFF; - *ebx = ride_set_vehicles(rideIndex, setting, value, flags, ex); + auto rideSetVehicleAction = RideSetVehicleAction(ride->id, RideSetVehicleType::NumCarsPerTrain, numCarsPerVehicle); + GameActions::Execute(&rideSetVehicleAction); } /** diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index d077171d6e..b36d9ef09d 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -13,6 +13,7 @@ #include "../Game.h" #include "../OpenRCT2.h" #include "../actions/LargeSceneryRemoveAction.hpp" +#include "../actions/RideSetVehiclesAction.hpp" #include "../actions/SmallSceneryRemoveAction.hpp" #include "../actions/TrackPlaceAction.hpp" #include "../actions/TrackRemoveAction.hpp" @@ -1960,13 +1961,17 @@ static money32 place_track_design(int16_t x, int16_t y, int16_t z, uint8_t flags if (entryIndex != 0xFF) { - game_do_command(0, flags | (2 << 8), 0, ride->id | (entryIndex << 8), GAME_COMMAND_SET_RIDE_VEHICLES, 0, 0); + auto colour = ride_get_unused_preset_vehicle_colour(entryIndex); + auto rideSetVehicleAction = RideSetVehicleAction(ride->id, RideSetVehicleType::RideEntry, entryIndex, colour); + GameActions::ExecuteNested(&rideSetVehicleAction); } game_do_command(0, flags | (td6->ride_mode << 8), 0, ride->id | (0 << 8), GAME_COMMAND_SET_RIDE_SETTING, 0, 0); - game_do_command(0, flags | (0 << 8), 0, ride->id | (td6->number_of_trains << 8), GAME_COMMAND_SET_RIDE_VEHICLES, 0, 0); - game_do_command( - 0, flags | (1 << 8), 0, ride->id | (td6->number_of_cars_per_train << 8), GAME_COMMAND_SET_RIDE_VEHICLES, 0, 0); + auto rideSetVehicleAction2 = RideSetVehicleAction(ride->id, RideSetVehicleType::NumTrains, td6->number_of_trains); + GameActions::ExecuteNested(&rideSetVehicleAction2); + auto rideSetVehicleAction3 = RideSetVehicleAction( + ride->id, RideSetVehicleType::NumCarsPerTrain, td6->number_of_cars_per_train); + GameActions::ExecuteNested(&rideSetVehicleAction3); game_do_command(0, flags | (td6->depart_flags << 8), 0, ride->id | (1 << 8), GAME_COMMAND_SET_RIDE_SETTING, 0, 0); game_do_command(0, flags | (td6->min_waiting_time << 8), 0, ride->id | (2 << 8), GAME_COMMAND_SET_RIDE_SETTING, 0, 0); game_do_command(0, flags | (td6->max_waiting_time << 8), 0, ride->id | (3 << 8), GAME_COMMAND_SET_RIDE_SETTING, 0, 0);