From b0b050d42f8b6c7bae8cdebe07d97e06e5bf9b59 Mon Sep 17 00:00:00 2001 From: Aaron van Geffen Date: Thu, 20 Mar 2025 16:37:47 +0100 Subject: [PATCH] Add extra editor step for entering scenario details --- data/language/en-GB.txt | 1 + src/openrct2-ui/UiStringIds.h | 1 + .../windows/EditorBottomToolbar.cpp | 71 ++++++---- .../windows/EditorScenarioOptions.cpp | 123 ++++++++++-------- src/openrct2/Editor.cpp | 3 +- src/openrct2/Editor.h | 7 +- src/openrct2/ride/Ride.cpp | 1 + 7 files changed, 130 insertions(+), 77 deletions(-) diff --git a/data/language/en-GB.txt b/data/language/en-GB.txt index eb98e6bd33..8317ea44a4 100644 --- a/data/language/en-GB.txt +++ b/data/language/en-GB.txt @@ -3805,3 +3805,4 @@ STR_6757 :Show land restriction options STR_6758 :Loan options STR_6759 :Business model STR_6760 :Earnings: +STR_6761 :Scenario Details diff --git a/src/openrct2-ui/UiStringIds.h b/src/openrct2-ui/UiStringIds.h index f1aae049ca..13744c1221 100644 --- a/src/openrct2-ui/UiStringIds.h +++ b/src/openrct2-ui/UiStringIds.h @@ -473,6 +473,7 @@ namespace OpenRCT2 STR_EDITOR_STEP_OPTIONS_SELECTION = 3204, STR_EDITOR_STEP_ROLLERCOASTER_DESIGNER = 3207, STR_EDITOR_STEP_SAVE_SCENARIO = 3206, + STR_EDITOR_STEP_SCENARIO_DETAILS = 6761, STR_EDITOR_STEP_TRACK_DESIGNS_MANAGER = 3208, STR_FORWARD_TO_NEXT_STEP = 3210, STR_UNABLE_TO_SAVE_SCENARIO_FILE = 3320, diff --git a/src/openrct2-ui/windows/EditorBottomToolbar.cpp b/src/openrct2-ui/windows/EditorBottomToolbar.cpp index 5d16d85264..60d9fe48ff 100644 --- a/src/openrct2-ui/windows/EditorBottomToolbar.cpp +++ b/src/openrct2-ui/windows/EditorBottomToolbar.cpp @@ -53,10 +53,15 @@ namespace OpenRCT2::Ui::Windows using FuncPtr = void (EditorBottomToolbarWindow::*)() const; static constexpr StringId kEditorStepNames[] = { - STR_EDITOR_STEP_OBJECT_SELECTION, STR_EDITOR_STEP_LANDSCAPE_EDITOR, - STR_EDITOR_STEP_INVENTIONS_LIST_SET_UP, STR_EDITOR_STEP_OPTIONS_SELECTION, - STR_EDITOR_STEP_OBJECTIVE_SELECTION, STR_EDITOR_STEP_SAVE_SCENARIO, - STR_EDITOR_STEP_ROLLERCOASTER_DESIGNER, STR_EDITOR_STEP_TRACK_DESIGNS_MANAGER, + STR_EDITOR_STEP_OBJECT_SELECTION, // EditorStep::ObjectSelection + STR_EDITOR_STEP_LANDSCAPE_EDITOR, // EditorStep::LandscapeEditor + STR_EDITOR_STEP_INVENTIONS_LIST_SET_UP, // EditorStep::InventionsListSetUp + STR_EDITOR_STEP_OPTIONS_SELECTION, // EditorStep::OptionsSelection + STR_EDITOR_STEP_OBJECTIVE_SELECTION, // EditorStep::ObjectiveSelection + STR_EDITOR_STEP_SCENARIO_DETAILS, // EditorStep::ScenarioDetails + STR_EDITOR_STEP_SAVE_SCENARIO, // EditorStep::SaveScenario + STR_EDITOR_STEP_ROLLERCOASTER_DESIGNER, // EditorStep::RollercoasterDesigner + STR_EDITOR_STEP_TRACK_DESIGNS_MANAGER, // EditorStep::DesignsManager }; public: @@ -178,6 +183,16 @@ namespace OpenRCT2::Ui::Windows GfxInvalidateScreen(); } + void JumpBackToObjectiveSelection() const + { + auto* windowMgr = Ui::GetWindowManager(); + windowMgr->CloseAll(); + + ContextOpenWindow(WindowClass::EditorScenarioOptions); + getGameState().editorStep = EditorStep::ObjectiveSelection; + GfxInvalidateScreen(); + } + void JumpBackToOptionsSelection() const { auto* windowMgr = Ui::GetWindowManager(); @@ -226,6 +241,16 @@ namespace OpenRCT2::Ui::Windows GfxInvalidateScreen(); } + void JumpForwardToObjectiveSelection() const + { + auto* windowMgr = Ui::GetWindowManager(); + windowMgr->CloseAll(); + + ContextOpenWindow(WindowClass::EditorScenarioOptions); + getGameState().editorStep = EditorStep::ObjectiveSelection; + GfxInvalidateScreen(); + } + void JumpForwardToOptionsSelection() const { auto* windowMgr = Ui::GetWindowManager(); @@ -236,13 +261,13 @@ namespace OpenRCT2::Ui::Windows GfxInvalidateScreen(); } - void JumpForwardToObjectiveSelection() const + void JumpForwardToScenarioDetails() const { auto* windowMgr = Ui::GetWindowManager(); windowMgr->CloseAll(); ContextOpenWindow(WindowClass::EditorScenarioOptions); - getGameState().editorStep = EditorStep::ObjectiveSelection; + getGameState().editorStep = EditorStep::ScenarioDetails; GfxInvalidateScreen(); } @@ -377,25 +402,27 @@ namespace OpenRCT2::Ui::Windows } static constexpr FuncPtr kPreviousButtonMouseUp[] = { - nullptr, - &EditorBottomToolbarWindow::JumpBackToObjectSelection, - &EditorBottomToolbarWindow::JumpBackToLandscapeEditor, - &EditorBottomToolbarWindow::JumpBackToInventionListSetUp, - &EditorBottomToolbarWindow::JumpBackToOptionsSelection, - nullptr, - &EditorBottomToolbarWindow::JumpBackToObjectSelection, - nullptr, + /* ObjectSelection */ nullptr, + /* LandscapeEditor */ &EditorBottomToolbarWindow::JumpBackToObjectSelection, + /* InventionsListSetUp */ &EditorBottomToolbarWindow::JumpBackToLandscapeEditor, + /* OptionsSelection */ &EditorBottomToolbarWindow::JumpBackToInventionListSetUp, + /* ObjectiveSelection */ &EditorBottomToolbarWindow::JumpBackToOptionsSelection, + /* ScenarioDetails */ &EditorBottomToolbarWindow::JumpBackToObjectiveSelection, + /* SaveScenario */ nullptr, + /* RollercoasterDesigner */ &EditorBottomToolbarWindow::JumpBackToObjectSelection, + /* DesignsManager */ nullptr, }; static constexpr FuncPtr kNextButtonMouseUp[] = { - &EditorBottomToolbarWindow::JumpForwardFromObjectSelection, - &EditorBottomToolbarWindow::JumpForwardToInventionListSetUp, - &EditorBottomToolbarWindow::JumpForwardToOptionsSelection, - &EditorBottomToolbarWindow::JumpForwardToObjectiveSelection, - &EditorBottomToolbarWindow::JumpForwardToSaveScenario, - nullptr, - nullptr, - nullptr, + /* ObjectSelection */ &EditorBottomToolbarWindow::JumpForwardFromObjectSelection, + /* LandscapeEditor */ &EditorBottomToolbarWindow::JumpForwardToInventionListSetUp, + /* InventionsListSetUp */ &EditorBottomToolbarWindow::JumpForwardToOptionsSelection, + /* OptionsSelection */ &EditorBottomToolbarWindow::JumpForwardToObjectiveSelection, + /* ObjectiveSelection */ &EditorBottomToolbarWindow::JumpForwardToScenarioDetails, + /* ScenarioDetails */ &EditorBottomToolbarWindow::JumpForwardToSaveScenario, + /* SaveScenario */ nullptr, + /* RollercoasterDesigner */ nullptr, + /* DesignsManager */ nullptr, }; }; diff --git a/src/openrct2-ui/windows/EditorScenarioOptions.cpp b/src/openrct2-ui/windows/EditorScenarioOptions.cpp index ab37fa2602..ad49ed8944 100644 --- a/src/openrct2-ui/windows/EditorScenarioOptions.cpp +++ b/src/openrct2-ui/windows/EditorScenarioOptions.cpp @@ -509,25 +509,51 @@ namespace OpenRCT2::Ui::Windows } private: + /** + * + * rct2: 0x00672609 + */ + bool AnyRidesExist() + { + // Check if there are any rides (not shops or facilities) + const auto& rideManager = GetRideManager(); + return std::any_of( + rideManager.begin(), rideManager.end(), [](const Ride& rideToCheck) { return rideToCheck.isRide(); }); + } + void HideUnavailableTabs() { if (gLegacyScene != LegacyScene::scenarioEditor) return; - // Disable tabs based on current editor step auto step = getGameState().editorStep; - SetWidgetDisabled(WIDX_TAB_1, step == EditorStep::ObjectiveSelection); - for (auto i = 1; i < WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_COUNT; i++) - SetWidgetDisabled(WIDX_TAB_1 + i, step == EditorStep::SaveScenario); + bool isObjectiveSelection = step == EditorStep::ObjectiveSelection; + bool isScenarioDetails = step == EditorStep::ScenarioDetails; + bool isOtherTab = !isObjectiveSelection && !isScenarioDetails; + + // Disable tabs based on current editor step + SetWidgetDisabled(WIDX_TAB_1, !isObjectiveSelection); + SetWidgetDisabled(WIDX_TAB_2, !isScenarioDetails); + for (auto i = 2; i < WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_COUNT; i++) + SetWidgetDisabled(WIDX_TAB_1 + i, !isOtherTab); + + SetWidgetDisabled(WIDX_TAB_6, !(isOtherTab && AnyRidesExist())); // Reposition tabs based on availability so there are no gaps + widgets[WIDX_TAB_1].left = 3; + widgets[WIDX_TAB_1].right = widgets[WIDX_TAB_1].left + 30; WindowAlignTabs(this, WIDX_TAB_1, WIDX_TAB_6); // Switch tabs if our current tab has become unavailable - if (WidgetIsDisabled(*this, WIDX_TAB_1) && page == WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_OBJECTIVE) - SetPage(WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_SCENARIO_INFO); - else if (!WidgetIsDisabled(*this, WIDX_TAB_1) && page != WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_OBJECTIVE) - SetPage(WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_OBJECTIVE); + if (IsWidgetDisabled(WIDX_TAB_1 + page)) + { + if (isObjectiveSelection) + SetPage(WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_OBJECTIVE); + else if (isScenarioDetails) + SetPage(WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_SCENARIO_DETAILS); + else + SetPage(WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_FINANCIAL); + } } void SetPressedTab() @@ -549,41 +575,56 @@ namespace OpenRCT2::Ui::Windows int32_t spriteIndex; // Tab 1 - widget = &widgets[WIDX_TAB_1]; - spriteIndex = SPR_TAB_OBJECTIVE_0; - if (page == WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_OBJECTIVE) - spriteIndex += (frame_no / 4) % 16; + if (!IsWidgetDisabled(WIDX_TAB_1)) + { + widget = &widgets[WIDX_TAB_1]; + spriteIndex = SPR_TAB_OBJECTIVE_0; + if (page == WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_OBJECTIVE) + spriteIndex += (frame_no / 4) % 16; - GfxDrawSprite(dpi, ImageId(spriteIndex), windowPos + ScreenCoordsXY{ widget->left, widget->top }); + GfxDrawSprite(dpi, ImageId(spriteIndex), windowPos + ScreenCoordsXY{ widget->left, widget->top }); + } // Tab 2 - widget = &widgets[WIDX_TAB_2]; - spriteIndex = SPR_TAB_KIOSKS_AND_FACILITIES_0; - if (page == WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_SCENARIO_DETAILS) - spriteIndex += (frame_no / 4) % 8; + if (!IsWidgetDisabled(WIDX_TAB_2)) + { + widget = &widgets[WIDX_TAB_2]; + spriteIndex = SPR_TAB_KIOSKS_AND_FACILITIES_0; + if (page == WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_SCENARIO_DETAILS) + spriteIndex += (frame_no / 4) % 8; - GfxDrawSprite(dpi, ImageId(spriteIndex), windowPos + ScreenCoordsXY{ widget->left, widget->top }); + GfxDrawSprite(dpi, ImageId(spriteIndex), windowPos + ScreenCoordsXY{ widget->left, widget->top }); + } // Tab 3 - widget = &widgets[WIDX_TAB_3]; - spriteIndex = SPR_TAB_FINANCES_SUMMARY_0; - if (page == WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_FINANCIAL) - spriteIndex += (frame_no / 2) % 8; + if (!IsWidgetDisabled(WIDX_TAB_3)) + { + widget = &widgets[WIDX_TAB_3]; + spriteIndex = SPR_TAB_FINANCES_SUMMARY_0; + if (page == WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_FINANCIAL) + spriteIndex += (frame_no / 2) % 8; - GfxDrawSprite(dpi, ImageId(spriteIndex), windowPos + ScreenCoordsXY{ widget->left, widget->top }); + GfxDrawSprite(dpi, ImageId(spriteIndex), windowPos + ScreenCoordsXY{ widget->left, widget->top }); + } // Tab 4 - widget = &widgets[WIDX_TAB_4]; - spriteIndex = SPR_TAB_GUESTS_0; - if (page == WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_GUESTS) - spriteIndex += (frame_no / 4) % 8; + if (!IsWidgetDisabled(WIDX_TAB_4)) + { + widget = &widgets[WIDX_TAB_4]; + spriteIndex = SPR_TAB_GUESTS_0; + if (page == WINDOW_EDITOR_SCENARIO_OPTIONS_PAGE_GUESTS) + spriteIndex += (frame_no / 4) % 8; - GfxDrawSprite(dpi, ImageId(spriteIndex), windowPos + ScreenCoordsXY{ widget->left, widget->top }); + GfxDrawSprite(dpi, ImageId(spriteIndex), windowPos + ScreenCoordsXY{ widget->left, widget->top }); + } // Tab 5 - widget = &widgets[WIDX_TAB_5]; - spriteIndex = SPR_G2_MAP_GEN_TERRAIN_TAB; - GfxDrawSprite(dpi, ImageId(spriteIndex), windowPos + ScreenCoordsXY{ widget->left, widget->top }); + if (!IsWidgetDisabled(WIDX_TAB_5)) + { + widget = &widgets[WIDX_TAB_5]; + spriteIndex = SPR_G2_MAP_GEN_TERRAIN_TAB; + GfxDrawSprite(dpi, ImageId(spriteIndex), windowPos + ScreenCoordsXY{ widget->left, widget->top }); + } // Tab 6 if (!IsWidgetDisabled(WIDX_TAB_6)) @@ -611,32 +652,12 @@ namespace OpenRCT2::Ui::Windows SetWidgets(window_editor_scenario_options_widgets[page]); Invalidate(); - UpdateDisabledWidgets(); OnResize(); OnPrepareDraw(); InitScrollWidgets(); Invalidate(); } - /** - * - * rct2: 0x00672609 - */ - void UpdateDisabledWidgets() - { - // Check if there are any rides (not shops or facilities) - const auto& rideManager = GetRideManager(); - if (std::any_of( - rideManager.begin(), rideManager.end(), [](const Ride& rideToCheck) { return rideToCheck.isRide(); })) - { - disabled_widgets &= ~(1uLL << WIDX_TAB_6); - } - else - { - disabled_widgets |= (1uLL << WIDX_TAB_6); - } - } - #pragma region Objective /** diff --git a/src/openrct2/Editor.cpp b/src/openrct2/Editor.cpp index 12855c2d2f..8941ce5cdd 100644 --- a/src/openrct2/Editor.cpp +++ b/src/openrct2/Editor.cpp @@ -151,7 +151,7 @@ namespace OpenRCT2::Editor ScenarioReset(gameState); gLegacyScene = LegacyScene::scenarioEditor; - gameState.editorStep = EditorStep::ObjectiveSelection; + gameState.editorStep = EditorStep::OptionsSelection; gameState.scenarioCategory = ScenarioCategory::other; ViewportInitAll(); OpenEditorWindows(); @@ -372,6 +372,7 @@ namespace OpenRCT2::Editor break; case EditorStep::OptionsSelection: case EditorStep::ObjectiveSelection: + case EditorStep::ScenarioDetails: if (windowMgr->FindByClass(WindowClass::EditorScenarioOptions) != nullptr) { return; diff --git a/src/openrct2/Editor.h b/src/openrct2/Editor.h index 61751b9121..6281cee5cf 100644 --- a/src/openrct2/Editor.h +++ b/src/openrct2/Editor.h @@ -38,9 +38,10 @@ enum class EditorStep : uint8_t InventionsListSetUp, // 2 OptionsSelection, // 3 ObjectiveSelection, // 4 - SaveScenario, // 5 - RollercoasterDesigner, // 6 - DesignsManager, // 7 + ScenarioDetails, // 5 + SaveScenario, // 6 + RollercoasterDesigner, // 7 + DesignsManager, // 8 Invalid = 255, // 255 }; diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index db60d1142b..d4b1257cbb 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -973,6 +973,7 @@ void Ride::updateAll() break; case EditorStep::OptionsSelection: case EditorStep::ObjectiveSelection: + case EditorStep::ScenarioDetails: case EditorStep::SaveScenario: case EditorStep::RollercoasterDesigner: case EditorStep::DesignsManager: