mirror of https://github.com/OpenRCT2/OpenRCT2.git
Feature: "Load Scenario" title sequence command
New command goes by LOADSC in script files and in the enumeration. Scenarios are stored using the internal also used for localisation. Scenarios selected can only be scenarios to originally come with one of the games or expansions. Modified Scenario Select window to have a mode just for title editor scenario selection.
This commit is contained in:
parent
ec69af0410
commit
92fc010b9a
|
@ -4480,6 +4480,14 @@ STR_6170 :Tweaks
|
|||
STR_6171 :Search
|
||||
STR_6172 :{SMALLFONT}{BLACK}Search
|
||||
STR_6173 :Please provide the name to search:
|
||||
STR_6174 :Load Save
|
||||
STR_6175 :Load Scenario
|
||||
STR_6176 :Scenario to load:
|
||||
STR_6177 :Load{MOVE_X}{87}No scenario selected
|
||||
STR_6178 :Load{MOVE_X}{87}{RED}Missing scenario
|
||||
STR_6179 :Select
|
||||
STR_6180 :No scenario selected
|
||||
STR_6181 :{RED}Missing scenario
|
||||
|
||||
#############
|
||||
# Scenarios #
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
- Feature: Allow using object files from RCT Classic.
|
||||
- Feature: Title sequences now testable in-game.
|
||||
- Feature: Vehicles with matching capabilities are now always switchable.
|
||||
- Feature: Add search box to track design window.
|
||||
- Feature: Add load scenario command to title sequences.
|
||||
- Fix: [#816] In the map window, there are more peeps flickering than there are selected (original bug).
|
||||
- Fix: [#996, #2589, #2875] Viewport scrolling no longer shakes or gets stuck.
|
||||
- Fix: [#1185] Close button colour of prompt windows does not match.
|
||||
|
|
|
@ -247,7 +247,7 @@ public:
|
|||
return window_track_list_open(rideItem);
|
||||
}
|
||||
case WC_SCENARIO_SELECT:
|
||||
return window_scenarioselect_open((scenarioselect_callback) intent->GetPointerExtra(INTENT_EXTRA_CALLBACK));
|
||||
return window_scenarioselect_open((scenarioselect_callback) intent->GetPointerExtra(INTENT_EXTRA_CALLBACK), false);
|
||||
case WD_VEHICLE:
|
||||
return window_ride_open_vehicle((rct_vehicle *) intent->GetPointerExtra(INTENT_EXTRA_VEHICLE));
|
||||
case WD_TRACK:
|
||||
|
|
|
@ -221,7 +221,7 @@ static void window_server_start_mouseup(rct_window *w, rct_widgetindex widgetInd
|
|||
window_invalidate(w);
|
||||
break;
|
||||
case WIDX_START_SERVER:
|
||||
window_scenarioselect_open(window_server_start_scenarioselect_callback);
|
||||
window_scenarioselect_open(window_server_start_scenarioselect_callback, false);
|
||||
break;
|
||||
case WIDX_LOAD_SERVER:
|
||||
network_set_password(_password);
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include <openrct2/interface/themes.h>
|
||||
#include <openrct2/interface/viewport.h>
|
||||
#include <openrct2/interface/widget.h>
|
||||
#include <openrct2/scenario/ScenarioRepository.h>
|
||||
#include <openrct2/scenario/ScenarioSources.h>
|
||||
#include <openrct2/localisation/localisation.h>
|
||||
#include <openrct2/util/Util.h>
|
||||
#include <openrct2-ui/interface/Dropdown.h>
|
||||
|
@ -36,7 +38,8 @@ typedef struct TITLE_COMMAND_ORDER {
|
|||
} TITLE_COMMAND_ORDER;
|
||||
|
||||
static TITLE_COMMAND_ORDER _window_title_command_editor_orders[] = {
|
||||
{ TITLE_SCRIPT_LOAD, STR_TITLE_EDITOR_ACTION_LOAD, STR_TITLE_EDITOR_ARGUMENT_SAVEFILE },
|
||||
{ TITLE_SCRIPT_LOAD, STR_TITLE_EDITOR_ACTION_LOAD_SAVE, STR_TITLE_EDITOR_ARGUMENT_SAVEFILE },
|
||||
{ TITLE_SCRIPT_LOADSC, STR_TITLE_EDITOR_ACTION_LOAD_SCENARIO, STR_TITLE_EDITOR_ARGUMENT_SCENARIO },
|
||||
{ TITLE_SCRIPT_LOCATION, STR_TITLE_EDITOR_COMMAND_TYPE_LOCATION, STR_TITLE_EDITOR_ARGUMENT_COORDINATES },
|
||||
{ TITLE_SCRIPT_ROTATE, STR_TITLE_EDITOR_COMMAND_TYPE_ROTATE, STR_TITLE_EDITOR_ARGUMENT_ROTATIONS },
|
||||
{ TITLE_SCRIPT_ZOOM, STR_TITLE_EDITOR_COMMAND_TYPE_ZOOM, STR_TITLE_EDITOR_ARGUMENT_ZOOM_LEVEL },
|
||||
|
@ -46,7 +49,7 @@ static TITLE_COMMAND_ORDER _window_title_command_editor_orders[] = {
|
|||
{ TITLE_SCRIPT_END, STR_TITLE_EDITOR_END, STR_NONE },
|
||||
};
|
||||
|
||||
#define NUM_COMMANDS 8
|
||||
#define NUM_COMMANDS 9
|
||||
|
||||
enum WINDOW_WATER_WIDGET_IDX {
|
||||
WIDX_BACKGROUND,
|
||||
|
@ -60,6 +63,7 @@ enum WINDOW_WATER_WIDGET_IDX {
|
|||
WIDX_INPUT,
|
||||
WIDX_INPUT_DROPDOWN,
|
||||
WIDX_GET,
|
||||
WIDX_SELECT,
|
||||
WIDX_OKAY,
|
||||
WIDX_CANCEL
|
||||
};
|
||||
|
@ -94,6 +98,7 @@ static rct_widget window_title_command_editor_widgets[] = {
|
|||
{ WWT_DROPDOWN_BUTTON, 1, WW-28, WW-18, BY2+1, BY2+10, STR_DROPDOWN_GLYPH, STR_NONE },
|
||||
|
||||
{ WWT_DROPDOWN_BUTTON, 1, WS+WHA+3, WW-WS-1, BY2-14, BY2-3, STR_TITLE_COMMAND_EDITOR_ACTION_GET_LOCATION, STR_NONE }, // Get location/zoom/etc
|
||||
{ WWT_DROPDOWN_BUTTON, 1, WS+WHA+12, WW-WS-1, BY2-14, BY2-3, STR_TITLE_COMMAND_EDITOR_ACTION_SELECT_SCENARIO, STR_NONE }, // Select scenario
|
||||
|
||||
{ WWT_DROPDOWN_BUTTON, 1, 10, 80, WH-21, WH-10, STR_OK, STR_NONE }, // OKAY
|
||||
{ WWT_DROPDOWN_BUTTON, 1, WW-80, WW-10, WH-21, WH-10, STR_CANCEL, STR_NONE }, // Cancel
|
||||
|
@ -109,6 +114,7 @@ static void window_title_command_editor_invalidate(rct_window * w);
|
|||
static void window_title_command_editor_paint(rct_window * w, rct_drawpixelinfo * dpi);
|
||||
static void window_title_command_editor_textinput(rct_window * w, rct_widgetindex widgetIndex, char * text);
|
||||
static void window_title_command_editor_inputsize(rct_window * w);
|
||||
static void scenario_select_callback(const utf8 * path);
|
||||
static sint32 get_command_info_index(sint32 index);
|
||||
static TITLE_COMMAND_ORDER get_command_info(sint32 index);
|
||||
static LocationXY16 get_location();
|
||||
|
@ -145,6 +151,16 @@ static rct_window_event_list window_title_command_editor_events = {
|
|||
nullptr
|
||||
};
|
||||
|
||||
static void scenario_select_callback(const utf8 * path)
|
||||
{
|
||||
if (command.Type == TITLE_SCRIPT_LOADSC)
|
||||
{
|
||||
const utf8 * fileName = path_get_filename(path);
|
||||
auto scenario = GetScenarioRepository()->GetByFilename(fileName);
|
||||
safe_strcpy(command.Scenario, scenario->internal_name, sizeof(command.Scenario));
|
||||
}
|
||||
}
|
||||
|
||||
static sint32 get_command_info_index(sint32 index)
|
||||
{
|
||||
for (sint32 i = 0; i < NUM_COMMANDS; i++)
|
||||
|
@ -225,6 +241,7 @@ void window_title_command_editor_open(TitleSequence * sequence, sint32 index, bo
|
|||
(1 << WIDX_INPUT) |
|
||||
(1 << WIDX_INPUT_DROPDOWN) |
|
||||
(1 << WIDX_GET) |
|
||||
(1 << WIDX_SELECT) |
|
||||
(1 << WIDX_OKAY) |
|
||||
(1 << WIDX_CANCEL);
|
||||
window_init_scroll_widgets(window);
|
||||
|
@ -298,6 +315,9 @@ static void window_title_command_editor_mouseup(rct_window * w, rct_widgetindex
|
|||
}
|
||||
window_invalidate(w);
|
||||
break;
|
||||
case WIDX_SELECT:
|
||||
window_scenarioselect_open(scenario_select_callback, true);
|
||||
break;
|
||||
case WIDX_OKAY:
|
||||
if (_window_title_command_editor_insert)
|
||||
{
|
||||
|
@ -446,6 +466,8 @@ static void window_title_command_editor_dropdown(rct_window * w, rct_widgetindex
|
|||
command.SaveIndex = 0xFF;
|
||||
}
|
||||
break;
|
||||
case TITLE_SCRIPT_LOADSC:
|
||||
command.Scenario[0] = '\0';
|
||||
}
|
||||
window_invalidate(w);
|
||||
break;
|
||||
|
@ -561,6 +583,7 @@ static void window_title_command_editor_invalidate(rct_window * w)
|
|||
window_title_command_editor_widgets[WIDX_INPUT].type = WWT_EMPTY;
|
||||
window_title_command_editor_widgets[WIDX_INPUT_DROPDOWN].type = WWT_EMPTY;
|
||||
window_title_command_editor_widgets[WIDX_GET].type = WWT_EMPTY;
|
||||
window_title_command_editor_widgets[WIDX_SELECT].type = WWT_EMPTY;
|
||||
switch (command.Type)
|
||||
{
|
||||
case TITLE_SCRIPT_LOAD:
|
||||
|
@ -568,6 +591,10 @@ static void window_title_command_editor_invalidate(rct_window * w)
|
|||
window_title_command_editor_widgets[WIDX_INPUT].type = WWT_DROPDOWN;
|
||||
window_title_command_editor_widgets[WIDX_INPUT_DROPDOWN].type = WWT_DROPDOWN_BUTTON;
|
||||
break;
|
||||
case TITLE_SCRIPT_LOADSC:
|
||||
window_title_command_editor_widgets[WIDX_INPUT].type = WWT_DROPDOWN;
|
||||
window_title_command_editor_widgets[WIDX_SELECT].type = WWT_DROPDOWN_BUTTON;
|
||||
break;
|
||||
case TITLE_SCRIPT_LOCATION:
|
||||
window_title_command_editor_widgets[WIDX_TEXTBOX_X].type = WWT_TEXT_BOX;
|
||||
window_title_command_editor_widgets[WIDX_TEXTBOX_Y].type = WWT_TEXT_BOX;
|
||||
|
@ -642,4 +669,42 @@ static void window_title_command_editor_paint(rct_window * w, rct_drawpixelinfo
|
|||
w->widgets[WIDX_INPUT_DROPDOWN].left - w->widgets[WIDX_INPUT].left - 4);
|
||||
}
|
||||
}
|
||||
else if (command.Type == TITLE_SCRIPT_LOADSC)
|
||||
{
|
||||
if (command.Scenario[0] == '\0')
|
||||
{
|
||||
gfx_draw_string_left_clipped(
|
||||
dpi,
|
||||
STR_TITLE_COMMAND_EDITOR_NO_SCENARIO_SELECTED,
|
||||
nullptr,
|
||||
w->colours[1],
|
||||
w->x + w->widgets[WIDX_INPUT].left + 1,
|
||||
w->y + w->widgets[WIDX_INPUT].top,
|
||||
w->widgets[WIDX_INPUT_DROPDOWN].left - w->widgets[WIDX_INPUT].left - 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char * name = "";
|
||||
rct_string_id nameString = STR_STRING;
|
||||
auto scenario =
|
||||
GetScenarioRepository()->GetByInternalName(command.Scenario);
|
||||
if (scenario != nullptr)
|
||||
{
|
||||
name = scenario->name;
|
||||
}
|
||||
else
|
||||
{
|
||||
nameString = STR_TITLE_COMMAND_EDITOR_MISSING_SCENARIO;
|
||||
}
|
||||
set_format_arg(0, uintptr_t, name);
|
||||
gfx_draw_string_left_clipped(
|
||||
dpi,
|
||||
nameString,
|
||||
gCommonFormatArgs,
|
||||
w->colours[1],
|
||||
w->x + w->widgets[WIDX_INPUT].left + 1,
|
||||
w->y + w->widgets[WIDX_INPUT].top,
|
||||
w->widgets[WIDX_INPUT_DROPDOWN].left - w->widgets[WIDX_INPUT].left - 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1002,6 +1002,27 @@ static void window_title_editor_scrollpaint_commands(rct_window * w, rct_drawpix
|
|||
set_format_arg(0, uintptr_t, name);
|
||||
break;
|
||||
}
|
||||
case TITLE_SCRIPT_LOADSC:
|
||||
{
|
||||
commandName = STR_TITLE_EDITOR_COMMAND_LOAD_FILE;
|
||||
const char * name = "";
|
||||
auto scenario =
|
||||
GetScenarioRepository()->GetByInternalName(command->Scenario);
|
||||
if (command->Scenario[0] == '\0')
|
||||
{
|
||||
commandName = STR_TITLE_EDITOR_COMMAND_LOAD_NO_SCENARIO;
|
||||
}
|
||||
else if (scenario != nullptr)
|
||||
{
|
||||
name = scenario->name;
|
||||
}
|
||||
else
|
||||
{
|
||||
commandName = STR_TITLE_EDITOR_COMMAND_LOAD_MISSING_SCENARIO;
|
||||
}
|
||||
set_format_arg(0, uintptr_t, name);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
log_warning("Unknown command %d", command->Type);
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@ static void window_title_menu_mouseup(rct_window *w, rct_widgetindex widgetIndex
|
|||
else {
|
||||
window_close_by_class(WC_LOADSAVE);
|
||||
window_close_by_class(WC_SERVER_LIST);
|
||||
window_scenarioselect_open(window_title_menu_scenarioselect_callback);
|
||||
window_scenarioselect_open(window_title_menu_scenarioselect_callback, false);
|
||||
}
|
||||
break;
|
||||
case WIDX_CONTINUE_SAVED_GAME:
|
||||
|
|
|
@ -145,12 +145,13 @@ static bool is_locking_enabled(rct_window *w);
|
|||
|
||||
static scenarioselect_callback _callback;
|
||||
static bool _showLockedInformation = false;
|
||||
static bool _titleEditor = false;
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006781B5
|
||||
*/
|
||||
rct_window * window_scenarioselect_open(scenarioselect_callback callback)
|
||||
rct_window * window_scenarioselect_open(scenarioselect_callback callback, bool titleEditor)
|
||||
{
|
||||
rct_window* window;
|
||||
sint32 windowWidth;
|
||||
|
@ -158,6 +159,12 @@ rct_window * window_scenarioselect_open(scenarioselect_callback callback)
|
|||
|
||||
_callback = callback;
|
||||
|
||||
if (_titleEditor != titleEditor)
|
||||
{
|
||||
_titleEditor = titleEditor;
|
||||
window_close_by_class(WC_SCENARIO_SELECT);
|
||||
}
|
||||
|
||||
window = window_bring_to_front_by_class(WC_SCENARIO_SELECT);
|
||||
if (window != nullptr)
|
||||
return window;
|
||||
|
@ -166,18 +173,17 @@ rct_window * window_scenarioselect_open(scenarioselect_callback callback)
|
|||
scenario_repository_scan();
|
||||
|
||||
// Shrink the window if we're showing scenarios by difficulty level.
|
||||
if (gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_DIFFICULTY) {
|
||||
if (gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_DIFFICULTY && !_titleEditor)
|
||||
windowWidth = 610;
|
||||
} else {
|
||||
else
|
||||
windowWidth = 733;
|
||||
}
|
||||
|
||||
window = window_create_centred(
|
||||
windowWidth,
|
||||
windowHeight,
|
||||
&window_scenarioselect_events,
|
||||
WC_SCENARIO_SELECT,
|
||||
WF_10
|
||||
WF_10 | (titleEditor ? WF_STICK_TO_FRONT : 0)
|
||||
);
|
||||
window->widgets = window_scenarioselect_widgets;
|
||||
window->enabled_widgets = (1 << WIDX_CLOSE) | (1 << WIDX_TAB1) | (1 << WIDX_TAB2)
|
||||
|
@ -202,13 +208,20 @@ static void window_scenarioselect_init_tabs(rct_window *w)
|
|||
{
|
||||
sint32 showPages = 0;
|
||||
size_t numScenarios = scenario_repository_get_count();
|
||||
for (size_t i = 0; i < numScenarios; i++) {
|
||||
for (size_t i = 0; i < numScenarios; i++)
|
||||
{
|
||||
const scenario_index_entry *scenario = scenario_repository_get_by_index(i);
|
||||
if (gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN) {
|
||||
if (gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN || _titleEditor)
|
||||
{
|
||||
if (_titleEditor && scenario->source_game == SCENARIO_SOURCE_OTHER)
|
||||
continue;
|
||||
showPages |= 1 << scenario->source_game;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
sint32 category = scenario->category;
|
||||
if (category > SCENARIO_CATEGORY_OTHER) {
|
||||
if (category > SCENARIO_CATEGORY_OTHER)
|
||||
{
|
||||
category = SCENARIO_CATEGORY_OTHER;
|
||||
}
|
||||
showPages |= 1 << category;
|
||||
|
@ -294,6 +307,10 @@ static void window_scenarioselect_scrollmousedown(rct_window *w, sint32 scrollIn
|
|||
audio_play_sound(SOUND_CLICK_1, 0, w->x + (w->width / 2));
|
||||
gFirstTimeSaving = true;
|
||||
_callback(listItem->scenario.scenario->path);
|
||||
if (_titleEditor)
|
||||
{
|
||||
window_close(w);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -383,7 +400,7 @@ static void window_scenarioselect_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
sint32 x = (widget->left + widget->right) / 2 + w->x;
|
||||
sint32 y = (widget->top + widget->bottom) / 2 + w->y - 3;
|
||||
|
||||
if (gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN) {
|
||||
if (gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN || _titleEditor) {
|
||||
set_format_arg(0, rct_string_id, ScenarioOriginStringIds[i]);
|
||||
} else { // old-style
|
||||
set_format_arg(0, rct_string_id, ScenarioCategoryStringIds[i]);
|
||||
|
@ -460,7 +477,7 @@ static void window_scenarioselect_scrollpaint(rct_window *w, rct_drawpixelinfo *
|
|||
rct_string_id highlighted_format = (theme_get_flags() & UITHEME_FLAG_USE_ALTERNATIVE_SCENARIO_SELECT_FONT) ? STR_WHITE_STRING : STR_WINDOW_COLOUR_2_STRINGID;
|
||||
rct_string_id unhighlighted_format = (theme_get_flags() & UITHEME_FLAG_USE_ALTERNATIVE_SCENARIO_SELECT_FONT) ? STR_WHITE_STRING : STR_BLACK_STRING;
|
||||
|
||||
bool wide = gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN;
|
||||
bool wide = gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN || _titleEditor;
|
||||
|
||||
rct_widget *listWidget = &w->widgets[WIDX_SCENARIOLIST];
|
||||
sint32 listWidth = listWidget->right - listWidget->left - 12;
|
||||
|
@ -573,15 +590,17 @@ static void initialise_list_items(rct_window *w)
|
|||
uint8 currentHeading = UINT8_MAX;
|
||||
for (size_t i = 0; i < numScenarios; i++) {
|
||||
const scenario_index_entry *scenario = scenario_repository_get_by_index(i);
|
||||
if (!is_scenario_visible(w, scenario)) {
|
||||
|
||||
if (!is_scenario_visible(w, scenario))
|
||||
continue;
|
||||
if (_titleEditor && scenario->source_game == SCENARIO_SOURCE_OTHER)
|
||||
continue;
|
||||
}
|
||||
|
||||
sc_list_item *listItem;
|
||||
|
||||
// Category heading
|
||||
rct_string_id headingStringId = STR_NONE;
|
||||
if (gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN) {
|
||||
if (gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN || _titleEditor) {
|
||||
if (w->selected_tab != SCENARIO_SOURCE_REAL && currentHeading != scenario->category) {
|
||||
currentHeading = scenario->category;
|
||||
headingStringId = ScenarioCategoryStringIds[currentHeading];
|
||||
|
@ -676,7 +695,7 @@ static void initialise_list_items(rct_window *w)
|
|||
|
||||
static bool is_scenario_visible(rct_window *w, const scenario_index_entry *scenario)
|
||||
{
|
||||
if (gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN) {
|
||||
if (gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN || _titleEditor) {
|
||||
if (scenario->source_game != w->selected_tab) {
|
||||
return false;
|
||||
}
|
||||
|
@ -694,14 +713,14 @@ static bool is_scenario_visible(rct_window *w, const scenario_index_entry *scena
|
|||
|
||||
static bool is_locking_enabled(rct_window *w)
|
||||
{
|
||||
if (gConfigGeneral.scenario_select_mode != SCENARIO_SELECT_MODE_ORIGIN) {
|
||||
if (gConfigGeneral.scenario_select_mode != SCENARIO_SELECT_MODE_ORIGIN)
|
||||
return false;
|
||||
}
|
||||
if (!gConfigGeneral.scenario_unlocking_enabled) {
|
||||
if (!gConfigGeneral.scenario_unlocking_enabled)
|
||||
return false;
|
||||
}
|
||||
if (w->selected_tab >= 6) {
|
||||
if (w->selected_tab >= 6)
|
||||
return false;
|
||||
}
|
||||
if (_titleEditor)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ rct_window * window_guest_list_open_with_filter(sint32 type, sint32 index);
|
|||
rct_window * window_staff_fire_prompt_open(rct_peep* peep);
|
||||
void window_title_editor_open(sint32 tab);
|
||||
void window_title_command_editor_open(struct TitleSequence * sequence, sint32 command, bool insert);
|
||||
rct_window * window_scenarioselect_open(scenarioselect_callback callback);
|
||||
rct_window * window_scenarioselect_open(scenarioselect_callback callback, bool titleEditor);
|
||||
|
||||
rct_window * window_error_open(rct_string_id title, rct_string_id message);
|
||||
|
||||
|
|
|
@ -3822,6 +3822,15 @@ enum {
|
|||
STR_GUESTS_FILTER_BY_NAME_TIP = 6172,
|
||||
STR_GUESTS_ENTER_NAME_TO_SEARCH = 6173,
|
||||
|
||||
STR_TITLE_EDITOR_ACTION_LOAD_SAVE = 6174,
|
||||
STR_TITLE_EDITOR_ACTION_LOAD_SCENARIO = 6175,
|
||||
STR_TITLE_EDITOR_ARGUMENT_SCENARIO = 6176,
|
||||
STR_TITLE_EDITOR_COMMAND_LOAD_NO_SCENARIO = 6177,
|
||||
STR_TITLE_EDITOR_COMMAND_LOAD_MISSING_SCENARIO = 6178,
|
||||
STR_TITLE_COMMAND_EDITOR_ACTION_SELECT_SCENARIO = 6179,
|
||||
STR_TITLE_COMMAND_EDITOR_NO_SCENARIO_SELECTED = 6180,
|
||||
STR_TITLE_COMMAND_EDITOR_MISSING_SCENARIO = 6181,
|
||||
|
||||
// Have to include resource strings (from scenarios and objects) for the time being now that language is partially working
|
||||
STR_COUNT = 32768
|
||||
};
|
||||
|
|
|
@ -269,6 +269,8 @@ public:
|
|||
desc.title = name.c_str();
|
||||
}
|
||||
|
||||
String::Set(dst->internal_name, sizeof(dst->internal_name), desc.title);
|
||||
|
||||
rct_string_id localisedStringIds[3];
|
||||
if (language_get_localised_scenario_strings(desc.title, localisedStringIds))
|
||||
{
|
||||
|
|
|
@ -123,7 +123,7 @@ class ScenarioFileIndex final : public FileIndex<scenario_index_entry>
|
|||
{
|
||||
private:
|
||||
static constexpr uint32 MAGIC_NUMBER = 0x58444953; // SIDX
|
||||
static constexpr uint16 VERSION = 2;
|
||||
static constexpr uint16 VERSION = 3;
|
||||
static constexpr auto PATTERN = "*.sc4;*.sc6";
|
||||
|
||||
public:
|
||||
|
@ -170,6 +170,7 @@ protected:
|
|||
stream->WriteValue(item.objective_arg_2);
|
||||
stream->WriteValue(item.objective_arg_3);
|
||||
|
||||
stream->Write(item.internal_name, sizeof(item.internal_name));
|
||||
stream->Write(item.name, sizeof(item.name));
|
||||
stream->Write(item.details, sizeof(item.details));
|
||||
}
|
||||
|
@ -192,6 +193,7 @@ protected:
|
|||
item.objective_arg_3 = stream->ReadValue<sint16>();
|
||||
item.highscore = nullptr;
|
||||
|
||||
stream->Read(item.internal_name, sizeof(item.internal_name));
|
||||
stream->Read(item.name, sizeof(item.name));
|
||||
stream->Read(item.details, sizeof(item.details));
|
||||
|
||||
|
@ -279,6 +281,9 @@ private:
|
|||
ScenarioSources::NormaliseName(entry.name, sizeof(entry.name), entry.name);
|
||||
}
|
||||
|
||||
// entry.name will be translated later so keep the untranslated name here
|
||||
String::Set(entry.internal_name, sizeof(entry.internal_name), entry.name);
|
||||
|
||||
String::Set(entry.details, sizeof(entry.details), s6Info->details);
|
||||
|
||||
// Look up and store information regarding the origins of this scenario.
|
||||
|
@ -380,6 +385,21 @@ public:
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
const scenario_index_entry * GetByInternalName(const utf8 * name) const override {
|
||||
for (size_t i = 0; i < _scenarios.size(); i++) {
|
||||
const scenario_index_entry * scenario = &_scenarios[i];
|
||||
|
||||
if (scenario->source_game == SCENARIO_SOURCE_OTHER)
|
||||
continue;
|
||||
|
||||
// Note: this is always case insensitive search for cross platform consistency
|
||||
if (String::Equals(name, scenario->internal_name, true)) {
|
||||
return &_scenarios[i];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const scenario_index_entry * GetByPath(const utf8 * path) const override
|
||||
{
|
||||
for (const auto &scenario : _scenarios)
|
||||
|
|
|
@ -46,7 +46,8 @@ typedef struct scenario_index_entry
|
|||
sint16 objective_arg_3;
|
||||
scenario_highscore_entry * highscore;
|
||||
|
||||
utf8 name[64];
|
||||
utf8 internal_name[64]; // Untranslated name
|
||||
utf8 name[64]; // Translated name
|
||||
utf8 details[256];
|
||||
} scenario_index_entry;
|
||||
|
||||
|
@ -69,6 +70,10 @@ interface IScenarioRepository
|
|||
virtual size_t GetCount() const abstract;
|
||||
virtual const scenario_index_entry * GetByIndex(size_t index) const abstract;
|
||||
virtual const scenario_index_entry * GetByFilename(const utf8 * filename) const abstract;
|
||||
/**
|
||||
* Does not return custom scenarios due to the fact that they may have the same name.
|
||||
*/
|
||||
virtual const scenario_index_entry * GetByInternalName(const utf8 * name) const abstract;
|
||||
virtual const scenario_index_entry * GetByPath(const utf8 * path) const abstract;
|
||||
|
||||
virtual bool TryRecordHighscore(const utf8 * scenarioFileName, money32 companyValue, const utf8 * name) abstract;
|
||||
|
|
|
@ -314,7 +314,7 @@ namespace ScenarioSources
|
|||
}
|
||||
}
|
||||
|
||||
outDesc->title = nullptr;
|
||||
outDesc->title = "";
|
||||
outDesc->id = SC_UNIDENTIFIED;
|
||||
outDesc->source = SCENARIO_SOURCE_OTHER;
|
||||
outDesc->index = -1;
|
||||
|
|
|
@ -29,6 +29,9 @@
|
|||
#include "../core/String.hpp"
|
||||
#include "../core/StringBuilder.hpp"
|
||||
#include "../core/Zip.h"
|
||||
#include "../scenario/ScenarioRepository.h"
|
||||
#include "../scenario/ScenarioSources.h"
|
||||
#include "../util/Util.h"
|
||||
#include "TitleSequence.h"
|
||||
|
||||
|
||||
|
@ -475,6 +478,16 @@ static std::vector<TitleCommand> LegacyScriptRead(utf8 * script, size_t scriptLe
|
|||
command.Type = TITLE_SCRIPT_LOADRCT1;
|
||||
command.SaveIndex = atoi(part1) & 0xFF;
|
||||
}
|
||||
else if (_stricmp(token, "LOADSC") == 0)
|
||||
{
|
||||
command.Type = TITLE_SCRIPT_LOADSC;
|
||||
// Confirm the scenario exists
|
||||
//source_desc desc;
|
||||
//if (ScenarioSources::TryGetByName(part1, &desc))
|
||||
//{
|
||||
safe_strcpy(command.Scenario, part1, sizeof(command.Scenario));
|
||||
//}
|
||||
}
|
||||
}
|
||||
if (command.Type != TITLE_SCRIPT_UNDEFINED)
|
||||
{
|
||||
|
@ -517,7 +530,8 @@ static void LegacyScriptGetLine(IStream * stream, char * parts)
|
|||
{
|
||||
if (!whitespace)
|
||||
{
|
||||
if (part == 0 && cindex == 4 && _strnicmp(parts, "LOAD", 4) == 0)
|
||||
if (part == 0 && ((cindex == 4 && _strnicmp(parts, "LOAD", 4) == 0) ||
|
||||
(cindex == 6 && _strnicmp(parts, "LOADSC", 6) == 0)))
|
||||
{
|
||||
load = true;
|
||||
}
|
||||
|
@ -595,6 +609,17 @@ static utf8 * LegacyScriptWrite(TitleSequence * seq)
|
|||
sb.Append(seq->Saves[command->SaveIndex]);
|
||||
}
|
||||
break;
|
||||
case TITLE_SCRIPT_LOADSC:
|
||||
if (command->Scenario[0] == '\0')
|
||||
{
|
||||
sb.Append("LOADSC <No scenario name>");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append("LOADSC ");
|
||||
sb.Append(command->Scenario);
|
||||
}
|
||||
break;
|
||||
case TITLE_SCRIPT_LOCATION:
|
||||
String::Format(buffer, sizeof(buffer), "LOCATION %u %u", command->X, command->Y);
|
||||
sb.Append(buffer);
|
||||
|
@ -634,6 +659,7 @@ bool TitleSequenceIsLoadCommand(const TitleCommand * command)
|
|||
case TITLE_SCRIPT_LOADMM:
|
||||
case TITLE_SCRIPT_LOAD:
|
||||
case TITLE_SCRIPT_LOADRCT1:
|
||||
case TITLE_SCRIPT_LOADSC:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
#include "../common.h"
|
||||
|
||||
#define TITLE_COMMAND_SCENARIO_LENGTH 64
|
||||
|
||||
typedef struct TitleCommand
|
||||
{
|
||||
uint8 Type;
|
||||
|
@ -32,6 +34,7 @@ typedef struct TitleCommand
|
|||
uint8 Zoom; // ZOOM
|
||||
uint8 Speed; // SPEED
|
||||
uint16 Milliseconds; // WAIT
|
||||
utf8 Scenario[TITLE_COMMAND_SCENARIO_LENGTH]; // LOADSC
|
||||
};
|
||||
} TitleCommand;
|
||||
|
||||
|
@ -70,6 +73,7 @@ enum TITLE_SCRIPT
|
|||
TITLE_SCRIPT_LOOP,
|
||||
TITLE_SCRIPT_ENDLOOP,
|
||||
TITLE_SCRIPT_LOADRCT1,
|
||||
TITLE_SCRIPT_LOADSC,
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -339,6 +339,21 @@ private:
|
|||
}
|
||||
break;
|
||||
}
|
||||
case TITLE_SCRIPT_LOADSC:
|
||||
{
|
||||
bool loadSuccess = false;
|
||||
auto scenario = GetScenarioRepository()->GetByInternalName(command->Scenario);
|
||||
if (scenario != nullptr)
|
||||
{
|
||||
loadSuccess = LoadParkFromFile(scenario->path);
|
||||
}
|
||||
if (!loadSuccess)
|
||||
{
|
||||
Console::Error::WriteLine("Failed to load: \"%s\" for the title sequence.", command->Scenario);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue