diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index 9f3dee1676..60f52286e6 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -4305,6 +4305,10 @@ STR_5993 :{SMALLFONT}{BLACK}Copy selected element STR_5994 :{SMALLFONT}{BLACK}Paste copied element STR_5995 :Booster STR_5996 :Booster speed +STR_5997 :Add/set money +STR_5998 :Add money +STR_5999 :Set money +STR_6000 :Enter new value ############# # Scenarios # diff --git a/src/openrct2/cheats.c b/src/openrct2/cheats.c index a8ada295f4..b524f362a8 100644 --- a/src/openrct2/cheats.c +++ b/src/openrct2/cheats.c @@ -195,9 +195,9 @@ static void cheat_reset_crash_status() FOR_ALL_RIDES(i, ride){ //reset crash status if (ride->lifecycle_flags & RIDE_LIFECYCLE_CRASHED) - ride->lifecycle_flags&=~RIDE_LIFECYCLE_CRASHED; + ride->lifecycle_flags &= ~RIDE_LIFECYCLE_CRASHED; //reset crash history - ride->last_crash_type=RIDE_CRASH_TYPE_NONE; + ride->last_crash_type = RIDE_CRASH_TYPE_NONE; } window_invalidate_by_class(WC_RIDE); } @@ -214,15 +214,50 @@ static void cheat_10_minute_inspections() window_invalidate_by_class(WC_RIDE); } -static void cheat_increase_money(money32 amount) +static void cheat_no_money(bool enabled) { - money32 currentMoney; + 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) +{ + money32 money = clamp(INT_MIN, amount, INT_MAX); + gCashEncrypted = ENCRYPT_MONEY(money); + + window_invalidate_by_class(WC_FINANCES); + window_invalidate_by_class(WC_BOTTOM_TOOLBAR); +} + +static void cheat_add_money(money32 amount) +{ + money32 currentMoney = DECRYPT_MONEY(gCashEncrypted); + if (amount >= 0) { + if (currentMoney < INT_MAX - amount) + currentMoney += amount; + else + currentMoney = INT_MAX; + } + else { + money32 absAmount = amount * -1; + if (currentMoney > INT_MIN + absAmount) + currentMoney -= absAmount; + else + currentMoney = INT_MIN; + } - currentMoney = DECRYPT_MONEY(gCashEncrypted); - if (currentMoney < INT_MAX - amount) - currentMoney += amount; - else - currentMoney = INT_MAX; gCashEncrypted = ENCRYPT_MONEY(currentMoney); window_invalidate_by_class(WC_FINANCES); @@ -232,7 +267,7 @@ static void cheat_increase_money(money32 amount) static void cheat_clear_loan() { // First give money - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_INCREASEMONEY, gBankLoan, GAME_COMMAND_CHEAT, 0, 0); + cheat_add_money(gBankLoan); // Then pay the loan money32 newLoan; @@ -309,12 +344,12 @@ static void cheat_give_all_guests(int object) break; case OBJECT_BALLOON: peep->item_standard_flags |= PEEP_ITEM_BALLOON; - peep->balloon_colour=scenario_rand_max(31); + peep->balloon_colour = scenario_rand_max(31); peep_update_sprite_type(peep); break; case OBJECT_UMBRELLA: peep->item_standard_flags |= PEEP_ITEM_UMBRELLA; - peep->umbrella_colour=scenario_rand_max(31); + peep->umbrella_colour = scenario_rand_max(31); peep_update_sprite_type(peep); break; } @@ -343,9 +378,9 @@ static void cheat_remove_all_guests() ride_clear_for_construction(i); ride_set_status(i, RIDE_STATUS_CLOSED); - for(int i=0;i<4;i++) { - ride->queue_length[i] = 0; - ride->last_peep_in_queue[i] = SPRITE_INDEX_NULL; + for(int j = 0; j < 4; j++) { + ride->queue_length[j] = 0; + ride->last_peep_in_queue[j] = SPRITE_INDEX_NULL; } } window_invalidate_by_class(WC_RIDE); @@ -407,7 +442,9 @@ void game_command_cheat(int* eax, int* ebx, int* ecx, int* edx, int* esi, int* e case CHEAT_IGNORERIDEINTENSITY: gCheatsIgnoreRideIntensity = *edx != 0; break; case CHEAT_DISABLEVANDALISM: gCheatsDisableVandalism = *edx != 0; break; case CHEAT_DISABLELITTERING: gCheatsDisableLittering = *edx != 0; break; - case CHEAT_INCREASEMONEY: cheat_increase_money(*edx); 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; diff --git a/src/openrct2/cheats.h b/src/openrct2/cheats.h index 64a90906be..bd3fc77221 100644 --- a/src/openrct2/cheats.h +++ b/src/openrct2/cheats.h @@ -56,7 +56,9 @@ enum { CHEAT_IGNORERIDEINTENSITY, CHEAT_DISABLEVANDALISM, CHEAT_DISABLELITTERING, - CHEAT_INCREASEMONEY, + CHEAT_NOMONEY, + CHEAT_ADDMONEY, + CHEAT_SETMONEY, CHEAT_CLEARLOAN, CHEAT_SETGUESTPARAMETER, CHEAT_GENERATEGUESTS, diff --git a/src/openrct2/interface/console.c b/src/openrct2/interface/console.c index f1b7c8714f..1e7f53eef2 100644 --- a/src/openrct2/interface/console.c +++ b/src/openrct2/interface/console.c @@ -737,8 +737,24 @@ static int cc_set(const utf8 **argv, int argc) } if (strcmp(argv[0], "money") == 0 && invalidArguments(&invalidArgs, double_valid[0])) { - gCashEncrypted = ENCRYPT_MONEY(MONEY((int)double_val[0], ((int)(double_val[0] * 100)) % 100)); - console_execute_silent("get money"); + money32 money = MONEY((int)double_val[0], ((int)(double_val[0] * 100)) % 100); + bool run_get_money = true; + if (gCashEncrypted != ENCRYPT_MONEY(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_silent("get money") + //does not print value accurately. Instead, print the argument. + if (network_get_mode() == NETWORK_MODE_CLIENT) { + run_get_money = false; + console_printf("money %d.%d0", money / 10, money % 10); + } + } + else { + console_writeline_error("Network error: Permission denied!"); + } + } + if (run_get_money) { + console_execute_silent("get money"); + } } else if (strcmp(argv[0], "scenario_initial_cash") == 0 && invalidArguments(&invalidArgs, int_valid[0])) { gInitialCash = clamp(MONEY(int_val[0], 0), MONEY(0, 0), MONEY(1000000, 00)); diff --git a/src/openrct2/localisation/localisation.c b/src/openrct2/localisation/localisation.c index 01287c48ad..50f12742ff 100644 --- a/src/openrct2/localisation/localisation.c +++ b/src/openrct2/localisation/localisation.c @@ -1212,6 +1212,109 @@ void format_string_to_upper(utf8 *dest, size_t size, rct_string_id format, void } } +money32 string_to_money(char * string_to_monetise) +{ + const char* decimal_char = language_get_string(STR_LOCALE_DECIMAL_POINT); + char * text_ptr = string_to_monetise; + int i, j, sign; + //Remove everything except numbers decimal, and minus sign(s) + for (i = 0; text_ptr[i] != '\0'; ++i) { + while (!( + (text_ptr[i] >= '0' && text_ptr[i] <= '9') || + (text_ptr[i] == decimal_char[0]) || + (text_ptr[i] == '-') || + (text_ptr[i] == '\0') + )) { + //move everything over to the left by one + for (j = i; text_ptr[j] != '\0'; ++j) { + text_ptr[j] = text_ptr[j + 1]; + } + text_ptr[j] = '\0'; + } + } + + //if first character of shortened string is a minus, consider number negative + if (text_ptr[0] == '-') { + sign = -1; + } + else { + sign = 1; + } + + //now minus signs can be removed from string + for (i = 0; text_ptr[i] != '\0'; ++i) { + if (text_ptr[i] == '-') { + for (j = i; text_ptr[j] != '\0'; ++j) { + text_ptr[j] = text_ptr[j + 1]; + } + text_ptr[j] = '\0'; + } + } + + //Due to the nature of strstr and strtok, decimals at the very beginning will be ignored, causing + //".1" to be interpreted as "1". To prevent this, prefix with "0" if decimal is at the beginning. + char * buffer = (char *)malloc(strlen(string_to_monetise) + 4); + if (string_to_monetise[0] == decimal_char[0]) { + strcpy(buffer, "0"); + strcpy(buffer + 1, string_to_monetise); + } + else { + strcpy(buffer, string_to_monetise); + } + + int number = 0, decimal = 0; + if (strstr(buffer, decimal_char) == NULL) { + //if decimal char does not exist, no tokenising is needed. + number = atoi(buffer); + } + else { + char *numberText = strtok(buffer, decimal_char); + char *decimalText = strtok(NULL, decimal_char); + + if (numberText != NULL) number = atoi(numberText); + if (decimalText != NULL) decimal = atoi(decimalText); + + //The second parameter in MONEY must be two digits in length, while the game only ever uses + //the first of the two digits. + //Convert invalid numbers, such as ".6", ".234", ".05", to ".60", ".20", ".00" (respectively) + while (decimal > 10) decimal /= 10; + if (decimal < 10) decimal *= 10; + } + free(buffer); + + money32 result = MONEY(number, decimal); + //check if MONEY resulted in overflow + if ((number > 0 && result < 0) || result / 10 < number) { + result = INT_MAX; + } + result *= sign; + return result; +} + +void money_to_string(money32 amount, char * buffer_to_put_value_to, size_t buffer_len) +{ + if (amount == MONEY32_UNDEFINED) { + snprintf(buffer_to_put_value_to, buffer_len, "0"); + return; + } + int sign = amount >= 0 ? 1 : -1; + int a = abs(amount); + if (a / 10 > 0 && a % 10 > 0) { // if whole and decimal exist + const char* decimal_char = language_get_string(STR_LOCALE_DECIMAL_POINT); + snprintf(buffer_to_put_value_to, buffer_len, "%d%s%d0", (a / 10) * sign, decimal_char, a % 10); + } + else if (a / 10 > 0 && a % 10 == 0) { // if whole exists, but not decimal + snprintf(buffer_to_put_value_to, buffer_len, "%d", (a / 10) * sign); + } + else if (a / 10 == 0 && a % 10 > 0) { //if decimal exists, but not whole + const char* decimal_char = language_get_string(STR_LOCALE_DECIMAL_POINT); + snprintf(buffer_to_put_value_to, buffer_len, "%s0%s%d0", sign < 0 ? "-" : "", decimal_char, a % 10); + } + else { + snprintf(buffer_to_put_value_to, buffer_len, "0"); + } +} + utf8 *win1252_to_utf8_alloc(const char *src, size_t srcMaxSize) { size_t stringLength = strnlen(src, srcMaxSize); diff --git a/src/openrct2/localisation/localisation.h b/src/openrct2/localisation/localisation.h index 3700edd706..bcb06e8992 100644 --- a/src/openrct2/localisation/localisation.h +++ b/src/openrct2/localisation/localisation.h @@ -39,6 +39,9 @@ utf8 *get_string_end(const utf8 *text); size_t get_string_size(const utf8 *text); int get_string_length(const utf8 *text); +money32 string_to_money(char * string_to_monetise); +void money_to_string(money32 amount, char * buffer_to_put_value_to, size_t buffer_len); + void user_string_clear_all(); rct_string_id user_string_allocate(int base, const utf8 *text); void user_string_free(rct_string_id id); diff --git a/src/openrct2/localisation/string_ids.h b/src/openrct2/localisation/string_ids.h index bcc7474d76..048518e5b4 100644 --- a/src/openrct2/localisation/string_ids.h +++ b/src/openrct2/localisation/string_ids.h @@ -3028,8 +3028,8 @@ enum { STR_CHANGELOG_TITLE = 5344, STR_CHEAT_TITLE_FINANCIAL = 5345, STR_CHEAT_TITLE_GUEST = 5346, - STR_CHEAT_TITLE_RIDE = 5347, - STR_CHEAT_TITLE_PARK = 5348, + STR_CHEAT_TITLE_PARK = 5347, + STR_CHEAT_TITLE_RIDE = 5348, STR_OBJECT_FILTER_ALL_RIDES_TIP = 5349, STR_MAX = 5350, STR_MIN = 5351, @@ -3643,10 +3643,14 @@ enum { STR_MAP_ELEMENT_LIMIT_REACHED = 5992, STR_TILE_INSPECTOR_COPY_TIP = 5993, STR_TILE_INSPECTOR_PASTE_TIP = 5994, - STR_BOOSTER = 5995, STR_RIDE_CONSTRUCTION_BOOSTER_SPEED = 5996, + STR_ADD_SET_MONEY = 5997, + STR_ADD_MONEY = 5998, + STR_SET_MONEY = 5999, + STR_ENTER_NEW_VALUE = 6000, + // Have to include resource strings (from scenarios and objects) for the time being now that language is partially working STR_COUNT = 32768 }; diff --git a/src/openrct2/windows/cheats.c b/src/openrct2/windows/cheats.c index 03c2008b8b..152e27d965 100644 --- a/src/openrct2/windows/cheats.c +++ b/src/openrct2/windows/cheats.c @@ -31,10 +31,15 @@ #include "../cheats.h" #include "../network/network.h" #include "../management/marketing.h" +#include "../util/util.h" #include "error.h" #include "dropdown.h" -#define CHEATS_PARK_RATING_SPINNER_PAUSE 20 +#define MONEY_DEFAULT MONEY(5000,00) +#define MONEY_INCREMENT_DIV MONEY(1000,00) +#define MONEY_DIGITS 14 +static utf8 _moneySpinnerText[MONEY_DIGITS]; +static money32 _moneySpinnerValue = MONEY_DEFAULT; enum { WINDOW_CHEATS_PAGE_MONEY, @@ -61,9 +66,15 @@ enum WINDOW_CHEATS_WIDGET_IDX { WIDX_TAB_2, WIDX_TAB_3, WIDX_TAB_4, - WIDX_HIGH_MONEY, + WIDX_NO_MONEY, + WIDX_ADD_SET_MONEY_GROUP, + WIDX_MONEY_SPINNER, + WIDX_MONEY_SPINNER_INCREMENT, + WIDX_MONEY_SPINNER_DECREMENT, + WIDX_ADD_MONEY, + WIDX_SET_MONEY, WIDX_CLEAR_LOAN, - WIDX_GUEST_PARAMETERS_GROUP = 8, //Same as HIGH_MONEY as it is also the 8th widget but on a different page + WIDX_GUEST_PARAMETERS_GROUP = 8, //Same as NO_MONEY as it is also the 8th widget but on a different page WIDX_GUEST_HAPPINESS_MAX, WIDX_GUEST_HAPPINESS_MIN, WIDX_GUEST_ENERGY_MAX, @@ -175,9 +186,15 @@ enum WINDOW_CHEATS_WIDGET_IDX { static rct_widget window_cheats_money_widgets[] = { MAIN_CHEATS_WIDGETS, - { WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(1), HPL(1), STR_CHEAT_5K_MONEY, STR_NONE }, // high money - { WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(3), HPL(3), STR_CHEAT_CLEAR_LOAN, STR_NONE }, // Clear loan - { WIDGETS_END }, + { WWT_CHECKBOX, 1, XPL(0), WPL(0), YPL(0), HPL(0), STR_MAKE_PARK_NO_MONEY, STR_NONE }, // No money + { WWT_GROUPBOX, 1, XPL(0) - GROUP_SPACE, WPL(1) + GROUP_SPACE, YPL(1), HPL(3.5), STR_ADD_SET_MONEY, STR_NONE }, // add / set money group frame + { WWT_SPINNER, 1, XPL(0), WPL(1) - 10, YPL(2) + 2, HPL(2) - 3, STR_NONE, STR_NONE }, // money value + { WWT_DROPDOWN_BUTTON, 1, WPL(1) - 10, WPL(1), YPL(2) + 3, YPL(2) + 7, STR_NUMERIC_UP, STR_NONE }, // increase money + { WWT_DROPDOWN_BUTTON, 1, WPL(1) - 10, WPL(1), YPL(2) + 8, YPL(2) + 12, STR_NUMERIC_DOWN, STR_NONE }, // decrease money + { WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(3), HPL(3), STR_ADD_MONEY, STR_NONE }, // add money + { WWT_CLOSEBOX, 1, XPL(1), WPL(1), YPL(3), HPL(3), STR_SET_MONEY, STR_NONE }, // set money + { WWT_CLOSEBOX, 1, XPL(0), WPL(0), YPL(5), HPL(5), STR_CHEAT_CLEAR_LOAN, STR_NONE }, // Clear loan + { WIDGETS_END }, }; static rct_widget window_cheats_guests_widgets[] = { @@ -271,6 +288,7 @@ static rct_widget *window_cheats_page_widgets[] = { }; static void window_cheats_money_mouseup(rct_window *w, int widgetIndex); +static void window_cheats_money_mousedown(int widgetIndex, rct_window *w, rct_widget* widget); static void window_cheats_misc_mousedown(int widgetIndex, rct_window *w, rct_widget* widget); static void window_cheats_misc_dropdown(rct_window *w, int widgetIndex, int dropdownIndex); static void window_cheats_guests_mouseup(rct_window *w, int widgetIndex); @@ -280,12 +298,13 @@ static void window_cheats_update(rct_window *w); static void window_cheats_invalidate(rct_window *w); static void window_cheats_paint(rct_window *w, rct_drawpixelinfo *dpi); static void window_cheats_set_page(rct_window *w, int page); +static void window_cheats_text_input(rct_window *w, int widgetIndex, char *text); static rct_window_event_list window_cheats_money_events = { NULL, window_cheats_money_mouseup, NULL, - NULL, + window_cheats_money_mousedown, NULL, NULL, window_cheats_update, @@ -301,7 +320,7 @@ static rct_window_event_list window_cheats_money_events = { NULL, NULL, NULL, - NULL, + window_cheats_text_input, NULL, NULL, NULL, @@ -413,9 +432,12 @@ static rct_window_event_list *window_cheats_page_events[] = { &window_cheats_rides_events, }; +#define MAIN_CHEAT_ENABLED_WIDGETS (1ULL << WIDX_CLOSE) | (1ULL << WIDX_TAB_1) | (1ULL << WIDX_TAB_2) | (1ULL << WIDX_TAB_3) | (1ULL << WIDX_TAB_4) + static uint64 window_cheats_page_enabled_widgets[] = { - (1ULL << WIDX_CLOSE) | (1ULL << WIDX_TAB_1) | (1ULL << WIDX_TAB_2) | (1ULL << WIDX_TAB_3) | (1ULL << WIDX_TAB_4) | (1ULL << WIDX_HIGH_MONEY) | (1ULL << WIDX_CLEAR_LOAN), - (1ULL << WIDX_CLOSE) | (1ULL << WIDX_TAB_1) | (1ULL << WIDX_TAB_2) | (1ULL << WIDX_TAB_3) | (1ULL << WIDX_TAB_4) | (1ULL << WIDX_GUEST_PARAMETERS_GROUP) | + MAIN_CHEAT_ENABLED_WIDGETS | (1ULL << WIDX_NO_MONEY) | (1ULL << WIDX_ADD_SET_MONEY_GROUP) | (1ULL << WIDX_MONEY_SPINNER) | (1ULL << WIDX_MONEY_SPINNER_INCREMENT) | + (1ULL << WIDX_MONEY_SPINNER_DECREMENT) | (1ULL << WIDX_ADD_MONEY) | (1ULL << WIDX_SET_MONEY) | (1ULL << WIDX_CLEAR_LOAN), + MAIN_CHEAT_ENABLED_WIDGETS | (1ULL << WIDX_GUEST_PARAMETERS_GROUP) | (1ULL << WIDX_GUEST_HAPPINESS_MAX) | (1ULL << WIDX_GUEST_HAPPINESS_MIN) | (1ULL << WIDX_GUEST_ENERGY_MAX) | (1ULL << WIDX_GUEST_ENERGY_MIN) | (1ULL << WIDX_GUEST_HUNGER_MAX) | (1ULL << WIDX_GUEST_HUNGER_MIN) | (1ULL << WIDX_GUEST_THIRST_MAX) | (1ULL << WIDX_GUEST_THIRST_MIN) | (1ULL << WIDX_GUEST_NAUSEA_MAX) | (1ULL << WIDX_GUEST_NAUSEA_MIN) | (1ULL << WIDX_GUEST_NAUSEA_TOLERANCE_MAX) | (1ULL << WIDX_GUEST_NAUSEA_TOLERANCE_MIN) | @@ -423,29 +445,34 @@ static uint64 window_cheats_page_enabled_widgets[] = { (1ULL << WIDX_GUEST_IGNORE_RIDE_INTENSITY) | (1ULL << WIDX_GIVE_ALL_GUESTS_GROUP) | (1ULL << WIDX_GIVE_GUESTS_MONEY) | (1ULL << WIDX_GIVE_GUESTS_PARK_MAPS) | (1ULL << WIDX_GIVE_GUESTS_BALLOONS) | (1ULL << WIDX_GIVE_GUESTS_UMBRELLAS) | (1ULL << WIDX_TRAM_GUESTS) | (1ULL << WIDX_REMOVE_ALL_GUESTS) | (1ULL << WIDX_EXPLODE_GUESTS) | (1ULL << WIDX_DISABLE_VANDALISM) | (1ULL << WIDX_DISABLE_LITTERING), - (1ULL << WIDX_CLOSE) | (1ULL << WIDX_TAB_1) | (1ULL << WIDX_TAB_2) | (1ULL << WIDX_TAB_3) | (1ULL << WIDX_TAB_4) | (1ULL << WIDX_FREEZE_CLIMATE) | + MAIN_CHEAT_ENABLED_WIDGETS | (1ULL << WIDX_FREEZE_CLIMATE) | (1ULL << WIDX_OPEN_CLOSE_PARK) | (1ULL << WIDX_WEATHER) | (1ULL << WIDX_WEATHER_DROPDOWN_BUTTON) | (1ULL << WIDX_CLEAR_GRASS) | (1ULL << WIDX_MOWED_GRASS) | (1ULL << WIDX_WATER_PLANTS) | (1ULL << WIDX_DISABLE_PLANT_AGING) | (1ULL << WIDX_FIX_VANDALISM) | (1ULL << WIDX_REMOVE_LITTER) | (1ULL << WIDX_WIN_SCENARIO) | (1ULL << WIDX_HAVE_FUN) | (1ULL << WIDX_NEVERENDING_MARKETING) | (1ULL << WIDX_UNLOCK_ALL_PRICES) | (1ULL << WIDX_SANDBOX_MODE) | (1ULL << WIDX_RESET_DATE) | (1ULL << WIDX_FAST_STAFF) | (1ULL << WIDX_NORMAL_STAFF) | (1ULL << WIDX_PARK_PARAMETERS) | (1ULL << WIDX_FORCE_PARK_RATING) | (1ULL << WIDX_INCREASE_PARK_RATING) | (1ULL << WIDX_DECREASE_PARK_RATING), - (1ULL << WIDX_CLOSE) | (1ULL << WIDX_TAB_1) | (1ULL << WIDX_TAB_2) | (1ULL << WIDX_TAB_3) | (1ULL << WIDX_TAB_4) | (1ULL << WIDX_RENEW_RIDES) | + MAIN_CHEAT_ENABLED_WIDGETS | (1ULL << WIDX_RENEW_RIDES) | (1ULL << WIDX_MAKE_DESTRUCTIBLE) | (1ULL << WIDX_FIX_ALL) | (1ULL << WIDX_FAST_LIFT_HILL) | (1ULL << WIDX_DISABLE_BRAKES_FAILURE) | (1ULL << WIDX_DISABLE_ALL_BREAKDOWNS) | (1ULL << WIDX_BUILD_IN_PAUSE_MODE) | (1ULL << WIDX_RESET_CRASH_STATUS) | (1ULL << WIDX_10_MINUTE_INSPECTIONS) | (1ULL << WIDX_SHOW_ALL_OPERATING_MODES) | (1ULL << WIDX_SHOW_VEHICLES_FROM_OTHER_TRACK_TYPES) | (1ULL << WIDX_DISABLE_TRAIN_LENGTH_LIMITS) | (1ULL << WIDX_ENABLE_CHAIN_LIFT_ON_ALL_TRACK) | (1ULL << WIDX_ENABLE_ARBITRARY_RIDE_TYPE_CHANGES) }; +static uint64 window_cheats_page_hold_down_widgets[] = { + (1ULL << WIDX_MONEY_SPINNER_INCREMENT) | (1ULL << WIDX_MONEY_SPINNER_DECREMENT) | (1ULL << WIDX_ADD_MONEY), + 0, + (1ULL << WIDX_INCREASE_PARK_RATING) | (1ULL << WIDX_DECREASE_PARK_RATING), + 0 +}; + static rct_string_id window_cheats_page_titles[] = { STR_CHEAT_TITLE_FINANCIAL, STR_CHEAT_TITLE_GUEST, - STR_CHEAT_TITLE_RIDE, STR_CHEAT_TITLE_PARK, + STR_CHEAT_TITLE_RIDE, }; static void window_cheats_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w); -int park_rating_spinner_pressed_for = 0; - void window_cheats_open() { rct_window* window; @@ -458,37 +485,69 @@ void window_cheats_open() window = window_create(32, 32, WW, WH, &window_cheats_money_events, WC_CHEATS, 0); window->widgets = window_cheats_money_widgets; window->enabled_widgets = window_cheats_page_enabled_widgets[0]; + 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; } +static void window_cheats_money_mousedown(int widgetIndex, rct_window *w, rct_widget* widget) +{ + switch (widgetIndex) { + case WIDX_MONEY_SPINNER_INCREMENT: + _moneySpinnerValue = min(INT_MAX, MONEY_INCREMENT_DIV * (_moneySpinnerValue / MONEY_INCREMENT_DIV + 1)); + widget_invalidate_by_class(WC_CHEATS, WIDX_MONEY_SPINNER); + break; + case WIDX_MONEY_SPINNER_DECREMENT: + _moneySpinnerValue = max(INT_MIN, MONEY_INCREMENT_DIV * (_moneySpinnerValue / MONEY_INCREMENT_DIV - 1)); + 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); + break; + } +} + static void window_cheats_misc_mousedown(int widgetIndex, rct_window *w, rct_widget* widget) { - rct_widget *dropdownWidget; - int i; + switch (widgetIndex) { + case WIDX_INCREASE_PARK_RATING: + park_rating_spinner_value = min(999, 10 * (park_rating_spinner_value / 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); + break; + case WIDX_DECREASE_PARK_RATING: + park_rating_spinner_value = max(0, 10 * (park_rating_spinner_value / 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); + break; + case WIDX_WEATHER_DROPDOWN_BUTTON:{ + rct_widget *dropdownWidget; + int i, currentWeather; - if (widgetIndex != WIDX_WEATHER_DROPDOWN_BUTTON) - return; - - dropdownWidget = widget - 1; - - for (i = 0; i < 6; i++) { - gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL; - gDropdownItemsArgs[i] = WeatherTypes[i]; - } - window_dropdown_show_text_custom_width( - w->x + dropdownWidget->left, - w->y + dropdownWidget->top, - dropdownWidget->bottom - dropdownWidget->top + 1, - w->colours[1], - DROPDOWN_FLAG_STAY_OPEN, - 6, - dropdownWidget->right - dropdownWidget->left - 3 + dropdownWidget = widget - 1; + + for (i = 0; i < 6; i++) { + gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL; + gDropdownItemsArgs[i] = WeatherTypes[i]; + } + window_dropdown_show_text_custom_width( + w->x + dropdownWidget->left, + w->y + dropdownWidget->top, + dropdownWidget->bottom - dropdownWidget->top + 1, + w->colours[1], + DROPDOWN_FLAG_STAY_OPEN, + 6, + dropdownWidget->right - dropdownWidget->left - 3 ); - int currentWeather = gClimateCurrentWeather; - dropdown_set_checked(currentWeather, true); + currentWeather = gClimateCurrentWeather; + dropdown_set_checked(currentWeather, true); + } + break; + } } static void window_cheats_misc_dropdown(rct_window *w, int widgetIndex, int dropdownIndex) @@ -511,8 +570,15 @@ static void window_cheats_money_mouseup(rct_window *w, int widgetIndex) case WIDX_TAB_4: window_cheats_set_page(w, widgetIndex - WIDX_TAB_1); break; - case WIDX_HIGH_MONEY: - game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_INCREASEMONEY, CHEATS_MONEY_INCREMENT, GAME_COMMAND_CHEAT, 0, 0); + 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); + break; + case WIDX_MONEY_SPINNER: + money_to_string(_moneySpinnerValue, _moneySpinnerText, MONEY_DIGITS); + window_text_input_raw_open(w, WIDX_MONEY_SPINNER, STR_ENTER_NEW_VALUE, STR_ENTER_NEW_VALUE, _moneySpinnerText, MONEY_DIGITS); + break; + case WIDX_SET_MONEY: + game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETMONEY, _moneySpinnerValue, GAME_COMMAND_CHEAT, 0, 0); break; case WIDX_CLEAR_LOAN: game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_CLEARLOAN, CHEATS_MONEY_INCREMENT, GAME_COMMAND_CHEAT, 0, 0); @@ -685,18 +751,6 @@ static void window_cheats_misc_mouseup(rct_window *w, int widgetIndex) game_do_command(0, GAME_COMMAND_FLAG_APPLY, CHEAT_SETFORCEDPARKRATING, park_rating_spinner_value, GAME_COMMAND_CHEAT, 0, 0); } break; - case WIDX_INCREASE_PARK_RATING: - park_rating_spinner_value = min(999, 10 * (park_rating_spinner_value / 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); - break; - case WIDX_DECREASE_PARK_RATING: - park_rating_spinner_value = max(0, 10 * (park_rating_spinner_value / 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); - break; } } @@ -769,29 +823,23 @@ static void window_cheats_rides_mouseup(rct_window *w, int widgetIndex) } } +static void window_cheats_text_input(rct_window *w, int widgetIndex, char *text) { + if (text == NULL) + return; + + if (w->page == WINDOW_CHEATS_PAGE_MONEY && widgetIndex == WIDX_MONEY_SPINNER) { + money32 val = string_to_money(text); + if (val != MONEY32_UNDEFINED) { + _moneySpinnerValue = val; + } + window_invalidate(w); + } +} + static void window_cheats_update(rct_window *w) { w->frame_no++; widget_invalidate(w, WIDX_TAB_1 + w->page); - - if (widget_is_pressed(w, WIDX_INCREASE_PARK_RATING) || widget_is_pressed(w, WIDX_DECREASE_PARK_RATING)) - park_rating_spinner_pressed_for++; - else - park_rating_spinner_pressed_for = 0; - if (park_rating_spinner_pressed_for >= CHEATS_PARK_RATING_SPINNER_PAUSE) - if (!(w->frame_no % 3)){ - if (widget_is_pressed(w, WIDX_INCREASE_PARK_RATING)){ - park_rating_spinner_value = min(999, 10 * (park_rating_spinner_value / 10 + 1)); - widget_invalidate_by_class(WC_CHEATS, WIDX_PARK_RATING_SPINNER); - if (get_forced_park_rating() >= 0) - set_forced_park_rating(park_rating_spinner_value); - } else if (widget_is_pressed(w, WIDX_DECREASE_PARK_RATING)){ - park_rating_spinner_value = max(0, 10 * (park_rating_spinner_value / 10 - 1)); - widget_invalidate_by_class(WC_CHEATS, WIDX_PARK_RATING_SPINNER); - if (get_forced_park_rating() >= 0) - set_forced_park_rating(park_rating_spinner_value); - } - } } static void window_cheats_invalidate(rct_window *w) @@ -807,11 +855,29 @@ static void window_cheats_invalidate(rct_window *w) } w->pressed_widgets = 0; + w->disabled_widgets = 0; + + // Set correct active tab + for (i = 0; i < 7; i++) + w->pressed_widgets &= ~(1 << (WIDX_TAB_1 + i)); + w->pressed_widgets |= 1LL << (WIDX_TAB_1 + w->page); + + // Set title + w->widgets[WIDX_TITLE].text = window_cheats_page_titles[w->page]; switch (w->page) { - case WINDOW_CHEATS_PAGE_MONEY: - set_format_arg(0, int, 50000); - break; + case WINDOW_CHEATS_PAGE_MONEY:{ + widget_set_checkbox_value(w, WIDX_NO_MONEY, gParkFlags & PARK_FLAGS_NO_MONEY); + + uint64 money_widgets = (1 << WIDX_ADD_SET_MONEY_GROUP) | (1 << WIDX_MONEY_SPINNER) | (1 << WIDX_MONEY_SPINNER_INCREMENT) | + (1 << WIDX_MONEY_SPINNER_DECREMENT) | (1 << WIDX_ADD_MONEY) | (1 << WIDX_SET_MONEY) | (1 << WIDX_CLEAR_LOAN); + if (gParkFlags & PARK_FLAGS_NO_MONEY) { + w->disabled_widgets |= money_widgets; + } + else { + w->disabled_widgets &= ~money_widgets; + } + }break; case WINDOW_CHEATS_PAGE_GUESTS: set_format_arg(0, int, 10000); widget_set_checkbox_value(w, WIDX_GUEST_IGNORE_RIDE_INTENSITY, gCheatsIgnoreRideIntensity); @@ -841,15 +907,6 @@ static void window_cheats_invalidate(rct_window *w) break; } - // Set correct active tab - for (i = 0; i < 7; i++) - w->pressed_widgets &= ~(1 << (WIDX_TAB_1 + i)); - w->pressed_widgets |= 1LL << (WIDX_TAB_1 + w->page); - - // Set title - w->widgets[WIDX_TITLE].text = window_cheats_page_titles[w->page]; - - // Current weather window_cheats_misc_widgets[WIDX_WEATHER].text = WeatherTypes[gClimateCurrentWeather]; } @@ -860,9 +917,12 @@ static void window_cheats_paint(rct_window *w, rct_drawpixelinfo *dpi) window_cheats_draw_tab_images(dpi, w); if (w->page == WINDOW_CHEATS_PAGE_MONEY){ - set_format_arg(0, money32, CHEATS_MONEY_INCREMENT); - gfx_draw_string_left(dpi, STR_CHEAT_5K_MONEY_TIP, gCommonFormatArgs, COLOUR_BLACK, w->x + XPL(0) + TXTO, w->y + YPL(0) + TXTO); - gfx_draw_string_left(dpi, STR_CHEAT_CLEAR_LOAN_TIP, NULL, COLOUR_BLACK, w->x + XPL(0) + TXTO, w->y + YPL(2) + TXTO); + uint8 colour = w->colours[2]; + set_format_arg(0, money32, _moneySpinnerValue); + if (widget_is_disabled(w, WIDX_MONEY_SPINNER)) { + colour |= COLOUR_FLAG_INSET; + } + gfx_draw_string_left(dpi, STR_BOTTOM_TOOLBAR_CASH, gCommonFormatArgs, colour, w->x + XPL(0) + TXTO, w->y + YPL(2) + TXTO); } else if(w->page == WINDOW_CHEATS_PAGE_MISC){ gfx_draw_string_left(dpi, STR_CHEAT_STAFF_SPEED, NULL, COLOUR_BLACK, w->x + XPL(0) + TXTO, w->y + YPL(16) + TXTO); @@ -922,7 +982,7 @@ static void window_cheats_set_page(rct_window *w, int page) w->frame_no = 0; w->enabled_widgets = window_cheats_page_enabled_widgets[page]; - + w->hold_down_widgets = window_cheats_page_hold_down_widgets[page]; w->pressed_widgets = 0; w->event_handlers = window_cheats_page_events[page];