From f8271e93b01341957b4e77a67fa50eb1b2b1391e Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 14 May 2018 12:27:25 +0100 Subject: [PATCH 1/3] Refactor code base to allow easy addition of new object types --- .../windows/EditorObjectSelection.cpp | 240 +++++++++--------- src/openrct2/EditorObjectSelectionSession.cpp | 2 +- src/openrct2/interface/Window.h | 2 +- src/openrct2/object/ObjectJsonHelpers.cpp | 24 ++ src/openrct2/object/ObjectManager.cpp | 50 ++-- src/openrct2/object/ObjectManager.h | 1 + src/openrct2/paint/tile_element/Surface.cpp | 34 ++- src/openrct2/rct1/S4Importer.cpp | 3 + 8 files changed, 192 insertions(+), 164 deletions(-) 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); From 6f00e6aafe8228e3b323473ae509170eb85aa9bc Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 14 May 2018 13:05:59 +0100 Subject: [PATCH 2/3] Make ObjectRepositoryItem C++ --- .../windows/EditorObjectSelection.cpp | 27 ++++---- src/openrct2/EditorObjectSelectionSession.cpp | 15 +++-- src/openrct2/object/ObjectRepository.cpp | 66 +++++++------------ src/openrct2/object/ObjectRepository.h | 30 ++++----- src/openrct2/object/RideObject.cpp | 8 +-- src/openrct2/object/SceneryGroupObject.cpp | 9 +-- src/openrct2/ride/TrackDesign.cpp | 2 +- src/openrct2/ride/TrackDesignRepository.cpp | 4 +- 8 files changed, 67 insertions(+), 94 deletions(-) diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index dc5f2c2242..c224fd63a4 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -277,8 +277,8 @@ static void visible_list_dispose() static bool visible_list_sort_ride_name(const list_item &a, const list_item &b) { - auto nameA = a.repositoryItem->Name; - auto nameB = b.repositoryItem->Name; + auto nameA = a.repositoryItem->Name.c_str(); + auto nameB = b.repositoryItem->Name.c_str(); return strcmp(nameA, nameB) < 0; } @@ -361,7 +361,7 @@ static void window_editor_object_selection_init_widgets() if (!_window_editor_object_selection_widgets_initialised) { _window_editor_object_selection_widgets_initialised = true; - const auto &tabWidget = widgets[widgets.size() - 2]; + auto tabWidget = widgets[widgets.size() - 2]; for (sint32 i = 1; i < OBJECT_TYPE_COUNT; i++) { widgets.insert(widgets.end() - 1, tabWidget); @@ -1035,7 +1035,7 @@ static void window_editor_object_selection_paint(rct_window *w, rct_drawpixelinf y = w->y + widget->bottom + 3; width = w->width - w->widgets[WIDX_LIST].right - 6; set_format_arg(0, rct_string_id, STR_STRING); - set_format_arg(2, const char *, listItem->repositoryItem->Name); + set_format_arg(2, const char *, listItem->repositoryItem->Name.c_str()); gfx_draw_string_centred_clipped(dpi, STR_WINDOW_COLOUR_2_STRINGID, gCommonFormatArgs, COLOUR_BLACK, x, y, width); // Draw description of object @@ -1067,7 +1067,7 @@ static void window_editor_object_selection_paint(rct_window *w, rct_drawpixelinf // gfx_draw_string_right(dpi, stringId, nullptr, 2, w->x + w->width - 5, w->y + w->height - 3 - 12 - 14); // Draw object dat name - const char *path = path_get_filename(listItem->repositoryItem->Path); + const char *path = path_get_filename(listItem->repositoryItem->Path.c_str()); set_format_arg(0, rct_string_id, STR_STRING); set_format_arg(2, const char *, path); gfx_draw_string_right(dpi, STR_WINDOW_COLOUR_2_STRINGID, gCommonFormatArgs, COLOUR_BLACK, w->x + w->width - 5, w->y + w->height - 3 - 12); @@ -1134,7 +1134,7 @@ static void window_editor_object_selection_scrollpaint(rct_window *w, rct_drawpi } // Draw text - safe_strcpy(buffer, listItem.repositoryItem->Name, 256 - (buffer - bufferWithColour)); + safe_strcpy(buffer, listItem.repositoryItem->Name.c_str(), 256 - (buffer - bufferWithColour)); if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) { while (*buffer != 0 && *buffer != 9) buffer++; @@ -1317,8 +1317,7 @@ static bool filter_string(const ObjectRepositoryItem * item) return true; // Object doesn't have a name - utf8 *name = item->Name; - if (name == nullptr || name[0] == '\0') + if (item->Name.empty()) return false; // Get ride type @@ -1329,9 +1328,9 @@ static bool filter_string(const ObjectRepositoryItem * item) char type_lower[MAX_PATH]; char object_path[MAX_PATH]; char filter_lower[sizeof(_filter_string)]; - safe_strcpy(name_lower, name, MAX_PATH); + safe_strcpy(name_lower, item->Name.c_str(), MAX_PATH); safe_strcpy(type_lower, rideTypeName, MAX_PATH); - safe_strcpy(object_path, item->Path, MAX_PATH); + safe_strcpy(object_path, item->Path.c_str(), MAX_PATH); safe_strcpy(filter_lower, _filter_string, sizeof(_filter_string)); // Make use of lowercase characters only @@ -1383,9 +1382,9 @@ static bool filter_chunks(const ObjectRepositoryItem * item) uint8 rideType = 0; for (sint32 i = 0; i < MAX_RIDE_TYPES_PER_RIDE_ENTRY; i++) { - if (item->RideType[i] != RIDE_TYPE_NULL) + if (item->RideInfo.RideType[i] != RIDE_TYPE_NULL) { - rideType = item->RideType[i]; + rideType = item->RideInfo.RideType[i]; break; } } @@ -1426,12 +1425,12 @@ static rct_string_id get_ride_type_string_id(const ObjectRepositoryItem * item) rct_string_id result = STR_NONE; for (sint32 i = 0; i < MAX_RIDE_TYPES_PER_RIDE_ENTRY; i++) { - uint8 rideType = item->RideType[i]; + uint8 rideType = item->RideInfo.RideType[i]; if (rideType != RIDE_TYPE_NULL) { if (RideGroupManager::RideTypeHasRideGroups(rideType)) { - const RideGroup * rideGroup = RideGroupManager::RideGroupFind(rideType, item->RideGroupIndex); + const RideGroup * rideGroup = RideGroupManager::RideGroupFind(rideType, item->RideInfo.RideGroupIndex); result = rideGroup->Naming.name; } else diff --git a/src/openrct2/EditorObjectSelectionSession.cpp b/src/openrct2/EditorObjectSelectionSession.cpp index d654b0ec83..4f686f08bf 100644 --- a/src/openrct2/EditorObjectSelectionSession.cpp +++ b/src/openrct2/EditorObjectSelectionSession.cpp @@ -61,7 +61,7 @@ static void setup_track_manager_objects() { *selectionFlags |= OBJECT_SELECTION_FLAG_6; - for (auto rideType : item->RideType) + for (auto rideType : item->RideInfo.RideType) { if (rideType != RIDE_TYPE_NULL && ride_type_has_flag(rideType, RIDE_TYPE_FLAG_HAS_TRACK)) { @@ -90,7 +90,7 @@ static void setup_track_designer_objects() { *selectionFlags |= OBJECT_SELECTION_FLAG_6; - for (uint8 rideType : item->RideType) + for (uint8 rideType : item->RideInfo.RideType) { if (rideType != RIDE_TYPE_NULL) { @@ -420,8 +420,9 @@ sint32 window_editor_object_selection_select_object(uint8 bh, sint32 flags, cons uint8 objectType = object_entry_get_type(&item->ObjectEntry); if (objectType == OBJECT_TYPE_SCENERY_GROUP && (flags & (1 << 2))) { - for (sint32 j = 0; j < item->NumThemeObjects; j++) { - window_editor_object_selection_select_object(++bh, flags, &item->ThemeObjects[j]); + for (const auto& sgEntry : item->SceneryGroupInfo.Entries) + { + window_editor_object_selection_select_object(++bh, flags, &sgEntry); } } @@ -450,8 +451,10 @@ sint32 window_editor_object_selection_select_object(uint8 bh, sint32 flags, cons } if (objectType == OBJECT_TYPE_SCENERY_GROUP && (flags & (1 << 2))) { - for (uint16 j = 0; j < item->NumThemeObjects; j++) { - if (!window_editor_object_selection_select_object(++bh, flags, &item->ThemeObjects[j])) { + for (const auto& sgEntry : item->SceneryGroupInfo.Entries) + { + if (!window_editor_object_selection_select_object(++bh, flags, &sgEntry)) + { _maxObjectsWasHit = true; } } diff --git a/src/openrct2/object/ObjectRepository.cpp b/src/openrct2/object/ObjectRepository.cpp index 16dc9a9851..f4e21b4db8 100644 --- a/src/openrct2/object/ObjectRepository.cpp +++ b/src/openrct2/object/ObjectRepository.cpp @@ -121,8 +121,8 @@ public: { ObjectRepositoryItem item = { 0 }; item.ObjectEntry = *object->GetObjectEntry(); - item.Path = String::Duplicate(path); - item.Name = String::Duplicate(object->GetName()); + item.Path = path; + item.Name = object->GetName(); object->SetRepositoryItem(&item); delete object; return std::make_tuple(true, item); @@ -139,22 +139,22 @@ protected: switch (object_entry_get_type(&item.ObjectEntry)) { case OBJECT_TYPE_RIDE: - stream->WriteValue(item.RideFlags); + stream->WriteValue(item.RideInfo.RideFlags); for (sint32 i = 0; i < MAX_CATEGORIES_PER_RIDE; i++) { - stream->WriteValue(item.RideCategory[i]); + stream->WriteValue(item.RideInfo.RideCategory[i]); } for (sint32 i = 0; i < MAX_RIDE_TYPES_PER_RIDE_ENTRY; i++) { - stream->WriteValue(item.RideType[i]); + stream->WriteValue(item.RideInfo.RideType[i]); } - stream->WriteValue(item.RideGroupIndex); + stream->WriteValue(item.RideInfo.RideGroupIndex); break; case OBJECT_TYPE_SCENERY_GROUP: - stream->WriteValue(item.NumThemeObjects); - for (uint16 i = 0; i < item.NumThemeObjects; i++) + stream->WriteValue((uint16)item.SceneryGroupInfo.Entries.size()); + for (const auto& entry : item.SceneryGroupInfo.Entries) { - stream->WriteValue(item.ThemeObjects[i]); + stream->WriteValue(entry); } break; } @@ -162,7 +162,7 @@ protected: ObjectRepositoryItem Deserialise(IStream * stream) const override { - ObjectRepositoryItem item = { 0 }; + ObjectRepositoryItem item; item.ObjectEntry = stream->ReadValue(); item.Path = stream->ReadString(); @@ -170,25 +170,27 @@ protected: switch (object_entry_get_type(&item.ObjectEntry)) { case OBJECT_TYPE_RIDE: - item.RideFlags = stream->ReadValue(); + item.RideInfo.RideFlags = stream->ReadValue(); for (sint32 i = 0; i < 2; i++) { - item.RideCategory[i] = stream->ReadValue(); + item.RideInfo.RideCategory[i] = stream->ReadValue(); } for (sint32 i = 0; i < MAX_RIDE_TYPES_PER_RIDE_ENTRY; i++) { - item.RideType[i] = stream->ReadValue(); + item.RideInfo.RideType[i] = stream->ReadValue(); } - item.RideGroupIndex = stream->ReadValue(); + item.RideInfo.RideGroupIndex = stream->ReadValue(); break; case OBJECT_TYPE_SCENERY_GROUP: - item.NumThemeObjects = stream->ReadValue(); - item.ThemeObjects = Memory::AllocateArray(item.NumThemeObjects); - for (uint16 i = 0; i < item.NumThemeObjects; i++) { - item.ThemeObjects[i] = stream->ReadValue(); + auto numEntries = stream->ReadValue(); + item.SceneryGroupInfo.Entries = std::vector(numEntries); + for (size_t i = 0; i < numEntries; i++) + { + item.SceneryGroupInfo.Entries[i] = stream->ReadValue(); + } + break; } - break; } return item; } @@ -286,7 +288,7 @@ public: } else { - return ObjectFactory::CreateObjectFromLegacyFile(*this, ori->Path); + return ObjectFactory::CreateObjectFromLegacyFile(*this, ori->Path.c_str()); } } @@ -376,10 +378,6 @@ public: private: void ClearItems() { - for (auto &item : _items) - { - FreeItem(&item); - } _items.clear(); _itemMap.clear(); } @@ -437,8 +435,8 @@ private: } else { - Console::Error::WriteLine("Object conflict: '%s'", conflict->Path); - Console::Error::WriteLine(" : '%s'", item.Path); + Console::Error::WriteLine("Object conflict: '%s'", conflict->Path.c_str()); + Console::Error::WriteLine(" : '%s'", item.Path.c_str()); return false; } } @@ -454,22 +452,6 @@ private: } } - static void FreeItem(ObjectRepositoryItem * item) - { - Memory::Free(item->Path); - Memory::Free(item->Name); - item->Path = nullptr; - item->Name = nullptr; - - uint8 objectType = object_entry_get_type(&item->ObjectEntry); - switch (objectType) { - case OBJECT_TYPE_SCENERY_GROUP: - Memory::Free(item->ThemeObjects); - item->ThemeObjects = nullptr; - break; - } - } - static void SaveObject(const utf8 * path, const rct_object_entry * entry, const void * data, size_t dataSize, diff --git a/src/openrct2/object/ObjectRepository.h b/src/openrct2/object/ObjectRepository.h index ffd03cae6f..b46d0f9e98 100644 --- a/src/openrct2/object/ObjectRepository.h +++ b/src/openrct2/object/ObjectRepository.h @@ -40,24 +40,20 @@ struct ObjectRepositoryItem { size_t Id; rct_object_entry ObjectEntry; - utf8 * Path; - utf8 * Name; - Object * LoadedObject; - union + std::string Path; + std::string Name; + Object * LoadedObject{}; + struct { - struct - { - uint8 RideFlags; - uint8 RideCategory[2]; - uint8 RideType[MAX_RIDE_TYPES_PER_RIDE_ENTRY]; - uint8 RideGroupIndex; - }; - struct - { - uint16 NumThemeObjects; - rct_object_entry * ThemeObjects; - }; - }; + uint8 RideFlags; + uint8 RideCategory[2]; + uint8 RideType[MAX_RIDE_TYPES_PER_RIDE_ENTRY]; + uint8 RideGroupIndex; + } RideInfo; + struct + { + std::vector Entries; + } SceneryGroupInfo; }; interface IObjectRepository diff --git a/src/openrct2/object/RideObject.cpp b/src/openrct2/object/RideObject.cpp index b142bad575..3def718bde 100644 --- a/src/openrct2/object/RideObject.cpp +++ b/src/openrct2/object/RideObject.cpp @@ -372,15 +372,15 @@ void RideObject::SetRepositoryItem(ObjectRepositoryItem * item) const { for (sint32 i = 0; i < RCT2_MAX_RIDE_TYPES_PER_RIDE_ENTRY; i++) { - item->RideType[i] = _legacyType.ride_type[i]; + item->RideInfo.RideType[i] = _legacyType.ride_type[i]; } for (sint32 i = 0; i < RCT2_MAX_CATEGORIES_PER_RIDE; i++) { - item->RideCategory[i] = _legacyType.category[i]; + item->RideInfo.RideCategory[i] = _legacyType.category[i]; } uint8 flags = 0; - item->RideFlags = flags; + item->RideInfo.RideFlags = flags; // Find the first non-null ride type, to be used when checking the ride group uint8 rideTypeIdx = ride_entry_get_first_non_null_ride_type(&_legacyType); @@ -408,7 +408,7 @@ void RideObject::SetRepositoryItem(ObjectRepositoryItem * item) const } } - item->RideGroupIndex = rideGroupIndex; + item->RideInfo.RideGroupIndex = rideGroupIndex; } void RideObject::ReadLegacyVehicle(IReadObjectContext * context, IStream * stream, rct_ride_entry_vehicle * vehicle) diff --git a/src/openrct2/object/SceneryGroupObject.cpp b/src/openrct2/object/SceneryGroupObject.cpp index 32c42cc6af..d946f1f454 100644 --- a/src/openrct2/object/SceneryGroupObject.cpp +++ b/src/openrct2/object/SceneryGroupObject.cpp @@ -107,14 +107,7 @@ void SceneryGroupObject::UpdateEntryIndexes() void SceneryGroupObject::SetRepositoryItem(ObjectRepositoryItem * item) const { - Memory::Free(item->ThemeObjects); - - item->NumThemeObjects = (uint16)_items.size(); - item->ThemeObjects = Memory::AllocateArray(_items.size()); - for (size_t i = 0; i < _items.size(); i++) - { - item->ThemeObjects[i] = _items[i]; - } + item->SceneryGroupInfo.Entries = _items; } std::vector SceneryGroupObject::ReadItems(IStream * stream) diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 0eb3006313..bdaa0ee993 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -1900,7 +1900,7 @@ static money32 place_track_design(sint16 x, sint16 y, sint16 z, uint8 flags, uin const ObjectRepositoryItem * ori = object_repository_find_object_by_name(rideEntryObject->name); if (ori != nullptr) { - uint8 rideGroupIndex = ori->RideGroupIndex; + uint8 rideGroupIndex = ori->RideInfo.RideGroupIndex; const RideGroup * td6RideGroup = RideGroupManager::RideGroupFind(td6->type, rideGroupIndex); uint8 * availableRideEntries = get_ride_entry_indices_for_ride_type(td6->type); diff --git a/src/openrct2/ride/TrackDesignRepository.cpp b/src/openrct2/ride/TrackDesignRepository.cpp index 96c56eafb4..1ab16851ca 100644 --- a/src/openrct2/ride/TrackDesignRepository.cpp +++ b/src/openrct2/ride/TrackDesignRepository.cpp @@ -205,7 +205,7 @@ public: } const ObjectRepositoryItem * ori = repo->FindObject(item.ObjectEntry.c_str()); - uint8 rideGroupIndex = (ori != nullptr) ? ori->RideGroupIndex : 0; + uint8 rideGroupIndex = (ori != nullptr) ? ori->RideInfo.RideGroupIndex : 0; const RideGroup * itemRideGroup = RideGroupManager::RideGroupFind(rideType, rideGroupIndex); if (itemRideGroup != nullptr && itemRideGroup->Equals(rideGroup)) @@ -270,7 +270,7 @@ public: } const ObjectRepositoryItem * ori = repo->FindObject(item.ObjectEntry.c_str()); - uint8 rideGroupIndex = (ori != nullptr) ? ori->RideGroupIndex : 0; + uint8 rideGroupIndex = (ori != nullptr) ? ori->RideInfo.RideGroupIndex : 0; const RideGroup * itemRideGroup = RideGroupManager::RideGroupFind(rideType, rideGroupIndex); if (itemRideGroup != nullptr && itemRideGroup->Equals(rideGroup)) From 58241d33fcdf55dbe3b4d15046f7e05fe43b0fd6 Mon Sep 17 00:00:00 2001 From: Ted John Date: Tue, 15 May 2018 12:08:20 +0100 Subject: [PATCH 3/3] Use constant for max ride categories --- src/openrct2/object/ObjectRepository.cpp | 2 +- src/openrct2/object/ObjectRepository.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openrct2/object/ObjectRepository.cpp b/src/openrct2/object/ObjectRepository.cpp index f4e21b4db8..5bb854d5ff 100644 --- a/src/openrct2/object/ObjectRepository.cpp +++ b/src/openrct2/object/ObjectRepository.cpp @@ -171,7 +171,7 @@ protected: switch (object_entry_get_type(&item.ObjectEntry)) { case OBJECT_TYPE_RIDE: item.RideInfo.RideFlags = stream->ReadValue(); - for (sint32 i = 0; i < 2; i++) + for (sint32 i = 0; i < MAX_CATEGORIES_PER_RIDE; i++) { item.RideInfo.RideCategory[i] = stream->ReadValue(); } diff --git a/src/openrct2/object/ObjectRepository.h b/src/openrct2/object/ObjectRepository.h index b46d0f9e98..7664d3149a 100644 --- a/src/openrct2/object/ObjectRepository.h +++ b/src/openrct2/object/ObjectRepository.h @@ -46,7 +46,7 @@ struct ObjectRepositoryItem struct { uint8 RideFlags; - uint8 RideCategory[2]; + uint8 RideCategory[MAX_CATEGORIES_PER_RIDE]; uint8 RideType[MAX_RIDE_TYPES_PER_RIDE_ENTRY]; uint8 RideGroupIndex; } RideInfo;