diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 9bcf5ba87c..febed0c9c6 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -2,6 +2,7 @@ ------------------------------------------------------------------------ - Feature: [#20141] Add additional track pieces to the Giga Coaster. - Feature: [OpenMusic#46] Added Mystic ride music style. +- Feature: [#20825] Made setting the game speed a game action. - Change: [#20790] Default ride price set to free if park charges for entry. - Fix: [#20356] Cannot set tertiary colour on small scenery. - Fix: [#20737] Spent money in player window underflows when getting refunds. diff --git a/distribution/openrct2.d.ts b/distribution/openrct2.d.ts index caf4312222..0d954e7cdb 100644 --- a/distribution/openrct2.d.ts +++ b/distribution/openrct2.d.ts @@ -322,6 +322,7 @@ declare global { queryAction(action: "footpathplace", args: FootpathPlaceArgs, callback?: (result: GameActionResult) => void): void; queryAction(action: "footpathlayoutplace", args: FootpathLayoutPlaceArgs, callback?: (result: GameActionResult) => void): void; queryAction(action: "footpathremove", args: FootpathRemoveArgs, callback?: (result: GameActionResult) => void): void; + queryAction(action: "gamesetspeed", args: GameSetSpeedArgs, callback?: (result: GameActionResult) => void): void; queryAction(action: "guestsetflags", args: GuestSetFlagsArgs, callback?: (result: GameActionResult) => void): void; queryAction(action: "guestsetname", args: GuestSetNameArgs, callback?: (result: GameActionResult) => void): void; queryAction(action: "landbuyrights", args: LandBuyRightsArgs, callback?: (result: GameActionResult) => void): void; @@ -413,6 +414,7 @@ declare global { executeAction(action: "footpathplace", args: FootpathPlaceArgs, callback?: (result: GameActionResult) => void): void; executeAction(action: "footpathlayoutplace", args: FootpathLayoutPlaceArgs, callback?: (result: GameActionResult) => void): void; executeAction(action: "footpathremove", args: FootpathRemoveArgs, callback?: (result: GameActionResult) => void): void; + executeAction(action: "gamesetspeed", args: GameSetSpeedArgs, callback?: (result: GameActionResult) => void): void; executeAction(action: "guestsetflags", args: GuestSetFlagsArgs, callback?: (result: GameActionResult) => void): void; executeAction(action: "guestsetname", args: GuestSetNameArgs, callback?: (result: GameActionResult) => void): void; executeAction(action: "landbuyrights", args: LandBuyRightsArgs, callback?: (result: GameActionResult) => void): void; @@ -646,6 +648,7 @@ declare global { "footpathplace" | "footpathlayoutplace" | "footpathremove" | + "gamesetspeed" | "guestsetflags" | "guestsetname" | "landbuyrights" | @@ -814,6 +817,10 @@ declare global { z: number; } + interface GameSetSpeedArgs extends GameActionArgs { + speed: number; + } + // recommendation: use Peep.setFlag instead of the GuestSetFlag action interface GuestSetFlagsArgs extends GameActionArgs { peep: number; diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index c30a5980fb..f9a016ad48 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -3661,10 +3662,12 @@ void TopToolbar::FastforwardMenuDropdown(int16_t dropdownIndex) { if (dropdownIndex >= 0 && dropdownIndex <= 5) { - gGameSpeed = dropdownIndex + 1; - if (gGameSpeed >= 5) - gGameSpeed = 8; - w->Invalidate(); + auto newSpeed = dropdownIndex + 1; + if (newSpeed >= 5) + newSpeed = 8; + + auto setSpeedAction = GameSetSpeedAction(newSpeed); + GameActions::Execute(&setSpeedAction); } } } diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 3743405a1b..0defe78448 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -19,6 +19,7 @@ #include "ParkImporter.h" #include "PlatformEnvironment.h" #include "ReplayManager.h" +#include "actions/GameSetSpeedAction.h" #include "actions/LoadOrQuitAction.h" #include "audio/audio.h" #include "config/Config.h" @@ -97,24 +98,28 @@ using namespace OpenRCT2; void GameResetSpeed() { - gGameSpeed = 1; - WindowInvalidateByClass(WindowClass::TopToolbar); + auto setSpeedAction = GameSetSpeedAction(1); + GameActions::Execute(&setSpeedAction); } void GameIncreaseGameSpeed() { - gGameSpeed = std::min(gConfigGeneral.DebuggingTools ? 5 : 4, gGameSpeed + 1); - if (gGameSpeed == 5) - gGameSpeed = 8; - WindowInvalidateByClass(WindowClass::TopToolbar); + auto newSpeed = std::min(gConfigGeneral.DebuggingTools ? 5 : 4, gGameSpeed + 1); + if (newSpeed == 5) + newSpeed = 8; + + auto setSpeedAction = GameSetSpeedAction(newSpeed); + GameActions::Execute(&setSpeedAction); } void GameReduceGameSpeed() { - gGameSpeed = std::max(1, gGameSpeed - 1); - if (gGameSpeed == 7) - gGameSpeed = 4; - WindowInvalidateByClass(WindowClass::TopToolbar); + auto newSpeed = std::max(1, gGameSpeed - 1); + if (newSpeed == 7) + newSpeed = 4; + + auto setSpeedAction = GameSetSpeedAction(newSpeed); + GameActions::Execute(&setSpeedAction); } /** @@ -777,7 +782,7 @@ void GameLoadOrQuitNoSavePrompt() { InputSetFlag(INPUT_FLAG_5, false); } - gGameSpeed = 1; + GameResetSpeed(); gFirstTimeSaving = true; GameNotifyMapChange(); GameUnloadScripts(); diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index b4ea9b1563..cb198801d0 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -103,6 +103,7 @@ enum class GameCommand : int32_t Custom, // GA ChangeMapSize, FreezeRideRating, + SetGameSpeed, Count, }; diff --git a/src/openrct2/actions/GameActionRegistry.cpp b/src/openrct2/actions/GameActionRegistry.cpp index ad89abd454..f374464966 100644 --- a/src/openrct2/actions/GameActionRegistry.cpp +++ b/src/openrct2/actions/GameActionRegistry.cpp @@ -23,6 +23,7 @@ #include "FootpathPlaceAction.h" #include "FootpathRemoveAction.h" #include "GameAction.h" +#include "GameSetSpeedAction.h" #include "GuestSetFlagsAction.h" #include "GuestSetNameAction.h" #include "LandBuyRightsAction.h" @@ -206,6 +207,7 @@ namespace GameActions REGISTER_ACTION(ParkSetDateAction); REGISTER_ACTION(CheatSetAction); REGISTER_ACTION(MapChangeSizeAction); + REGISTER_ACTION(GameSetSpeedAction); #ifdef ENABLE_SCRIPTING REGISTER_ACTION(CustomAction); #endif diff --git a/src/openrct2/actions/GameSetSpeedAction.cpp b/src/openrct2/actions/GameSetSpeedAction.cpp new file mode 100644 index 0000000000..d4ea96bf23 --- /dev/null +++ b/src/openrct2/actions/GameSetSpeedAction.cpp @@ -0,0 +1,68 @@ +/***************************************************************************** + * Copyright (c) 2014-2023 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. + *****************************************************************************/ + +#include "GameSetSpeedAction.h" + +#include "../config/Config.h" + +GameSetSpeedAction::GameSetSpeedAction(int32_t speed) + : _speed(speed) +{ +} + +void GameSetSpeedAction::AcceptParameters(GameActionParameterVisitor& visitor) +{ + visitor.Visit("speed", _speed); +} + +uint16_t GameSetSpeedAction::GetActionFlags() const +{ + return GameAction::GetActionFlags() | GameActions::Flags::AllowWhilePaused; +} + +void GameSetSpeedAction::Serialise(DataSerialiser& stream) +{ + GameAction::Serialise(stream); + + stream << DS_TAG(_speed); +} + +GameActions::Result GameSetSpeedAction::Query() const +{ + GameActions::Result res = GameActions::Result(); + + if (!IsValidSpeed(_speed)) + { + LOG_WARNING("Invalid game command for speed %u", _speed); + return GameActions::Result(GameActions::Status::InvalidParameters, STR_NONE, STR_NONE); + } + + return res; +} + +GameActions::Result GameSetSpeedAction::Execute() const +{ + GameActions::Result res = GameActions::Result(); + + if (!IsValidSpeed(_speed)) + { + LOG_WARNING("Invalid game command for speed %u", _speed); + return GameActions::Result(GameActions::Status::InvalidParameters, STR_NONE, STR_NONE); + } + + gGameSpeed = _speed; + WindowInvalidateByClass(WindowClass::TopToolbar); + + return res; +} + +bool GameSetSpeedAction::IsValidSpeed(int32_t speed) const +{ + return (speed >= 1 && speed <= 4) || (gConfigGeneral.DebuggingTools && speed == 8); +} diff --git a/src/openrct2/actions/GameSetSpeedAction.h b/src/openrct2/actions/GameSetSpeedAction.h new file mode 100644 index 0000000000..1348f89dda --- /dev/null +++ b/src/openrct2/actions/GameSetSpeedAction.h @@ -0,0 +1,33 @@ +/***************************************************************************** + * Copyright (c) 2014-2023 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 "GameAction.h" + +class GameSetSpeedAction final : public GameActionBase +{ +private: + int32_t _speed{ 1 }; + +public: + GameSetSpeedAction() = default; + GameSetSpeedAction(int32_t speed); + + void AcceptParameters(GameActionParameterVisitor& visitor) override; + + uint16_t GetActionFlags() const override; + + void Serialise(DataSerialiser& stream) override; + GameActions::Result Query() const override; + GameActions::Result Execute() const override; + +private: + bool IsValidSpeed(int32_t speed) const; +}; diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index 49134f082c..4dbcaa9ccb 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -93,6 +93,7 @@ + @@ -617,6 +618,7 @@ + diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index 39aa046969..cc73769c4a 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -43,7 +43,7 @@ // It is used for making sure only compatible builds get connected, even within // single OpenRCT2 version. -#define NETWORK_STREAM_VERSION "4" +#define NETWORK_STREAM_VERSION "5" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION diff --git a/src/openrct2/scripting/ScriptEngine.cpp b/src/openrct2/scripting/ScriptEngine.cpp index c2626a4ae7..7989a0ed67 100644 --- a/src/openrct2/scripting/ScriptEngine.cpp +++ b/src/openrct2/scripting/ScriptEngine.cpp @@ -1326,6 +1326,7 @@ const static EnumMap ActionNameToType = { { "footpathremove", GameCommand::RemovePath }, { "footpathadditionplace", GameCommand::PlaceFootpathAddition }, { "footpathadditionremove", GameCommand::RemoveFootpathAddition }, + { "gamesetspeed", GameCommand::SetGameSpeed }, { "guestsetflags", GameCommand::GuestSetFlags }, { "guestsetname", GameCommand::SetGuestName }, { "landbuyrights", GameCommand::BuyLandRights },