diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index e85f71f0b5..dc5f2c2242 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -69,7 +69,7 @@ enum static constexpr uint8 _numSourceGameItems = 8; static uint32 _filter_flags; -static uint16 _filter_object_counts[11]; +static uint16 _filter_object_counts[OBJECT_TYPE_COUNT]; static char _filter_string[MAX_PATH]; @@ -85,58 +85,42 @@ static char _filter_string[MAX_PATH]; #define _FILTER_SELECTED (_filter_flags & FILTER_SELECTED) #define _FILTER_NONSELECTED (_filter_flags & FILTER_NONSELECTED) -enum { - WINDOW_OBJECT_SELECTION_PAGE_RIDE_VEHICLES_ATTRACTIONS, - WINDOW_OBJECT_SELECTION_PAGE_SMALL_SCENERY, - WINDOW_OBJECT_SELECTION_PAGE_LARGE_SCENERY, - WINDOW_OBJECT_SELECTION_PAGE_WALLS_FENCES, - WINDOW_OBJECT_SELECTION_PAGE_PATH_SIGNS, - WINDOW_OBJECT_SELECTION_PAGE_FOOTPATHS, - WINDOW_OBJECT_SELECTION_PAGE_PATH_EXTRAS, - WINDOW_OBJECT_SELECTION_PAGE_SCENERY_GROUPS, - WINDOW_OBJECT_SELECTION_PAGE_PARK_ENTRANCE, - WINDOW_OBJECT_SELECTION_PAGE_WATER, - WINDOW_OBJECT_SELECTION_PAGE_COUNT +struct ObjectPageDesc +{ + rct_string_id Caption; + uint32 Image; + bool IsAdvanced; }; -static constexpr const rct_string_id ObjectSelectionPageNames[WINDOW_OBJECT_SELECTION_PAGE_COUNT] = { - STR_OBJECT_SELECTION_RIDE_VEHICLES_ATTRACTIONS, - STR_OBJECT_SELECTION_SMALL_SCENERY, - STR_OBJECT_SELECTION_LARGE_SCENERY, - STR_OBJECT_SELECTION_WALLS_FENCES, - STR_OBJECT_SELECTION_PATH_SIGNS, - STR_OBJECT_SELECTION_FOOTPATHS, - STR_OBJECT_SELECTION_PATH_EXTRAS, - STR_OBJECT_SELECTION_SCENERY_GROUPS, - STR_OBJECT_SELECTION_PARK_ENTRANCE, - STR_OBJECT_SELECTION_WATER, +static constexpr const ObjectPageDesc ObjectSelectionPages[OBJECT_TYPE_COUNT] = { + { STR_OBJECT_SELECTION_RIDE_VEHICLES_ATTRACTIONS, SPR_TAB_RIDE_16, false }, + { STR_OBJECT_SELECTION_SMALL_SCENERY, SPR_TAB_SCENERY_TREES, true }, + { STR_OBJECT_SELECTION_LARGE_SCENERY, SPR_TAB_SCENERY_URBAN, true }, + { STR_OBJECT_SELECTION_WALLS_FENCES, SPR_TAB_SCENERY_WALLS, true }, + { STR_OBJECT_SELECTION_PATH_SIGNS, SPR_TAB_SCENERY_SIGNAGE, true }, + { STR_OBJECT_SELECTION_FOOTPATHS, SPR_TAB_SCENERY_PATHS, false }, + { STR_OBJECT_SELECTION_PATH_EXTRAS, SPR_TAB_SCENERY_PATH_ITEMS, false }, + { STR_OBJECT_SELECTION_SCENERY_GROUPS, SPR_TAB_SCENERY_STATUES, false }, + { STR_OBJECT_SELECTION_PARK_ENTRANCE, SPR_TAB_PARK, false }, + { STR_OBJECT_SELECTION_WATER, SPR_TAB_WATER, false }, + { STR_OBJECT_SELECTION_SCENARIO_DESCRIPTION, SPR_TAB_STATS, false }, }; #pragma region Widgets enum WINDOW_STAFF_LIST_WIDGET_IDX { - WIDX_BACKGROUND, // 0, 1 - WIDX_TITLE, // 1, 2 - WIDX_CLOSE, // 2, 4 - WIDX_TAB_CONTENT_PANEL, // 3, 8 - WIDX_TAB_1, // 4, 10 - WIDX_TAB_2, // 5, 20 - WIDX_TAB_3, // 6, 40 - WIDX_TAB_4, // 7, 80 - WIDX_TAB_5, // 8, 100 - WIDX_TAB_6, // 9, 200 - WIDX_TAB_7, // 10, 400 - WIDX_TAB_8, // 11, 800 - WIDX_TAB_9, // 12, 1000 - WIDX_TAB_10, // 13, 2000 - WIDX_ADVANCED, // 14, 4000 - WIDX_LIST, // 15, 8000 - WIDX_PREVIEW, // 16, 10000 - WIDX_INSTALL_TRACK, // 17, 20000 - WIDX_FILTER_DROPDOWN, // 18, 40000 - WIDX_FILTER_STRING_BUTTON, // 19, 80000 - WIDX_FILTER_CLEAR_BUTTON, // 20, 100000 - WIDX_FILTER_RIDE_TAB_FRAME, // 21, 200000 + WIDX_BACKGROUND, + WIDX_TITLE, + WIDX_CLOSE, + WIDX_TAB_CONTENT_PANEL, + WIDX_ADVANCED, + WIDX_LIST, + WIDX_PREVIEW, + WIDX_INSTALL_TRACK, + WIDX_FILTER_DROPDOWN, + WIDX_FILTER_STRING_BUTTON, + WIDX_FILTER_CLEAR_BUTTON, + WIDX_FILTER_RIDE_TAB_FRAME, WIDX_FILTER_RIDE_TAB_ALL, WIDX_FILTER_RIDE_TAB_TRANSPORT, WIDX_FILTER_RIDE_TAB_GENTLE, @@ -146,25 +130,17 @@ enum WINDOW_STAFF_LIST_WIDGET_IDX { WIDX_FILTER_RIDE_TAB_STALL, WIDX_LIST_SORT_TYPE, WIDX_LIST_SORT_RIDE, + WIDX_TAB_1, }; validate_global_widx(WC_EDITOR_OBJECT_SELECTION, WIDX_TAB_1); -static rct_widget window_editor_object_selection_widgets[] = { +static bool _window_editor_object_selection_widgets_initialised; +static std::vector _window_editor_object_selection_widgets = { { WWT_FRAME, 0, 0, 599, 0, 399, 0xFFFFFFFF, STR_NONE }, { WWT_CAPTION, 0, 1, 598, 1, 14, STR_OBJECT_SELECTION, STR_WINDOW_TITLE_TIP }, { WWT_CLOSEBOX, 0, 587, 597, 2, 13, STR_CLOSE_X, STR_CLOSE_WINDOW_TIP }, { WWT_RESIZE, 1, 0, 599, 43, 399, 0xFFFFFFFF, STR_NONE }, - { WWT_TAB, 1, 3, 33, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_STRING_DEFINED_TOOLTIP }, - { WWT_TAB, 1, 34, 64, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_STRING_DEFINED_TOOLTIP }, - { WWT_TAB, 1, 65, 95, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_STRING_DEFINED_TOOLTIP }, - { WWT_TAB, 1, 96, 126, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_STRING_DEFINED_TOOLTIP }, - { WWT_TAB, 1, 127, 157, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_STRING_DEFINED_TOOLTIP }, - { WWT_TAB, 1, 158, 188, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_STRING_DEFINED_TOOLTIP }, - { WWT_TAB, 1, 189, 219, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_STRING_DEFINED_TOOLTIP }, - { WWT_TAB, 1, 220, 250, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_STRING_DEFINED_TOOLTIP }, - { WWT_TAB, 1, 251, 281, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_STRING_DEFINED_TOOLTIP }, - { WWT_TAB, 1, 282, 312, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_STRING_DEFINED_TOOLTIP }, { WWT_BUTTON, 0, 470, 591, 23, 34, STR_OBJECT_SELECTION_ADVANCED, STR_OBJECT_SELECTION_ADVANCED_TIP }, { WWT_SCROLL, 1, 4, 291, 60, 386, SCROLL_VERTICAL, STR_NONE }, { WWT_FLATBTN, 1, 391, 504, 46, 159, 0xFFFFFFFF, STR_NONE }, @@ -182,6 +158,10 @@ static rct_widget window_editor_object_selection_widgets[] = { { WWT_TAB, 1, 189, 219, 47, 73, IMAGE_TYPE_REMAP | SPR_TAB, STR_SHOPS_STALLS_TIP }, { WWT_TABLE_HEADER, 1, 4, 204, 80, 93, STR_NONE, STR_NONE }, { WWT_TABLE_HEADER, 1, 205, 291, 80, 93, STR_NONE, STR_NONE }, + + { WWT_TAB, 1, 3, 33, 17, 43, IMAGE_TYPE_REMAP | SPR_TAB, STR_STRING_DEFINED_TOOLTIP }, + // Copied object type times... + { WIDGETS_END } }; @@ -252,6 +232,7 @@ static bool filter_chunks(const ObjectRepositoryItem * item); static void filter_update_counts(); static std::string object_get_description(const void * object); +static sint32 get_selected_object_type(rct_window * w); enum { RIDE_SORT_TYPE, @@ -323,7 +304,7 @@ static void visible_list_refresh(rct_window *w) uint8 selectionFlags = _objectSelectionFlags[i]; const ObjectRepositoryItem * item = &items[i]; uint8 objectType = item->ObjectEntry.flags & 0x0F; - if (objectType == w->selected_tab && !(selectionFlags & OBJECT_SELECTION_FLAG_6) && + if (objectType == get_selected_object_type(w) && !(selectionFlags & OBJECT_SELECTION_FLAG_6) && filter_source(item) && filter_string(item) && filter_chunks(item) && @@ -374,15 +355,29 @@ static void visible_list_refresh(rct_window *w) window_invalidate(w); } +static void window_editor_object_selection_init_widgets() +{ + auto &widgets = _window_editor_object_selection_widgets; + if (!_window_editor_object_selection_widgets_initialised) + { + _window_editor_object_selection_widgets_initialised = true; + const auto &tabWidget = widgets[widgets.size() - 2]; + for (sint32 i = 1; i < OBJECT_TYPE_COUNT; i++) + { + widgets.insert(widgets.end() - 1, tabWidget); + } + } +} + /** * * rct2: 0x006AA64E */ rct_window * window_editor_object_selection_open() { - rct_window* window; + window_editor_object_selection_init_widgets(); - window = window_bring_to_front_by_class(WC_EDITOR_OBJECT_SELECTION); + auto window = window_bring_to_front_by_class(WC_EDITOR_OBJECT_SELECTION); if (window != nullptr) return window; @@ -396,8 +391,8 @@ rct_window * window_editor_object_selection_open() WC_EDITOR_OBJECT_SELECTION, WF_10 | WF_RESIZABLE ); - window_editor_object_selection_widgets[WIDX_FILTER_STRING_BUTTON].string = _filter_string; - window->widgets = window_editor_object_selection_widgets; + window->widgets = _window_editor_object_selection_widgets.data(); + window->widgets[WIDX_FILTER_STRING_BUTTON].string = _filter_string; window->enabled_widgets = (1 << WIDX_ADVANCED) | @@ -412,8 +407,10 @@ rct_window * window_editor_object_selection_open() _filter_flags = gConfigInterface.object_selection_filter_flags; memset(_filter_string, 0, sizeof(_filter_string)); - for (sint32 i = WIDX_TAB_1; i <= WIDX_TAB_10; i++) + for (sint32 i = WIDX_TAB_1; i < WIDX_TAB_1 + OBJECT_TYPE_COUNT; i++) + { window->enabled_widgets |= (1LL << i); + } window_init_scroll_widgets(window); window->var_4AE = 0; @@ -482,19 +479,6 @@ static void window_editor_object_selection_mouseup(rct_window *w, rct_widgetinde window_close(w); } break; - - case WIDX_TAB_1: - case WIDX_TAB_2: - case WIDX_TAB_3: - case WIDX_TAB_4: - case WIDX_TAB_5: - case WIDX_TAB_6: - case WIDX_TAB_7: - case WIDX_TAB_8: - case WIDX_TAB_9: - case WIDX_TAB_10: - window_editor_object_set_page(w, widgetIndex - WIDX_TAB_1); - break; case WIDX_FILTER_RIDE_TAB_ALL: _filter_flags |= FILTER_RIDES; gConfigInterface.object_selection_filter_flags = _filter_flags; @@ -575,6 +559,12 @@ static void window_editor_object_selection_mouseup(rct_window *w, rct_widgetinde } visible_list_refresh(w); break; + default: + if (widgetIndex >= WIDX_TAB_1 && widgetIndex < WIDX_TAB_1 + OBJECT_TYPE_COUNT) + { + window_editor_object_set_page(w, widgetIndex - WIDX_TAB_1); + } + break; } } @@ -695,7 +685,7 @@ static void window_editor_object_selection_scroll_mousedown(rct_window *w, sint3 // when windows attempt to draw objects that don't exist any more window_close_all_except_class(WC_EDITOR_OBJECT_SELECTION); - sint32 selected_object = get_object_from_object_selection((w->selected_tab & 0xFF), y); + sint32 selected_object = get_object_from_object_selection(get_selected_object_type(w), y); if (selected_object == -1) return; @@ -755,7 +745,7 @@ static void window_editor_object_selection_scroll_mousedown(rct_window *w, sint3 */ static void window_editor_object_selection_scroll_mouseover(rct_window *w, sint32 scrollIndex, sint32 x, sint32 y) { - sint32 selectedObject = get_object_from_object_selection(w->selected_tab & 0xFF, y); + sint32 selectedObject = get_object_from_object_selection(get_selected_object_type(w), y); if (selectedObject != -1) { list_item * listItem = &_listItems[selectedObject]; uint8 objectSelectionFlags = *listItem->flags; @@ -787,22 +777,13 @@ static void window_editor_object_selection_scroll_mouseover(rct_window *w, sint3 */ static void window_editor_object_selection_tooltip(rct_window* w, rct_widgetindex widgetIndex, rct_string_id *stringId) { - switch (widgetIndex) { - case WIDX_TAB_1: - case WIDX_TAB_2: - case WIDX_TAB_3: - case WIDX_TAB_4: - case WIDX_TAB_5: - case WIDX_TAB_6: - case WIDX_TAB_7: - case WIDX_TAB_8: - case WIDX_TAB_9: - case WIDX_TAB_10: - set_format_arg(0, rct_string_id, ObjectSelectionPageNames[(widgetIndex - WIDX_TAB_1)]); - break; - default: + if (widgetIndex >= WIDX_TAB_1 && widgetIndex < WIDX_TAB_1 + OBJECT_TYPE_COUNT) + { + set_format_arg(0, rct_string_id, ObjectSelectionPages[(widgetIndex - WIDX_TAB_1)].Caption); + } + else + { set_format_arg(0, rct_string_id, STR_LIST); - break; } } @@ -840,7 +821,7 @@ static void window_editor_object_selection_invalidate(rct_window *w) w->pressed_widgets &= ~(1 << WIDX_ADVANCED); // Set window title and buttons - set_format_arg(0, rct_string_id, ObjectSelectionPageNames[w->selected_tab]); + set_format_arg(0, rct_string_id, ObjectSelectionPages[get_selected_object_type(w)].Caption); if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) { w->widgets[WIDX_TITLE].text = STR_TRACK_DESIGNS_MANAGER_SELECT_RIDE_TYPE; w->widgets[WIDX_INSTALL_TRACK].type = WWT_BUTTON; @@ -853,13 +834,18 @@ static void window_editor_object_selection_invalidate(rct_window *w) } // Align tabs, hide advanced ones + bool advancedMode = (w->list_information_type & 1) != 0; sint32 x = 3; - for (sint32 i = 0; i < WINDOW_OBJECT_SELECTION_PAGE_COUNT; i++) { - rct_widget *widget = &w->widgets[WIDX_TAB_1 + i]; - - if (!(w->list_information_type & 1) && ((1 << i) & 0x5E)) { + for (sint32 i = 0; i < OBJECT_TYPE_COUNT; i++) + { + auto widget = &w->widgets[WIDX_TAB_1 + i]; + if ((!advancedMode && ObjectSelectionPages[i].IsAdvanced) || + i == OBJECT_TYPE_SCENARIO_TEXT) + { widget->type = WWT_EMPTY; - } else { + } + else + { widget->type = WWT_TAB; widget->left = x; widget->right = x + 30; @@ -869,8 +855,10 @@ static void window_editor_object_selection_invalidate(rct_window *w) if (gScreenFlags & (SCREEN_FLAGS_TRACK_MANAGER | SCREEN_FLAGS_TRACK_DESIGNER)) { w->widgets[WIDX_ADVANCED].type = WWT_EMPTY; - for (sint32 i = 1; i < WINDOW_OBJECT_SELECTION_PAGE_COUNT; i++) + for (sint32 i = 1; i < OBJECT_TYPE_COUNT; i++) + { w->widgets[WIDX_TAB_1 + i].type = WWT_EMPTY; + } x = 150; } else { w->widgets[WIDX_ADVANCED].type = WWT_BUTTON; @@ -883,7 +871,7 @@ static void window_editor_object_selection_invalidate(rct_window *w) w->widgets[WIDX_PREVIEW].right = w->widgets[WIDX_PREVIEW].left + 113; w->widgets[WIDX_FILTER_RIDE_TAB_FRAME].right = w->widgets[WIDX_LIST].right; - bool ridePage = (w->selected_tab == WINDOW_OBJECT_SELECTION_PAGE_RIDE_VEHICLES_ATTRACTIONS); + bool ridePage = (get_selected_object_type(w) == OBJECT_TYPE_RIDE); w->widgets[WIDX_LIST].top = (ridePage ? 118 : 60); w->widgets[WIDX_FILTER_STRING_BUTTON].right = w->widgets[WIDX_LIST].right - 77; w->widgets[WIDX_FILTER_STRING_BUTTON].top = (ridePage ? 80 : 46); @@ -942,28 +930,19 @@ static void window_editor_object_selection_paint(rct_window *w, rct_drawpixelinf rct_object_entry *highlightedEntry; rct_string_id stringId; - /*if (w->selected_tab == WINDOW_OBJECT_SELECTION_PAGE_RIDE_VEHICLES_ATTRACTIONS) { - gfx_fill_rect_inset(dpi, - w->x + w->widgets[WIDX_FILTER_RIDE_TAB_ALL].left - 1, - w->y + w->widgets[WIDX_FILTER_RIDE_TAB_ALL].bottom, - w->x + w->widgets[WIDX_FILTER_RIDE_TAB_STALL].right + 1, - w->y + w->widgets[WIDX_FILTER_RIDE_TAB_ALL].bottom + 2, - w->colours[1], - 0x10 - ); - }*/ - window_draw_widgets(w, dpi); // Draw tabs - for (i = 0; i < WINDOW_OBJECT_SELECTION_PAGE_COUNT; i++) { + for (i = 0; i < OBJECT_TYPE_COUNT; i++) + { widget = &w->widgets[WIDX_TAB_1 + i]; - if (widget->type == WWT_EMPTY) - continue; - - x = w->x + widget->left; - y = w->y + widget->top; - gfx_draw_sprite(dpi, SPR_TAB_RIDE_16 + i, x, y, 0); + if (widget->type != WWT_EMPTY) + { + auto image = ObjectSelectionPages[i].Image; + x = w->x + widget->left; + y = w->y + widget->top; + gfx_draw_sprite(dpi, image, x, y, 0); + } } const sint32 ride_tabs[] = { SPR_TAB_RIDE_16, IMAGE_TYPE_REMAP | SPR_TAB_RIDES_TRANSPORT_0, SPR_TAB_RIDES_GENTLE_0, IMAGE_TYPE_REMAP | SPR_TAB_RIDES_ROLLER_COASTERS_0, SPR_TAB_RIDES_THRILL_0, SPR_TAB_RIDES_WATER_0, SPR_TAB_RIDES_SHOP_0, SPR_TAB_FINANCES_RESEARCH_0 }; @@ -972,7 +951,8 @@ static void window_editor_object_selection_paint(rct_window *w, rct_drawpixelinf }; // Draw ride tabs - if (w->selected_tab == WINDOW_OBJECT_SELECTION_PAGE_RIDE_VEHICLES_ATTRACTIONS) { + if (get_selected_object_type(w) == OBJECT_TYPE_RIDE) + { for (i = 0; i < 7; i++) { widget = &w->widgets[WIDX_FILTER_RIDE_TAB_ALL + i]; if (widget->type == WWT_EMPTY) @@ -1008,8 +988,8 @@ static void window_editor_object_selection_paint(rct_window *w, rct_drawpixelinf x = w->x + 3; y = w->y + w->height - 13; - sint32 numSelected = _numSelectedObjectsForType[w->selected_tab]; - sint32 totalSelectable = object_entry_group_counts[w->selected_tab]; + sint32 numSelected = _numSelectedObjectsForType[get_selected_object_type(w)]; + sint32 totalSelectable = object_entry_group_counts[get_selected_object_type(w)]; if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER) totalSelectable = 4; @@ -1076,7 +1056,7 @@ static void window_editor_object_selection_paint(rct_window *w, rct_drawpixelinf gfx_draw_string_right(dpi, stringId, nullptr, COLOUR_WHITE, w->x + w->width - 5, w->y + w->height - 3 - 12 - 14); // - if (w->selected_tab == WINDOW_OBJECT_SELECTION_PAGE_RIDE_VEHICLES_ATTRACTIONS) { + if (get_selected_object_type(w) == OBJECT_TYPE_RIDE) { y = w->y + w->height - 3 - 12 - 14 - 14; stringId = get_ride_type_string_id(listItem->repositoryItem); gfx_draw_string_right(dpi, stringId, nullptr, COLOUR_WHITE, w->x + w->width - 5, y); @@ -1101,7 +1081,7 @@ static void window_editor_object_selection_scrollpaint(rct_window *w, rct_drawpi { sint32 x, y, colour, colour2; - bool ridePage = (w->selected_tab == WINDOW_OBJECT_SELECTION_PAGE_RIDE_VEHICLES_ATTRACTIONS); + bool ridePage = (get_selected_object_type(w) == OBJECT_TYPE_RIDE); uint8 paletteIndex = ColourMapA[w->colours[1]].mid_light; gfx_clear(dpi, paletteIndex); @@ -1178,7 +1158,7 @@ static void window_editor_object_set_page(rct_window *w, sint32 page) w->scrolls[0].v_top = 0; w->frame_no = 0; - if (page == WINDOW_OBJECT_SELECTION_PAGE_RIDE_VEHICLES_ATTRACTIONS) { + if (page == OBJECT_TYPE_RIDE) { _listSortType = RIDE_SORT_TYPE; _listSortDescending = false; } else { @@ -1192,9 +1172,10 @@ static void window_editor_object_set_page(rct_window *w, sint32 page) static void window_editor_object_selection_set_pressed_tab(rct_window *w) { - sint32 i; - for (i = 0; i < WINDOW_OBJECT_SELECTION_PAGE_COUNT; i++) + for (sint32 i = 0; i < OBJECT_TYPE_COUNT; i++) + { w->pressed_widgets &= ~(1 << (WIDX_TAB_1 + i)); + } w->pressed_widgets |= 1LL << (WIDX_TAB_1 + w->selected_tab); } @@ -1477,3 +1458,8 @@ static std::string object_get_description(const void * object) return ""; } } + +static sint32 get_selected_object_type(rct_window * w) +{ + return w->selected_tab; +} diff --git a/src/openrct2/EditorObjectSelectionSession.cpp b/src/openrct2/EditorObjectSelectionSession.cpp index 1567440f53..d654b0ec83 100644 --- a/src/openrct2/EditorObjectSelectionSession.cpp +++ b/src/openrct2/EditorObjectSelectionSession.cpp @@ -223,7 +223,7 @@ void sub_6AB211() sint32 numObjects = (sint32)object_repository_get_items_count(); _objectSelectionFlags = std::vector(numObjects); - for (uint8 objectType = 0; objectType < 11; objectType++) { + for (uint8 objectType = 0; objectType < OBJECT_TYPE_COUNT; objectType++) { _numSelectedObjectsForType[objectType] = 0; _numAvailableObjectsForType[objectType] = 0; } diff --git a/src/openrct2/interface/Window.h b/src/openrct2/interface/Window.h index b590921238..6ba8855362 100644 --- a/src/openrct2/interface/Window.h +++ b/src/openrct2/interface/Window.h @@ -462,7 +462,7 @@ enum { #define WC_TRACK_DESIGN_PLACE__WIDX_ROTATE 3 #define WC_MAP__WIDX_LAND_TOOL 13 #define WC_MAP__WIDX_ROTATE_90 20 -#define WC_EDITOR_OBJECT_SELECTION__WIDX_TAB_1 4 +#define WC_EDITOR_OBJECT_SELECTION__WIDX_TAB_1 21 #define WC_CLEAR_SCENERY__WIDX_PREVIEW 3 #define WC_LAND_RIGHTS__WIDX_PREVIEW 3 #define WC_STAFF__WIDX_PICKUP 10 diff --git a/src/openrct2/object/ObjectJsonHelpers.cpp b/src/openrct2/object/ObjectJsonHelpers.cpp index 7a63121f1c..05c1867732 100644 --- a/src/openrct2/object/ObjectJsonHelpers.cpp +++ b/src/openrct2/object/ObjectJsonHelpers.cpp @@ -306,6 +306,30 @@ namespace ObjectJsonHelpers } } } + else if (String::StartsWith(s, "$G1")) + { + auto range = ParseRange(s.substr(3)); + if (range.size() > 0) + { + for (auto i : range) + { + auto og1 = gfx_get_g1_element(i); + if (og1 == nullptr) + { + rct_g1_element g1{}; + result.push_back(g1); + } + else + { + auto length = g1_calculate_data_size(og1); + auto g1 = *og1; + g1.offset = (uint8 *)std::malloc(length); + std::memcpy(g1.offset, og1->offset, length); + result.push_back(g1); + } + } + } + } else if (String::StartsWith(s, "$RCT2:OBJDATA/")) { auto name = s.substr(14); diff --git a/src/openrct2/object/ObjectManager.cpp b/src/openrct2/object/ObjectManager.cpp index b5649492be..40448fef5f 100644 --- a/src/openrct2/object/ObjectManager.cpp +++ b/src/openrct2/object/ObjectManager.cpp @@ -58,13 +58,6 @@ public: Object * GetLoadedObject(size_t index) override { - if (index >= OBJECT_ENTRY_COUNT) - { -#ifdef DEBUG - log_warning("Object index %u exceeds maximum of %d.", index, OBJECT_ENTRY_COUNT); -#endif - return nullptr; - } if (index >= _loadedObjects.size()) { return nullptr; @@ -82,11 +75,7 @@ public: return nullptr; } - size_t objectIndex = index; - for (sint32 i = 0; i < objectType; i++) - { - objectIndex += object_entry_group_counts[i]; - } + auto objectIndex = GetIndexFromTypeEntry(objectType, index); return GetLoadedObject(objectIndex); } @@ -121,7 +110,7 @@ public: loadedObject = ori->LoadedObject; if (loadedObject == nullptr) { - uint8 objectType = object_entry_get_type(entry); + uint8 objectType = object_entry_get_type(&ori->ObjectEntry); sint32 slot = FindSpareSlot(objectType); if (slot != -1) { @@ -164,6 +153,7 @@ public: else { SetNewLoadedObjectList(std::get<1>(loadedObjects)); + LoadDefaultObjects(); UpdateSceneryGroupIndexes(); ResetTypeToRideEntryIndexMap(); log_verbose("%u / %u new objects loaded", numNewLoadedObjects, requiredObjects.size()); @@ -241,6 +231,12 @@ public: return objects; } + void LoadDefaultObjects() override + { + // We currently will load new object types here that apply to all + // loaded RCT1 and RCT2 save files. + } + static rct_string_id GetObjectSourceGameString(const rct_object_entry * entry) { switch (object_entry_get_source_game(entry)) @@ -265,15 +261,27 @@ public: } private: + Object * LoadObject(const std::string &name) + { + rct_object_entry entry{}; + std::copy_n(name.c_str(), 8, entry.name); + return LoadObject(&entry); + } + sint32 FindSpareSlot(uint8 objectType) { - sint32 firstIndex = GetIndexFromTypeEntry(objectType, 0); - sint32 endIndex = firstIndex + object_entry_group_counts[objectType]; - for (sint32 i = firstIndex; i < endIndex; i++) + size_t firstIndex = GetIndexFromTypeEntry(objectType, 0); + size_t endIndex = firstIndex + object_entry_group_counts[objectType]; + for (size_t i = firstIndex; i < endIndex; i++) { - if (_loadedObjects.size() > (size_t)i && _loadedObjects[i] == nullptr) + if (_loadedObjects.size() <= i) { - return i; + _loadedObjects.resize(i + 1); + return (sint32)i; + } + else if (_loadedObjects[i] == nullptr) + { + return (sint32)i; } } return -1; @@ -565,14 +573,14 @@ private: Console::Error::WriteLine("[%s] Object could not be loaded.", objName); } - static sint32 GetIndexFromTypeEntry(uint8 objectType, uint8 entryIndex) + static sint32 GetIndexFromTypeEntry(sint32 objectType, size_t entryIndex) { sint32 result = 0; - for (uint8 i = 0; i < objectType; i++) + for (sint32 i = 0; i < objectType; i++) { result += object_entry_group_counts[i]; } - result += entryIndex; + result += (sint32)entryIndex; return result; } }; diff --git a/src/openrct2/object/ObjectManager.h b/src/openrct2/object/ObjectManager.h index 4dc90be046..cdb825f9f3 100644 --- a/src/openrct2/object/ObjectManager.h +++ b/src/openrct2/object/ObjectManager.h @@ -36,6 +36,7 @@ interface IObjectManager virtual Object * LoadObject(const rct_object_entry * entry) abstract; virtual bool LoadObjects(const rct_object_entry * entries, size_t count) abstract; + virtual void LoadDefaultObjects() abstract; virtual void UnloadObjects(const rct_object_entry * entries, size_t count) abstract; virtual void UnloadAll() abstract; diff --git a/src/openrct2/paint/tile_element/Surface.cpp b/src/openrct2/paint/tile_element/Surface.cpp index f6f695fa14..4d7f6344e6 100644 --- a/src/openrct2/paint/tile_element/Surface.cpp +++ b/src/openrct2/paint/tile_element/Surface.cpp @@ -499,6 +499,16 @@ static constexpr const tile_surface_boundary_data _tileSurfaceBoundaries[4] = }; // clang-format on +static uint32 get_edge_image(uint8 index, uint8 type) +{ + return _terrainEdgeSpriteIds[index][type]; +} + +static uint32 get_tunnel_image(uint8 index, uint8 type) +{ + return _terrainEdgeTunnelSpriteIds[index][type]; +} + static uint8 viewport_surface_paint_setup_get_relative_slope(const rct_tile_element * tileElement, sint32 rotation) { const uint8 slope = tileElement->properties.surface.slope; @@ -692,10 +702,10 @@ static void viewport_surface_draw_tile_side_bottom(paint_session * session, enum if (!is_csg_loaded() && edgeStyle >= TERRAIN_EDGE_RCT2_COUNT) edgeStyle = TERRAIN_EDGE_ROCK; - uint32 base_image_id = _terrainEdgeSpriteIds[edgeStyle][0]; + uint32 base_image_id = get_edge_image(edgeStyle, 0); if (gCurrentViewportFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE) { - base_image_id = _terrainEdgeSpriteIds[edgeStyle][1]; + base_image_id = get_edge_image(edgeStyle, 1); } if (edge == EDGE_BOTTOMRIGHT) @@ -783,10 +793,8 @@ static void viewport_surface_draw_tile_side_bottom(paint_session * session, enum boundBoxLength -= 16; } - uint32 image_id = _terrainEdgeTunnelSpriteIds[edgeStyle][tunnelType] + (edge == EDGE_BOTTOMRIGHT ? 2 : 0); - sub_98197C( - session, image_id, offset.x, offset.y, tunnelBounds.x, tunnelBounds.y, boundBoxLength - 1, zOffset, 0, 0, - boundBoxOffsetZ); + uint32 image_id = get_tunnel_image(edgeStyle, tunnelType) + (edge == EDGE_BOTTOMRIGHT ? 2 : 0); + sub_98197C(session, image_id, offset.x, offset.y, tunnelBounds.x, tunnelBounds.y, boundBoxLength - 1, zOffset, 0, 0, boundBoxOffsetZ); boundBoxOffsetZ = curHeight * 16; boundBoxLength = _tunnelHeights[tunnelType][1] * 16; @@ -797,10 +805,8 @@ static void viewport_surface_draw_tile_side_bottom(paint_session * session, enum boundBoxLength -= 16; } - image_id = _terrainEdgeTunnelSpriteIds[edgeStyle][tunnelType] + (edge == EDGE_BOTTOMRIGHT ? 2 : 0) + 1; - sub_98197C( - session, image_id, offset.x, offset.y, tunnelBounds.x, tunnelBounds.y, boundBoxLength - 1, curHeight * 16, - tunnelTopBoundBoxOffset.x, tunnelTopBoundBoxOffset.y, boundBoxOffsetZ); + image_id = get_tunnel_image(edgeStyle, tunnelType) + (edge == EDGE_BOTTOMRIGHT ? 2 : 0) + 1; + sub_98197C(session, image_id, offset.x, offset.y, tunnelBounds.x, tunnelBounds.y, boundBoxLength - 1, curHeight * 16, tunnelTopBoundBoxOffset.x, tunnelTopBoundBoxOffset.y, boundBoxOffsetZ); curHeight += _tunnelHeights[tunnelType][0]; tunnelIndex++; @@ -895,10 +901,10 @@ static void viewport_surface_draw_tile_side_top(paint_session * session, enum ed if (isWater) { - base_image_id = _terrainEdgeSpriteIds[terrain][2]; // var_08 + base_image_id = get_edge_image(terrain, 2); // var_08 if (gCurrentViewportFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE) { - base_image_id = _terrainEdgeSpriteIds[terrain][1]; // var_04 + base_image_id = get_edge_image(terrain, 1); // var_04 } base_image_id += (edge == EDGE_TOPLEFT ? 5 : 0); } @@ -907,12 +913,12 @@ static void viewport_surface_draw_tile_side_top(paint_session * session, enum ed if (!(gCurrentViewportFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE)) { const uint8 incline = (cl - al) + 1; - const uint32 image_id = _terrainEdgeSpriteIds[terrain][3] + (edge == EDGE_TOPLEFT ? 3 : 0) + incline; // var_c; + const uint32 image_id = get_edge_image(terrain, 3) + (edge == EDGE_TOPLEFT ? 3 : 0) + incline; // var_c; const sint16 y = (dl - al) * 16; paint_attach_to_previous_ps(session, image_id, 0, y); return; } - base_image_id = _terrainEdgeSpriteIds[terrain][1] + (edge == EDGE_TOPLEFT ? 5 : 0); // var_04 + base_image_id = get_edge_image(terrain, 1) + (edge == EDGE_TOPLEFT ? 5 : 0); // var_04 } uint8 cur_height = Math::Min(ch, ah); diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 25611330f6..3adc06d917 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -1834,6 +1834,9 @@ private: void LoadObjects() { + auto objectManager = OpenRCT2::GetContext()->GetObjectManager(); + objectManager->LoadDefaultObjects(); + LoadObjects(OBJECT_TYPE_RIDE, _rideEntries); LoadObjects(OBJECT_TYPE_SMALL_SCENERY, _smallSceneryEntries); LoadObjects(OBJECT_TYPE_LARGE_SCENERY, _largeSceneryEntries);