From e1401acb472600079285bba7f8a919e7721dab88 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 9 Apr 2022 11:40:25 +0100 Subject: [PATCH 1/4] Use start scenario logic when choosing new game --- src/openrct2-ui/windows/ServerStart.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/openrct2-ui/windows/ServerStart.cpp b/src/openrct2-ui/windows/ServerStart.cpp index b64be43961..b0d7e89d35 100644 --- a/src/openrct2-ui/windows/ServerStart.cpp +++ b/src/openrct2-ui/windows/ServerStart.cpp @@ -22,6 +22,8 @@ # include # include +using namespace OpenRCT2; + static char _port[7]; static char _name[65]; static char _description[MAX_SERVER_DESCRIPTION_LENGTH]; @@ -127,7 +129,7 @@ static void WindowServerStartClose(rct_window* w) static void WindowServerStartScenarioselectCallback(const utf8* path) { game_notify_map_change(); - if (context_load_park_from_file(path)) + if (GetContext()->LoadParkFromFile(path, false, true)) { network_begin_server(gConfigNetwork.default_port, gConfigNetwork.listen_address.c_str()); } From d2528c63a1b7e21d64592daffba29c350d716081 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 9 Apr 2022 11:54:23 +0100 Subject: [PATCH 2/4] Reset scenario when saving a scenario --- src/openrct2/Editor.cpp | 16 +--------------- src/openrct2/scenario/Scenario.cpp | 20 +++++++++++++++----- src/openrct2/scenario/Scenario.h | 1 + 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/openrct2/Editor.cpp b/src/openrct2/Editor.cpp index 4c9019b942..b291ac63ff 100644 --- a/src/openrct2/Editor.cpp +++ b/src/openrct2/Editor.cpp @@ -133,27 +133,13 @@ namespace Editor return; } - if (gParkFlags & PARK_FLAGS_NO_MONEY) - { - gParkFlags |= PARK_FLAGS_NO_MONEY_SCENARIO; - } - else - { - gParkFlags &= ~PARK_FLAGS_NO_MONEY_SCENARIO; - } - gParkFlags |= PARK_FLAGS_NO_MONEY; - + scenario_reset(); climate_reset(gClimate); - // Clear the scenario completion status - gParkFlags &= ~PARK_FLAGS_SCENARIO_COMPLETE_NAME_INPUT; - gScenarioCompletedCompanyValue = MONEY64_UNDEFINED; - gScreenFlags = SCREEN_FLAGS_SCENARIO_EDITOR; gEditorStep = EditorStep::ObjectiveSelection; gScenarioCategory = SCENARIO_CATEGORY_OTHER; viewport_init_all(); - News::InitQueue(); context_open_window_view(WV_EDITOR_MAIN); FinaliseMainView(); gScreenAge = 0; diff --git a/src/openrct2/scenario/Scenario.cpp b/src/openrct2/scenario/Scenario.cpp index 94308baa67..72edda8bb5 100644 --- a/src/openrct2/scenario/Scenario.cpp +++ b/src/openrct2/scenario/Scenario.cpp @@ -91,7 +91,16 @@ using namespace OpenRCT2; void scenario_begin() { game_load_init(); + scenario_reset(); + if (gScenarioObjective.Type != OBJECTIVE_NONE && !gLoadKeepWindowsOpen) + context_open_window_view(WV_PARK_OBJECTIVE); + + gScreenAge = 0; +} + +void scenario_reset() +{ // Set the scenario pseudo-random seeds Random::Rct2::Seed s{ 0x1234567F ^ Platform::GetTicks(), 0x789FABCD ^ Platform::GetTicks() }; gScenarioRand.seed(s); @@ -102,8 +111,6 @@ void scenario_begin() research_reset_current_item(); scenery_set_default_placement_configuration(); News::InitQueue(); - if (gScenarioObjective.Type != OBJECTIVE_NONE && !gLoadKeepWindowsOpen) - context_open_window_view(WV_PARK_OBJECTIVE); auto& park = GetContext()->GetGameState()->GetPark(); gParkRating = park.CalculateParkRating(); @@ -143,10 +150,13 @@ void scenario_begin() gCurrentProfit = 0; gWeeklyProfitAverageDividend = 0; gWeeklyProfitAverageDivisor = 0; - gScenarioCompletedCompanyValue = MONEY64_UNDEFINED; gTotalAdmissions = 0; gTotalIncomeFromAdmissions = 0; + + gParkFlags &= ~PARK_FLAGS_SCENARIO_COMPLETE_NAME_INPUT; + gScenarioCompletedCompanyValue = MONEY64_UNDEFINED; gScenarioCompletedBy = "?"; + park.ResetHistories(); finance_reset_history(); award_reset(); @@ -176,8 +186,6 @@ void scenario_begin() } gParkFlags |= PARK_FLAGS_SPRITES_INITIALISED; - - gScreenAge = 0; } static void scenario_end() @@ -606,6 +614,8 @@ bool scenario_prepare_for_save() // Fix #2385: saved scenarios did not initialise temperatures to selected climate climate_reset(gClimate); + scenario_reset(); + return true; } diff --git a/src/openrct2/scenario/Scenario.h b/src/openrct2/scenario/Scenario.h index 60f5788e28..dcb8d5ff8d 100644 --- a/src/openrct2/scenario/Scenario.h +++ b/src/openrct2/scenario/Scenario.h @@ -169,6 +169,7 @@ extern std::string gScenarioFileName; void load_from_sc6(const char* path); void scenario_begin(); +void scenario_reset(); void scenario_update(); bool scenario_create_ducks(); bool AllowEarlyCompletion(); From 11f4993c035c2a987277111dbe4085c4a7d007f8 Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 9 Apr 2022 12:36:31 +0100 Subject: [PATCH 3/4] Remove no money scenerio flag --- .../windows/EditorObjectiveOptions.cpp | 5 ++--- .../windows/EditorScenarioOptions.cpp | 21 ++++--------------- src/openrct2/Editor.cpp | 8 ------- .../actions/ScenarioSetSettingAction.cpp | 4 ++-- src/openrct2/rct1/S4Importer.cpp | 4 +--- src/openrct2/rct2/S6Importer.cpp | 10 ++++++++- src/openrct2/scenario/Scenario.cpp | 3 --- .../scripting/bindings/world/ScPark.cpp | 1 - src/openrct2/world/Park.h | 2 +- 9 files changed, 19 insertions(+), 39 deletions(-) diff --git a/src/openrct2-ui/windows/EditorObjectiveOptions.cpp b/src/openrct2-ui/windows/EditorObjectiveOptions.cpp index 6beb44656d..bb7e59511d 100644 --- a/src/openrct2-ui/windows/EditorObjectiveOptions.cpp +++ b/src/openrct2-ui/windows/EditorObjectiveOptions.cpp @@ -386,7 +386,7 @@ static void WindowEditorObjectiveOptionsShowObjectiveDropdown(rct_window* w) if (i == OBJECTIVE_NONE || i == OBJECTIVE_BUILD_THE_BEST) continue; - const bool objectiveAllowedByMoneyUsage = !(parkFlags & PARK_FLAGS_NO_MONEY_SCENARIO) || !ObjectiveNeedsMoney(i); + const bool objectiveAllowedByMoneyUsage = !(parkFlags & PARK_FLAGS_NO_MONEY) || !ObjectiveNeedsMoney(i); // This objective can only work if the player can ask money for rides. const bool objectiveAllowedByPaymentSettings = (i != OBJECTIVE_MONTHLY_RIDE_INCOME) || park_ride_prices_unlocked(); if (objectiveAllowedByMoneyUsage && objectiveAllowedByPaymentSettings) @@ -659,8 +659,7 @@ static void WindowEditorObjectiveOptionsMainUpdate(rct_window* w) objectiveType = gScenarioObjective.Type; // Check if objective is allowed by money and pay-per-ride settings. - const bool objectiveAllowedByMoneyUsage = !(parkFlags & PARK_FLAGS_NO_MONEY_SCENARIO) - || !ObjectiveNeedsMoney(objectiveType); + const bool objectiveAllowedByMoneyUsage = !(parkFlags & PARK_FLAGS_NO_MONEY) || !ObjectiveNeedsMoney(objectiveType); // This objective can only work if the player can ask money for rides. const bool objectiveAllowedByPaymentSettings = (objectiveType != OBJECTIVE_MONTHLY_RIDE_INCOME) || park_ride_prices_unlocked(); diff --git a/src/openrct2-ui/windows/EditorScenarioOptions.cpp b/src/openrct2-ui/windows/EditorScenarioOptions.cpp index c09cf61c4c..af44adfd46 100644 --- a/src/openrct2-ui/windows/EditorScenarioOptions.cpp +++ b/src/openrct2-ui/windows/EditorScenarioOptions.cpp @@ -387,17 +387,7 @@ static void WindowEditorScenarioOptionsFinancialMouseup(rct_window* w, rct_widge break; case WIDX_NO_MONEY: { - int32_t newMoneySetting; - - if (gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) - { - newMoneySetting = (gParkFlags & PARK_FLAGS_NO_MONEY_SCENARIO) ? 0 : 1; - } - else - { - newMoneySetting = (gParkFlags & PARK_FLAGS_NO_MONEY) ? 0 : 1; - } - + auto newMoneySetting = (gParkFlags & PARK_FLAGS_NO_MONEY) ? 0 : 1; auto scenarioSetSetting = ScenarioSetSettingAction(ScenarioSetSetting::NoMoney, newMoneySetting); GameActions::Execute(&scenarioSetSetting); w->Invalidate(); @@ -583,8 +573,7 @@ static void WindowEditorScenarioOptionsFinancialInvalidate(rct_window* w) WindowEditorScenarioOptionsSetPressedTab(w); - if (((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && (gParkFlags & PARK_FLAGS_NO_MONEY_SCENARIO)) - || (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && (gParkFlags & PARK_FLAGS_NO_MONEY))) + if (gParkFlags & PARK_FLAGS_NO_MONEY) { w->pressed_widgets |= (1ULL << WIDX_NO_MONEY); for (int32_t i = WIDX_INITIAL_CASH; i <= WIDX_FORBID_MARKETING; i++) @@ -871,8 +860,7 @@ static void WindowEditorScenarioOptionsGuestsInvalidate(rct_window* w) WindowEditorScenarioOptionsSetPressedTab(w); - if (((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && (gParkFlags & PARK_FLAGS_NO_MONEY_SCENARIO)) - || (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && (gParkFlags & PARK_FLAGS_NO_MONEY))) + if (gParkFlags & PARK_FLAGS_NO_MONEY) { w->widgets[WIDX_CASH_PER_GUEST].type = WindowWidgetType::Empty; w->widgets[WIDX_CASH_PER_GUEST_INCREASE].type = WindowWidgetType::Empty; @@ -1207,8 +1195,7 @@ static void WindowEditorScenarioOptionsParkInvalidate(rct_window* w) WindowEditorScenarioOptionsSetPressedTab(w); - if (((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && (gParkFlags & PARK_FLAGS_NO_MONEY_SCENARIO)) - || (!(gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) && (gParkFlags & PARK_FLAGS_NO_MONEY))) + if (gParkFlags & PARK_FLAGS_NO_MONEY) { for (int32_t i = WIDX_LAND_COST; i <= WIDX_ENTRY_PRICE_DECREASE; i++) w->widgets[i].type = WindowWidgetType::Empty; diff --git a/src/openrct2/Editor.cpp b/src/openrct2/Editor.cpp index b291ac63ff..f05c845a4c 100644 --- a/src/openrct2/Editor.cpp +++ b/src/openrct2/Editor.cpp @@ -344,14 +344,6 @@ namespace Editor gGuestChangeModifier = 0; if (fromSave) { - if (gParkFlags & PARK_FLAGS_NO_MONEY) - { - gParkFlags |= PARK_FLAGS_NO_MONEY_SCENARIO; - } - else - { - gParkFlags &= ~PARK_FLAGS_NO_MONEY_SCENARIO; - } gParkFlags |= PARK_FLAGS_NO_MONEY; if (gParkEntranceFee == 0) diff --git a/src/openrct2/actions/ScenarioSetSettingAction.cpp b/src/openrct2/actions/ScenarioSetSettingAction.cpp index 1f31fdd56f..cf58706178 100644 --- a/src/openrct2/actions/ScenarioSetSettingAction.cpp +++ b/src/openrct2/actions/ScenarioSetSettingAction.cpp @@ -46,11 +46,11 @@ GameActions::Result ScenarioSetSettingAction::Execute() const { if (_value != 0) { - gParkFlags |= PARK_FLAGS_NO_MONEY_SCENARIO; + gParkFlags |= PARK_FLAGS_NO_MONEY; } else { - gParkFlags &= ~PARK_FLAGS_NO_MONEY_SCENARIO; + gParkFlags &= ~PARK_FLAGS_NO_MONEY; } } else diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index ecaa95101f..6180fb1562 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -2206,11 +2206,9 @@ namespace RCT1 gParkFlags |= PARK_FLAGS_UNLOCK_ALL_PRICES; } - // RCT2 uses two flags for no money (due to the scenario editor). RCT1 used only one. - // Copy its value to make no money scenarios such as Arid Heights work properly. if (_s4.park_flags & RCT1_PARK_FLAGS_NO_MONEY) { - gParkFlags |= PARK_FLAGS_NO_MONEY_SCENARIO; + gParkFlags |= PARK_FLAGS_NO_MONEY; } gParkSize = _s4.park_size; diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index b2a6ad78a1..0f7bbb9c2a 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -252,7 +252,15 @@ namespace RCT2 gInitialCash = ToMoney64(_s6.initial_cash); gBankLoan = ToMoney64(_s6.current_loan); - gParkFlags = _s6.park_flags; + + gParkFlags = _s6.park_flags & ~PARK_FLAGS_NO_MONEY_SCENARIO; + + // RCT2 used a different flag for `no money` when the park is a scenario + if (_s6.header.type == S6_TYPE_SCENARIO && (_s6.park_flags & PARK_FLAGS_NO_MONEY_SCENARIO)) + gParkFlags |= PARK_FLAGS_NO_MONEY; + else + gParkFlags &= ~PARK_FLAGS_NO_MONEY; + gParkEntranceFee = _s6.park_entrance_fee; // rct1_park_entrance_x // rct1_park_entrance_y diff --git a/src/openrct2/scenario/Scenario.cpp b/src/openrct2/scenario/Scenario.cpp index 72edda8bb5..49396ce1d5 100644 --- a/src/openrct2/scenario/Scenario.cpp +++ b/src/openrct2/scenario/Scenario.cpp @@ -105,9 +105,6 @@ void scenario_reset() Random::Rct2::Seed s{ 0x1234567F ^ Platform::GetTicks(), 0x789FABCD ^ Platform::GetTicks() }; gScenarioRand.seed(s); - gParkFlags &= ~PARK_FLAGS_NO_MONEY; - if (gParkFlags & PARK_FLAGS_NO_MONEY_SCENARIO) - gParkFlags |= PARK_FLAGS_NO_MONEY; research_reset_current_item(); scenery_set_default_placement_configuration(); News::InitQueue(); diff --git a/src/openrct2/scripting/bindings/world/ScPark.cpp b/src/openrct2/scripting/bindings/world/ScPark.cpp index 1f21a1c920..1d07f262e7 100644 --- a/src/openrct2/scripting/bindings/world/ScPark.cpp +++ b/src/openrct2/scripting/bindings/world/ScPark.cpp @@ -41,7 +41,6 @@ namespace OpenRCT2::Scripting { "difficultGuestGeneration", PARK_FLAGS_DIFFICULT_GUEST_GENERATION }, { "freeParkEntry", PARK_FLAGS_PARK_FREE_ENTRY }, { "difficultParkRating", PARK_FLAGS_DIFFICULT_PARK_RATING }, - { "noMoney", PARK_FLAGS_NO_MONEY_SCENARIO }, { "unlockAllPrices", PARK_FLAGS_UNLOCK_ALL_PRICES }, }); diff --git a/src/openrct2/world/Park.h b/src/openrct2/world/Park.h index d065282459..057a7ba2b7 100644 --- a/src/openrct2/world/Park.h +++ b/src/openrct2/world/Park.h @@ -34,7 +34,7 @@ enum : uint32_t PARK_FLAGS_PARK_FREE_ENTRY = (1 << 13), PARK_FLAGS_DIFFICULT_PARK_RATING = (1 << 14), PARK_FLAGS_LOCK_REAL_NAMES_OPTION_DEPRECATED = (1 << 15), // Deprecated now we use a persistent 'real names' setting - PARK_FLAGS_NO_MONEY_SCENARIO = (1 << 17), // equivalent to PARK_FLAGS_NO_MONEY, but used in scenario editor + PARK_FLAGS_NO_MONEY_SCENARIO = (1 << 17), // Deprecated, originally used in scenario editor PARK_FLAGS_SPRITES_INITIALISED = (1 << 18), // After a scenario is loaded this prevents edits in the scenario editor PARK_FLAGS_SIX_FLAGS_DEPRECATED = (1 << 19), // Not used anymore PARK_FLAGS_UNLOCK_ALL_PRICES = (1u << 31), // OpenRCT2 only! From 92fe3bf5e8848035fbf9c541f29c63b3363bd84b Mon Sep 17 00:00:00 2001 From: Ted John Date: Sat, 9 Apr 2022 12:36:47 +0100 Subject: [PATCH 4/4] Fix drawing of scenario editor buttons --- .../windows/EditorBottomToolbar.cpp | 219 ++++++++---------- 1 file changed, 95 insertions(+), 124 deletions(-) diff --git a/src/openrct2-ui/windows/EditorBottomToolbar.cpp b/src/openrct2-ui/windows/EditorBottomToolbar.cpp index 45001c8ee2..b3e6359ba7 100644 --- a/src/openrct2-ui/windows/EditorBottomToolbar.cpp +++ b/src/openrct2-ui/windows/EditorBottomToolbar.cpp @@ -352,141 +352,112 @@ void WindowEditorBottomToolbarInvalidate(rct_window* w) } } +static void WindowEditorBottomToolbarDrawLeftButtonBack(rct_window* w, rct_drawpixelinfo* dpi) +{ + auto previousWidget = w->widgets[WIDX_PREVIOUS_IMAGE]; + auto leftTop = w->windowPos + ScreenCoordsXY{ previousWidget.left, previousWidget.top }; + auto rightBottom = w->windowPos + ScreenCoordsXY{ previousWidget.right, previousWidget.bottom }; + gfx_filter_rect(dpi, { leftTop, rightBottom }, FilterPaletteID::Palette51); +} + +static void WindowEditorBottomToolbarDrawLeftButton(rct_window* w, rct_drawpixelinfo* dpi) +{ + const auto topLeft = w->windowPos + + ScreenCoordsXY{ w->widgets[WIDX_PREVIOUS_IMAGE].left + 1, w->widgets[WIDX_PREVIOUS_IMAGE].top + 1 }; + const auto bottomRight = w->windowPos + + ScreenCoordsXY{ w->widgets[WIDX_PREVIOUS_IMAGE].right - 1, w->widgets[WIDX_PREVIOUS_IMAGE].bottom - 1 }; + gfx_fill_rect_inset(dpi, { topLeft, bottomRight }, w->colours[1], INSET_RECT_F_30); + + gfx_draw_sprite( + dpi, ImageId(SPR_PREVIOUS), + w->windowPos + ScreenCoordsXY{ w->widgets[WIDX_PREVIOUS_IMAGE].left + 6, w->widgets[WIDX_PREVIOUS_IMAGE].top + 6 }); + + colour_t textColour = NOT_TRANSLUCENT(w->colours[1]); + if (gHoverWidget.window_classification == WC_BOTTOM_TOOLBAR && gHoverWidget.widget_index == WIDX_PREVIOUS_STEP_BUTTON) + { + textColour = COLOUR_WHITE; + } + + int16_t textX = (w->widgets[WIDX_PREVIOUS_IMAGE].left + 30 + w->widgets[WIDX_PREVIOUS_IMAGE].right) / 2 + w->windowPos.x; + int16_t textY = w->widgets[WIDX_PREVIOUS_IMAGE].top + 6 + w->windowPos.y; + + rct_string_id stringId = EditorStepNames[EnumValue(gEditorStep) - 1]; + if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) + stringId = STR_EDITOR_STEP_OBJECT_SELECTION; + + DrawTextBasic(dpi, { textX, textY }, STR_BACK_TO_PREVIOUS_STEP, {}, { textColour, TextAlignment::CENTRE }); + DrawTextBasic(dpi, { textX, textY + 10 }, stringId, {}, { textColour, TextAlignment::CENTRE }); +} + +static void WindowEditorBottomToolbarDrawRightButtonBack(rct_window* w, rct_drawpixelinfo* dpi) +{ + auto nextWidget = w->widgets[WIDX_NEXT_IMAGE]; + auto leftTop = w->windowPos + ScreenCoordsXY{ nextWidget.left, nextWidget.top }; + auto rightBottom = w->windowPos + ScreenCoordsXY{ nextWidget.right, nextWidget.bottom }; + gfx_filter_rect(dpi, { leftTop, rightBottom }, FilterPaletteID::Palette51); +} + +static void WindowEditorBottomToolbarDrawRightButton(rct_window* w, rct_drawpixelinfo* dpi) +{ + const auto topLeft = w->windowPos + + ScreenCoordsXY{ w->widgets[WIDX_NEXT_IMAGE].left + 1, w->widgets[WIDX_NEXT_IMAGE].top + 1 }; + const auto bottomRight = w->windowPos + + ScreenCoordsXY{ w->widgets[WIDX_NEXT_IMAGE].right - 1, w->widgets[WIDX_NEXT_IMAGE].bottom - 1 }; + gfx_fill_rect_inset(dpi, { topLeft, bottomRight }, w->colours[1], INSET_RECT_F_30); + + gfx_draw_sprite( + dpi, ImageId(SPR_NEXT), + w->windowPos + ScreenCoordsXY{ w->widgets[WIDX_NEXT_IMAGE].right - 29, w->widgets[WIDX_NEXT_IMAGE].top + 6 }); + + colour_t textColour = NOT_TRANSLUCENT(w->colours[1]); + + if (gHoverWidget.window_classification == WC_BOTTOM_TOOLBAR && gHoverWidget.widget_index == WIDX_NEXT_STEP_BUTTON) + { + textColour = COLOUR_WHITE; + } + + int16_t textX = (w->widgets[WIDX_NEXT_IMAGE].left + w->widgets[WIDX_NEXT_IMAGE].right - 30) / 2 + w->windowPos.x; + int16_t textY = w->widgets[WIDX_NEXT_IMAGE].top + 6 + w->windowPos.y; + + rct_string_id stringId = EditorStepNames[EnumValue(gEditorStep) + 1]; + if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) + stringId = STR_EDITOR_STEP_ROLLERCOASTER_DESIGNER; + + DrawTextBasic(dpi, { textX, textY }, STR_FORWARD_TO_NEXT_STEP, {}, { textColour, TextAlignment::CENTRE }); + DrawTextBasic(dpi, { textX, textY + 10 }, stringId, {}, { textColour, TextAlignment::CENTRE }); +} + +static void WindowEditorBottomToolbarDrawStepText(rct_window* w, rct_drawpixelinfo* dpi) +{ + int16_t stateX = (w->widgets[WIDX_PREVIOUS_IMAGE].right + w->widgets[WIDX_NEXT_IMAGE].left) / 2 + w->windowPos.x; + int16_t stateY = w->height - 0x0C + w->windowPos.y; + DrawTextBasic( + dpi, { stateX, stateY }, EditorStepNames[EnumValue(gEditorStep)], {}, + { static_cast(NOT_TRANSLUCENT(w->colours[2]) | COLOUR_FLAG_OUTLINE), TextAlignment::CENTRE }); +} + /** * * rct2: 0x0066F25C */ void WindowEditorBottomToolbarPaint(rct_window* w, rct_drawpixelinfo* dpi) { - bool drawPreviousButton = false; - bool drawNextButton = false; + auto drawPreviousButton = w->widgets[WIDX_PREVIOUS_STEP_BUTTON].type != WindowWidgetType::Empty; + auto drawNextButton = w->widgets[WIDX_NEXT_STEP_BUTTON].type != WindowWidgetType::Empty; - if (gEditorStep == EditorStep::ObjectSelection) - { - drawNextButton = true; - } - else if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) - { - drawPreviousButton = true; - } - else if (GetNumFreeEntities() != MAX_ENTITIES) - { - drawNextButton = true; - } - else if (gParkFlags & PARK_FLAGS_SPRITES_INITIALISED) - { - drawNextButton = true; - } - else - { - drawPreviousButton = true; - } + if (drawPreviousButton) + WindowEditorBottomToolbarDrawLeftButtonBack(w, dpi); - if (!(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER)) - { - auto previousWidget = window_editor_bottom_toolbar_widgets[WIDX_PREVIOUS_IMAGE]; - auto nextWidget = window_editor_bottom_toolbar_widgets[WIDX_NEXT_IMAGE]; - - if (drawPreviousButton) - { - auto leftTop = w->windowPos + ScreenCoordsXY{ previousWidget.left, previousWidget.top }; - auto rightBottom = w->windowPos + ScreenCoordsXY{ previousWidget.right, previousWidget.bottom }; - gfx_filter_rect(dpi, { leftTop, rightBottom }, FilterPaletteID::Palette51); - } - - if ((drawPreviousButton || drawNextButton) && gEditorStep != EditorStep::RollercoasterDesigner) - { - auto leftTop = w->windowPos + ScreenCoordsXY{ nextWidget.left, nextWidget.top }; - auto rightBottom = w->windowPos + ScreenCoordsXY{ nextWidget.right, nextWidget.bottom }; - gfx_filter_rect(dpi, { leftTop, rightBottom }, FilterPaletteID::Palette51); - } - } + if (drawNextButton) + WindowEditorBottomToolbarDrawRightButtonBack(w, dpi); WindowDrawWidgets(w, dpi); - if (!(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER)) - { - const auto topLeft = w->windowPos - + ScreenCoordsXY{ window_editor_bottom_toolbar_widgets[WIDX_PREVIOUS_IMAGE].left + 1, - window_editor_bottom_toolbar_widgets[WIDX_PREVIOUS_IMAGE].top + 1 }; - const auto bottomRight = w->windowPos - + ScreenCoordsXY{ window_editor_bottom_toolbar_widgets[WIDX_PREVIOUS_IMAGE].right - 1, - window_editor_bottom_toolbar_widgets[WIDX_PREVIOUS_IMAGE].bottom - 1 }; - if (drawPreviousButton) - { - gfx_fill_rect_inset(dpi, { topLeft, bottomRight }, w->colours[1], INSET_RECT_F_30); - } + if (drawPreviousButton) + WindowEditorBottomToolbarDrawLeftButton(w, dpi); - if ((drawPreviousButton || drawNextButton) && gEditorStep != EditorStep::RollercoasterDesigner) - { - gfx_fill_rect_inset(dpi, { topLeft, bottomRight }, w->colours[1], INSET_RECT_F_30); - } + if (drawNextButton) + WindowEditorBottomToolbarDrawRightButton(w, dpi); - int16_t stateX = (window_editor_bottom_toolbar_widgets[WIDX_PREVIOUS_IMAGE].right - + window_editor_bottom_toolbar_widgets[WIDX_NEXT_IMAGE].left) - / 2 - + w->windowPos.x; - int16_t stateY = w->height - 0x0C + w->windowPos.y; - DrawTextBasic( - dpi, { stateX, stateY }, EditorStepNames[EnumValue(gEditorStep)], {}, - { static_cast(NOT_TRANSLUCENT(w->colours[2]) | COLOUR_FLAG_OUTLINE), TextAlignment::CENTRE }); - - if (drawPreviousButton) - { - gfx_draw_sprite( - dpi, ImageId(SPR_PREVIOUS), - w->windowPos - + ScreenCoordsXY{ window_editor_bottom_toolbar_widgets[WIDX_PREVIOUS_IMAGE].left + 6, - window_editor_bottom_toolbar_widgets[WIDX_PREVIOUS_IMAGE].top + 6 }); - - colour_t textColour = NOT_TRANSLUCENT(w->colours[1]); - if (gHoverWidget.window_classification == WC_BOTTOM_TOOLBAR - && gHoverWidget.widget_index == WIDX_PREVIOUS_STEP_BUTTON) - { - textColour = COLOUR_WHITE; - } - - int16_t textX = (window_editor_bottom_toolbar_widgets[WIDX_PREVIOUS_IMAGE].left + 30 - + window_editor_bottom_toolbar_widgets[WIDX_PREVIOUS_IMAGE].right) - / 2 - + w->windowPos.x; - int16_t textY = window_editor_bottom_toolbar_widgets[WIDX_PREVIOUS_IMAGE].top + 6 + w->windowPos.y; - - rct_string_id stringId = EditorStepNames[EnumValue(gEditorStep) - 1]; - if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) - stringId = STR_EDITOR_STEP_OBJECT_SELECTION; - - DrawTextBasic(dpi, { textX, textY }, STR_BACK_TO_PREVIOUS_STEP, {}, { textColour, TextAlignment::CENTRE }); - DrawTextBasic(dpi, { textX, textY + 10 }, stringId, {}, { textColour, TextAlignment::CENTRE }); - } - - if ((drawPreviousButton || drawNextButton) && gEditorStep != EditorStep::RollercoasterDesigner) - { - gfx_draw_sprite( - dpi, ImageId(SPR_NEXT), - w->windowPos - + ScreenCoordsXY{ window_editor_bottom_toolbar_widgets[WIDX_NEXT_IMAGE].right - 29, - window_editor_bottom_toolbar_widgets[WIDX_NEXT_IMAGE].top + 6 }); - - colour_t textColour = NOT_TRANSLUCENT(w->colours[1]); - - if (gHoverWidget.window_classification == WC_BOTTOM_TOOLBAR && gHoverWidget.widget_index == WIDX_NEXT_STEP_BUTTON) - { - textColour = COLOUR_WHITE; - } - - int16_t textX = (window_editor_bottom_toolbar_widgets[WIDX_NEXT_IMAGE].left - + window_editor_bottom_toolbar_widgets[WIDX_NEXT_IMAGE].right - 30) - / 2 - + w->windowPos.x; - int16_t textY = window_editor_bottom_toolbar_widgets[WIDX_NEXT_IMAGE].top + 6 + w->windowPos.y; - - rct_string_id stringId = EditorStepNames[EnumValue(gEditorStep) + 1]; - if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) - stringId = STR_EDITOR_STEP_ROLLERCOASTER_DESIGNER; - - DrawTextBasic(dpi, { textX, textY }, STR_FORWARD_TO_NEXT_STEP, {}, { textColour, TextAlignment::CENTRE }); - DrawTextBasic(dpi, { textX, textY + 10 }, stringId, {}, { textColour, TextAlignment::CENTRE }); - } - } + WindowEditorBottomToolbarDrawStepText(w, dpi); }