From cd8c67ddac5b4969311692e420ae8af39ffdee8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= Date: Sat, 4 May 2019 15:28:38 +0200 Subject: [PATCH] Implement SetCheatAction. (#8990) * Implement SetCheatAction. * Bump up network version --- src/openrct2-ui/windows/Cheats.cpp | 252 ++-- src/openrct2-ui/windows/TopToolbar.cpp | 10 +- src/openrct2/Cheats.cpp | 1019 ++--------------- src/openrct2/Cheats.h | 110 +- src/openrct2/Game.cpp | 15 +- src/openrct2/ReplayManager.cpp | 11 + .../actions/GameActionRegistration.cpp | 2 + src/openrct2/actions/SetCheatAction.hpp | 792 +++++++++++++ src/openrct2/core/DataSerialiserTraits.h | 21 + src/openrct2/interface/InteractiveConsole.cpp | 101 +- src/openrct2/interface/Screenshot.cpp | 11 +- src/openrct2/network/Network.cpp | 2 +- src/openrct2/network/NetworkTypes.h | 1 + src/openrct2/peep/Peep.h | 4 + 14 files changed, 1158 insertions(+), 1193 deletions(-) create mode 100644 src/openrct2/actions/SetCheatAction.hpp diff --git a/src/openrct2-ui/windows/Cheats.cpp b/src/openrct2-ui/windows/Cheats.cpp index 4755f98376..e21ce7a0ba 100644 --- a/src/openrct2-ui/windows/Cheats.cpp +++ b/src/openrct2-ui/windows/Cheats.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,10 @@ static utf8 _moneySpinnerText[MONEY_STRING_MAXLENGTH]; static money32 _moneySpinnerValue = CHEATS_MONEY_DEFAULT; static int32_t _selectedStaffSpeed = 1; +static int32_t _parkRatingSpinnerValue; +static int32_t _yearSpinnerValue = 1; +static int32_t _monthSpinnerValue = 1; +static int32_t _daySpinnerValue = 1; // clang-format off enum @@ -613,7 +618,7 @@ rct_window* window_cheats_open() window->hold_down_widgets = window_cheats_page_hold_down_widgets[0]; window_init_scroll_widgets(window); window_cheats_set_page(window, WINDOW_CHEATS_PAGE_MONEY); - park_rating_spinner_value = get_forced_park_rating() >= 0 ? get_forced_park_rating() : 999; + _parkRatingSpinnerValue = get_forced_park_rating() >= 0 ? get_forced_park_rating() : 999; return window; } @@ -633,45 +638,45 @@ static void window_cheats_money_mousedown(rct_window* w, rct_widgetindex widgetI widget_invalidate_by_class(WC_CHEATS, WIDX_MONEY_SPINNER); break; case WIDX_ADD_MONEY: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_ADDMONEY, _moneySpinnerValue, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::AddMoney, _moneySpinnerValue); break; case WIDX_YEAR_UP: - year_spinner_value++; - year_spinner_value = std::clamp(year_spinner_value, 1, MAX_YEAR); + _yearSpinnerValue++; + _yearSpinnerValue = std::clamp(_yearSpinnerValue, 1, MAX_YEAR); widget_invalidate(w, WIDX_YEAR_BOX); break; case WIDX_YEAR_DOWN: - year_spinner_value--; - year_spinner_value = std::clamp(year_spinner_value, 1, MAX_YEAR); + _yearSpinnerValue--; + _yearSpinnerValue = std::clamp(_yearSpinnerValue, 1, MAX_YEAR); widget_invalidate(w, WIDX_YEAR_BOX); break; case WIDX_MONTH_UP: - month_spinner_value++; - month_spinner_value = std::clamp(month_spinner_value, 1, (int)MONTH_COUNT); - day_spinner_value = std::clamp(day_spinner_value, 1, (int)days_in_month[month_spinner_value - 1]); + _monthSpinnerValue++; + _monthSpinnerValue = std::clamp(_monthSpinnerValue, 1, (int)MONTH_COUNT); + _daySpinnerValue = std::clamp(_daySpinnerValue, 1, (int)days_in_month[_monthSpinnerValue - 1]); widget_invalidate(w, WIDX_MONTH_BOX); widget_invalidate(w, WIDX_DAY_BOX); break; case WIDX_MONTH_DOWN: - month_spinner_value--; - month_spinner_value = std::clamp(month_spinner_value, 1, (int)MONTH_COUNT); - day_spinner_value = std::clamp(day_spinner_value, 1, (int)days_in_month[month_spinner_value - 1]); + _monthSpinnerValue--; + _monthSpinnerValue = std::clamp(_monthSpinnerValue, 1, (int)MONTH_COUNT); + _daySpinnerValue = std::clamp(_daySpinnerValue, 1, (int)days_in_month[_monthSpinnerValue - 1]); widget_invalidate(w, WIDX_MONTH_BOX); widget_invalidate(w, WIDX_DAY_BOX); break; case WIDX_DAY_UP: - day_spinner_value++; - day_spinner_value = std::clamp(day_spinner_value, 1, (int)days_in_month[month_spinner_value - 1]); + _daySpinnerValue++; + _daySpinnerValue = std::clamp(_daySpinnerValue, 1, (int)days_in_month[_monthSpinnerValue - 1]); widget_invalidate(w, WIDX_DAY_BOX); break; case WIDX_DAY_DOWN: - day_spinner_value--; - day_spinner_value = std::clamp(day_spinner_value, 1, (int)days_in_month[month_spinner_value - 1]); + _daySpinnerValue--; + _daySpinnerValue = std::clamp(_daySpinnerValue, 1, (int)days_in_month[_monthSpinnerValue - 1]); widget_invalidate(w, WIDX_DAY_BOX); break; case WIDX_DATE_SET: { - auto setDateAction = ParkSetDateAction(year_spinner_value, month_spinner_value, day_spinner_value); + auto setDateAction = ParkSetDateAction(_yearSpinnerValue, _monthSpinnerValue, _daySpinnerValue); GameActions::Execute(&setDateAction); window_invalidate_by_class(WC_BOTTOM_TOOLBAR); break; @@ -694,18 +699,21 @@ static void window_cheats_misc_mousedown(rct_window* w, rct_widgetindex widgetIn switch (widgetIndex) { case WIDX_INCREASE_PARK_RATING: - park_rating_spinner_value = std::min(999, 10 * (park_rating_spinner_value / 10 + 1)); + _parkRatingSpinnerValue = std::min(999, 10 * (_parkRatingSpinnerValue / 10 + 1)); widget_invalidate_by_class(WC_CHEATS, WIDX_PARK_RATING_SPINNER); if (get_forced_park_rating() >= 0) - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETFORCEDPARKRATING, park_rating_spinner_value, GAME_COMMAND_CHEAT, 0, 0); + { + auto setCheatAction = SetCheatAction(CheatType::SetForcedParkRating, _parkRatingSpinnerValue); + GameActions::Execute(&setCheatAction); + } break; case WIDX_DECREASE_PARK_RATING: - park_rating_spinner_value = std::max(0, 10 * (park_rating_spinner_value / 10 - 1)); + _parkRatingSpinnerValue = std::max(0, 10 * (_parkRatingSpinnerValue / 10 - 1)); widget_invalidate_by_class(WC_CHEATS, WIDX_PARK_RATING_SPINNER); if (get_forced_park_rating() >= 0) - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETFORCEDPARKRATING, park_rating_spinner_value, GAME_COMMAND_CHEAT, 0, 0); + { + CheatsSet(CheatType::SetForcedParkRating, _parkRatingSpinnerValue); + } break; case WIDX_WEATHER_DROPDOWN_BUTTON: { @@ -755,7 +763,7 @@ static void window_cheats_misc_dropdown([[maybe_unused]] rct_window* w, rct_widg } else if (widgetIndex == WIDX_WEATHER_DROPDOWN_BUTTON) { - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_FORCEWEATHER, dropdownIndex, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::ForceWeather, dropdownIndex); } else if (widgetIndex == WIDX_STAFF_SPEED_DROPDOWN_BUTTON) { @@ -769,7 +777,7 @@ static void window_cheats_misc_dropdown([[maybe_unused]] rct_window* w, rct_widg speed = CHEATS_STAFF_NORMAL_SPEED; } - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETSTAFFSPEED, speed, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetStaffSpeed, speed); _selectedStaffSpeed = dropdownIndex; } } @@ -788,8 +796,7 @@ static void window_cheats_money_mouseup(rct_window* w, rct_widgetindex widgetInd window_cheats_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_NO_MONEY: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_NOMONEY, gParkFlags & PARK_FLAGS_NO_MONEY ? 0 : 1, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::NoMoney, gParkFlags & PARK_FLAGS_NO_MONEY ? 0 : 1); break; case WIDX_MONEY_SPINNER: money_to_string(_moneySpinnerValue, _moneySpinnerText, MONEY_STRING_MAXLENGTH, false); @@ -797,10 +804,10 @@ static void window_cheats_money_mouseup(rct_window* w, rct_widgetindex widgetInd w, WIDX_MONEY_SPINNER, STR_ENTER_NEW_VALUE, STR_ENTER_NEW_VALUE, _moneySpinnerText, MONEY_STRING_MAXLENGTH); break; case WIDX_SET_MONEY: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETMONEY, _moneySpinnerValue, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetMoney, _moneySpinnerValue); break; case WIDX_CLEAR_LOAN: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_CLEARLOAN, CHEATS_MONEY_DEFAULT, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::ClearLoan, CHEATS_MONEY_DEFAULT); break; } } @@ -819,108 +826,82 @@ static void window_cheats_guests_mouseup(rct_window* w, rct_widgetindex widgetIn window_cheats_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_GUEST_HAPPINESS_MAX: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_HAPPINESS, GAME_COMMAND_CHEAT, - PEEP_MAX_HAPPINESS, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_HAPPINESS, PEEP_MAX_HAPPINESS); break; case WIDX_GUEST_HAPPINESS_MIN: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_HAPPINESS, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_HAPPINESS, 0); break; case WIDX_GUEST_ENERGY_MAX: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_ENERGY, GAME_COMMAND_CHEAT, - PEEP_MAX_ENERGY, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_ENERGY, PEEP_MAX_ENERGY); break; case WIDX_GUEST_ENERGY_MIN: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_ENERGY, GAME_COMMAND_CHEAT, - PEEP_MIN_ENERGY, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_ENERGY, PEEP_MIN_ENERGY); break; case WIDX_GUEST_HUNGER_MAX: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_HUNGER, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_HUNGER, 0); break; case WIDX_GUEST_HUNGER_MIN: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_HUNGER, GAME_COMMAND_CHEAT, 255, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_HUNGER, PEEP_MAX_HUNGER); break; case WIDX_GUEST_THIRST_MAX: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_THIRST, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_THIRST, 0); break; case WIDX_GUEST_THIRST_MIN: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_THIRST, GAME_COMMAND_CHEAT, 255, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_THIRST, PEEP_MAX_THIRST); break; case WIDX_GUEST_NAUSEA_MAX: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_NAUSEA, GAME_COMMAND_CHEAT, 255, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_NAUSEA, PEEP_MAX_NAUSEA); break; case WIDX_GUEST_NAUSEA_MIN: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_NAUSEA, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_NAUSEA, 0); break; case WIDX_GUEST_NAUSEA_TOLERANCE_MAX: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_NAUSEA_TOLERANCE, GAME_COMMAND_CHEAT, - PEEP_NAUSEA_TOLERANCE_HIGH, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_NAUSEA_TOLERANCE, PEEP_NAUSEA_TOLERANCE_HIGH); break; case WIDX_GUEST_NAUSEA_TOLERANCE_MIN: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_NAUSEA_TOLERANCE, GAME_COMMAND_CHEAT, - PEEP_NAUSEA_TOLERANCE_NONE, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_NAUSEA_TOLERANCE, PEEP_NAUSEA_TOLERANCE_NONE); break; case WIDX_GUEST_BATHROOM_MAX: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_BATHROOM, GAME_COMMAND_CHEAT, 255, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_BATHROOM, PEEP_MAX_BATHROOM); break; case WIDX_GUEST_BATHROOM_MIN: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_BATHROOM, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_BATHROOM, 0); break; case WIDX_GUEST_RIDE_INTENSITY_MORE_THAN_1: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY, - GAME_COMMAND_CHEAT, 1, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY, 1); break; case WIDX_GUEST_RIDE_INTENSITY_LESS_THAN_15: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGUESTPARAMETER, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY, - GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetGuestParameter, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY, 0); break; case WIDX_TRAM_GUESTS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_GENERATEGUESTS, CHEATS_TRAM_INCREMENT, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::GenerateGuests, CHEATS_TRAM_INCREMENT); break; case WIDX_REMOVE_ALL_GUESTS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_REMOVEALLGUESTS, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::RemoveAllGuests); break; case WIDX_EXPLODE_GUESTS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_EXPLODEGUESTS, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::ExplodeGuests); break; case WIDX_GIVE_GUESTS_MONEY: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_GIVEALLGUESTS, OBJECT_MONEY, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::GiveAllGuests, OBJECT_MONEY); break; case WIDX_GIVE_GUESTS_PARK_MAPS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_GIVEALLGUESTS, OBJECT_PARK_MAP, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::GiveAllGuests, OBJECT_PARK_MAP); break; case WIDX_GIVE_GUESTS_BALLOONS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_GIVEALLGUESTS, OBJECT_BALLOON, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::GiveAllGuests, OBJECT_BALLOON); break; case WIDX_GIVE_GUESTS_UMBRELLAS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_GIVEALLGUESTS, OBJECT_UMBRELLA, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::GiveAllGuests, OBJECT_UMBRELLA); break; case WIDX_GUEST_IGNORE_RIDE_INTENSITY: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_IGNORERIDEINTENSITY, !gCheatsIgnoreRideIntensity, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::IgnoreRideIntensity, !gCheatsIgnoreRideIntensity); break; case WIDX_DISABLE_VANDALISM: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLEVANDALISM, !gCheatsDisableVandalism, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::DisableVandalism, !gCheatsDisableVandalism); break; case WIDX_DISABLE_LITTERING: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLELITTERING, !gCheatsDisableLittering, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::DisableLittering, !gCheatsDisableLittering); break; } } @@ -939,42 +920,40 @@ static void window_cheats_misc_mouseup(rct_window* w, rct_widgetindex widgetInde window_cheats_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_FREEZE_WEATHER: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_FREEZEWEATHER, !gCheatsFreezeWeather, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::FreezeWeather, !gCheatsFreezeWeather); break; case WIDX_OPEN_CLOSE_PARK: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_OPENCLOSEPARK, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::OpenClosePark); break; case WIDX_CLEAR_GRASS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGRASSLENGTH, GRASS_LENGTH_CLEAR_0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetGrassLength, GRASS_LENGTH_CLEAR_0); break; case WIDX_MOWED_GRASS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGRASSLENGTH, GRASS_LENGTH_MOWED, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetGrassLength, GRASS_LENGTH_MOWED); break; case WIDX_WATER_PLANTS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_WATERPLANTS, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::WaterPlants); break; case WIDX_FIX_VANDALISM: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_FIXVANDALISM, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::FixVandalism); break; case WIDX_REMOVE_LITTER: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_REMOVELITTER, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::RemoveLitter); break; case WIDX_DISABLE_PLANT_AGING: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLEPLANTAGING, !gCheatsDisablePlantAging, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::DisablePlantAging, !gCheatsDisablePlantAging); break; case WIDX_WIN_SCENARIO: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_WINSCENARIO, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::WinScenario); break; case WIDX_HAVE_FUN: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_HAVEFUN, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::HaveFun); break; case WIDX_OWN_ALL_LAND: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_OWNALLLAND, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::OwnAllLand); break; case WIDX_NEVERENDING_MARKETING: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_NEVERENDINGMARKETING, !gCheatsNeverendingMarketing, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::NeverEndingMarketing, !gCheatsNeverendingMarketing); break; case WIDX_PARK_PARAMETERS: context_open_window(WC_EDITOR_SCENARIO_OPTIONS); @@ -982,12 +961,11 @@ static void window_cheats_misc_mouseup(rct_window* w, rct_widgetindex widgetInde case WIDX_FORCE_PARK_RATING: if (get_forced_park_rating() >= 0) { - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETFORCEDPARKRATING, -1, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetForcedParkRating, -1); } else { - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETFORCEDPARKRATING, park_rating_spinner_value, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetForcedParkRating, _parkRatingSpinnerValue); } break; } @@ -1007,89 +985,80 @@ static void window_cheats_rides_mouseup(rct_window* w, rct_widgetindex widgetInd window_cheats_set_page(w, widgetIndex - WIDX_TAB_1); break; case WIDX_RENEW_RIDES: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_RENEWRIDES, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::RenewRides); break; case WIDX_MAKE_DESTRUCTIBLE: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_MAKEDESTRUCTIBLE, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::MakeDestructible); break; case WIDX_FIX_ALL: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_FIXRIDES, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::FixRides); break; case WIDX_FAST_LIFT_HILL: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_FASTLIFTHILL, !gCheatsFastLiftHill, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::FastLiftHill, !gCheatsFastLiftHill); + break; case WIDX_DISABLE_BRAKES_FAILURE: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLEBRAKESFAILURE, !gCheatsDisableBrakesFailure, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::DisableBrakesFailure, !gCheatsDisableBrakesFailure); break; case WIDX_DISABLE_ALL_BREAKDOWNS: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLEALLBREAKDOWNS, !gCheatsDisableAllBreakdowns, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::DisableAllBreakdowns, !gCheatsDisableAllBreakdowns); break; case WIDX_BUILD_IN_PAUSE_MODE: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_BUILDINPAUSEMODE, !gCheatsBuildInPauseMode, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::BuildInPauseMode, !gCheatsBuildInPauseMode); break; case WIDX_RESET_CRASH_STATUS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_RESETCRASHSTATUS, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::ResetCrashStatus); break; case WIDX_10_MINUTE_INSPECTIONS: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_10MINUTEINSPECTIONS, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::TenMinuteInspections); break; case WIDX_SHOW_ALL_OPERATING_MODES: + { if (!gCheatsShowAllOperatingModes) { context_show_error(STR_WARNING_IN_CAPS, STR_THIS_FEATURE_IS_CURRENTLY_UNSTABLE); } - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SHOWALLOPERATINGMODES, !gCheatsShowAllOperatingModes, GAME_COMMAND_CHEAT, 0, - 0); - break; + CheatsSet(CheatType::ShowAllOperatingModes, !gCheatsShowAllOperatingModes); + } + break; case WIDX_SHOW_VEHICLES_FROM_OTHER_TRACK_TYPES: + { if (!gCheatsShowVehiclesFromOtherTrackTypes) { context_show_error(STR_WARNING_IN_CAPS, STR_THIS_FEATURE_IS_CURRENTLY_UNSTABLE); } - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_SHOWVEHICLESFROMOTHERTRACKTYPES, !gCheatsShowVehiclesFromOtherTrackTypes, - GAME_COMMAND_CHEAT, 0, 0); - break; + CheatsSet(CheatType::ShowVehiclesFromOtherTrackTypes, !gCheatsShowVehiclesFromOtherTrackTypes); + } + break; case WIDX_DISABLE_TRAIN_LENGTH_LIMITS: + { if (!gCheatsDisableTrainLengthLimit) { context_show_error(STR_WARNING_IN_CAPS, STR_THIS_FEATURE_IS_CURRENTLY_UNSTABLE); } - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLETRAINLENGTHLIMIT, !gCheatsDisableTrainLengthLimit, GAME_COMMAND_CHEAT, - 0, 0); - break; + CheatsSet(CheatType::DisableTrainLengthLimit, !gCheatsDisableTrainLengthLimit); + } + break; case WIDX_ENABLE_CHAIN_LIFT_ON_ALL_TRACK: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_ENABLECHAINLIFTONALLTRACK, !gCheatsEnableChainLiftOnAllTrack, - GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::EnableChainLiftOnAllTrack, !gCheatsEnableChainLiftOnAllTrack); break; case WIDX_ENABLE_ARBITRARY_RIDE_TYPE_CHANGES: + { if (!gCheatsAllowArbitraryRideTypeChanges) { context_show_error(STR_WARNING_IN_CAPS, STR_THIS_FEATURE_IS_CURRENTLY_UNSTABLE); } - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_ALLOW_ARBITRARY_RIDE_TYPE_CHANGES, !gCheatsAllowArbitraryRideTypeChanges, - GAME_COMMAND_CHEAT, 0, 0); - break; + CheatsSet(CheatType::AllowArbitraryRideTypeChanges, !gCheatsAllowArbitraryRideTypeChanges); + } + break; case WIDX_DISABLE_RIDE_VALUE_AGING: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLERIDEVALUEAGING, !gCheatsDisableRideValueAging, GAME_COMMAND_CHEAT, 0, - 0); + CheatsSet(CheatType::DisableRideValueAging, !gCheatsDisableRideValueAging); break; case WIDX_IGNORE_RESEARCH_STATUS: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_IGNORERESEARCHSTATUS, !gCheatsIgnoreResearchStatus, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::IgnoreResearchStatus, !gCheatsIgnoreResearchStatus); break; case WIDX_ENABLE_ALL_DRAWABLE_TRACK_PIECES: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_ENABLEALLDRAWABLETRACKPIECES, !gCheatsEnableAllDrawableTrackPieces, - GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::EnableAllDrawableTrackPieces, !gCheatsEnableAllDrawableTrackPieces); break; } } @@ -1207,26 +1176,25 @@ static void window_cheats_paint(rct_window* w, rct_drawpixelinfo* dpi) { colour |= COLOUR_FLAG_INSET; } - int32_t actual_month = month_spinner_value - 1; + int32_t actual_month = _monthSpinnerValue - 1; gfx_draw_string_left( dpi, STR_BOTTOM_TOOLBAR_CASH, gCommonFormatArgs, colour, w->x + XPL(0) + TXTO, w->y + YPL(2) + TXTO); gfx_draw_string_left(dpi, STR_YEAR, nullptr, COLOUR_BLACK, w->x + XPL(0) + TXTO, w->y + YPL(7) + TXTO); gfx_draw_string_left(dpi, STR_MONTH, nullptr, COLOUR_BLACK, w->x + XPL(0) + TXTO, w->y + YPL(8) + TXTO); gfx_draw_string_left(dpi, STR_DAY, nullptr, COLOUR_BLACK, w->x + XPL(0) + TXTO, w->y + YPL(9) + TXTO); gfx_draw_string_right( - dpi, STR_FORMAT_INTEGER, &year_spinner_value, w->colours[1], w->x + WPL(1) - 34 - TXTO, w->y + YPL(7) + TXTO); + dpi, STR_FORMAT_INTEGER, &_yearSpinnerValue, w->colours[1], w->x + WPL(1) - 34 - TXTO, w->y + YPL(7) + TXTO); gfx_draw_string_right( dpi, STR_FORMAT_MONTH, &actual_month, w->colours[1], w->x + WPL(1) - 34 - TXTO, w->y + YPL(8) + TXTO); gfx_draw_string_right( - dpi, STR_FORMAT_INTEGER, &day_spinner_value, w->colours[1], w->x + WPL(1) - 34 - TXTO, w->y + YPL(9) + TXTO); + dpi, STR_FORMAT_INTEGER, &_daySpinnerValue, w->colours[1], w->x + WPL(1) - 34 - TXTO, w->y + YPL(9) + TXTO); } else if (w->page == WINDOW_CHEATS_PAGE_MISC) { gfx_draw_string_left(dpi, STR_CHEAT_STAFF_SPEED, nullptr, COLOUR_BLACK, w->x + XPL(0) + TXTO, w->y + YPL(17) + TXTO); gfx_draw_string_left(dpi, STR_FORCE_WEATHER, nullptr, COLOUR_BLACK, w->x + XPL(0) + TXTO, w->y + YPL(10) + TXTO); gfx_draw_string_right( - dpi, STR_FORMAT_INTEGER, &park_rating_spinner_value, w->colours[1], w->x + WPL(1) - 34 - TXTO, - w->y + YPL(5) + TXTO); + dpi, STR_FORMAT_INTEGER, &_parkRatingSpinnerValue, w->colours[1], w->x + WPL(1) - 34 - TXTO, w->y + YPL(5) + TXTO); } else if (w->page == WINDOW_CHEATS_PAGE_GUESTS) { diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 25595f9da5..dadbdc6735 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -3421,16 +3422,13 @@ static void top_toolbar_cheats_menu_dropdown(int16_t dropdownIndex) context_open_window(WC_EDITOR_SCENARIO_OPTIONS); break; case DDIDX_ENABLE_SANDBOX_MODE: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SANDBOXMODE, !gCheatsSandboxMode, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SandboxMode, !gCheatsSandboxMode); break; case DDIDX_DISABLE_CLEARANCE_CHECKS: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLECLEARANCECHECKS, !gCheatsDisableClearanceChecks, GAME_COMMAND_CHEAT, 0, - 0); + CheatsSet(CheatType::DisableClearanceChecks, !gCheatsDisableClearanceChecks); break; case DDIDX_DISABLE_SUPPORT_LIMITS: - game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLESUPPORTLIMITS, !gCheatsDisableSupportLimits, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::DisableSupportLimits, !gCheatsDisableSupportLimits); break; } } diff --git a/src/openrct2/Cheats.cpp b/src/openrct2/Cheats.cpp index d1b1025e61..a7758e77d7 100644 --- a/src/openrct2/Cheats.cpp +++ b/src/openrct2/Cheats.cpp @@ -11,6 +11,7 @@ #include "GameState.h" #include "actions/ParkSetLoanAction.hpp" +#include "actions/SetCheatAction.hpp" #include "config/Config.h" #include "localisation/Localisation.h" #include "network/network.h" @@ -49,616 +50,7 @@ bool gCheatsDisableRideValueAging = false; bool gCheatsIgnoreResearchStatus = false; bool gCheatsEnableAllDrawableTrackPieces = false; -int32_t park_rating_spinner_value; -int32_t year_spinner_value = 1; -int32_t month_spinner_value = 1; -int32_t day_spinner_value = 1; - -#pragma region Cheat functions - -static void cheat_set_grass_length(int32_t length) -{ - int32_t x, y; - - for (y = 0; y < MAXIMUM_MAP_SIZE_TECHNICAL; y++) - { - for (x = 0; x < MAXIMUM_MAP_SIZE_TECHNICAL; x++) - { - auto surfaceElement = map_get_surface_element_at(x, y)->AsSurface(); - if (surfaceElement != nullptr && (surfaceElement->GetOwnership() & OWNERSHIP_OWNED) - && surfaceElement->GetWaterHeight() == 0 && surfaceElement->CanGrassGrow()) - { - surfaceElement->SetGrassLength(length); - } - } - } - - gfx_invalidate_screen(); -} - -static void cheat_water_plants() -{ - tile_element_iterator it; - - tile_element_iterator_begin(&it); - do - { - if (it.element->GetType() == TILE_ELEMENT_TYPE_SMALL_SCENERY) - { - it.element->AsSmallScenery()->SetAge(0); - } - } while (tile_element_iterator_next(&it)); - - gfx_invalidate_screen(); -} - -static void cheat_fix_vandalism() -{ - tile_element_iterator it; - - tile_element_iterator_begin(&it); - do - { - if (it.element->GetType() != TILE_ELEMENT_TYPE_PATH) - continue; - - if (!(it.element)->AsPath()->HasAddition()) - continue; - - it.element->AsPath()->SetIsBroken(false); - } while (tile_element_iterator_next(&it)); - - gfx_invalidate_screen(); -} - -static void cheat_remove_litter() -{ - rct_litter* litter; - uint16_t spriteIndex, nextSpriteIndex; - - for (spriteIndex = gSpriteListHead[SPRITE_LIST_LITTER]; spriteIndex != SPRITE_INDEX_NULL; spriteIndex = nextSpriteIndex) - { - litter = &(get_sprite(spriteIndex)->litter); - nextSpriteIndex = litter->next; - sprite_remove((rct_sprite*)litter); - } - - tile_element_iterator it; - rct_scenery_entry* sceneryEntry; - - tile_element_iterator_begin(&it); - do - { - if (it.element->GetType() != TILE_ELEMENT_TYPE_PATH) - continue; - - if (!(it.element)->AsPath()->HasAddition()) - continue; - - sceneryEntry = it.element->AsPath()->GetAdditionEntry(); - if (sceneryEntry->path_bit.flags & PATH_BIT_FLAG_IS_BIN) - it.element->AsPath()->SetAdditionStatus(0xFF); - - } while (tile_element_iterator_next(&it)); - - gfx_invalidate_screen(); -} - -static void cheat_fix_rides() -{ - ride_id_t rideIndex; - Ride* ride; - - FOR_ALL_RIDES (rideIndex, ride) - { - if ((ride->mechanic_status != RIDE_MECHANIC_STATUS_FIXING) - && (ride->lifecycle_flags & (RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN))) - { - auto mechanic = ride_get_assigned_mechanic(ride); - if (mechanic != nullptr) - { - mechanic->RemoveFromRide(); - } - - ride_fix_breakdown(ride, 0); - ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; - } - } -} - -static void cheat_renew_rides() -{ - int32_t i; - Ride* ride; - - FOR_ALL_RIDES (i, ride) - { - ride->Renew(); - } - window_invalidate_by_class(WC_RIDE); -} - -static void cheat_make_destructible() -{ - int32_t i; - Ride* ride; - FOR_ALL_RIDES (i, ride) - { - if (ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE) - ride->lifecycle_flags &= ~RIDE_LIFECYCLE_INDESTRUCTIBLE; - if (ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK) - ride->lifecycle_flags &= ~RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK; - } - window_invalidate_by_class(WC_RIDE); -} - -static void cheat_reset_crash_status() -{ - int32_t i; - Ride* ride; - - FOR_ALL_RIDES (i, ride) - { - // Reset crash status - if (ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED) - ride->lifecycle_flags &= ~RIDE_LIFECYCLE_CRASHED; - // Reset crash history - ride->last_crash_type = RIDE_CRASH_TYPE_NONE; - } - window_invalidate_by_class(WC_RIDE); -} - -static void cheat_10_minute_inspections() -{ - int32_t i; - Ride* ride; - - FOR_ALL_RIDES (i, ride) - { - // Set inspection interval to 10 minutes - ride->inspection_interval = RIDE_INSPECTION_EVERY_10_MINUTES; - } - window_invalidate_by_class(WC_RIDE); -} - -static void cheat_no_money(bool enabled) -{ - if (enabled) - { - gParkFlags |= PARK_FLAGS_NO_MONEY; - } - else - { - gParkFlags &= ~PARK_FLAGS_NO_MONEY; - } - // Invalidate all windows that have anything to do with finance - window_invalidate_by_class(WC_RIDE); - window_invalidate_by_class(WC_PEEP); - window_invalidate_by_class(WC_PARK_INFORMATION); - window_invalidate_by_class(WC_FINANCES); - window_invalidate_by_class(WC_BOTTOM_TOOLBAR); - window_invalidate_by_class(WC_TOP_TOOLBAR); - window_invalidate_by_class(WC_CHEATS); -} - -static void cheat_set_money(money32 amount) -{ - gCash = amount; - - window_invalidate_by_class(WC_FINANCES); - window_invalidate_by_class(WC_BOTTOM_TOOLBAR); -} - -static void cheat_add_money(money32 amount) -{ - gCash = add_clamp_money32(gCash, amount); - - window_invalidate_by_class(WC_FINANCES); - window_invalidate_by_class(WC_BOTTOM_TOOLBAR); -} - -static void cheat_clear_loan() -{ - // First give money - cheat_add_money(gBankLoan); - - // Then pay the loan - auto gameAction = ParkSetLoanAction(MONEY(0, 00)); - GameActions::Execute(&gameAction); -} - -static void cheat_generate_guests(int32_t count) -{ - auto& park = GetContext()->GetGameState()->GetPark(); - for (int32_t i = 0; i < count; i++) - { - park.GenerateGuest(); - } - window_invalidate_by_class(WC_BOTTOM_TOOLBAR); -} - -static void cheat_set_guest_parameter(int32_t parameter, int32_t value) -{ - int32_t spriteIndex; - Peep* p; - FOR_ALL_GUESTS (spriteIndex, p) - { - auto peep = p->AsGuest(); - assert(peep != nullptr); - switch (parameter) - { - case GUEST_PARAMETER_HAPPINESS: - peep->happiness = value; - peep->happiness_target = value; - // Clear the 'red-faced with anger' status if we're making the guest happy - if (value > 0) - { - peep->peep_flags &= ~PEEP_FLAGS_ANGRY; - peep->angriness = 0; - } - break; - case GUEST_PARAMETER_ENERGY: - peep->energy = value; - peep->energy_target = value; - break; - case GUEST_PARAMETER_HUNGER: - peep->hunger = value; - break; - case GUEST_PARAMETER_THIRST: - peep->thirst = value; - break; - case GUEST_PARAMETER_NAUSEA: - peep->nausea = value; - peep->nausea_target = value; - break; - case GUEST_PARAMETER_NAUSEA_TOLERANCE: - peep->nausea_tolerance = value; - break; - case GUEST_PARAMETER_BATHROOM: - peep->toilet = value; - break; - case GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY: - peep->intensity = (15 << 4) | value; - break; - } - peep->UpdateSpriteType(); - } -} - -static void cheat_give_all_guests(int32_t object) -{ - int32_t spriteIndex; - Peep* p; - FOR_ALL_GUESTS (spriteIndex, p) - { - auto peep = p->AsGuest(); - assert(peep != nullptr); - switch (object) - { - case OBJECT_MONEY: - peep->cash_in_pocket = MONEY(1000, 00); - break; - case OBJECT_PARK_MAP: - peep->item_standard_flags |= PEEP_ITEM_MAP; - break; - case OBJECT_BALLOON: - peep->item_standard_flags |= PEEP_ITEM_BALLOON; - peep->balloon_colour = scenario_rand_max(COLOUR_COUNT - 1); - peep->UpdateSpriteType(); - break; - case OBJECT_UMBRELLA: - peep->item_standard_flags |= PEEP_ITEM_UMBRELLA; - peep->umbrella_colour = scenario_rand_max(COLOUR_COUNT - 1); - peep->UpdateSpriteType(); - break; - } - } - window_invalidate_by_class(WC_PEEP); -} - -static void cheat_remove_all_guests() -{ - Peep* peep; - rct_vehicle* vehicle; - uint16_t spriteIndex, nextSpriteIndex; - ride_id_t rideIndex; - Ride* ride; - - FOR_ALL_RIDES (rideIndex, ride) - { - ride->num_riders = 0; - - for (size_t stationIndex = 0; stationIndex < MAX_STATIONS; stationIndex++) - { - ride->stations[stationIndex].QueueLength = 0; - ride->stations[stationIndex].LastPeepInQueue = SPRITE_INDEX_NULL; - } - - for (auto trainIndex : ride->vehicles) - { - spriteIndex = trainIndex; - while (spriteIndex != SPRITE_INDEX_NULL) - { - vehicle = GET_VEHICLE(spriteIndex); - for (size_t i = 0, offset = 0; i < vehicle->num_peeps; i++) - { - while (vehicle->peep[i + offset] == SPRITE_INDEX_NULL) - { - offset++; - } - peep = GET_PEEP(vehicle->peep[i + offset]); - vehicle->mass -= peep->mass; - } - - for (auto& peepInTrainIndex : vehicle->peep) - { - peepInTrainIndex = SPRITE_INDEX_NULL; - } - - vehicle->num_peeps = 0; - vehicle->next_free_seat = 0; - - spriteIndex = vehicle->next_vehicle_on_train; - } - } - } - - for (spriteIndex = gSpriteListHead[SPRITE_LIST_PEEP]; spriteIndex != SPRITE_INDEX_NULL; spriteIndex = nextSpriteIndex) - { - peep = &(get_sprite(spriteIndex)->peep); - nextSpriteIndex = peep->next; - if (peep->type == PEEP_TYPE_GUEST) - { - peep->Remove(); - } - } - - window_invalidate_by_class(WC_RIDE); - gfx_invalidate_screen(); -} - -static void cheat_explode_guests() -{ - int32_t sprite_index; - Peep* peep; - - FOR_ALL_GUESTS (sprite_index, peep) - { - if (scenario_rand_max(6) == 0) - { - peep->peep_flags |= PEEP_FLAGS_EXPLODE; - } - } -} - -static void cheat_set_staff_speed(uint8_t value) -{ - uint16_t spriteIndex; - Peep* peep; - - FOR_ALL_STAFF (spriteIndex, peep) - { - peep->energy = value; - peep->energy_target = value; - } -} - -static void cheat_own_all_land() -{ - const int32_t min = 32; - const int32_t max = gMapSizeUnits - 32; - - for (CoordsXY coords = { min, min }; coords.y <= max; coords.y += 32) - { - for (coords.x = min; coords.x <= max; coords.x += 32) - { - TileElement* surfaceElement = map_get_surface_element_at(coords); - if (surfaceElement == nullptr) - continue; - - // Ignore already owned tiles. - if (surfaceElement->AsSurface()->GetOwnership() & OWNERSHIP_OWNED) - continue; - - int32_t base_z = surfaceElement->base_height; - int32_t destOwnership = check_max_allowable_land_rights_for_tile(coords.x >> 5, coords.y >> 5, base_z); - - // only own tiles that were not set to 0 - if (destOwnership != OWNERSHIP_UNOWNED) - { - surfaceElement->AsSurface()->SetOwnership(destOwnership); - update_park_fences_around_tile(coords); - uint16_t baseHeight = surfaceElement->base_height * 8; - map_invalidate_tile(coords.x, coords.y, baseHeight, baseHeight + 16); - } - } - } - - // Completely unown peep spawn points - for (const auto& spawn : gPeepSpawns) - { - int32_t x = spawn.x; - int32_t y = spawn.y; - if (x != PEEP_SPAWN_UNDEFINED) - { - TileElement* surfaceElement = map_get_surface_element_at({ x, y }); - surfaceElement->AsSurface()->SetOwnership(OWNERSHIP_UNOWNED); - update_park_fences_around_tile({ x, y }); - uint16_t baseHeight = surfaceElement->base_height * 8; - map_invalidate_tile(x, y, baseHeight, baseHeight + 16); - } - } - - map_count_remaining_land_rights(); -} - -#pragma endregion - -void game_command_cheat( - [[maybe_unused]] int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi, - [[maybe_unused]] int32_t* ebp) -{ - int32_t cheat = *ecx; - if (*ebx & GAME_COMMAND_FLAG_APPLY) - { - switch (cheat) - { - case CHEAT_SANDBOXMODE: - gCheatsSandboxMode = *edx != 0; - window_invalidate_by_class(WC_MAP); - window_invalidate_by_class(WC_FOOTPATH); - break; - case CHEAT_DISABLECLEARANCECHECKS: - gCheatsDisableClearanceChecks = *edx != 0; - break; - case CHEAT_DISABLESUPPORTLIMITS: - gCheatsDisableSupportLimits = *edx != 0; - break; - case CHEAT_SHOWALLOPERATINGMODES: - gCheatsShowAllOperatingModes = *edx != 0; - break; - case CHEAT_SHOWVEHICLESFROMOTHERTRACKTYPES: - gCheatsShowVehiclesFromOtherTrackTypes = *edx != 0; - break; - case CHEAT_FASTLIFTHILL: - gCheatsFastLiftHill = *edx != 0; - break; - case CHEAT_DISABLEBRAKESFAILURE: - gCheatsDisableBrakesFailure = *edx != 0; - break; - case CHEAT_DISABLEALLBREAKDOWNS: - gCheatsDisableAllBreakdowns = *edx != 0; - break; - case CHEAT_DISABLETRAINLENGTHLIMIT: - gCheatsDisableTrainLengthLimit = *edx != 0; - break; - case CHEAT_ENABLECHAINLIFTONALLTRACK: - gCheatsEnableChainLiftOnAllTrack = *edx != 0; - break; - case CHEAT_BUILDINPAUSEMODE: - gCheatsBuildInPauseMode = *edx != 0; - break; - case CHEAT_IGNORERIDEINTENSITY: - gCheatsIgnoreRideIntensity = *edx != 0; - break; - case CHEAT_DISABLEVANDALISM: - gCheatsDisableVandalism = *edx != 0; - break; - case CHEAT_DISABLELITTERING: - gCheatsDisableLittering = *edx != 0; - break; - case CHEAT_NOMONEY: - cheat_no_money(*edx != 0); - break; - case CHEAT_ADDMONEY: - cheat_add_money(*edx); - break; - case CHEAT_SETMONEY: - cheat_set_money(*edx); - break; - case CHEAT_CLEARLOAN: - cheat_clear_loan(); - break; - case CHEAT_SETGUESTPARAMETER: - cheat_set_guest_parameter(*edx, *edi); - break; - case CHEAT_GENERATEGUESTS: - cheat_generate_guests(*edx); - break; - case CHEAT_REMOVEALLGUESTS: - cheat_remove_all_guests(); - break; - case CHEAT_EXPLODEGUESTS: - cheat_explode_guests(); - break; - case CHEAT_GIVEALLGUESTS: - cheat_give_all_guests(*edx); - break; - case CHEAT_SETGRASSLENGTH: - cheat_set_grass_length(*edx); - break; - case CHEAT_WATERPLANTS: - cheat_water_plants(); - break; - case CHEAT_FIXVANDALISM: - cheat_fix_vandalism(); - break; - case CHEAT_REMOVELITTER: - cheat_remove_litter(); - break; - case CHEAT_DISABLEPLANTAGING: - gCheatsDisablePlantAging = *edx != 0; - break; - case CHEAT_SETSTAFFSPEED: - cheat_set_staff_speed(*edx); - break; - case CHEAT_RENEWRIDES: - cheat_renew_rides(); - break; - case CHEAT_MAKEDESTRUCTIBLE: - cheat_make_destructible(); - break; - case CHEAT_FIXRIDES: - cheat_fix_rides(); - break; - case CHEAT_RESETCRASHSTATUS: - cheat_reset_crash_status(); - break; - case CHEAT_10MINUTEINSPECTIONS: - cheat_10_minute_inspections(); - break; - case CHEAT_WINSCENARIO: - scenario_success(); - break; - case CHEAT_FORCEWEATHER: - climate_force_weather(*edx); - break; - case CHEAT_FREEZEWEATHER: - gCheatsFreezeWeather = *edx != 0; - break; - case CHEAT_NEVERENDINGMARKETING: - gCheatsNeverendingMarketing = *edx != 0; - break; - case CHEAT_OPENCLOSEPARK: - park_set_open(!park_is_open()); - break; - case CHEAT_HAVEFUN: - gScenarioObjectiveType = OBJECTIVE_HAVE_FUN; - break; - case CHEAT_SETFORCEDPARKRATING: - if (*edx > -1) - { - park_rating_spinner_value = *edx; - } - set_forced_park_rating(*edx); - break; - case CHEAT_ALLOW_ARBITRARY_RIDE_TYPE_CHANGES: - gCheatsAllowArbitraryRideTypeChanges = *edx != 0; - window_invalidate_by_class(WC_RIDE); - break; - case CHEAT_OWNALLLAND: - cheat_own_all_land(); - break; - case CHEAT_DISABLERIDEVALUEAGING: - gCheatsDisableRideValueAging = *edx != 0; - break; - case CHEAT_IGNORERESEARCHSTATUS: - gCheatsIgnoreResearchStatus = *edx != 0; - break; - case CHEAT_ENABLEALLDRAWABLETRACKPIECES: - gCheatsEnableAllDrawableTrackPieces = *edx != 0; - break; - } - if (network_get_mode() == NETWORK_MODE_NONE) - { - config_save_default(); - } - window_invalidate_by_class(WC_CHEATS); - } - *ebx = 0; -} - -void cheats_reset() +void CheatsReset() { gCheatsSandboxMode = false; gCheatsDisableClearanceChecks = false; @@ -682,308 +74,109 @@ void cheats_reset() gCheatsIgnoreResearchStatus = false; } -// Generates the string to print for the server log when a cheat is used. -const char* cheats_get_cheat_string(int cheat, int edx, int edi) +void CheatsSet(CheatType cheatType, int32_t param1 /* = 0*/, int32_t param2 /* = 0*/) { - switch (cheat) - { - case CHEAT_SANDBOXMODE: - if (gCheatsSandboxMode) - { - return language_get_string(STR_CHEAT_SANDBOX_MODE_DISABLE); - } - else - { - return language_get_string(STR_CHEAT_SANDBOX_MODE); - } - case CHEAT_DISABLECLEARANCECHECKS: - return language_get_string(STR_DISABLE_CLEARANCE_CHECKS); - case CHEAT_DISABLESUPPORTLIMITS: - return language_get_string(STR_DISABLE_SUPPORT_LIMITS); - case CHEAT_SHOWALLOPERATINGMODES: - return language_get_string(STR_CHEAT_SHOW_ALL_OPERATING_MODES); - case CHEAT_SHOWVEHICLESFROMOTHERTRACKTYPES: - return language_get_string(STR_CHEAT_SHOW_VEHICLES_FROM_OTHER_TRACK_TYPES); - case CHEAT_FASTLIFTHILL: - return language_get_string(STR_CHEAT_UNLOCK_OPERATING_LIMITS); - case CHEAT_DISABLEBRAKESFAILURE: - return language_get_string(STR_CHEAT_DISABLE_BRAKES_FAILURE); - case CHEAT_DISABLEALLBREAKDOWNS: - return language_get_string(STR_CHEAT_DISABLE_BREAKDOWNS); - case CHEAT_DISABLETRAINLENGTHLIMIT: - return language_get_string(STR_CHEAT_DISABLE_TRAIN_LENGTH_LIMIT); - case CHEAT_ENABLECHAINLIFTONALLTRACK: - return language_get_string(STR_CHEAT_ENABLE_CHAIN_LIFT_ON_ALL_TRACK); - case CHEAT_BUILDINPAUSEMODE: - return language_get_string(STR_CHEAT_BUILD_IN_PAUSE_MODE); - case CHEAT_IGNORERIDEINTENSITY: - return language_get_string(STR_CHEAT_IGNORE_INTENSITY); - case CHEAT_DISABLEVANDALISM: - return language_get_string(STR_CHEAT_DISABLE_VANDALISM); - case CHEAT_DISABLELITTERING: - return language_get_string(STR_CHEAT_DISABLE_LITTERING); - case CHEAT_NOMONEY: - return language_get_string(STR_MAKE_PARK_NO_MONEY); - case CHEAT_ADDMONEY: - return language_get_string(STR_LOG_CHEAT_ADD_MONEY); - case CHEAT_CLEARLOAN: - return language_get_string(STR_CHEAT_CLEAR_LOAN); - case CHEAT_SETGUESTPARAMETER: - { - static char cheat_string[128]; - safe_strcpy(cheat_string, language_get_string(STR_CHEAT_SET_GUESTS_PARAMETERS), 128); - safe_strcat(cheat_string, " ", 128); - switch (edx) - { - case GUEST_PARAMETER_HAPPINESS: - safe_strcat(cheat_string, language_get_string(STR_CHEAT_GUEST_HAPPINESS), 128); - safe_strcat(cheat_string, " ", 128); - if (edi == 255) - { - safe_strcat(cheat_string, language_get_string(STR_MAX), 128); - } - else if (edi == 0) - { - safe_strcat(cheat_string, language_get_string(STR_MIN), 128); - } - break; - case GUEST_PARAMETER_ENERGY: - safe_strcat(cheat_string, language_get_string(STR_CHEAT_GUEST_ENERGY), 128); - safe_strcat(cheat_string, " ", 128); - if (edi == 127) - { - safe_strcat(cheat_string, language_get_string(STR_MAX), 128); - } - else if (edi == 0) - { - safe_strcat(cheat_string, language_get_string(STR_MIN), 128); - } - break; - case GUEST_PARAMETER_HUNGER: - safe_strcat(cheat_string, language_get_string(STR_CHEAT_GUEST_HUNGER), 128); - safe_strcat(cheat_string, " ", 128); - if (edi == 255) - { - safe_strcat(cheat_string, language_get_string(STR_MIN), 128); - } - else if (edi == 0) - { - safe_strcat(cheat_string, language_get_string(STR_MAX), 128); - } - break; - case GUEST_PARAMETER_THIRST: - safe_strcat(cheat_string, language_get_string(STR_CHEAT_GUEST_THIRST), 128); - safe_strcat(cheat_string, " ", 128); - if (edi == 255) - { - safe_strcat(cheat_string, language_get_string(STR_MIN), 128); - } - else if (edi == 0) - { - safe_strcat(cheat_string, language_get_string(STR_MAX), 128); - } - break; - case GUEST_PARAMETER_NAUSEA: - safe_strcat(cheat_string, language_get_string(STR_CHEAT_GUEST_NAUSEA), 128); - safe_strcat(cheat_string, " ", 128); - if (edi == 255) - { - safe_strcat(cheat_string, language_get_string(STR_MAX), 128); - } - else if (edi == 0) - { - safe_strcat(cheat_string, language_get_string(STR_MIN), 128); - } - break; - case GUEST_PARAMETER_NAUSEA_TOLERANCE: - safe_strcat(cheat_string, language_get_string(STR_CHEAT_GUEST_NAUSEA_TOLERANCE), 128); - safe_strcat(cheat_string, " ", 128); - if (edi == PEEP_NAUSEA_TOLERANCE_HIGH) - { - safe_strcat(cheat_string, language_get_string(STR_MAX), 128); - } - else if (edi == PEEP_NAUSEA_TOLERANCE_NONE) - { - safe_strcat(cheat_string, language_get_string(STR_MIN), 128); - } - break; - case GUEST_PARAMETER_BATHROOM: - safe_strcat(cheat_string, language_get_string(STR_CHEAT_GUEST_BATHROOM), 128); - safe_strcat(cheat_string, " ", 128); - if (edi == 255) - { - safe_strcat(cheat_string, language_get_string(STR_MAX), 128); - } - else if (edi == 0) - { - safe_strcat(cheat_string, language_get_string(STR_MIN), 128); - } - break; - case GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY: - safe_strcat(cheat_string, language_get_string(STR_CHEAT_GUEST_PREFERRED_INTENSITY), 128); - safe_strcat(cheat_string, " ", 128); - if (edi == 1) - { - safe_strcat(cheat_string, language_get_string(STR_CHEAT_MORE_THAN_1), 128); - } - else if (edi == 0) - { - safe_strcat(cheat_string, language_get_string(STR_CHEAT_LESS_THAN_15), 128); - } - break; - } - return cheat_string; - } - case CHEAT_GENERATEGUESTS: - return language_get_string(STR_CHEAT_LARGE_TRAM_GUESTS); - case CHEAT_REMOVEALLGUESTS: - return language_get_string(STR_CHEAT_REMOVE_ALL_GUESTS); - case CHEAT_EXPLODEGUESTS: - return language_get_string(STR_CHEAT_EXPLODE); - case CHEAT_GIVEALLGUESTS: - { - static char cheat_string[64]; - safe_strcpy(cheat_string, language_get_string(STR_CHEAT_GIVE_ALL_GUESTS), 64); - safe_strcat(cheat_string, " ", 64); - switch (edx) - { - case OBJECT_MONEY: - { - char money[16]; - set_format_arg(0, money32, CHEATS_GIVE_GUESTS_MONEY); - format_string(money, 16, STR_CHEAT_CURRENCY_FORMAT, gCommonFormatArgs); - safe_strcat(cheat_string, money, 64); - break; - } - case OBJECT_PARK_MAP: - safe_strcat(cheat_string, language_get_string(STR_SHOP_ITEM_PLURAL_PARK_MAP), 64); - break; - case OBJECT_BALLOON: - safe_strcat(cheat_string, language_get_string(STR_SHOP_ITEM_PLURAL_BALLOON), 64); - break; - case OBJECT_UMBRELLA: - safe_strcat(cheat_string, language_get_string(STR_SHOP_ITEM_PLURAL_UMBRELLA), 64); - break; - } - return cheat_string; - } - case CHEAT_SETGRASSLENGTH: - if (edx == 0) - { - return language_get_string(STR_CHEAT_MOWED_GRASS); - } - return language_get_string(STR_CHEAT_CLEAR_GRASS); - case CHEAT_WATERPLANTS: - return language_get_string(STR_CHEAT_WATER_PLANTS); - case CHEAT_FIXVANDALISM: - return language_get_string(STR_CHEAT_FIX_VANDALISM); - case CHEAT_REMOVELITTER: - return language_get_string(STR_CHEAT_REMOVE_LITTER); - case CHEAT_DISABLEPLANTAGING: - return language_get_string(STR_CHEAT_DISABLE_PLANT_AGING); - case CHEAT_SETSTAFFSPEED: - { - static char cheat_string[64]; - safe_strcpy(cheat_string, language_get_string(STR_CHEAT_STAFF_SPEED), 64); - safe_strcat(cheat_string, " ", 64); - if (edx == CHEATS_STAFF_FAST_SPEED) - { - safe_strcat(cheat_string, language_get_string(STR_FAST), 64); - } - else if (edx == CHEATS_STAFF_NORMAL_SPEED) - { - safe_strcat(cheat_string, language_get_string(STR_NORMAL), 64); - } - return cheat_string; - } - case CHEAT_RENEWRIDES: - return language_get_string(STR_CHEAT_RENEW_RIDES); - case CHEAT_MAKEDESTRUCTIBLE: - return language_get_string(STR_CHEAT_MAKE_DESTRUCTABLE); - case CHEAT_FIXRIDES: - return language_get_string(STR_CHEAT_FIX_ALL_RIDES); - case CHEAT_RESETCRASHSTATUS: - return language_get_string(STR_CHEAT_RESET_CRASH_STATUS); - case CHEAT_10MINUTEINSPECTIONS: - return language_get_string(STR_CHEAT_10_MINUTE_INSPECTIONS); - case CHEAT_WINSCENARIO: - return language_get_string(STR_CHEAT_WIN_SCENARIO); - case CHEAT_FORCEWEATHER: - { - static char cheat_string[64]; - safe_strcpy(cheat_string, language_get_string(STR_FORCE_WEATHER), 64); - safe_strcat(cheat_string, " ", 64); - switch (edx) - { - case 0: - safe_strcat(cheat_string, language_get_string(STR_SUNNY), 64); - break; - case 1: - safe_strcat(cheat_string, language_get_string(STR_PARTIALLY_CLOUDY), 64); - break; - case 2: - safe_strcat(cheat_string, language_get_string(STR_CLOUDY), 64); - break; - case 3: - safe_strcat(cheat_string, language_get_string(STR_RAIN), 64); - break; - case 4: - safe_strcat(cheat_string, language_get_string(STR_HEAVY_RAIN), 64); - break; - case 5: - safe_strcat(cheat_string, language_get_string(STR_THUNDERSTORM), 64); - break; - } - return cheat_string; - } - case CHEAT_FREEZEWEATHER: - if (gCheatsFreezeWeather) - { - return language_get_string(STR_CHEAT_UNFREEZE_WEATHER); - } - else - { - return language_get_string(STR_CHEAT_FREEZE_WEATHER); - } - case CHEAT_NEVERENDINGMARKETING: - return language_get_string(STR_CHEAT_NEVERENDING_MARKETING); - case CHEAT_OPENCLOSEPARK: - if (park_is_open()) - { - return language_get_string(STR_CHEAT_CLOSE_PARK); - } - else - { - return language_get_string(STR_CHEAT_OPEN_PARK); - } - case CHEAT_HAVEFUN: - return language_get_string(STR_CHEAT_HAVE_FUN); - case CHEAT_SETFORCEDPARKRATING: - { - static char cheat_string[64]; - safe_strcpy(cheat_string, language_get_string(STR_FORCE_PARK_RATING), 64); - safe_strcat(cheat_string, " ", 64); - - char buffer[8]; - snprintf(buffer, sizeof(buffer), "%d", park_rating_spinner_value); - char* park_rating = buffer; - safe_strcat(cheat_string, park_rating, 64); - - return cheat_string; - } - case CHEAT_ALLOW_ARBITRARY_RIDE_TYPE_CHANGES: - return language_get_string(STR_CHEAT_ALLOW_ARBITRARY_RIDE_TYPE_CHANGES); - case CHEAT_SETMONEY: - return language_get_string(STR_SET_MONEY); - case CHEAT_OWNALLLAND: - return language_get_string(STR_CHEAT_OWN_ALL_LAND); - case CHEAT_DISABLERIDEVALUEAGING: - return language_get_string(STR_CHEAT_DISABLE_RIDE_VALUE_AGING); - case CHEAT_IGNORERESEARCHSTATUS: - return language_get_string(STR_CHEAT_IGNORE_RESEARCH_STATUS); - case CHEAT_ENABLEALLDRAWABLETRACKPIECES: - return language_get_string(STR_CHEAT_ENABLE_ALL_DRAWABLE_TRACK_PIECES); - } - - return ""; + auto setCheatAction = SetCheatAction(cheatType, param1, param2); + GameActions::Execute(&setCheatAction); +} + +const char* CheatsGetName(CheatType cheatType) +{ + switch (cheatType) + { + case CheatType::SandboxMode: + return language_get_string(STR_CHEAT_SANDBOX_MODE); + case CheatType::DisableClearanceChecks: + return language_get_string(STR_DISABLE_CLEARANCE_CHECKS); + case CheatType::DisableSupportLimits: + return language_get_string(STR_DISABLE_SUPPORT_LIMITS); + case CheatType::ShowAllOperatingModes: + return language_get_string(STR_CHEAT_SHOW_ALL_OPERATING_MODES); + case CheatType::ShowVehiclesFromOtherTrackTypes: + return language_get_string(STR_CHEAT_SHOW_VEHICLES_FROM_OTHER_TRACK_TYPES); + case CheatType::FastLiftHill: + return language_get_string(STR_CHEAT_UNLOCK_OPERATING_LIMITS); + case CheatType::DisableBrakesFailure: + return language_get_string(STR_CHEAT_DISABLE_BRAKES_FAILURE); + case CheatType::DisableAllBreakdowns: + return language_get_string(STR_CHEAT_DISABLE_BREAKDOWNS); + case CheatType::DisableTrainLengthLimit: + return language_get_string(STR_CHEAT_DISABLE_TRAIN_LENGTH_LIMIT); + case CheatType::EnableChainLiftOnAllTrack: + return language_get_string(STR_CHEAT_ENABLE_CHAIN_LIFT_ON_ALL_TRACK); + case CheatType::BuildInPauseMode: + return language_get_string(STR_CHEAT_BUILD_IN_PAUSE_MODE); + case CheatType::IgnoreRideIntensity: + return language_get_string(STR_CHEAT_IGNORE_INTENSITY); + case CheatType::DisableVandalism: + return language_get_string(STR_CHEAT_DISABLE_VANDALISM); + case CheatType::DisableLittering: + return language_get_string(STR_CHEAT_DISABLE_LITTERING); + case CheatType::NoMoney: + return language_get_string(STR_MAKE_PARK_NO_MONEY); + case CheatType::AddMoney: + return language_get_string(STR_LOG_CHEAT_ADD_MONEY); + case CheatType::ClearLoan: + return language_get_string(STR_CHEAT_CLEAR_LOAN); + case CheatType::SetGuestParameter: + return language_get_string(STR_CHEAT_SET_GUESTS_PARAMETERS); + case CheatType::GenerateGuests: + return language_get_string(STR_CHEAT_LARGE_TRAM_GUESTS); + case CheatType::RemoveAllGuests: + return language_get_string(STR_CHEAT_REMOVE_ALL_GUESTS); + case CheatType::ExplodeGuests: + return language_get_string(STR_CHEAT_EXPLODE); + case CheatType::GiveAllGuests: + return language_get_string(STR_CHEAT_GIVE_ALL_GUESTS); + case CheatType::SetGrassLength: + return language_get_string(STR_CHEAT_CLEAR_GRASS); + case CheatType::WaterPlants: + return language_get_string(STR_CHEAT_WATER_PLANTS); + case CheatType::FixVandalism: + return language_get_string(STR_CHEAT_FIX_VANDALISM); + case CheatType::RemoveLitter: + return language_get_string(STR_CHEAT_REMOVE_LITTER); + case CheatType::DisablePlantAging: + return language_get_string(STR_CHEAT_DISABLE_PLANT_AGING); + case CheatType::SetStaffSpeed: + return language_get_string(STR_CHEAT_STAFF_SPEED); + case CheatType::RenewRides: + return language_get_string(STR_CHEAT_RENEW_RIDES); + case CheatType::MakeDestructible: + return language_get_string(STR_CHEAT_MAKE_DESTRUCTABLE); + case CheatType::FixRides: + return language_get_string(STR_CHEAT_FIX_ALL_RIDES); + case CheatType::ResetCrashStatus: + return language_get_string(STR_CHEAT_RESET_CRASH_STATUS); + case CheatType::TenMinuteInspections: + return language_get_string(STR_CHEAT_10_MINUTE_INSPECTIONS); + case CheatType::WinScenario: + return language_get_string(STR_CHEAT_WIN_SCENARIO); + case CheatType::ForceWeather: + return language_get_string(STR_FORCE_WEATHER); + case CheatType::FreezeWeather: + return language_get_string(STR_CHEAT_FREEZE_WEATHER); + case CheatType::NeverEndingMarketing: + return language_get_string(STR_CHEAT_NEVERENDING_MARKETING); + case CheatType::OpenClosePark: + return language_get_string(STR_CHEAT_OPEN_PARK); + case CheatType::HaveFun: + return language_get_string(STR_CHEAT_HAVE_FUN); + case CheatType::SetForcedParkRating: + return language_get_string(STR_FORCE_PARK_RATING); + case CheatType::AllowArbitraryRideTypeChanges: + return language_get_string(STR_CHEAT_ALLOW_ARBITRARY_RIDE_TYPE_CHANGES); + case CheatType::SetMoney: + return language_get_string(STR_SET_MONEY); + case CheatType::OwnAllLand: + return language_get_string(STR_CHEAT_OWN_ALL_LAND); + case CheatType::DisableRideValueAging: + return language_get_string(STR_CHEAT_DISABLE_RIDE_VALUE_AGING); + case CheatType::IgnoreResearchStatus: + return language_get_string(STR_CHEAT_IGNORE_RESEARCH_STATUS); + case CheatType::EnableAllDrawableTrackPieces: + return language_get_string(STR_CHEAT_ENABLE_ALL_DRAWABLE_TRACK_PIECES); + default: + return "Unknown Cheat"; + } } diff --git a/src/openrct2/Cheats.h b/src/openrct2/Cheats.h index b690ba18c1..a582b98c1e 100644 --- a/src/openrct2/Cheats.h +++ b/src/openrct2/Cheats.h @@ -34,55 +34,56 @@ extern bool gCheatsAllowArbitraryRideTypeChanges; extern bool gCheatsIgnoreResearchStatus; extern bool gCheatsEnableAllDrawableTrackPieces; -enum +enum class CheatType : int32_t { - CHEAT_SANDBOXMODE, - CHEAT_DISABLECLEARANCECHECKS, - CHEAT_DISABLESUPPORTLIMITS, - CHEAT_SHOWALLOPERATINGMODES, - CHEAT_SHOWVEHICLESFROMOTHERTRACKTYPES, - CHEAT_DISABLETRAINLENGTHLIMIT, - CHEAT_ENABLECHAINLIFTONALLTRACK, - CHEAT_FASTLIFTHILL, - CHEAT_DISABLEBRAKESFAILURE, - CHEAT_DISABLEALLBREAKDOWNS, - CHEAT_UNLOCKALLPRICES, - CHEAT_BUILDINPAUSEMODE, - CHEAT_IGNORERIDEINTENSITY, - CHEAT_DISABLEVANDALISM, - CHEAT_DISABLELITTERING, - CHEAT_NOMONEY, - CHEAT_ADDMONEY, - CHEAT_SETMONEY, - CHEAT_CLEARLOAN, - CHEAT_SETGUESTPARAMETER, - CHEAT_GENERATEGUESTS, - CHEAT_REMOVEALLGUESTS, - CHEAT_EXPLODEGUESTS, - CHEAT_GIVEALLGUESTS, - CHEAT_SETGRASSLENGTH, - CHEAT_WATERPLANTS, - CHEAT_DISABLEPLANTAGING, - CHEAT_FIXVANDALISM, - CHEAT_REMOVELITTER, - CHEAT_SETSTAFFSPEED, - CHEAT_RENEWRIDES, - CHEAT_MAKEDESTRUCTIBLE, - CHEAT_FIXRIDES, - CHEAT_RESETCRASHSTATUS, - CHEAT_10MINUTEINSPECTIONS, - CHEAT_WINSCENARIO, - CHEAT_FORCEWEATHER, - CHEAT_FREEZEWEATHER, - CHEAT_OPENCLOSEPARK, - CHEAT_HAVEFUN, - CHEAT_SETFORCEDPARKRATING, - CHEAT_NEVERENDINGMARKETING, - CHEAT_ALLOW_ARBITRARY_RIDE_TYPE_CHANGES, - CHEAT_OWNALLLAND, - CHEAT_DISABLERIDEVALUEAGING, - CHEAT_IGNORERESEARCHSTATUS, - CHEAT_ENABLEALLDRAWABLETRACKPIECES, + SandboxMode, + DisableClearanceChecks, + DisableSupportLimits, + ShowAllOperatingModes, + ShowVehiclesFromOtherTrackTypes, + DisableTrainLengthLimit, + EnableChainLiftOnAllTrack, + FastLiftHill, + DisableBrakesFailure, + DisableAllBreakdowns, + UnlockAllPrices, + BuildInPauseMode, + IgnoreRideIntensity, + DisableVandalism, + DisableLittering, + NoMoney, + AddMoney, + SetMoney, + ClearLoan, + SetGuestParameter, + GenerateGuests, + RemoveAllGuests, + ExplodeGuests, + GiveAllGuests, + SetGrassLength, + WaterPlants, + DisablePlantAging, + FixVandalism, + RemoveLitter, + SetStaffSpeed, + RenewRides, + MakeDestructible, + FixRides, + ResetCrashStatus, + TenMinuteInspections, + WinScenario, + ForceWeather, + FreezeWeather, + OpenClosePark, + HaveFun, + SetForcedParkRating, + NeverEndingMarketing, + AllowArbitraryRideTypeChanges, + OwnAllLand, + DisableRideValueAging, + IgnoreResearchStatus, + EnableAllDrawableTrackPieces, + Count, }; enum @@ -111,15 +112,8 @@ enum #define CHEATS_STAFF_NORMAL_SPEED 0x60 #define CHEATS_STAFF_FREEZE_SPEED 0 -extern int32_t park_rating_spinner_value; -extern int32_t year_spinner_value; -extern int32_t month_spinner_value; -extern int32_t day_spinner_value; - -void game_command_cheat(int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); - -void cheats_reset(); - -const char* cheats_get_cheat_string(int cheat, int edx, int edi); +void CheatsReset(); +const char* CheatsGetName(CheatType cheatType); +void CheatsSet(CheatType cheatType, int32_t param1 = 0, int32_t param2 = 0); #endif diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index d211f75eae..0901871363 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -577,18 +577,7 @@ void game_log_multiplayer_command(int command, const int* eax, const int* ebx, c } char log_msg[256]; - if (command == GAME_COMMAND_CHEAT) - { - // Get cheat name - const char* cheat = cheats_get_cheat_string(*ecx, *edx, *edi); - char* args[2] = { - (char*)player_name, - (char*)cheat, - }; - format_string(log_msg, 256, STR_LOG_CHEAT_USED, args); - network_append_server_log(log_msg); - } - else if (command == GAME_COMMAND_DEMOLISH_RIDE && (*ebp == 1 || *ebp == 0)) + if (command == GAME_COMMAND_DEMOLISH_RIDE && (*ebp == 1 || *ebp == 0)) { // ebp is 1 if command comes from ride window prompt, so we don't log "demolishing" ride previews // Get ride name Ride* ride = get_ride(*edx); @@ -1228,7 +1217,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = { nullptr, game_command_modify_groups, game_command_kick_player, - game_command_cheat, + nullptr, game_command_pickup_guest, game_command_pickup_staff, game_command_balloon_press, diff --git a/src/openrct2/ReplayManager.cpp b/src/openrct2/ReplayManager.cpp index 456948824f..baafa4c97c 100644 --- a/src/openrct2/ReplayManager.cpp +++ b/src/openrct2/ReplayManager.cpp @@ -18,6 +18,7 @@ #include "actions/GameAction.h" #include "actions/RideEntranceExitPlaceAction.hpp" #include "actions/RideSetSetting.hpp" +#include "actions/SetCheatAction.hpp" #include "actions/TrackPlaceAction.hpp" #include "config/Config.h" #include "core/DataSerialiser.h" @@ -526,6 +527,16 @@ namespace OpenRCT2 result.action->SetFlags(command.ebx & 0xFF); break; } + case GAME_COMMAND_CHEAT: + { + int32_t param1 = command.edx; + int32_t param2 = command.edi; + CheatType cheatType = static_cast(command.ecx); + + result.action = std::make_unique(cheatType, param1, param2); + result.action->SetFlags(command.ebx & 0xFF); + break; + } default: throw std::runtime_error("Deprecated game command requires replay translation."); } diff --git a/src/openrct2/actions/GameActionRegistration.cpp b/src/openrct2/actions/GameActionRegistration.cpp index e43fd171c7..67fe2817c6 100644 --- a/src/openrct2/actions/GameActionRegistration.cpp +++ b/src/openrct2/actions/GameActionRegistration.cpp @@ -53,6 +53,7 @@ #include "RideSetSetting.hpp" #include "RideSetStatus.hpp" #include "RideSetVehiclesAction.hpp" +#include "SetCheatAction.hpp" #include "SetParkEntranceFeeAction.hpp" #include "SignSetNameAction.hpp" #include "SignSetStyleAction.hpp" @@ -149,5 +150,6 @@ namespace GameActions Register(); Register(); Register(); + Register(); } } // namespace GameActions diff --git a/src/openrct2/actions/SetCheatAction.hpp b/src/openrct2/actions/SetCheatAction.hpp new file mode 100644 index 0000000000..06ed56b4f3 --- /dev/null +++ b/src/openrct2/actions/SetCheatAction.hpp @@ -0,0 +1,792 @@ +/***************************************************************************** + * Copyright (c) 2014-2019 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 "../GameState.h" +#include "../config/Config.h" +#include "../core/String.hpp" +#include "../drawing/Drawing.h" +#include "../localisation/Localisation.h" +#include "../localisation/StringIds.h" +#include "../network/network.h" +#include "../ride/Ride.h" +#include "../scenario/Scenario.h" +#include "../ui/UiContext.h" +#include "../util/Util.h" +#include "../windows/Intent.h" +#include "../world/Banner.h" +#include "../world/Climate.h" +#include "../world/Footpath.h" +#include "../world/Map.h" +#include "../world/Park.h" +#include "../world/Scenery.h" +#include "../world/Sprite.h" +#include "../world/Surface.h" +#include "GameAction.h" +#include "ParkSetLoanAction.hpp" +#include "ParkSetParameterAction.hpp" + +DEFINE_GAME_ACTION(SetCheatAction, GAME_COMMAND_CHEAT, GameActionResult) +{ + using ParametersRange = std::pair, std::pair>; + +private: + NetworkCheatType_t _cheatType; + int32_t _param1 = 0; + int32_t _param2 = 0; + +public: + SetCheatAction() = default; + SetCheatAction(CheatType cheatType, int32_t param1 = 0, int32_t param2 = 0) + : _cheatType(static_cast(cheatType)) + , _param1(param1) + , _param2(param2) + { + } + + uint16_t GetActionFlags() const override + { + return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED; + } + + void Serialise(DataSerialiser & stream) override + { + GameAction::Serialise(stream); + stream << DS_TAG(_cheatType) << DS_TAG(_param1) << DS_TAG(_param2); + } + + GameActionResult::Ptr Query() const override + { + if (static_cast(_cheatType) >= static_cast(CheatType::Count)) + { + MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + + ParametersRange validRange = GetParameterRange(static_cast(_cheatType.id)); + + if (_param1 < validRange.first.first || _param1 > validRange.first.second) + { + MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + if (_param2 < validRange.second.first || _param2 > validRange.second.second) + { + MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + + return MakeResult(); + } + + GameActionResult::Ptr Execute() const override + { + switch (static_cast(_cheatType.id)) + { + case CheatType::SandboxMode: + gCheatsSandboxMode = _param1 != 0; + window_invalidate_by_class(WC_MAP); + window_invalidate_by_class(WC_FOOTPATH); + break; + case CheatType::DisableClearanceChecks: + gCheatsDisableClearanceChecks = _param1 != 0; + break; + case CheatType::DisableSupportLimits: + gCheatsDisableSupportLimits = _param1 != 0; + break; + case CheatType::ShowAllOperatingModes: + gCheatsShowAllOperatingModes = _param1 != 0; + break; + case CheatType::ShowVehiclesFromOtherTrackTypes: + gCheatsShowVehiclesFromOtherTrackTypes = _param1 != 0; + break; + case CheatType::FastLiftHill: + gCheatsFastLiftHill = _param1 != 0; + break; + case CheatType::DisableBrakesFailure: + gCheatsDisableBrakesFailure = _param1 != 0; + break; + case CheatType::DisableAllBreakdowns: + gCheatsDisableAllBreakdowns = _param1 != 0; + break; + case CheatType::DisableTrainLengthLimit: + gCheatsDisableTrainLengthLimit = _param1 != 0; + break; + case CheatType::EnableChainLiftOnAllTrack: + gCheatsEnableChainLiftOnAllTrack = _param1 != 0; + break; + case CheatType::BuildInPauseMode: + gCheatsBuildInPauseMode = _param1 != 0; + break; + case CheatType::IgnoreRideIntensity: + gCheatsIgnoreRideIntensity = _param1 != 0; + break; + case CheatType::DisableVandalism: + gCheatsDisableVandalism = _param1 != 0; + break; + case CheatType::DisableLittering: + gCheatsDisableLittering = _param1 != 0; + break; + case CheatType::NoMoney: + SetScenarioNoMoney(_param1 != 0); + break; + case CheatType::AddMoney: + AddMoney(_param1); + break; + case CheatType::SetMoney: + SetMoney(_param1); + break; + case CheatType::ClearLoan: + ClearLoan(); + break; + case CheatType::SetGuestParameter: + SetGuestParameter(_param1, _param2); + break; + case CheatType::GenerateGuests: + GenerateGuests(_param1); + break; + case CheatType::RemoveAllGuests: + RemoveAllGuests(); + break; + case CheatType::ExplodeGuests: + ExplodeGuests(); + break; + case CheatType::GiveAllGuests: + GiveObjectToGuests(_param1); + break; + case CheatType::SetGrassLength: + SetGrassLength(_param1); + break; + case CheatType::WaterPlants: + WaterPlants(); + break; + case CheatType::FixVandalism: + FixVandalism(); + break; + case CheatType::RemoveLitter: + RemoveLitter(); + break; + case CheatType::DisablePlantAging: + gCheatsDisablePlantAging = _param1 != 0; + break; + case CheatType::SetStaffSpeed: + SetStaffSpeed(_param1); + break; + case CheatType::RenewRides: + RenewRides(); + break; + case CheatType::MakeDestructible: + MakeDestructible(); + break; + case CheatType::FixRides: + FixBrokenRides(); + break; + case CheatType::ResetCrashStatus: + ResetRideCrashStatus(); + break; + case CheatType::TenMinuteInspections: + Set10MinuteInspection(); + break; + case CheatType::WinScenario: + scenario_success(); + break; + case CheatType::ForceWeather: + climate_force_weather(_param1); + break; + case CheatType::FreezeWeather: + gCheatsFreezeWeather = _param1 != 0; + break; + case CheatType::NeverEndingMarketing: + gCheatsNeverendingMarketing = _param1 != 0; + break; + case CheatType::OpenClosePark: + ParkSetOpen(!park_is_open()); + break; + case CheatType::HaveFun: + gScenarioObjectiveType = OBJECTIVE_HAVE_FUN; + break; + case CheatType::SetForcedParkRating: + set_forced_park_rating(_param1); + break; + case CheatType::AllowArbitraryRideTypeChanges: + gCheatsAllowArbitraryRideTypeChanges = _param1 != 0; + window_invalidate_by_class(WC_RIDE); + break; + case CheatType::OwnAllLand: + OwnAllLand(); + break; + case CheatType::DisableRideValueAging: + gCheatsDisableRideValueAging = _param1 != 0; + break; + case CheatType::IgnoreResearchStatus: + gCheatsIgnoreResearchStatus = _param1 != 0; + break; + case CheatType::EnableAllDrawableTrackPieces: + gCheatsEnableAllDrawableTrackPieces = _param1 != 0; + break; + default: + { + log_error("Unabled cheat: %d", _cheatType.id); + MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_NONE); + } + break; + } + + if (network_get_mode() == NETWORK_MODE_NONE) + { + config_save_default(); + } + + window_invalidate_by_class(WC_CHEATS); + return MakeResult(); + } + +private: + ParametersRange GetParameterRange(CheatType cheatType) const + { + switch (static_cast(_cheatType.id)) + { + case CheatType::SandboxMode: + [[fallthrough]]; + case CheatType::DisableClearanceChecks: + [[fallthrough]]; + case CheatType::DisableSupportLimits: + [[fallthrough]]; + case CheatType::ShowAllOperatingModes: + [[fallthrough]]; + case CheatType::ShowVehiclesFromOtherTrackTypes: + [[fallthrough]]; + case CheatType::FastLiftHill: + [[fallthrough]]; + case CheatType::DisableBrakesFailure: + [[fallthrough]]; + case CheatType::DisableAllBreakdowns: + [[fallthrough]]; + case CheatType::DisableTrainLengthLimit: + [[fallthrough]]; + case CheatType::EnableChainLiftOnAllTrack: + [[fallthrough]]; + case CheatType::BuildInPauseMode: + [[fallthrough]]; + case CheatType::IgnoreRideIntensity: + [[fallthrough]]; + case CheatType::DisableVandalism: + [[fallthrough]]; + case CheatType::DisableLittering: + [[fallthrough]]; + case CheatType::NoMoney: + [[fallthrough]]; + case CheatType::DisablePlantAging: + [[fallthrough]]; + case CheatType::FreezeWeather: + [[fallthrough]]; + case CheatType::NeverEndingMarketing: + [[fallthrough]]; + case CheatType::AllowArbitraryRideTypeChanges: + [[fallthrough]]; + case CheatType::DisableRideValueAging: + [[fallthrough]]; + case CheatType::IgnoreResearchStatus: + [[fallthrough]]; + case CheatType::EnableAllDrawableTrackPieces: + [[fallthrough]]; + case CheatType::OpenClosePark: + return { { 0, 1 }, { 0, 0 } }; + case CheatType::AddMoney: + [[fallthrough]]; + case CheatType::SetMoney: + return { { std::numeric_limits::min(), std::numeric_limits::max() }, { 0, 0 } }; + case CheatType::SetGuestParameter: + switch (_param1) + { + case GUEST_PARAMETER_HAPPINESS: + return { { GUEST_PARAMETER_HAPPINESS, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY }, + { 0, PEEP_MAX_HAPPINESS } }; + case GUEST_PARAMETER_ENERGY: + return { { GUEST_PARAMETER_HAPPINESS, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY }, + { PEEP_MIN_ENERGY, PEEP_MAX_ENERGY } }; + case GUEST_PARAMETER_HUNGER: + return { { GUEST_PARAMETER_HAPPINESS, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY }, + { 0, PEEP_MAX_HUNGER } }; + case GUEST_PARAMETER_THIRST: + return { { GUEST_PARAMETER_HAPPINESS, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY }, + { 0, PEEP_MAX_THIRST } }; + case GUEST_PARAMETER_NAUSEA: + return { { GUEST_PARAMETER_HAPPINESS, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY }, + { 0, PEEP_MAX_NAUSEA } }; + case GUEST_PARAMETER_NAUSEA_TOLERANCE: + return { { GUEST_PARAMETER_HAPPINESS, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY }, + { PEEP_NAUSEA_TOLERANCE_NONE, PEEP_NAUSEA_TOLERANCE_HIGH } }; + case GUEST_PARAMETER_BATHROOM: + return { { GUEST_PARAMETER_HAPPINESS, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY }, + { 0, PEEP_MAX_BATHROOM } }; + case GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY: + return { { GUEST_PARAMETER_HAPPINESS, GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY }, { 0, 255 } }; + default: + return { { 0, 0 }, { 0, 0 } }; + } + case CheatType::GenerateGuests: + return { { 1, 10000 }, { 0, 0 } }; + case CheatType::GiveAllGuests: + return { { OBJECT_MONEY, OBJECT_UMBRELLA }, { 0, 0 } }; + case CheatType::SetGrassLength: + return { { 0, 7 }, { 0, 0 } }; + case CheatType::SetStaffSpeed: + return { { 0, 255 }, { 0, 0 } }; + case CheatType::ForceWeather: + return { { 0, 5 }, { 0, 0 } }; + case CheatType::SetForcedParkRating: + return { { 0, 999 }, { 0, 0 } }; + default: + return { { 0, 0 }, { 0, 0 } }; + } + } + + void SetGrassLength(int32_t length) const + { + int32_t x, y; + + for (y = 0; y < MAXIMUM_MAP_SIZE_TECHNICAL; y++) + { + for (x = 0; x < MAXIMUM_MAP_SIZE_TECHNICAL; x++) + { + auto surfaceElement = map_get_surface_element_at(x, y)->AsSurface(); + if (surfaceElement != nullptr && (surfaceElement->GetOwnership() & OWNERSHIP_OWNED) + && surfaceElement->GetWaterHeight() == 0 && surfaceElement->CanGrassGrow()) + { + surfaceElement->SetGrassLength(length); + } + } + } + + gfx_invalidate_screen(); + } + + void WaterPlants() const + { + tile_element_iterator it; + + tile_element_iterator_begin(&it); + do + { + if (it.element->GetType() == TILE_ELEMENT_TYPE_SMALL_SCENERY) + { + it.element->AsSmallScenery()->SetAge(0); + } + } while (tile_element_iterator_next(&it)); + + gfx_invalidate_screen(); + } + + void FixVandalism() const + { + tile_element_iterator it; + + tile_element_iterator_begin(&it); + do + { + if (it.element->GetType() != TILE_ELEMENT_TYPE_PATH) + continue; + + if (!(it.element)->AsPath()->HasAddition()) + continue; + + it.element->AsPath()->SetIsBroken(false); + } while (tile_element_iterator_next(&it)); + + gfx_invalidate_screen(); + } + + void RemoveLitter() const + { + rct_litter* litter; + uint16_t spriteIndex, nextSpriteIndex; + + for (spriteIndex = gSpriteListHead[SPRITE_LIST_LITTER]; spriteIndex != SPRITE_INDEX_NULL; spriteIndex = nextSpriteIndex) + { + litter = &(get_sprite(spriteIndex)->litter); + nextSpriteIndex = litter->next; + sprite_remove((rct_sprite*)litter); + } + + tile_element_iterator it; + rct_scenery_entry* sceneryEntry; + + tile_element_iterator_begin(&it); + do + { + if (it.element->GetType() != TILE_ELEMENT_TYPE_PATH) + continue; + + if (!(it.element)->AsPath()->HasAddition()) + continue; + + sceneryEntry = it.element->AsPath()->GetAdditionEntry(); + if (sceneryEntry->path_bit.flags & PATH_BIT_FLAG_IS_BIN) + it.element->AsPath()->SetAdditionStatus(0xFF); + + } while (tile_element_iterator_next(&it)); + + gfx_invalidate_screen(); + } + + void FixBrokenRides() const + { + ride_id_t rideIndex; + Ride* ride; + + FOR_ALL_RIDES (rideIndex, ride) + { + if ((ride->mechanic_status != RIDE_MECHANIC_STATUS_FIXING) + && (ride->lifecycle_flags & (RIDE_LIFECYCLE_BREAKDOWN_PENDING | RIDE_LIFECYCLE_BROKEN_DOWN))) + { + auto mechanic = ride_get_assigned_mechanic(ride); + if (mechanic != nullptr) + { + mechanic->RemoveFromRide(); + } + + ride_fix_breakdown(ride, 0); + ride->window_invalidate_flags |= RIDE_INVALIDATE_RIDE_MAIN | RIDE_INVALIDATE_RIDE_LIST; + } + } + } + + void RenewRides() const + { + int32_t i; + Ride* ride; + + FOR_ALL_RIDES (i, ride) + { + ride->Renew(); + } + window_invalidate_by_class(WC_RIDE); + } + + void MakeDestructible() const + { + int32_t i; + Ride* ride; + FOR_ALL_RIDES (i, ride) + { + if (ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE) + ride->lifecycle_flags &= ~RIDE_LIFECYCLE_INDESTRUCTIBLE; + if (ride->lifecycle_flags & RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK) + ride->lifecycle_flags &= ~RIDE_LIFECYCLE_INDESTRUCTIBLE_TRACK; + } + window_invalidate_by_class(WC_RIDE); + } + + void ResetRideCrashStatus() const + { + int32_t i; + Ride* ride; + + FOR_ALL_RIDES (i, ride) + { + // Reset crash status + if (ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED) + ride->lifecycle_flags &= ~RIDE_LIFECYCLE_CRASHED; + // Reset crash history + ride->last_crash_type = RIDE_CRASH_TYPE_NONE; + } + window_invalidate_by_class(WC_RIDE); + } + + void Set10MinuteInspection() const + { + int32_t i; + Ride* ride; + + FOR_ALL_RIDES (i, ride) + { + // Set inspection interval to 10 minutes + ride->inspection_interval = RIDE_INSPECTION_EVERY_10_MINUTES; + } + window_invalidate_by_class(WC_RIDE); + } + + void SetScenarioNoMoney(bool enabled) const + { + if (enabled) + { + gParkFlags |= PARK_FLAGS_NO_MONEY; + } + else + { + gParkFlags &= ~PARK_FLAGS_NO_MONEY; + } + // Invalidate all windows that have anything to do with finance + window_invalidate_by_class(WC_RIDE); + window_invalidate_by_class(WC_PEEP); + window_invalidate_by_class(WC_PARK_INFORMATION); + window_invalidate_by_class(WC_FINANCES); + window_invalidate_by_class(WC_BOTTOM_TOOLBAR); + window_invalidate_by_class(WC_TOP_TOOLBAR); + window_invalidate_by_class(WC_CHEATS); + } + + void SetMoney(money32 amount) const + { + gCash = amount; + + window_invalidate_by_class(WC_FINANCES); + window_invalidate_by_class(WC_BOTTOM_TOOLBAR); + } + + void AddMoney(money32 amount) const + { + gCash = add_clamp_money32(gCash, amount); + + window_invalidate_by_class(WC_FINANCES); + window_invalidate_by_class(WC_BOTTOM_TOOLBAR); + } + + void ClearLoan() const + { + // First give money + AddMoney(gBankLoan); + + // Then pay the loan + auto gameAction = ParkSetLoanAction(MONEY(0, 00)); + GameActions::ExecuteNested(&gameAction); + } + + void GenerateGuests(int32_t count) const + { + auto& park = OpenRCT2::GetContext()->GetGameState()->GetPark(); + for (int32_t i = 0; i < count; i++) + { + park.GenerateGuest(); + } + window_invalidate_by_class(WC_BOTTOM_TOOLBAR); + } + + void SetGuestParameter(int32_t parameter, int32_t value) const + { + int32_t spriteIndex; + Peep* p; + FOR_ALL_GUESTS (spriteIndex, p) + { + auto peep = p->AsGuest(); + assert(peep != nullptr); + switch (parameter) + { + case GUEST_PARAMETER_HAPPINESS: + peep->happiness = value; + peep->happiness_target = value; + // Clear the 'red-faced with anger' status if we're making the guest happy + if (value > 0) + { + peep->peep_flags &= ~PEEP_FLAGS_ANGRY; + peep->angriness = 0; + } + break; + case GUEST_PARAMETER_ENERGY: + peep->energy = value; + peep->energy_target = value; + break; + case GUEST_PARAMETER_HUNGER: + peep->hunger = value; + break; + case GUEST_PARAMETER_THIRST: + peep->thirst = value; + break; + case GUEST_PARAMETER_NAUSEA: + peep->nausea = value; + peep->nausea_target = value; + break; + case GUEST_PARAMETER_NAUSEA_TOLERANCE: + peep->nausea_tolerance = value; + break; + case GUEST_PARAMETER_BATHROOM: + peep->toilet = value; + break; + case GUEST_PARAMETER_PREFERRED_RIDE_INTENSITY: + peep->intensity = (15 << 4) | value; + break; + } + peep->UpdateSpriteType(); + } + } + + void GiveObjectToGuests(int32_t object) const + { + int32_t spriteIndex; + Peep* p; + FOR_ALL_GUESTS (spriteIndex, p) + { + auto peep = p->AsGuest(); + assert(peep != nullptr); + switch (object) + { + case OBJECT_MONEY: + peep->cash_in_pocket = MONEY(1000, 00); + break; + case OBJECT_PARK_MAP: + peep->item_standard_flags |= PEEP_ITEM_MAP; + break; + case OBJECT_BALLOON: + peep->item_standard_flags |= PEEP_ITEM_BALLOON; + peep->balloon_colour = scenario_rand_max(COLOUR_COUNT - 1); + peep->UpdateSpriteType(); + break; + case OBJECT_UMBRELLA: + peep->item_standard_flags |= PEEP_ITEM_UMBRELLA; + peep->umbrella_colour = scenario_rand_max(COLOUR_COUNT - 1); + peep->UpdateSpriteType(); + break; + } + } + window_invalidate_by_class(WC_PEEP); + } + + void RemoveAllGuests() const + { + Peep* peep; + rct_vehicle* vehicle; + uint16_t spriteIndex, nextSpriteIndex; + ride_id_t rideIndex; + Ride* ride; + + FOR_ALL_RIDES (rideIndex, ride) + { + ride->num_riders = 0; + + for (size_t stationIndex = 0; stationIndex < MAX_STATIONS; stationIndex++) + { + ride->stations[stationIndex].QueueLength = 0; + ride->stations[stationIndex].LastPeepInQueue = SPRITE_INDEX_NULL; + } + + for (auto trainIndex : ride->vehicles) + { + spriteIndex = trainIndex; + while (spriteIndex != SPRITE_INDEX_NULL) + { + vehicle = GET_VEHICLE(spriteIndex); + for (size_t i = 0, offset = 0; i < vehicle->num_peeps; i++) + { + while (vehicle->peep[i + offset] == SPRITE_INDEX_NULL) + { + offset++; + } + peep = GET_PEEP(vehicle->peep[i + offset]); + vehicle->mass -= peep->mass; + } + + for (auto& peepInTrainIndex : vehicle->peep) + { + peepInTrainIndex = SPRITE_INDEX_NULL; + } + + vehicle->num_peeps = 0; + vehicle->next_free_seat = 0; + + spriteIndex = vehicle->next_vehicle_on_train; + } + } + } + + for (spriteIndex = gSpriteListHead[SPRITE_LIST_PEEP]; spriteIndex != SPRITE_INDEX_NULL; spriteIndex = nextSpriteIndex) + { + peep = &(get_sprite(spriteIndex)->peep); + nextSpriteIndex = peep->next; + if (peep->type == PEEP_TYPE_GUEST) + { + peep->Remove(); + } + } + + window_invalidate_by_class(WC_RIDE); + gfx_invalidate_screen(); + } + + void ExplodeGuests() const + { + int32_t sprite_index; + Peep* peep; + + FOR_ALL_GUESTS (sprite_index, peep) + { + if (scenario_rand_max(6) == 0) + { + peep->peep_flags |= PEEP_FLAGS_EXPLODE; + } + } + } + + void SetStaffSpeed(uint8_t value) const + { + uint16_t spriteIndex; + Peep* peep; + + FOR_ALL_STAFF (spriteIndex, peep) + { + peep->energy = value; + peep->energy_target = value; + } + } + + void OwnAllLand() const + { + const int32_t min = 32; + const int32_t max = gMapSizeUnits - 32; + + for (CoordsXY coords = { min, min }; coords.y <= max; coords.y += 32) + { + for (coords.x = min; coords.x <= max; coords.x += 32) + { + TileElement* surfaceElement = map_get_surface_element_at(coords); + if (surfaceElement == nullptr) + continue; + + // Ignore already owned tiles. + if (surfaceElement->AsSurface()->GetOwnership() & OWNERSHIP_OWNED) + continue; + + int32_t base_z = surfaceElement->base_height; + int32_t destOwnership = check_max_allowable_land_rights_for_tile(coords.x >> 5, coords.y >> 5, base_z); + + // only own tiles that were not set to 0 + if (destOwnership != OWNERSHIP_UNOWNED) + { + surfaceElement->AsSurface()->SetOwnership(destOwnership); + update_park_fences_around_tile(coords); + uint16_t baseHeight = surfaceElement->base_height * 8; + map_invalidate_tile(coords.x, coords.y, baseHeight, baseHeight + 16); + } + } + } + + // Completely unown peep spawn points + for (const auto& spawn : gPeepSpawns) + { + int32_t x = spawn.x; + int32_t y = spawn.y; + if (x != PEEP_SPAWN_UNDEFINED) + { + TileElement* surfaceElement = map_get_surface_element_at({ x, y }); + surfaceElement->AsSurface()->SetOwnership(OWNERSHIP_UNOWNED); + update_park_fences_around_tile({ x, y }); + uint16_t baseHeight = surfaceElement->base_height * 8; + map_invalidate_tile(x, y, baseHeight, baseHeight + 16); + } + } + + map_count_remaining_land_rights(); + } + + void ParkSetOpen(bool isOpen) const + { + auto parkSetParameter = ParkSetParameterAction(isOpen ? ParkParameter::Open : ParkParameter::Close); + GameActions::ExecuteNested(&parkSetParameter); + } +}; diff --git a/src/openrct2/core/DataSerialiserTraits.h b/src/openrct2/core/DataSerialiserTraits.h index dde2c7b75c..a55bdf8aa5 100644 --- a/src/openrct2/core/DataSerialiserTraits.h +++ b/src/openrct2/core/DataSerialiserTraits.h @@ -9,6 +9,7 @@ #pragma once +#include "../Cheats.h" #include "../core/MemoryStream.h" #include "../localisation/Localisation.h" #include "../network/NetworkTypes.h" @@ -395,3 +396,23 @@ template<> struct DataSerializerTraits stream->Write(msg, strlen(msg)); } }; + +template<> struct DataSerializerTraits +{ + static void encode(IStream* stream, const NetworkCheatType_t& val) + { + uint32_t temp = ByteSwapBE(val.id); + stream->Write(&temp); + } + static void decode(IStream* stream, NetworkCheatType_t& val) + { + uint32_t temp; + stream->Read(&temp); + val.id = ByteSwapBE(temp); + } + static void log(IStream* stream, const NetworkCheatType_t& val) + { + const char* cheatName = CheatsGetName(static_cast(val.id)); + stream->Write(cheatName, strlen(cheatName)); + } +}; diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 8471897f1a..ecb41e51ed 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -18,6 +18,7 @@ #include "../actions/ClimateSetAction.hpp" #include "../actions/RideSetPriceAction.hpp" #include "../actions/RideSetSetting.hpp" +#include "../actions/SetCheatAction.hpp" #include "../actions/StaffSetCostumeAction.hpp" #include "../config/Config.h" #include "../core/Guard.hpp" @@ -753,26 +754,18 @@ static int32_t cc_set(InteractiveConsole& console, const arguments_t& argv) if (argv[0] == "money" && invalidArguments(&invalidArgs, double_valid[0])) { money32 money = MONEY((int32_t)double_val[0], ((int32_t)(double_val[0] * 100)) % 100); - bool run_get_money = true; if (gCash != money) { - if (game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETMONEY, money, GAME_COMMAND_CHEAT, 0, 0) - != MONEY32_UNDEFINED) - { - // When in networked client mode, console.Execute("get money") - // does not print value accurately. Instead, print the argument. - if (network_get_mode() == NETWORK_MODE_CLIENT) - { - run_get_money = false; - console.WriteFormatLine("money %d.%d0", money / 10, money % 10); - } - } - else - { - console.WriteLineError("Network error: Permission denied!"); - } + auto setCheatAction = SetCheatAction(CheatType::SetMoney, money); + setCheatAction.SetCallback([&console](const GameAction*, const GameActionResult* res) { + if (res->Error != GA_ERROR::OK) + console.WriteLineError("Network error: Permission denied!"); + else + console.Execute("get money"); + }); + GameActions::Execute(&setCheatAction); } - if (run_get_money) + else { console.Execute("get money"); } @@ -979,57 +972,55 @@ static int32_t cc_set(InteractiveConsole& console, const arguments_t& argv) { if (gCheatsSandboxMode != (int_val[0] != 0)) { - if (game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SANDBOXMODE, (int_val[0] != 0), GAME_COMMAND_CHEAT, 0, 0) - != MONEY32_UNDEFINED) - { - // Change it locally so it shows the accurate value in the - // "console.Execute("get cheat_sandbox_mode")" line when in networked client mode - gCheatsSandboxMode = (int_val[0] != 0); - } - else - { - console.WriteLineError("Network error: Permission denied!"); - } + auto setCheatAction = SetCheatAction(CheatType::SandboxMode, int_val[0] != 0); + setCheatAction.SetCallback([&console](const GameAction*, const GameActionResult* res) { + if (res->Error != GA_ERROR::OK) + console.WriteLineError("Network error: Permission denied!"); + else + console.Execute("get cheat_sandbox_mode"); + }); + GameActions::Execute(&setCheatAction); + } + else + { + console.Execute("get cheat_sandbox_mode"); } - console.Execute("get cheat_sandbox_mode"); } else if (argv[0] == "cheat_disable_clearance_checks" && invalidArguments(&invalidArgs, int_valid[0])) { if (gCheatsDisableClearanceChecks != (int_val[0] != 0)) { - if (game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLECLEARANCECHECKS, (int_val[0] != 0), GAME_COMMAND_CHEAT, 0, 0) - != MONEY32_UNDEFINED) - { - // Change it locally so it shows the accurate value in the - // "console.Execute("get cheat_disable_clearance_checks")" line when in networked client mode - gCheatsDisableClearanceChecks = (int_val[0] != 0); - } - else - { - console.WriteLineError("Network error: Permission denied!"); - } + auto setCheatAction = SetCheatAction(CheatType::DisableClearanceChecks, int_val[0] != 0); + setCheatAction.SetCallback([&console](const GameAction*, const GameActionResult* res) { + if (res->Error != GA_ERROR::OK) + console.WriteLineError("Network error: Permission denied!"); + else + console.Execute("get cheat_disable_clearance_checks"); + }); + GameActions::Execute(&setCheatAction); + } + else + { + console.Execute("get cheat_disable_clearance_checks"); } - console.Execute("get cheat_disable_clearance_checks"); } else if (argv[0] == "cheat_disable_support_limits" && invalidArguments(&invalidArgs, int_valid[0])) { if (gCheatsDisableSupportLimits != (int_val[0] != 0)) { - if (game_do_command( - 0, GAME_COMMAND_FLAG_APPLY, CHEAT_DISABLESUPPORTLIMITS, (int_val[0] != 0), GAME_COMMAND_CHEAT, 0, 0) - != MONEY32_UNDEFINED) - { - // Change it locally so it shows the accurate value in the - // "console.Execute("get cheat_disable_support_limits")" line when in networked client mode - gCheatsDisableSupportLimits = (int_val[0] != 0); - } - else - { - console.WriteLineError("Network error: Permission denied!"); - } + auto setCheatAction = SetCheatAction(CheatType::DisableSupportLimits, int_val[0] != 0); + setCheatAction.SetCallback([&console](const GameAction*, const GameActionResult* res) { + if (res->Error != GA_ERROR::OK) + console.WriteLineError("Network error: Permission denied!"); + else + console.Execute("get cheat_disable_support_limits"); + }); + GameActions::Execute(&setCheatAction); + } + else + { + console.Execute("get cheat_disable_support_limits"); } - console.Execute("get cheat_disable_support_limits"); } else if (argv[0] == "current_rotation" && invalidArguments(&invalidArgs, int_valid[0])) { diff --git a/src/openrct2/interface/Screenshot.cpp b/src/openrct2/interface/Screenshot.cpp index 2c413fa52a..b64b5989bb 100644 --- a/src/openrct2/interface/Screenshot.cpp +++ b/src/openrct2/interface/Screenshot.cpp @@ -13,6 +13,7 @@ #include "../Game.h" #include "../Intro.h" #include "../OpenRCT2.h" +#include "../actions/SetCheatAction.hpp" #include "../audio/audio.h" #include "../core/Console.hpp" #include "../core/Imaging.h" @@ -608,27 +609,27 @@ int32_t cmdline_for_screenshot(const char** argv, int32_t argc, ScreenshotOption if (options->mowed_grass) { - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGRASSLENGTH, GRASS_LENGTH_MOWED, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetGrassLength, GRASS_LENGTH_MOWED); } if (options->clear_grass || options->tidy_up_park) { - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETGRASSLENGTH, GRASS_LENGTH_CLEAR_0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::SetGrassLength, GRASS_LENGTH_CLEAR_0); } if (options->water_plants || options->tidy_up_park) { - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_WATERPLANTS, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::WaterPlants); } if (options->fix_vandalism || options->tidy_up_park) { - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_FIXVANDALISM, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::FixVandalism); } if (options->remove_litter || options->tidy_up_park) { - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_REMOVELITTER, 0, GAME_COMMAND_CHEAT, 0, 0); + CheatsSet(CheatType::RemoveLitter); } viewport_render(&dpi, &viewport, 0, 0, viewport.width, viewport.height); diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 47448a8558..cced3af44f 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -639,7 +639,7 @@ bool Network::BeginServer(uint16_t port, const std::string& address) ServerProviderEmail = gConfigNetwork.provider_email; ServerProviderWebsite = gConfigNetwork.provider_website; - cheats_reset(); + CheatsReset(); LoadGroups(); BeginChatLog(); BeginServerLog(); diff --git a/src/openrct2/network/NetworkTypes.h b/src/openrct2/network/NetworkTypes.h index 2308662055..2fd6d588e2 100644 --- a/src/openrct2/network/NetworkTypes.h +++ b/src/openrct2/network/NetworkTypes.h @@ -98,6 +98,7 @@ template struct NetworkObjectId_t // there is no way to specialize templates if they have the exact symbol. using NetworkPlayerId_t = NetworkObjectId_t; using NetworkRideId_t = NetworkObjectId_t; +using NetworkCheatType_t = NetworkObjectId_t; enum NetworkStatisticsGroup { diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index ecebd78f3f..4900cbc203 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -35,6 +35,10 @@ #define PEEP_MIN_ENERGY 32 #define PEEP_MAX_ENERGY 128 #define PEEP_MAX_ENERGY_TARGET 255 // Oddly, this differs from max energy! +#define PEEP_MAX_HUNGER 255 +#define PEEP_MAX_BATHROOM 255 +#define PEEP_MAX_NAUSEA 255 +#define PEEP_MAX_THIRST 255 struct TileElement; struct Ride;