From f29dc3ff34cedfe900ff96c0f289c220011d756e Mon Sep 17 00:00:00 2001 From: ZehM4tt Date: Tue, 18 Jul 2017 16:17:47 +0200 Subject: [PATCH] Fixed base class serialise not being called. Implemented RideSetStatus game action. --- src/openrct2/actions/GameActionCompat.cpp | 23 +++ .../actions/GameActionRegistration.cpp | 2 + .../actions/PlaceParkEntranceAction.hpp | 2 + src/openrct2/actions/RideCreateAction.hpp | 7 +- src/openrct2/actions/RideSetStatus.hpp | 131 ++++++++++++++++++ .../actions/SetParkEntranceFeeAction.hpp | 2 + src/openrct2/game.h | 8 +- src/openrct2/ride/ride.c | 109 +-------------- src/openrct2/ride/ride.h | 2 + 9 files changed, 173 insertions(+), 113 deletions(-) create mode 100644 src/openrct2/actions/RideSetStatus.hpp diff --git a/src/openrct2/actions/GameActionCompat.cpp b/src/openrct2/actions/GameActionCompat.cpp index df26e64cb3..aecb3acd9a 100644 --- a/src/openrct2/actions/GameActionCompat.cpp +++ b/src/openrct2/actions/GameActionCompat.cpp @@ -1,6 +1,7 @@ #include "PlaceParkEntranceAction.hpp" #include "SetParkEntranceFeeAction.hpp" #include "RideCreateAction.hpp" +#include "RideSetStatus.hpp" extern "C" { @@ -116,4 +117,26 @@ extern "C" #pragma endregion +#pragma region RideSetStatusAction + + void ride_set_status(sint32 rideIndex, sint32 status) + { + game_do_command(0, GAME_COMMAND_FLAG_APPLY, 0, rideIndex | (status << 8), GAME_COMMAND_SET_RIDE_STATUS, 0, 0); + + auto gameAction = RideSetStatusAction(); + gameAction.RideIndex = rideIndex; + gameAction.Status = status; + + GameActions::Execute(&gameAction); + } + + /** + * + * rct2: 0x006B4EA6 + */ + void game_command_set_ride_status(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 *edx, sint32 *esi, sint32 *edi, sint32 *ebp) + { + } + +#pragma endregion } diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index d7da40516e..5904db9ef4 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -2,6 +2,7 @@ #include "PlaceParkEntranceAction.hpp" #include "SetParkEntranceFeeAction.hpp" #include "RideCreateAction.hpp" +#include "RideSetStatus.hpp" namespace GameActions { @@ -10,6 +11,7 @@ void Register() Register(); Register(); Register(); + Register(); } } \ No newline at end of file diff --git a/src/openrct2/actions/PlaceParkEntranceAction.hpp b/src/openrct2/actions/PlaceParkEntranceAction.hpp index b12ef50027..dc854ebac9 100644 --- a/src/openrct2/actions/PlaceParkEntranceAction.hpp +++ b/src/openrct2/actions/PlaceParkEntranceAction.hpp @@ -45,6 +45,8 @@ public: void Serialise(DataSerialiser& stream) override { + GameAction::Serialise(stream); + stream << x << y << z << direction; } diff --git a/src/openrct2/actions/RideCreateAction.hpp b/src/openrct2/actions/RideCreateAction.hpp index a212d183d5..34ffa32163 100644 --- a/src/openrct2/actions/RideCreateAction.hpp +++ b/src/openrct2/actions/RideCreateAction.hpp @@ -54,6 +54,8 @@ public: void Serialise(DataSerialiser& stream) override { + GameAction::Serialise(stream); + stream << rideType << rideSubType; } @@ -280,8 +282,9 @@ public: ride_set_vehicle_colours_to_random_preset(ride, 0xFF & (res.RideColor() >> 8)); window_invalidate_by_class(WC_RIDE_LIST); - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION; - gCommandPosition.x = (uint16)0x8000; + res.ExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION; + res.Position.x = (uint16)0x8000; + return res; } }; diff --git a/src/openrct2/actions/RideSetStatus.hpp b/src/openrct2/actions/RideSetStatus.hpp new file mode 100644 index 0000000000..9e9a57f5b8 --- /dev/null +++ b/src/openrct2/actions/RideSetStatus.hpp @@ -0,0 +1,131 @@ +#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers +/***************************************************************************** +* OpenRCT2, an open source clone of Roller Coaster Tycoon 2. +* +* OpenRCT2 is the work of many authors, a full list can be found in contributors.md +* For more information, visit https://github.com/OpenRCT2/OpenRCT2 +* +* OpenRCT2 is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* A full copy of the GNU General Public License can be found in licence.txt +*****************************************************************************/ +#pragma endregion + +#pragma once + +#include "../core/MemoryStream.h" +#include "../localisation/string_ids.h" +#include "GameAction.h" + +extern "C" +{ +#include "../cheats.h" +#include "../interface/window.h" +#include "../world/park.h" +#include "../ride/ride.h" +} + +struct RideSetStatusAction : public GameAction +{ +public: + uint8 RideIndex; + uint8 Status; + + void Serialise(DataSerialiser& stream) override + { + GameAction::Serialise(stream); + + stream << RideIndex; + stream << Status; + } + + GameActionResult Query() const override + { + if (RideIndex >= MAX_RIDES) + { + log_warning("Invalid game command for ride %u", RideIndex); + return GameActionResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_SELECTION_OF_OBJECTS); + } + return GameActionResult(); + } + + GameActionResult Execute() const override + { + GameActionResult res; + res.ExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS; + + rct_ride *ride = get_ride(RideIndex); + + if (ride->type == RIDE_TYPE_NULL) + { + log_warning("Invalid game command for ride %u", RideIndex); + return GameActionResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_SELECTION_OF_OBJECTS); + } + + if (ride->overall_view != (uint16)-1) + { + res.Position.x = (ride->overall_view & 0xFF) * 32 + 16; + res.Position.y = (ride->overall_view >> 8) * 32 + 16; + res.Position.z = map_element_height(res.Position.x, res.Position.y); + } + + switch (Status) + { + case RIDE_STATUS_CLOSED: + if (ride->status == Status) { + if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN)) { + ride->lifecycle_flags &= ~RIDE_LIFECYCLE_CRASHED; + ride_clear_for_construction(RideIndex); + ride_remove_peeps(RideIndex); + } + } + + ride->status = RIDE_STATUS_CLOSED; + ride->lifecycle_flags &= ~RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING; + ride->race_winner = SPRITE_INDEX_NULL; + ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; + window_invalidate_by_number(WC_RIDE, RideIndex); + return res; + case RIDE_STATUS_TESTING: + case RIDE_STATUS_OPEN: + { + if (ride->status == Status) + { + return res; + } + + // Fix #3183: Make sure we close the construction window so the ride finishes any editing code before opening + // otherwise vehicles get added to the ride incorrectly (such as to a ghost station) + rct_window *constructionWindow = window_find_by_number(WC_RIDE_CONSTRUCTION, RideIndex); + if (constructionWindow != NULL) { + window_close(constructionWindow); + } + + if (Status == RIDE_STATUS_TESTING) { + if (!ride_is_valid_for_test(RideIndex, Status == RIDE_STATUS_OPEN, 1)) { + //*ebx = MONEY32_UNDEFINED; + return res; + } + } + else if (!ride_is_valid_for_open(RideIndex, Status == RIDE_STATUS_OPEN, 1)) { + //*ebx = MONEY32_UNDEFINED; + return res; + } + + ride->race_winner = SPRITE_INDEX_NULL; + ride->status = Status; + ride_get_measurement(RideIndex, NULL); + ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; + window_invalidate_by_number(WC_RIDE, RideIndex); + } + return res; + default: + Guard::Assert(false, "Invalid status passed: %u", Status); + } + + return GameActionResult(); + } +}; diff --git a/src/openrct2/actions/SetParkEntranceFeeAction.hpp b/src/openrct2/actions/SetParkEntranceFeeAction.hpp index 52751b34fc..9614dae8da 100644 --- a/src/openrct2/actions/SetParkEntranceFeeAction.hpp +++ b/src/openrct2/actions/SetParkEntranceFeeAction.hpp @@ -34,6 +34,8 @@ public: void Serialise(DataSerialiser& stream) override { + GameAction::Serialise(stream); + stream << Fee; } diff --git a/src/openrct2/game.h b/src/openrct2/game.h index 04790acb4c..99b89ddcdb 100644 --- a/src/openrct2/game.h +++ b/src/openrct2/game.h @@ -28,9 +28,9 @@ enum GAME_COMMAND { GAME_COMMAND_PLACE_TRACK, GAME_COMMAND_REMOVE_TRACK, GAME_COMMAND_LOAD_OR_QUIT, - GAME_COMMAND_CREATE_RIDE, + GAME_COMMAND_CREATE_RIDE, // GA GAME_COMMAND_DEMOLISH_RIDE, - GAME_COMMAND_SET_RIDE_STATUS, + GAME_COMMAND_SET_RIDE_STATUS, // GA GAME_COMMAND_SET_RIDE_VEHICLES, GAME_COMMAND_SET_RIDE_NAME, GAME_COMMAND_SET_RIDE_SETTING, @@ -59,10 +59,10 @@ enum GAME_COMMAND { GAME_COMMAND_SET_PARK_NAME, GAME_COMMAND_SET_PARK_OPEN, GAME_COMMAND_BUY_LAND_RIGHTS, - GAME_COMMAND_PLACE_PARK_ENTRANCE, + GAME_COMMAND_PLACE_PARK_ENTRANCE, // GA GAME_COMMAND_REMOVE_PARK_ENTRANCE, GAME_COMMAND_SET_MAZE_TRACK, - GAME_COMMAND_SET_PARK_ENTRANCE_FEE, + GAME_COMMAND_SET_PARK_ENTRANCE_FEE, // GA GAME_COMMAND_SET_STAFF_COLOUR, GAME_COMMAND_PLACE_WALL, GAME_COMMAND_REMOVE_WALL, diff --git a/src/openrct2/ride/ride.c b/src/openrct2/ride/ride.c index 86323cc8a2..9bb1c5b751 100644 --- a/src/openrct2/ride/ride.c +++ b/src/openrct2/ride/ride.c @@ -5195,7 +5195,7 @@ static rct_map_element *loc_6B4F6B(sint32 rideIndex, sint32 x, sint32 y) return NULL; } -static sint32 ride_is_valid_for_test(sint32 rideIndex, sint32 goingToBeOpen, sint32 isApplying) +sint32 ride_is_valid_for_test(sint32 rideIndex, sint32 goingToBeOpen, sint32 isApplying) { sint32 stationIndex; Ride *ride; @@ -5324,7 +5324,7 @@ static sint32 ride_is_valid_for_test(sint32 rideIndex, sint32 goingToBeOpen, sin * * rct2: 0x006B4EEA */ -static sint32 ride_is_valid_for_open(sint32 rideIndex, sint32 goingToBeOpen, sint32 isApplying) +sint32 ride_is_valid_for_open(sint32 rideIndex, sint32 goingToBeOpen, sint32 isApplying) { sint32 stationIndex; Ride *ride; @@ -5452,111 +5452,6 @@ static sint32 ride_is_valid_for_open(sint32 rideIndex, sint32 goingToBeOpen, sin return 1; } -void ride_set_status(sint32 rideIndex, sint32 status) -{ - game_do_command(0, GAME_COMMAND_FLAG_APPLY, 0, rideIndex | (status << 8), GAME_COMMAND_SET_RIDE_STATUS, 0, 0); -} - -/** - * - * rct2: 0x006B4EA6 - */ -void game_command_set_ride_status(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 *edx, sint32 *esi, sint32 *edi, sint32 *ebp) -{ - sint32 rideIndex, targetStatus; - Ride *ride; - - rideIndex = *edx & 0xFF; - if (rideIndex >= MAX_RIDES) - { - log_warning("Invalid game command for ride %u", rideIndex); - *ebx = MONEY32_UNDEFINED; - return; - } - targetStatus = (*edx >> 8) & 0xFF; - - gCommandExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_RUNNING_COSTS; - - ride = get_ride(rideIndex); - if (ride->type == RIDE_TYPE_NULL) - { - log_warning("Invalid game command for ride %u", rideIndex); - *ebx = MONEY32_UNDEFINED; - return; - } - - if (*ebx & GAME_COMMAND_FLAG_APPLY) { - if (ride->overall_view.xy != RCT_XY8_UNDEFINED) { - rct_xyz16 coord; - coord.x = ride->overall_view.x * 32 + 16; - coord.y = ride->overall_view.y * 32 + 16; - coord.z = map_element_height(coord.x, coord.y); - network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); - } - } - - switch (targetStatus) { - case RIDE_STATUS_CLOSED: - if (*ebx & GAME_COMMAND_FLAG_APPLY) { - if (ride->status == targetStatus) { - if (!(ride->lifecycle_flags & RIDE_LIFECYCLE_BROKEN_DOWN)) { - ride->lifecycle_flags &= ~RIDE_LIFECYCLE_CRASHED; - ride_clear_for_construction(rideIndex); - ride_remove_peeps(rideIndex); - } - } - - ride->status = RIDE_STATUS_CLOSED; - ride->lifecycle_flags &= ~RIDE_LIFECYCLE_PASS_STATION_NO_STOPPING; - ride->race_winner = SPRITE_INDEX_NULL; - ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; - window_invalidate_by_number(WC_RIDE, rideIndex); - } - *ebx = 0; - return; - case RIDE_STATUS_TESTING: - case RIDE_STATUS_OPEN: - if (ride->status == targetStatus) { - *ebx = 0; - return; - } - - if (*ebx & GAME_COMMAND_FLAG_APPLY) { - // Fix #3183: Make sure we close the construction window so the ride finishes any editing code before opening - // otherwise vehicles get added to the ride incorrectly (such as to a ghost station) - rct_window *constructionWindow = window_find_by_number(WC_RIDE_CONSTRUCTION, rideIndex); - if (constructionWindow != NULL) { - window_close(constructionWindow); - } - } else { - // #5787: We need to make sure ghost elements are removed before validating - // the track. - ride_construction_remove_ghosts(); - } - - if (targetStatus == RIDE_STATUS_TESTING) { - if (!ride_is_valid_for_test(rideIndex, targetStatus == RIDE_STATUS_OPEN, *ebx & GAME_COMMAND_FLAG_APPLY)) { - *ebx = MONEY32_UNDEFINED; - return; - } - } - else if (!ride_is_valid_for_open(rideIndex, targetStatus == RIDE_STATUS_OPEN, *ebx & GAME_COMMAND_FLAG_APPLY)) { - *ebx = MONEY32_UNDEFINED; - return; - } - - if (*ebx & GAME_COMMAND_FLAG_APPLY) { - ride->race_winner = SPRITE_INDEX_NULL; - ride->status = targetStatus; - ride_get_measurement(rideIndex, NULL); - ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; - window_invalidate_by_number(WC_RIDE, rideIndex); - } - *ebx = 0; - return; - } -} - void ride_set_name(sint32 rideIndex, const char *name) { typedef union name_union { diff --git a/src/openrct2/ride/ride.h b/src/openrct2/ride/ride.h index 108e3990e2..15ccc0dcbb 100644 --- a/src/openrct2/ride/ride.h +++ b/src/openrct2/ride/ride.h @@ -1062,6 +1062,8 @@ void ride_measurements_update(); rct_ride_measurement *ride_get_measurement(sint32 rideIndex, rct_string_id *message); void ride_breakdown_add_news_item(sint32 rideIndex); rct_peep *ride_find_closest_mechanic(Ride *ride, sint32 forInspection); +sint32 ride_is_valid_for_open(sint32 rideIndex, sint32 goingToBeOpen, sint32 isApplying); +sint32 ride_is_valid_for_test(sint32 rideIndex, sint32 goingToBeOpen, sint32 isApplying); sint32 ride_initialise_construction_window(sint32 rideIndex); void ride_construction_invalidate_current_track(); sint32 sub_6C683D(sint32* x, sint32* y, sint32* z, sint32 direction, sint32 type, uint16 extra_params, rct_map_element** output_element, uint16 flags);