1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-24 00:03:11 +01:00

Add extra editor step for entering scenario details

This commit is contained in:
Aaron van Geffen
2025-03-20 16:37:47 +01:00
parent 50f58d4c4f
commit b0b050d42f
7 changed files with 130 additions and 77 deletions

View File

@@ -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

View File

@@ -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,

View File

@@ -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,
};
};

View File

@@ -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
/**

View File

@@ -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;

View File

@@ -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
};

View File

@@ -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: