From daa00147d5e1df08d9da19adb2d9df63e99b8c91 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sun, 16 Jun 2019 21:17:02 +0200 Subject: [PATCH 01/10] Split off RCT12ResearchItem --- src/openrct2/management/Research.cpp | 10 --------- src/openrct2/rct12/RCT12.cpp | 15 ++++++++++++++ src/openrct2/rct12/RCT12.h | 31 ++++++++++++++++++++++++++++ src/openrct2/scenario/Scenario.h | 2 +- 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/openrct2/management/Research.cpp b/src/openrct2/management/Research.cpp index 581beed56e88..48f10c4743cd 100644 --- a/src/openrct2/management/Research.cpp +++ b/src/openrct2/management/Research.cpp @@ -1006,13 +1006,3 @@ bool rct_research_item::IsInventedEndMarker() const { return rawValue == RESEARCHED_ITEMS_SEPARATOR; } - -bool rct_research_item::IsUninventedEndMarker() const -{ - return rawValue == RESEARCHED_ITEMS_END; -} - -bool rct_research_item::IsRandomEndMarker() const -{ - return rawValue == RESEARCHED_ITEMS_END_2; -} diff --git a/src/openrct2/rct12/RCT12.cpp b/src/openrct2/rct12/RCT12.cpp index c94e2c2933d4..c3f3e5c9c302 100644 --- a/src/openrct2/rct12/RCT12.cpp +++ b/src/openrct2/rct12/RCT12.cpp @@ -915,3 +915,18 @@ void RCT12BannerElement::SetAllowedEdges(uint8_t newEdges) flags &= ~0b00001111; flags |= (newEdges & 0b00001111); } + +bool RCT12ResearchItem::IsInventedEndMarker() const +{ + return rawValue == RCT12_RESEARCHED_ITEMS_SEPARATOR; +} + +bool RCT12ResearchItem::IsUninventedEndMarker() const +{ + return rawValue == RCT12_RESEARCHED_ITEMS_END; +} + +bool RCT12ResearchItem::IsRandomEndMarker() const +{ + return rawValue == RCT12_RESEARCHED_ITEMS_END_2; +} diff --git a/src/openrct2/rct12/RCT12.h b/src/openrct2/rct12/RCT12.h index 8e8c5821fb1a..bfcbce33d4ac 100644 --- a/src/openrct2/rct12/RCT12.h +++ b/src/openrct2/rct12/RCT12.h @@ -49,6 +49,7 @@ constexpr uint16_t const RCT12_MAX_INVERSIONS = 31; constexpr uint16_t const RCT12_MAX_GOLF_HOLES = 31; constexpr uint16_t const RCT12_MAX_HELICES = 31; +<<<<<<< HEAD enum class RCT12TrackDesignVersion : uint8_t { TD4, @@ -56,6 +57,14 @@ enum class RCT12TrackDesignVersion : uint8_t TD6, unknown }; +======= +// Everything before this point has been researched +#define RCT12_RESEARCHED_ITEMS_SEPARATOR (-1) +// Everything before this point and after separator still requires research +#define RCT12_RESEARCHED_ITEMS_END (-2) +// Extra end of list entry. Leftover from RCT1. +#define RCT12_RESEARCHED_ITEMS_END_2 (-3) +>>>>>>> 04e9e626d... Split off RCT12ResearchItem #pragma pack(push, 1) @@ -658,6 +667,28 @@ struct RCT12MapAnimation }; assert_struct_size(RCT12MapAnimation, 6); +struct RCT12ResearchItem +{ + // Bit 16 (0: scenery entry, 1: ride entry) + union + { + int32_t rawValue; + struct + { + uint8_t entryIndex; + uint8_t baseRideType; + uint8_t type; // 0: scenery entry, 1: ride entry + uint8_t flags; + }; + }; + uint8_t category; + + bool IsInventedEndMarker() const; + bool IsRandomEndMarker() const; + bool IsUninventedEndMarker() const; +}; +assert_struct_size(RCT12ResearchItem, 5); + #pragma pack(pop) bool is_user_string_id(rct_string_id stringId); diff --git a/src/openrct2/scenario/Scenario.h b/src/openrct2/scenario/Scenario.h index ecb9918236f4..5b6c97483e72 100644 --- a/src/openrct2/scenario/Scenario.h +++ b/src/openrct2/scenario/Scenario.h @@ -238,7 +238,7 @@ struct rct_s6_data uint8_t last_entrance_style; uint8_t rct1_water_colour; uint8_t pad_01358842[2]; - rct_research_item research_items[MAX_RESEARCH_ITEMS]; + RCT12ResearchItem research_items[MAX_RESEARCH_ITEMS]; uint16_t map_base_z; char scenario_name[64]; char scenario_description[256]; From c3fdb728d1dab07d4284ddc4373cda0af3fcc296 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sun, 16 Jun 2019 21:21:06 +0200 Subject: [PATCH 02/10] Rename rct_research_item to ResearchItem --- .../windows/EditorInventionsList.cpp | 42 +++++++-------- src/openrct2/EditorObjectSelectionSession.cpp | 4 +- src/openrct2/interface/Window_internal.h | 4 +- src/openrct2/management/Research.cpp | 52 +++++++++---------- src/openrct2/management/Research.h | 18 +++---- src/openrct2/rct1/S4Importer.cpp | 4 +- 6 files changed, 62 insertions(+), 62 deletions(-) diff --git a/src/openrct2-ui/windows/EditorInventionsList.cpp b/src/openrct2-ui/windows/EditorInventionsList.cpp index ea7004781c0e..e4472402d4a5 100644 --- a/src/openrct2-ui/windows/EditorInventionsList.cpp +++ b/src/openrct2-ui/windows/EditorInventionsList.cpp @@ -84,7 +84,7 @@ static void window_editor_inventions_list_drag_cursor(rct_window *w, rct_widgeti static void window_editor_inventions_list_drag_moved(rct_window* w, int32_t x, int32_t y); static void window_editor_inventions_list_drag_paint(rct_window *w, rct_drawpixelinfo *dpi); -static rct_string_id window_editor_inventions_list_prepare_name(const rct_research_item * researchItem, bool withGap); +static rct_string_id window_editor_inventions_list_prepare_name(const ResearchItem * researchItem, bool withGap); // 0x0098177C static rct_window_event_list window_editor_inventions_list_events = { @@ -152,7 +152,7 @@ static rct_window_event_list window_editor_inventions_list_drag_events = { #pragma endregion -static rct_research_item *_editorInventionsListDraggedItem; +static ResearchItem *_editorInventionsListDraggedItem; static constexpr const rct_string_id EditorInventionsResearchCategories[] = { STR_RESEARCH_NEW_TRANSPORT_RIDES, @@ -165,8 +165,8 @@ static constexpr const rct_string_id EditorInventionsResearchCategories[] = { }; // clang-format on -static void window_editor_inventions_list_drag_open(rct_research_item* researchItem); -static void move_research_item(rct_research_item* beforeItem); +static void window_editor_inventions_list_drag_open(ResearchItem* researchItem); +static void move_research_item(ResearchItem* beforeItem); /** * @@ -196,10 +196,10 @@ static void research_rides_setup() * * rct2: 0x006855E7 */ -static void move_research_item(rct_research_item* beforeItem) +static void move_research_item(ResearchItem* beforeItem) { rct_window* w; - rct_research_item *researchItem, draggedItem; + ResearchItem *researchItem, draggedItem; if (_editorInventionsListDraggedItem + 1 == beforeItem) return; @@ -240,9 +240,9 @@ static void move_research_item(rct_research_item* beforeItem) * * rct2: 0x0068558E */ -static rct_research_item* window_editor_inventions_list_get_item_from_scroll_y(int32_t scrollIndex, int32_t y) +static ResearchItem* window_editor_inventions_list_get_item_from_scroll_y(int32_t scrollIndex, int32_t y) { - rct_research_item* researchItem; + ResearchItem* researchItem; researchItem = gResearchItems; @@ -272,9 +272,9 @@ static rct_research_item* window_editor_inventions_list_get_item_from_scroll_y(i * * rct2: 0x006855BB */ -static rct_research_item* window_editor_inventions_list_get_item_from_scroll_y_include_seps(int32_t scrollIndex, int32_t y) +static ResearchItem* window_editor_inventions_list_get_item_from_scroll_y_include_seps(int32_t scrollIndex, int32_t y) { - rct_research_item* researchItem; + ResearchItem* researchItem; researchItem = gResearchItems; @@ -300,7 +300,7 @@ static rct_research_item* window_editor_inventions_list_get_item_from_scroll_y_i return researchItem; } -static rct_research_item* get_research_item_at(int32_t x, int32_t y) +static ResearchItem* get_research_item_at(int32_t x, int32_t y) { rct_window* w = window_find_by_class(WC_EDITOR_INVENTION_LIST); if (w != nullptr && w->x <= x && w->y < y && w->x + w->width > x && w->y + w->height > y) @@ -443,7 +443,7 @@ static void window_editor_inventions_list_update(rct_window* w) */ static void window_editor_inventions_list_scrollgetheight(rct_window* w, int32_t scrollIndex, int32_t* width, int32_t* height) { - rct_research_item* researchItem; + ResearchItem* researchItem; *height = 0; @@ -468,7 +468,7 @@ static void window_editor_inventions_list_scrollgetheight(rct_window* w, int32_t */ static void window_editor_inventions_list_scrollmousedown(rct_window* w, int32_t scrollIndex, int32_t x, int32_t y) { - rct_research_item* researchItem; + ResearchItem* researchItem; researchItem = window_editor_inventions_list_get_item_from_scroll_y(scrollIndex, y); if (researchItem == nullptr) @@ -488,7 +488,7 @@ static void window_editor_inventions_list_scrollmousedown(rct_window* w, int32_t */ static void window_editor_inventions_list_scrollmouseover(rct_window* w, int32_t scrollIndex, int32_t x, int32_t y) { - rct_research_item* researchItem; + ResearchItem* researchItem; researchItem = window_editor_inventions_list_get_item_from_scroll_y(scrollIndex, y); if (researchItem != w->research_item) @@ -511,7 +511,7 @@ static void window_editor_inventions_list_scrollmouseover(rct_window* w, int32_t static void window_editor_inventions_list_cursor( rct_window* w, rct_widgetindex widgetIndex, int32_t x, int32_t y, int32_t* cursorId) { - rct_research_item* researchItem; + ResearchItem* researchItem; int32_t scrollIndex; switch (widgetIndex) @@ -589,7 +589,7 @@ static void window_editor_inventions_list_invalidate(rct_window* w) static void window_editor_inventions_list_paint(rct_window* w, rct_drawpixelinfo* dpi) { rct_widget* widget; - rct_research_item* researchItem; + ResearchItem* researchItem; rct_string_id stringId; int32_t x, y, width; @@ -676,7 +676,7 @@ static void window_editor_inventions_list_scrollpaint(rct_window* w, rct_drawpix uint8_t paletteIndex = ColourMapA[w->colours[1]].mid_light; gfx_clear(dpi, paletteIndex); - rct_research_item* researchItem = gResearchItems; + ResearchItem* researchItem = gResearchItems; int32_t researchItemEndMarker; if (scrollIndex == 1) @@ -786,7 +786,7 @@ static void window_editor_inventions_list_scrollpaint(rct_window* w, rct_drawpix * * rct2: 0x006852F4 */ -static void window_editor_inventions_list_drag_open(rct_research_item* researchItem) +static void window_editor_inventions_list_drag_open(ResearchItem* researchItem) { char buffer[256], *ptr; int32_t stringWidth; @@ -833,7 +833,7 @@ static void window_editor_inventions_list_drag_cursor( rct_window* inventionListWindow = window_find_by_class(WC_EDITOR_INVENTION_LIST); if (inventionListWindow != nullptr) { - rct_research_item* researchItem = get_research_item_at(x, y); + ResearchItem* researchItem = get_research_item_at(x, y); if (researchItem != inventionListWindow->research_item) { inventionListWindow->Invalidate(); @@ -849,7 +849,7 @@ static void window_editor_inventions_list_drag_cursor( */ static void window_editor_inventions_list_drag_moved(rct_window* w, int32_t x, int32_t y) { - rct_research_item* researchItem; + ResearchItem* researchItem; // Skip always researched items, so that the dragged item gets placed underneath them do @@ -881,7 +881,7 @@ static void window_editor_inventions_list_drag_paint(rct_window* w, rct_drawpixe gfx_draw_string_left(dpi, drawString, gCommonFormatArgs, COLOUR_BLACK | COLOUR_FLAG_OUTLINE, x, y); } -static rct_string_id window_editor_inventions_list_prepare_name(const rct_research_item* researchItem, bool withGap) +static rct_string_id window_editor_inventions_list_prepare_name(const ResearchItem* researchItem, bool withGap) { rct_string_id drawString; rct_string_id stringId = research_item_get_name(researchItem); diff --git a/src/openrct2/EditorObjectSelectionSession.cpp b/src/openrct2/EditorObjectSelectionSession.cpp index a8bc5285577a..54a30733578e 100644 --- a/src/openrct2/EditorObjectSelectionSession.cpp +++ b/src/openrct2/EditorObjectSelectionSession.cpp @@ -292,7 +292,7 @@ static void remove_selected_objects_from_research(const rct_object_entry* instal for (auto rideType : rideEntry->ride_type) { - rct_research_item tmp = {}; + ResearchItem tmp = {}; tmp.type = RESEARCH_ENTRY_TYPE_RIDE; tmp.entryIndex = entry_index; tmp.baseRideType = rideType; @@ -301,7 +301,7 @@ static void remove_selected_objects_from_research(const rct_object_entry* instal } else if (entry_type == OBJECT_TYPE_SCENERY_GROUP) { - rct_research_item tmp = {}; + ResearchItem tmp = {}; tmp.type = RESEARCH_ENTRY_TYPE_SCENERY; tmp.entryIndex = entry_index; research_remove(&tmp); diff --git a/src/openrct2/interface/Window_internal.h b/src/openrct2/interface/Window_internal.h index 1bac5b17c1f9..5297737acbda 100644 --- a/src/openrct2/interface/Window_internal.h +++ b/src/openrct2/interface/Window_internal.h @@ -14,7 +14,7 @@ #include #include -struct rct_research_item; +struct ResearchItem; struct rct_object_entry; /** @@ -79,7 +79,7 @@ struct rct_window { // 0x494 uint32_t highlighted_item; uint16_t ride_colour; - rct_research_item* research_item; + ResearchItem* research_item; rct_object_entry* object_entry; const scenario_index_entry* highlighted_scenario; struct diff --git a/src/openrct2/management/Research.cpp b/src/openrct2/management/Research.cpp index 48f10c4743cd..81dac49050de 100644 --- a/src/openrct2/management/Research.cpp +++ b/src/openrct2/management/Research.cpp @@ -46,13 +46,13 @@ uint8_t gResearchFundingLevel; uint8_t gResearchPriorities; uint16_t gResearchProgress; uint8_t gResearchProgressStage; -rct_research_item gResearchLastItem; +ResearchItem gResearchLastItem; uint8_t gResearchExpectedMonth; uint8_t gResearchExpectedDay; -rct_research_item gResearchNextItem; +ResearchItem gResearchNextItem; // 0x01358844[500] -rct_research_item gResearchItems[MAX_RESEARCH_ITEMS]; +ResearchItem gResearchItems[MAX_RESEARCH_ITEMS]; // 0x00EE787C uint8_t gResearchUncompletedCategories; @@ -81,7 +81,7 @@ void research_reset_items() void research_update_uncompleted_types() { int32_t uncompletedResearchTypes = 0; - rct_research_item* researchItem = gResearchItems; + ResearchItem* researchItem = gResearchItems; while (researchItem++->rawValue != RESEARCHED_ITEMS_SEPARATOR) ; @@ -133,7 +133,7 @@ static void research_invalidate_related_windows() */ static void research_next_design() { - rct_research_item *firstUnresearchedItem, *researchItem, tmp; + ResearchItem *firstUnresearchedItem, *researchItem, tmp; int32_t ignoreActiveResearchTypes; // Skip already researched items @@ -193,7 +193,7 @@ static void research_next_design() * * rct2: 0x006848D4 */ -void research_finish_item(rct_research_item* researchItem) +void research_finish_item(ResearchItem* researchItem) { gResearchLastItem = *researchItem; research_invalidate_related_windows(); @@ -230,7 +230,7 @@ void research_finish_item(rct_research_item* researchItem) bool seenRideEntry[MAX_RIDE_OBJECTS]{}; - rct_research_item* researchItem2 = gResearchItems; + ResearchItem* researchItem2 = gResearchItems; for (; researchItem2->rawValue != RESEARCHED_ITEMS_END; researchItem2++) { if (researchItem2->rawValue != RESEARCHED_ITEMS_SEPARATOR && researchItem2->type == RESEARCH_ENTRY_TYPE_RIDE) @@ -388,7 +388,7 @@ void research_update() void research_process_random_items() { - rct_research_item* research = gResearchItems; + ResearchItem* research = gResearchItems; for (; research->rawValue != RESEARCHED_ITEMS_END; research++) { } @@ -401,9 +401,9 @@ void research_process_random_items() continue; } - rct_research_item* edx = nullptr; - rct_research_item* ebp = nullptr; - rct_research_item* inner_research = gResearchItems; + ResearchItem* edx = nullptr; + ResearchItem* ebp = nullptr; + ResearchItem* inner_research = gResearchItems; do { if (research->rawValue == inner_research->rawValue) @@ -441,7 +441,7 @@ void research_reset_current_item() set_all_scenery_items_invented(); set_all_scenery_groups_not_invented(); - for (rct_research_item* research = gResearchItems; research->rawValue != RESEARCHED_ITEMS_SEPARATOR; research++) + for (ResearchItem* research = gResearchItems; research->rawValue != RESEARCHED_ITEMS_SEPARATOR; research++) { research_finish_item(research); } @@ -457,7 +457,7 @@ void research_reset_current_item() */ static void research_insert_unresearched(int32_t rawValue, int32_t category) { - rct_research_item *researchItem, *researchItem2; + ResearchItem *researchItem, *researchItem2; researchItem = gResearchItems; do @@ -470,7 +470,7 @@ static void research_insert_unresearched(int32_t rawValue, int32_t category) { researchItem2++; } - memmove(researchItem + 1, researchItem, (researchItem2 - researchItem + 1) * sizeof(rct_research_item)); + memmove(researchItem + 1, researchItem, (researchItem2 - researchItem + 1) * sizeof(ResearchItem)); // Place new item researchItem->rawValue = rawValue; @@ -486,7 +486,7 @@ static void research_insert_unresearched(int32_t rawValue, int32_t category) */ static void research_insert_researched(int32_t rawValue, uint8_t category) { - rct_research_item *researchItem, *researchItem2; + ResearchItem *researchItem, *researchItem2; researchItem = gResearchItems; // First check to make sure that entry is not already accounted for @@ -508,7 +508,7 @@ static void research_insert_researched(int32_t rawValue, uint8_t category) { researchItem2++; } - memmove(researchItem + 1, researchItem, (researchItem2 - researchItem + 1) * sizeof(rct_research_item)); + memmove(researchItem + 1, researchItem, (researchItem2 - researchItem + 1) * sizeof(ResearchItem)); // Place new item researchItem->rawValue = rawValue; @@ -522,9 +522,9 @@ static void research_insert_researched(int32_t rawValue, uint8_t category) * * rct2: 0x006857CF */ -void research_remove(rct_research_item* researchItem) +void research_remove(ResearchItem* researchItem) { - for (rct_research_item* researchItem2 = gResearchItems; researchItem2->rawValue != RESEARCHED_ITEMS_END; researchItem2++) + for (ResearchItem* researchItem2 = gResearchItems; researchItem2->rawValue != RESEARCHED_ITEMS_END; researchItem2++) { if (researchItem2->rawValue == researchItem->rawValue) { @@ -773,7 +773,7 @@ void set_every_ride_entry_not_invented() * * rct2: 0x0068563D */ -rct_string_id research_item_get_name(const rct_research_item* researchItem) +rct_string_id research_item_get_name(const ResearchItem* researchItem) { if (researchItem->type == RESEARCH_ENTRY_TYPE_RIDE) { @@ -824,7 +824,7 @@ rct_string_id research_get_friendly_base_ride_type_name(uint8_t trackType, rct_r */ void research_remove_flags() { - for (rct_research_item* research = gResearchItems; research->rawValue != RESEARCHED_ITEMS_END_2; research++) + for (ResearchItem* research = gResearchItems; research->rawValue != RESEARCHED_ITEMS_END_2; research++) { // Clear the always researched flags. if (research->rawValue > RESEARCHED_ITEMS_SEPARATOR) @@ -839,7 +839,7 @@ void research_fix() // Fix invalid research items for (int32_t i = 0; i < MAX_RESEARCH_ITEMS; i++) { - rct_research_item* researchItem = &gResearchItems[i]; + ResearchItem* researchItem = &gResearchItems[i]; if (researchItem->rawValue == RESEARCHED_ITEMS_SEPARATOR) continue; if (researchItem->rawValue == RESEARCHED_ITEMS_END) @@ -914,7 +914,7 @@ void research_fix() void research_items_make_all_unresearched() { - rct_research_item *researchItem, *nextResearchItem, researchItemTemp; + ResearchItem *researchItem, *nextResearchItem, researchItemTemp; int32_t sorted; do @@ -944,7 +944,7 @@ void research_items_make_all_unresearched() void research_items_make_all_researched() { - rct_research_item *researchItem, researchItemTemp; + ResearchItem *researchItem, researchItemTemp; // Find separator for (researchItem = gResearchItems; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR; researchItem++) @@ -967,7 +967,7 @@ void research_items_make_all_researched() */ void research_items_shuffle() { - rct_research_item *researchItem, *researchOrderBase, researchItemTemp; + ResearchItem *researchItem, *researchOrderBase, researchItemTemp; int32_t i, numNonResearchedItems; // Skip pre-researched items @@ -995,14 +995,14 @@ void research_items_shuffle() } } -bool research_item_is_always_researched(rct_research_item* researchItem) +bool research_item_is_always_researched(ResearchItem* researchItem) { return (researchItem->flags & (RESEARCH_ENTRY_FLAG_RIDE_ALWAYS_RESEARCHED | RESEARCH_ENTRY_FLAG_SCENERY_SET_ALWAYS_RESEARCHED)) != 0; } -bool rct_research_item::IsInventedEndMarker() const +bool ResearchItem::IsInventedEndMarker() const { return rawValue == RESEARCHED_ITEMS_SEPARATOR; } diff --git a/src/openrct2/management/Research.h b/src/openrct2/management/Research.h index 339d8115be48..63c4b2d1e4a4 100644 --- a/src/openrct2/management/Research.h +++ b/src/openrct2/management/Research.h @@ -16,7 +16,7 @@ struct rct_ride_entry; #pragma pack(push, 1) -struct rct_research_item +struct ResearchItem { // Bit 16 (0: scenery entry, 1: ride entry) union @@ -36,7 +36,7 @@ struct rct_research_item bool IsRandomEndMarker() const; bool IsUninventedEndMarker() const; }; -assert_struct_size(rct_research_item, 5); +assert_struct_size(ResearchItem, 5); #pragma pack(pop) enum @@ -100,10 +100,10 @@ extern uint16_t gResearchProgress; extern uint8_t gResearchProgressStage; extern uint8_t gResearchExpectedMonth; extern uint8_t gResearchExpectedDay; -extern rct_research_item gResearchLastItem; -extern rct_research_item gResearchNextItem; +extern ResearchItem gResearchLastItem; +extern ResearchItem gResearchNextItem; -extern rct_research_item gResearchItems[MAX_RESEARCH_ITEMS]; +extern ResearchItem gResearchItems[MAX_RESEARCH_ITEMS]; extern uint8_t gResearchUncompletedCategories; extern bool gSilentResearch; @@ -115,9 +115,9 @@ void research_populate_list_random(); void research_populate_list_researched(); void research_process_random_items(); -void research_finish_item(rct_research_item* researchItem); +void research_finish_item(ResearchItem* researchItem); void research_insert(int32_t researched, int32_t rawValue, uint8_t category); -void research_remove(rct_research_item* researchItem); +void research_remove(ResearchItem* researchItem); void research_insert_ride_entry(uint8_t entryIndex, bool researched); void research_insert_scenery_group_entry(uint8_t entryIndex, bool researched); @@ -139,7 +139,7 @@ void set_every_ride_type_invented(); void set_every_ride_type_not_invented(); void set_every_ride_entry_invented(); void set_every_ride_entry_not_invented(); -rct_string_id research_item_get_name(const rct_research_item* researchItem); +rct_string_id research_item_get_name(const ResearchItem* researchItem); rct_string_id research_get_friendly_base_ride_type_name(uint8_t trackType, rct_ride_entry* rideEntry); void research_remove_flags(); void research_fix(); @@ -147,4 +147,4 @@ void research_fix(); void research_items_make_all_unresearched(); void research_items_make_all_researched(); void research_items_shuffle(); -bool research_item_is_always_researched(rct_research_item* researchItem); +bool research_item_is_always_researched(ResearchItem* researchItem); diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index ec2ecd11182b..8cd788f202a2 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -2496,7 +2496,7 @@ class S4Importer final : public IParkImporter uint8_t researchItem = src->Assoc & 0x000000FF; uint8_t researchType = (src->Assoc & 0x00FF0000) >> 16; - rct_research_item tmpResearchItem = {}; + ResearchItem tmpResearchItem = {}; ConvertResearchEntry(&tmpResearchItem, researchItem, researchType); dst->Assoc = (uint32_t)tmpResearchItem.rawValue; } @@ -2540,7 +2540,7 @@ class S4Importer final : public IParkImporter gTotalRideValueForMoney = _s4.total_ride_value_for_money; } - void ConvertResearchEntry(rct_research_item* dst, uint8_t srcItem, uint8_t srcType) + void ConvertResearchEntry(ResearchItem* dst, uint8_t srcItem, uint8_t srcType) { dst->rawValue = RESEARCHED_ITEMS_SEPARATOR; if (srcType == RCT1_RESEARCH_TYPE_RIDE) From b1fb75e4961dd4e79ee0459b92b4036b343b570a Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sun, 16 Jun 2019 23:32:31 +0200 Subject: [PATCH 03/10] Move everything to research vectors --- .../windows/EditorInventionsList.cpp | 82 ++-- src/openrct2/management/Research.cpp | 350 +++++++----------- src/openrct2/management/Research.h | 6 +- src/openrct2/rct2/S6Exporter.cpp | 13 +- src/openrct2/rct2/S6Importer.cpp | 20 +- 5 files changed, 194 insertions(+), 277 deletions(-) diff --git a/src/openrct2-ui/windows/EditorInventionsList.cpp b/src/openrct2-ui/windows/EditorInventionsList.cpp index e4472402d4a5..38ed315cec38 100644 --- a/src/openrct2-ui/windows/EditorInventionsList.cpp +++ b/src/openrct2-ui/windows/EditorInventionsList.cpp @@ -242,26 +242,20 @@ static void move_research_item(ResearchItem* beforeItem) */ static ResearchItem* window_editor_inventions_list_get_item_from_scroll_y(int32_t scrollIndex, int32_t y) { - ResearchItem* researchItem; - - researchItem = gResearchItems; - + auto begin = gResearchItemsInvented.begin(); + auto end = gResearchItemsInvented.end(); if (scrollIndex != 0) { - // Skip pre-researched items - for (; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR; researchItem++) - { - } - researchItem++; + begin = gResearchItemsUninvented.begin(); + end = gResearchItemsUninvented.end(); } - for (; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR && researchItem->rawValue != RESEARCHED_ITEMS_END; - researchItem++) + for (auto it = begin; it != end; it++) { y -= SCROLLABLE_ROW_HEIGHT; if (y < 0) { - return researchItem; + return &*it; } } @@ -274,30 +268,24 @@ static ResearchItem* window_editor_inventions_list_get_item_from_scroll_y(int32_ */ static ResearchItem* window_editor_inventions_list_get_item_from_scroll_y_include_seps(int32_t scrollIndex, int32_t y) { - ResearchItem* researchItem; - - researchItem = gResearchItems; - + auto begin = gResearchItemsInvented.begin(); + auto end = gResearchItemsInvented.end(); if (scrollIndex != 0) { - // Skip pre-researched items - for (; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR; researchItem++) - { - } - researchItem++; + begin = gResearchItemsUninvented.begin(); + end = gResearchItemsUninvented.end(); } - for (; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR && researchItem->rawValue != RESEARCHED_ITEMS_END; - researchItem++) + for (auto it = begin; it != end; it++) { y -= SCROLLABLE_ROW_HEIGHT; if (y < 0) { - return researchItem; + return &*it; } } - return researchItem; + return &*(end - 1); } static ResearchItem* get_research_item_at(int32_t x, int32_t y) @@ -443,22 +431,14 @@ static void window_editor_inventions_list_update(rct_window* w) */ static void window_editor_inventions_list_scrollgetheight(rct_window* w, int32_t scrollIndex, int32_t* width, int32_t* height) { - ResearchItem* researchItem; - *height = 0; - - // Count / skip pre-researched items - for (researchItem = gResearchItems; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR; researchItem++) - *height += SCROLLABLE_ROW_HEIGHT; - - if (scrollIndex == 1) + if (scrollIndex == 0) { - researchItem++; - - // Count non pre-researched items - *height = 0; - for (; researchItem->rawValue != RESEARCHED_ITEMS_END; researchItem++) - *height += SCROLLABLE_ROW_HEIGHT; + *height += gResearchItemsInvented.size() * SCROLLABLE_ROW_HEIGHT; + } + else + { + *height += gResearchItemsUninvented.size() * SCROLLABLE_ROW_HEIGHT; } } @@ -676,21 +656,13 @@ static void window_editor_inventions_list_scrollpaint(rct_window* w, rct_drawpix uint8_t paletteIndex = ColourMapA[w->colours[1]].mid_light; gfx_clear(dpi, paletteIndex); - ResearchItem* researchItem = gResearchItems; - int32_t researchItemEndMarker; + auto it = gResearchItemsInvented.begin(); + auto researchItemEndMarker = gResearchItemsInvented.end(); if (scrollIndex == 1) { - // Skip pre-researched items - for (; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR; researchItem++) - { - } - researchItem++; - researchItemEndMarker = RESEARCHED_ITEMS_END; - } - else - { - researchItemEndMarker = RESEARCHED_ITEMS_SEPARATOR; + it = gResearchItemsUninvented.begin(); + researchItemEndMarker = gResearchItemsUninvented.end(); } int16_t boxWidth = (w->widgets[WIDX_RESEARCH_ORDER_SCROLL].right - w->widgets[WIDX_RESEARCH_ORDER_SCROLL].left); @@ -698,6 +670,7 @@ static void window_editor_inventions_list_scrollpaint(rct_window* w, rct_drawpix int32_t itemY = -SCROLLABLE_ROW_HEIGHT; do { + ResearchItem* researchItem = &*it; itemY += SCROLLABLE_ROW_HEIGHT; if (itemY + SCROLLABLE_ROW_HEIGHT < dpi->y || itemY >= dpi->y + dpi->height) continue; @@ -721,9 +694,6 @@ static void window_editor_inventions_list_scrollpaint(rct_window* w, rct_drawpix gfx_filter_rect(dpi, 0, top, boxWidth, bottom, PALETTE_DARKEN_1); } - if (researchItem->rawValue == RESEARCHED_ITEMS_SEPARATOR || researchItem->rawValue == RESEARCHED_ITEMS_END) - continue; - if (researchItem == _editorInventionsListDraggedItem) continue; @@ -777,7 +747,7 @@ static void window_editor_inventions_list_scrollpaint(rct_window* w, rct_drawpix gfx_clip_string(vehicleNameBuffer, columnSplitOffset - 11); gfx_draw_string(dpi, vehicleNameBuffer, colour, columnSplitOffset + 1, itemY); } - } while (researchItem++->rawValue != researchItemEndMarker); + } while (it++ != researchItemEndMarker); } #pragma region Drag item @@ -856,7 +826,7 @@ static void window_editor_inventions_list_drag_moved(rct_window* w, int32_t x, i { researchItem = get_research_item_at(x, y); y += LIST_ROW_HEIGHT; - } while (researchItem != nullptr && researchItem->rawValue >= 0 && research_item_is_always_researched(researchItem)); + } while (researchItem != nullptr && research_item_is_always_researched(researchItem)); if (researchItem != nullptr) move_research_item(researchItem); diff --git a/src/openrct2/management/Research.cpp b/src/openrct2/management/Research.cpp index 81dac49050de..3d2ec53536da 100644 --- a/src/openrct2/management/Research.cpp +++ b/src/openrct2/management/Research.cpp @@ -53,6 +53,8 @@ ResearchItem gResearchNextItem; // 0x01358844[500] ResearchItem gResearchItems[MAX_RESEARCH_ITEMS]; +std::vector gResearchItemsUninvented; +std::vector gResearchItemsInvented; // 0x00EE787C uint8_t gResearchUncompletedCategories; @@ -69,9 +71,8 @@ bool gSilentResearch = false; */ void research_reset_items() { - gResearchItems[0].rawValue = RESEARCHED_ITEMS_SEPARATOR; - gResearchItems[1].rawValue = RESEARCHED_ITEMS_END; - gResearchItems[2].rawValue = RESEARCHED_ITEMS_END_2; + gResearchItemsUninvented.clear(); + gResearchItemsInvented.clear(); } /** @@ -81,13 +82,10 @@ void research_reset_items() void research_update_uncompleted_types() { int32_t uncompletedResearchTypes = 0; - ResearchItem* researchItem = gResearchItems; - while (researchItem++->rawValue != RESEARCHED_ITEMS_SEPARATOR) - ; - for (; researchItem->rawValue != RESEARCHED_ITEMS_END; researchItem++) + for (auto const& researchItem : gResearchItemsUninvented) { - uncompletedResearchTypes |= (1 << researchItem->category); + uncompletedResearchTypes |= (1 << researchItem.category); } gResearchUncompletedCategories = uncompletedResearchTypes; @@ -133,27 +131,24 @@ static void research_invalidate_related_windows() */ static void research_next_design() { - ResearchItem *firstUnresearchedItem, *researchItem, tmp; - int32_t ignoreActiveResearchTypes; - - // Skip already researched items - firstUnresearchedItem = gResearchItems; - while (firstUnresearchedItem->rawValue != RESEARCHED_ITEMS_SEPARATOR) + if (gResearchItemsUninvented.empty()) { - firstUnresearchedItem++; + return; } - ignoreActiveResearchTypes = 0; - researchItem = firstUnresearchedItem; + ResearchItem researchItem; + + bool ignoreActiveResearchTypes = false; + auto it = gResearchItemsUninvented.begin(); for (;;) { - researchItem++; - if (researchItem->rawValue == RESEARCHED_ITEMS_END) + researchItem = *it; + if (it == gResearchItemsUninvented.end()) { if (!ignoreActiveResearchTypes) { - ignoreActiveResearchTypes = 1; - researchItem = firstUnresearchedItem; + ignoreActiveResearchTypes = true; + it = gResearchItemsUninvented.begin(); continue; } else @@ -167,24 +162,19 @@ static void research_next_design() return; } } - else if (ignoreActiveResearchTypes || (gResearchPriorities & (1 << researchItem->category))) + else if (ignoreActiveResearchTypes || (gResearchPriorities & (1 << researchItem.category))) { break; } + it++; } - gResearchNextItem = *researchItem; + gResearchNextItem = researchItem; gResearchProgress = 0; gResearchProgressStage = RESEARCH_STAGE_DESIGNING; - // Bubble research item up until it is above the researched items separator - do - { - tmp = *researchItem; - *researchItem = *(researchItem - 1); - *(researchItem - 1) = tmp; - researchItem--; - } while ((researchItem + 1)->rawValue != RESEARCHED_ITEMS_SEPARATOR); + gResearchItemsUninvented.erase(it); + gResearchItemsInvented.push_back(researchItem); research_invalidate_related_windows(); } @@ -229,15 +219,15 @@ void research_finish_item(ResearchItem* researchItem) ride_entry_set_invented(rideEntryIndex); bool seenRideEntry[MAX_RIDE_OBJECTS]{}; - - ResearchItem* researchItem2 = gResearchItems; - for (; researchItem2->rawValue != RESEARCHED_ITEMS_END; researchItem2++) + for (auto const& researchItem3 : gResearchItemsUninvented) { - if (researchItem2->rawValue != RESEARCHED_ITEMS_SEPARATOR && researchItem2->type == RESEARCH_ENTRY_TYPE_RIDE) - { - uint8_t index = researchItem2->entryIndex; - seenRideEntry[index] = true; - } + uint8_t index = researchItem3.entryIndex; + seenRideEntry[index] = true; + } + for (auto const& researchItem3 : gResearchItemsInvented) + { + uint8_t index = researchItem3.entryIndex; + seenRideEntry[index] = true; } // RCT2 made non-separated vehicles available at once, by removing all but one from research. @@ -386,54 +376,12 @@ void research_update() } } -void research_process_random_items() -{ - ResearchItem* research = gResearchItems; - for (; research->rawValue != RESEARCHED_ITEMS_END; research++) - { - } - - research++; - for (; research->rawValue != RESEARCHED_ITEMS_END_2; research += 2) - { - if (scenario_rand() & 1) - { - continue; - } - - ResearchItem* edx = nullptr; - ResearchItem* ebp = nullptr; - ResearchItem* inner_research = gResearchItems; - do - { - if (research->rawValue == inner_research->rawValue) - { - edx = inner_research; - } - if ((research + 1)->rawValue == inner_research->rawValue) - { - ebp = inner_research; - } - } while ((inner_research++)->rawValue != RESEARCHED_ITEMS_END); - assert(edx != nullptr); - edx->rawValue = research->rawValue; - assert(ebp != nullptr); - ebp->rawValue = (research + 1)->rawValue; - - uint8_t cat = edx->category; - edx->category = ebp->category; - ebp->category = cat; - } -} - /** * * rct2: 0x00684AC3 */ void research_reset_current_item() { - research_process_random_items(); - set_every_ride_type_not_invented(); set_every_ride_entry_not_invented(); @@ -441,9 +389,9 @@ void research_reset_current_item() set_all_scenery_items_invented(); set_all_scenery_groups_not_invented(); - for (ResearchItem* research = gResearchItems; research->rawValue != RESEARCHED_ITEMS_SEPARATOR; research++) + for (auto& researchItem : gResearchItemsInvented) { - research_finish_item(research); + research_finish_item(&researchItem); } gResearchLastItem.rawValue = RESEARCHED_ITEMS_SEPARATOR; @@ -455,29 +403,9 @@ void research_reset_current_item() * * rct2: 0x006857FA */ -static void research_insert_unresearched(int32_t rawValue, int32_t category) +static void research_insert_unresearched(int32_t rawValue, uint8_t category) { - ResearchItem *researchItem, *researchItem2; - - researchItem = gResearchItems; - do - { - if (researchItem->rawValue == RESEARCHED_ITEMS_END) - { - // Insert slot - researchItem2 = researchItem; - while (researchItem2->rawValue != RESEARCHED_ITEMS_END_2) - { - researchItem2++; - } - memmove(researchItem + 1, researchItem, (researchItem2 - researchItem + 1) * sizeof(ResearchItem)); - - // Place new item - researchItem->rawValue = rawValue; - researchItem->category = category; - break; - } - } while (rawValue != (researchItem++)->rawValue); + gResearchItemsUninvented.push_back({ rawValue, category }); } /** @@ -486,36 +414,14 @@ static void research_insert_unresearched(int32_t rawValue, int32_t category) */ static void research_insert_researched(int32_t rawValue, uint8_t category) { - ResearchItem *researchItem, *researchItem2; - - researchItem = gResearchItems; // First check to make sure that entry is not already accounted for - for (; researchItem->rawValue != RESEARCHED_ITEMS_END; researchItem++) + ResearchItem item = { rawValue, category }; + if (item.Exists()) { - if ((researchItem->rawValue & 0xFFFFFF) == (rawValue & 0xFFFFFF)) - { - return; - } + return; } - researchItem = gResearchItems; - do - { - if (researchItem->rawValue == RESEARCHED_ITEMS_SEPARATOR) - { - // Insert slot - researchItem2 = researchItem; - while (researchItem2->rawValue != RESEARCHED_ITEMS_END_2) - { - researchItem2++; - } - memmove(researchItem + 1, researchItem, (researchItem2 - researchItem + 1) * sizeof(ResearchItem)); - // Place new item - researchItem->rawValue = rawValue; - researchItem->category = category; - break; - } - } while (rawValue != (researchItem++)->rawValue); + gResearchItemsInvented.push_back(item); } /** @@ -524,16 +430,23 @@ static void research_insert_researched(int32_t rawValue, uint8_t category) */ void research_remove(ResearchItem* researchItem) { - for (ResearchItem* researchItem2 = gResearchItems; researchItem2->rawValue != RESEARCHED_ITEMS_END; researchItem2++) + for (auto it = gResearchItemsUninvented.begin(); it != gResearchItemsUninvented.end(); it++) { - if (researchItem2->rawValue == researchItem->rawValue) + auto& researchItem2 = *it; + if (researchItem2.Equals(researchItem)) + { + gResearchItemsUninvented.erase(it); + return; + } + } + for (auto it = gResearchItemsInvented.begin(); it != gResearchItemsInvented.end(); it++) + { + auto& researchItem2 = *it; + if (researchItem2.Equals(researchItem)) { - do - { - *researchItem2 = *(researchItem2 + 1); - } while (researchItem2++->rawValue != RESEARCHED_ITEMS_END_2); return; } + gResearchItemsInvented.erase(it); } } @@ -821,54 +734,76 @@ rct_string_id research_get_friendly_base_ride_type_name(uint8_t trackType, rct_r * * rct2: 0x00685A79 * Do not use the research list outside of the inventions list window with the flags + * Clears flags like "always researched". */ void research_remove_flags() { - for (ResearchItem* research = gResearchItems; research->rawValue != RESEARCHED_ITEMS_END_2; research++) + for (auto& researchItem : gResearchItemsUninvented) { - // Clear the always researched flags. - if (research->rawValue > RESEARCHED_ITEMS_SEPARATOR) - { - research->flags = 0; - } + researchItem.flags = 0; + } + for (auto& researchItem : gResearchItemsInvented) + { + researchItem.flags = 0; } } void research_fix() { // Fix invalid research items - for (int32_t i = 0; i < MAX_RESEARCH_ITEMS; i++) + for (auto it = gResearchItemsInvented.begin(); it != gResearchItemsInvented.end();) { - ResearchItem* researchItem = &gResearchItems[i]; - if (researchItem->rawValue == RESEARCHED_ITEMS_SEPARATOR) - continue; - if (researchItem->rawValue == RESEARCHED_ITEMS_END) + auto& researchItem = *it; + if (researchItem.type == RESEARCH_ENTRY_TYPE_RIDE) { - if (i == MAX_RESEARCH_ITEMS - 1) + rct_ride_entry* rideEntry = get_ride_entry(researchItem.entryIndex); + if (rideEntry == nullptr) { - (--researchItem)->rawValue = RESEARCHED_ITEMS_END; + gResearchItemsInvented.erase(it); + } + else + { + it++; } - (++researchItem)->rawValue = RESEARCHED_ITEMS_END_2; - break; } - if (researchItem->rawValue == RESEARCHED_ITEMS_END_2) - break; - if (researchItem->type == RESEARCH_ENTRY_TYPE_RIDE) + else + { + rct_scenery_group_entry* sceneryGroupEntry = get_scenery_group_entry(researchItem.rawValue); + if (sceneryGroupEntry == nullptr) + { + gResearchItemsInvented.erase(it); + } + else + { + it++; + } + } + } + for (auto it = gResearchItemsUninvented.begin(); it != gResearchItemsUninvented.end();) + { + auto& researchItem = *it; + if (researchItem.type == RESEARCH_ENTRY_TYPE_RIDE) { - rct_ride_entry* rideEntry = get_ride_entry(researchItem->entryIndex); + rct_ride_entry* rideEntry = get_ride_entry(researchItem.entryIndex); if (rideEntry == nullptr) { - research_remove(researchItem); - i--; + gResearchItemsUninvented.erase(it); + } + else + { + it++; } } else { - rct_scenery_group_entry* sceneryGroupEntry = get_scenery_group_entry(researchItem->rawValue); + rct_scenery_group_entry* sceneryGroupEntry = get_scenery_group_entry(researchItem.rawValue); if (sceneryGroupEntry == nullptr) { - research_remove(researchItem); - i--; + gResearchItemsUninvented.erase(it); + } + else + { + it++; } } } @@ -914,50 +849,19 @@ void research_fix() void research_items_make_all_unresearched() { - ResearchItem *researchItem, *nextResearchItem, researchItemTemp; - - int32_t sorted; - do + for (auto it = gResearchItemsInvented.begin(); it != gResearchItemsInvented.end();) { - sorted = 1; - for (researchItem = gResearchItems; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR; researchItem++) - { - if (research_item_is_always_researched(researchItem)) - continue; - - nextResearchItem = researchItem + 1; - if (nextResearchItem->rawValue == RESEARCHED_ITEMS_SEPARATOR - || research_item_is_always_researched(nextResearchItem)) - { - // Bubble up always researched item or separator - researchItemTemp = *researchItem; - *researchItem = *nextResearchItem; - *nextResearchItem = researchItemTemp; - sorted = 0; - - if (researchItem->rawValue == RESEARCHED_ITEMS_SEPARATOR) - break; - } - } - } while (!sorted); + auto& researchItem = *it; + gResearchItemsUninvented.push_back(researchItem); + } } void research_items_make_all_researched() { - ResearchItem *researchItem, researchItemTemp; - - // Find separator - for (researchItem = gResearchItems; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR; researchItem++) + for (auto it = gResearchItemsUninvented.begin(); it != gResearchItemsUninvented.end();) { - } - - // Move separator below all items - for (; (researchItem + 1)->rawValue != RESEARCHED_ITEMS_END; researchItem++) - { - // Swap separator with research item - researchItemTemp = *researchItem; - *researchItem = *(researchItem + 1); - *(researchItem + 1) = researchItemTemp; + auto& researchItem = *it; + gResearchItemsInvented.push_back(researchItem); } } @@ -967,31 +871,19 @@ void research_items_make_all_researched() */ void research_items_shuffle() { - ResearchItem *researchItem, *researchOrderBase, researchItemTemp; - int32_t i, numNonResearchedItems; - - // Skip pre-researched items - for (researchItem = gResearchItems; researchItem->rawValue != RESEARCHED_ITEMS_SEPARATOR; researchItem++) - { - } - researchItem++; - researchOrderBase = researchItem; - // Count non pre-researched items - numNonResearchedItems = 0; - for (; researchItem->rawValue != RESEARCHED_ITEMS_END; researchItem++) - numNonResearchedItems++; + size_t numNonResearchedItems = gResearchItemsUninvented.size(); // Shuffle list - for (i = 0; i < numNonResearchedItems; i++) + for (size_t i = 0; i < numNonResearchedItems; i++) { - int32_t ri = util_rand() % numNonResearchedItems; + size_t ri = util_rand() % numNonResearchedItems; if (ri == i) continue; - researchItemTemp = researchOrderBase[i]; - researchOrderBase[i] = researchOrderBase[ri]; - researchOrderBase[ri] = researchItemTemp; + ResearchItem researchItemTemp = gResearchItemsUninvented[i]; + gResearchItemsUninvented[i] = gResearchItemsUninvented[ri]; + gResearchItemsUninvented[ri] = researchItemTemp; } } @@ -1006,3 +898,27 @@ bool ResearchItem::IsInventedEndMarker() const { return rawValue == RESEARCHED_ITEMS_SEPARATOR; } + +bool ResearchItem::Equals(const ResearchItem* otherItem) const +{ + return (entryIndex == otherItem->entryIndex && baseRideType == otherItem->baseRideType && type == otherItem->type); +} + +bool ResearchItem::Exists() const +{ + for (auto const& researchItem : gResearchItemsUninvented) + { + if (researchItem.Equals(this)) + { + return true; + } + } + for (auto const& researchItem : gResearchItemsInvented) + { + if (researchItem.Equals(this)) + { + return true; + } + } + return false; +} diff --git a/src/openrct2/management/Research.h b/src/openrct2/management/Research.h index 63c4b2d1e4a4..abf988d049d5 100644 --- a/src/openrct2/management/Research.h +++ b/src/openrct2/management/Research.h @@ -35,6 +35,8 @@ struct ResearchItem bool IsInventedEndMarker() const; bool IsRandomEndMarker() const; bool IsUninventedEndMarker() const; + bool Equals(const ResearchItem* otherItem) const; + bool Exists() const; }; assert_struct_size(ResearchItem, 5); #pragma pack(pop) @@ -103,7 +105,8 @@ extern uint8_t gResearchExpectedDay; extern ResearchItem gResearchLastItem; extern ResearchItem gResearchNextItem; -extern ResearchItem gResearchItems[MAX_RESEARCH_ITEMS]; +extern std::vector gResearchItemsUninvented; +extern std::vector gResearchItemsInvented; extern uint8_t gResearchUncompletedCategories; extern bool gSilentResearch; @@ -113,7 +116,6 @@ void research_update(); void research_reset_current_item(); void research_populate_list_random(); void research_populate_list_researched(); -void research_process_random_items(); void research_finish_item(ResearchItem* researchItem); void research_insert(int32_t researched, int32_t rawValue, uint8_t category); diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index 18e825725e4c..e82e8653e12b 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -848,7 +848,18 @@ void S6Exporter::ExportResearchedSceneryItems() void S6Exporter::ExportResearchList() { - std::memcpy(_s6.research_items, gResearchItems, sizeof(_s6.research_items)); + size_t i = 0; + for (const auto& researchItem : gResearchItemsInvented) + { + _s6.research_items[i++] = RCT12ResearchItem{ researchItem.rawValue, researchItem.category }; + } + _s6.research_items[i++] = { RCT12_RESEARCHED_ITEMS_SEPARATOR, 0 }; + for (const auto& researchItem : gResearchItemsUninvented) + { + _s6.research_items[i++] = RCT12ResearchItem{ researchItem.rawValue, researchItem.category }; + } + _s6.research_items[i++] = { RCT12_RESEARCHED_ITEMS_END, 0 }; + _s6.research_items[i] = { RCT12_RESEARCHED_ITEMS_END_2, 0 }; } void S6Exporter::ExportMarketingCampaigns() diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 3c0081607473..40e8c7a9ac38 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -850,7 +850,25 @@ class S6Importer final : public IParkImporter void ImportResearchList() { - std::memcpy(gResearchItems, _s6.research_items, sizeof(_s6.research_items)); + bool invented = true; + for (size_t i = 0; i < sizeof(_s6.research_items); i++) + { + if (_s6.research_items[i].IsInventedEndMarker()) + { + invented = false; + continue; + } + else if (_s6.research_items[i].IsUninventedEndMarker() || _s6.research_items[i].IsRandomEndMarker()) + { + break; + } + + RCT12ResearchItem* ri = &_s6.research_items[i]; + if (invented) + gResearchItemsInvented.push_back(ResearchItem{ ri->rawValue, ri->category }); + else + gResearchItemsUninvented.push_back(ResearchItem{ ri->rawValue, ri->category }); + } } void ImportBanner(Banner* dst, const RCT12Banner* src) From 5ce3d4b947de48a4f4ae151717817bc67a323822 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 17 Jun 2019 19:31:54 +0200 Subject: [PATCH 04/10] Use new iterator syntax in more places --- .../windows/EditorInventionsList.cpp | 64 ++++++------------- src/openrct2/management/Research.cpp | 2 +- src/openrct2/management/Research.h | 2 +- 3 files changed, 23 insertions(+), 45 deletions(-) diff --git a/src/openrct2-ui/windows/EditorInventionsList.cpp b/src/openrct2-ui/windows/EditorInventionsList.cpp index 38ed315cec38..59d434d87608 100644 --- a/src/openrct2-ui/windows/EditorInventionsList.cpp +++ b/src/openrct2-ui/windows/EditorInventionsList.cpp @@ -242,20 +242,13 @@ static void move_research_item(ResearchItem* beforeItem) */ static ResearchItem* window_editor_inventions_list_get_item_from_scroll_y(int32_t scrollIndex, int32_t y) { - auto begin = gResearchItemsInvented.begin(); - auto end = gResearchItemsInvented.end(); - if (scrollIndex != 0) - { - begin = gResearchItemsUninvented.begin(); - end = gResearchItemsUninvented.end(); - } - - for (auto it = begin; it != end; it++) + auto& researchList = scrollIndex == 0 ? gResearchItemsInvented : gResearchItemsUninvented; + for (auto& researchItem : researchList) { y -= SCROLLABLE_ROW_HEIGHT; if (y < 0) { - return &*it; + return &researchItem; } } @@ -268,24 +261,17 @@ static ResearchItem* window_editor_inventions_list_get_item_from_scroll_y(int32_ */ static ResearchItem* window_editor_inventions_list_get_item_from_scroll_y_include_seps(int32_t scrollIndex, int32_t y) { - auto begin = gResearchItemsInvented.begin(); - auto end = gResearchItemsInvented.end(); - if (scrollIndex != 0) - { - begin = gResearchItemsUninvented.begin(); - end = gResearchItemsUninvented.end(); - } - - for (auto it = begin; it != end; it++) + auto& researchList = scrollIndex == 0 ? gResearchItemsInvented : gResearchItemsUninvented; + for (auto& researchItem : researchList) { y -= SCROLLABLE_ROW_HEIGHT; if (y < 0) { - return &*it; + return &researchItem; } } - return &*(end - 1); + return &researchList.back(); } static ResearchItem* get_research_item_at(int32_t x, int32_t y) @@ -655,27 +641,19 @@ static void window_editor_inventions_list_scrollpaint(rct_window* w, rct_drawpix // Draw background uint8_t paletteIndex = ColourMapA[w->colours[1]].mid_light; gfx_clear(dpi, paletteIndex); - - auto it = gResearchItemsInvented.begin(); - auto researchItemEndMarker = gResearchItemsInvented.end(); - - if (scrollIndex == 1) - { - it = gResearchItemsUninvented.begin(); - researchItemEndMarker = gResearchItemsUninvented.end(); - } - + int16_t boxWidth = (w->widgets[WIDX_RESEARCH_ORDER_SCROLL].right - w->widgets[WIDX_RESEARCH_ORDER_SCROLL].left); int16_t columnSplitOffset = boxWidth / 2; int32_t itemY = -SCROLLABLE_ROW_HEIGHT; - do + + const auto& researchList = scrollIndex == 0 ? gResearchItemsInvented : gResearchItemsUninvented; + for (const auto& researchItem : researchList) { - ResearchItem* researchItem = &*it; itemY += SCROLLABLE_ROW_HEIGHT; if (itemY + SCROLLABLE_ROW_HEIGHT < dpi->y || itemY >= dpi->y + dpi->height) continue; - if (w->research_item == researchItem) + if (w->research_item == &researchItem) { int32_t top, bottom; if (_editorInventionsListDraggedItem == nullptr) @@ -694,7 +672,7 @@ static void window_editor_inventions_list_scrollpaint(rct_window* w, rct_drawpix gfx_filter_rect(dpi, 0, top, boxWidth, bottom, PALETTE_DARKEN_1); } - if (researchItem == _editorInventionsListDraggedItem) + if (&researchItem == _editorInventionsListDraggedItem) continue; utf8 groupNameBuffer[256], vehicleNameBuffer[256]; @@ -702,9 +680,9 @@ static void window_editor_inventions_list_scrollpaint(rct_window* w, rct_drawpix utf8* vehicleNamePtr = vehicleNameBuffer; uint8_t colour; - if (research_item_is_always_researched(researchItem)) + if (research_item_is_always_researched(&researchItem)) { - if (w->research_item == researchItem && _editorInventionsListDraggedItem == nullptr) + if (w->research_item == &researchItem && _editorInventionsListDraggedItem == nullptr) gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM_EXTRA_DARK; else gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM_DARK; @@ -720,13 +698,13 @@ static void window_editor_inventions_list_scrollpaint(rct_window* w, rct_drawpix vehicleNamePtr = utf8_write_codepoint(vehicleNamePtr, colour); } - rct_string_id itemNameId = research_item_get_name(researchItem); + rct_string_id itemNameId = research_item_get_name(&researchItem); - if (researchItem->type == RESEARCH_ENTRY_TYPE_RIDE - && !RideGroupManager::RideTypeIsIndependent(researchItem->baseRideType)) + if (researchItem.type == RESEARCH_ENTRY_TYPE_RIDE + && !RideGroupManager::RideTypeIsIndependent(researchItem.baseRideType)) { - const auto rideEntry = get_ride_entry(researchItem->entryIndex); - const rct_string_id rideGroupName = get_ride_naming(researchItem->baseRideType, rideEntry).name; + const auto rideEntry = get_ride_entry(researchItem.entryIndex); + const rct_string_id rideGroupName = get_ride_naming(researchItem.baseRideType, rideEntry).name; format_string( groupNamePtr, std::size(groupNameBuffer), STR_INVENTIONS_LIST_RIDE_AND_VEHICLE_NAME, (void*)&rideGroupName); format_string(vehicleNamePtr, std::size(vehicleNameBuffer), itemNameId, nullptr); @@ -747,7 +725,7 @@ static void window_editor_inventions_list_scrollpaint(rct_window* w, rct_drawpix gfx_clip_string(vehicleNameBuffer, columnSplitOffset - 11); gfx_draw_string(dpi, vehicleNameBuffer, colour, columnSplitOffset + 1, itemY); } - } while (it++ != researchItemEndMarker); + } } #pragma region Drag item diff --git a/src/openrct2/management/Research.cpp b/src/openrct2/management/Research.cpp index 3d2ec53536da..6f7f79373e7e 100644 --- a/src/openrct2/management/Research.cpp +++ b/src/openrct2/management/Research.cpp @@ -887,7 +887,7 @@ void research_items_shuffle() } } -bool research_item_is_always_researched(ResearchItem* researchItem) +bool research_item_is_always_researched(const ResearchItem* researchItem) { return (researchItem->flags & (RESEARCH_ENTRY_FLAG_RIDE_ALWAYS_RESEARCHED | RESEARCH_ENTRY_FLAG_SCENERY_SET_ALWAYS_RESEARCHED)) diff --git a/src/openrct2/management/Research.h b/src/openrct2/management/Research.h index abf988d049d5..8a21ec705066 100644 --- a/src/openrct2/management/Research.h +++ b/src/openrct2/management/Research.h @@ -149,4 +149,4 @@ void research_fix(); void research_items_make_all_unresearched(); void research_items_make_all_researched(); void research_items_shuffle(); -bool research_item_is_always_researched(ResearchItem* researchItem); +bool research_item_is_always_researched(const ResearchItem* researchItem); From 1265913bdb3d000c7f163aa4b43e5ddcad885d58 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Mon, 17 Jun 2019 20:27:34 +0200 Subject: [PATCH 05/10] Fix dragging crash and some bugs --- .../windows/EditorInventionsList.cpp | 73 ++++++++----------- src/openrct2/management/Research.cpp | 4 +- src/openrct2/management/Research.h | 2 - 3 files changed, 35 insertions(+), 44 deletions(-) diff --git a/src/openrct2-ui/windows/EditorInventionsList.cpp b/src/openrct2-ui/windows/EditorInventionsList.cpp index 59d434d87608..46476a8d114f 100644 --- a/src/openrct2-ui/windows/EditorInventionsList.cpp +++ b/src/openrct2-ui/windows/EditorInventionsList.cpp @@ -152,7 +152,7 @@ static rct_window_event_list window_editor_inventions_list_drag_events = { #pragma endregion -static ResearchItem *_editorInventionsListDraggedItem; +static ResearchItem _editorInventionsListDraggedItem; static constexpr const rct_string_id EditorInventionsResearchCategories[] = { STR_RESEARCH_NEW_TRANSPORT_RIDES, @@ -198,37 +198,28 @@ static void research_rides_setup() */ static void move_research_item(ResearchItem* beforeItem) { - rct_window* w; - ResearchItem *researchItem, draggedItem; - - if (_editorInventionsListDraggedItem + 1 == beforeItem) - return; + research_remove(&_editorInventionsListDraggedItem); - // Back up the dragged item - draggedItem = *_editorInventionsListDraggedItem; + bool foundBeforeItem = false; - // Remove dragged item from list - researchItem = _editorInventionsListDraggedItem; - do + for (size_t i = 0; i < gResearchItemsInvented.size() && !foundBeforeItem; i++) { - *researchItem = *(researchItem + 1); - researchItem++; - } while (researchItem->rawValue != RESEARCHED_ITEMS_END_2); - // At end of this researchItem points to the end of the list - - if (beforeItem > _editorInventionsListDraggedItem) - beforeItem--; - - // Add dragged item to list - do + if (beforeItem == nullptr || gResearchItemsInvented[i].Equals(beforeItem)) + { + gResearchItemsInvented.insert((gResearchItemsInvented.begin() + i + 1), _editorInventionsListDraggedItem); + foundBeforeItem = true; + } + } + for (size_t i = 0; i < gResearchItemsUninvented.size() && !foundBeforeItem; i++) { - *researchItem = *(researchItem - 1); - researchItem--; - } while (researchItem != beforeItem); - - *researchItem = draggedItem; + if (beforeItem == nullptr || gResearchItemsUninvented[i].Equals(beforeItem)) + { + gResearchItemsUninvented.insert((gResearchItemsUninvented.begin() + i + 1), _editorInventionsListDraggedItem); + foundBeforeItem = true; + } + } - w = window_find_by_class(WC_EDITOR_INVENTION_LIST); + rct_window* w = window_find_by_class(WC_EDITOR_INVENTION_LIST); if (w != nullptr) { w->research_item = nullptr; @@ -322,7 +313,7 @@ rct_window* window_editor_inventions_list_open() w->var_4AE = 0; w->selected_tab = 0; w->research_item = nullptr; - _editorInventionsListDraggedItem = nullptr; + _editorInventionsListDraggedItem.rawValue = -1; w->min_width = WW; w->min_height = WH; @@ -401,13 +392,13 @@ static void window_editor_inventions_list_update(rct_window* w) window_event_invalidate_call(w); widget_invalidate(w, WIDX_TAB_1); - if (_editorInventionsListDraggedItem == nullptr) + if (_editorInventionsListDraggedItem.IsInventedEndMarker()) return; if (window_find_by_class(WC_EDITOR_INVENTION_LIST_DRAG) != nullptr) return; - _editorInventionsListDraggedItem = nullptr; + _editorInventionsListDraggedItem.rawValue = -1; w->Invalidate(); } @@ -420,11 +411,11 @@ static void window_editor_inventions_list_scrollgetheight(rct_window* w, int32_t *height = 0; if (scrollIndex == 0) { - *height += gResearchItemsInvented.size() * SCROLLABLE_ROW_HEIGHT; + *height += (int32_t)gResearchItemsInvented.size() * SCROLLABLE_ROW_HEIGHT; } else { - *height += gResearchItemsUninvented.size() * SCROLLABLE_ROW_HEIGHT; + *height += (int32_t)gResearchItemsUninvented.size() * SCROLLABLE_ROW_HEIGHT; } } @@ -582,8 +573,8 @@ static void window_editor_inventions_list_paint(rct_window* w, rct_drawpixelinfo dpi, w->x + widget->left + 1, w->y + widget->top + 1, w->x + widget->right - 1, w->y + widget->bottom - 1, ColourMapA[w->colours[1]].darkest); - researchItem = _editorInventionsListDraggedItem; - if (researchItem == nullptr) + researchItem = &_editorInventionsListDraggedItem; + if (researchItem->IsInventedEndMarker()) researchItem = w->research_item; // If the research item is null or a list separator. if (researchItem == nullptr || researchItem->rawValue < 0) @@ -641,7 +632,7 @@ static void window_editor_inventions_list_scrollpaint(rct_window* w, rct_drawpix // Draw background uint8_t paletteIndex = ColourMapA[w->colours[1]].mid_light; gfx_clear(dpi, paletteIndex); - + int16_t boxWidth = (w->widgets[WIDX_RESEARCH_ORDER_SCROLL].right - w->widgets[WIDX_RESEARCH_ORDER_SCROLL].left); int16_t columnSplitOffset = boxWidth / 2; int32_t itemY = -SCROLLABLE_ROW_HEIGHT; @@ -656,7 +647,7 @@ static void window_editor_inventions_list_scrollpaint(rct_window* w, rct_drawpix if (w->research_item == &researchItem) { int32_t top, bottom; - if (_editorInventionsListDraggedItem == nullptr) + if (_editorInventionsListDraggedItem.IsInventedEndMarker()) { // Highlight top = itemY; @@ -672,7 +663,7 @@ static void window_editor_inventions_list_scrollpaint(rct_window* w, rct_drawpix gfx_filter_rect(dpi, 0, top, boxWidth, bottom, PALETTE_DARKEN_1); } - if (&researchItem == _editorInventionsListDraggedItem) + if (researchItem.Equals(&_editorInventionsListDraggedItem)) continue; utf8 groupNameBuffer[256], vehicleNameBuffer[256]; @@ -682,7 +673,7 @@ static void window_editor_inventions_list_scrollpaint(rct_window* w, rct_drawpix uint8_t colour; if (research_item_is_always_researched(&researchItem)) { - if (w->research_item == &researchItem && _editorInventionsListDraggedItem == nullptr) + if (w->research_item == &researchItem && _editorInventionsListDraggedItem.IsInventedEndMarker()) gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM_EXTRA_DARK; else gCurrentFontSpriteBase = FONT_SPRITE_BASE_MEDIUM_DARK; @@ -741,7 +732,7 @@ static void window_editor_inventions_list_drag_open(ResearchItem* researchItem) rct_window* w; window_close_by_class(WC_EDITOR_INVENTION_LIST_DRAG); - _editorInventionsListDraggedItem = researchItem; + _editorInventionsListDraggedItem = *researchItem; rct_string_id stringId = research_item_get_name(researchItem); ptr = buffer; @@ -810,7 +801,7 @@ static void window_editor_inventions_list_drag_moved(rct_window* w, int32_t x, i move_research_item(researchItem); window_close(w); - _editorInventionsListDraggedItem = nullptr; + _editorInventionsListDraggedItem.rawValue = -1; window_invalidate_by_class(WC_EDITOR_INVENTION_LIST); } @@ -825,7 +816,7 @@ static void window_editor_inventions_list_drag_paint(rct_window* w, rct_drawpixe x = w->x; y = w->y + 2; - drawString = window_editor_inventions_list_prepare_name(_editorInventionsListDraggedItem, true); + drawString = window_editor_inventions_list_prepare_name(&_editorInventionsListDraggedItem, true); gfx_draw_string_left(dpi, drawString, gCommonFormatArgs, COLOUR_BLACK | COLOUR_FLAG_OUTLINE, x, y); } diff --git a/src/openrct2/management/Research.cpp b/src/openrct2/management/Research.cpp index 6f7f79373e7e..c3b32f131415 100644 --- a/src/openrct2/management/Research.cpp +++ b/src/openrct2/management/Research.cpp @@ -444,9 +444,9 @@ void research_remove(ResearchItem* researchItem) auto& researchItem2 = *it; if (researchItem2.Equals(researchItem)) { + gResearchItemsInvented.erase(it); return; } - gResearchItemsInvented.erase(it); } } @@ -853,6 +853,7 @@ void research_items_make_all_unresearched() { auto& researchItem = *it; gResearchItemsUninvented.push_back(researchItem); + gResearchItemsInvented.erase(it); } } @@ -862,6 +863,7 @@ void research_items_make_all_researched() { auto& researchItem = *it; gResearchItemsInvented.push_back(researchItem); + gResearchItemsUninvented.erase(it); } } diff --git a/src/openrct2/management/Research.h b/src/openrct2/management/Research.h index 8a21ec705066..7776463da1d6 100644 --- a/src/openrct2/management/Research.h +++ b/src/openrct2/management/Research.h @@ -33,8 +33,6 @@ struct ResearchItem uint8_t category; bool IsInventedEndMarker() const; - bool IsRandomEndMarker() const; - bool IsUninventedEndMarker() const; bool Equals(const ResearchItem* otherItem) const; bool Exists() const; }; From 9de2819cef6ba9e8fd6639a83720fb47dfa924e2 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Tue, 18 Jun 2019 20:14:26 +0200 Subject: [PATCH 06/10] Process feedback from code review --- .../windows/EditorInventionsList.cpp | 5 +-- src/openrct2/management/Research.cpp | 41 +++++-------------- src/openrct2/management/Research.h | 3 -- 3 files changed, 13 insertions(+), 36 deletions(-) diff --git a/src/openrct2-ui/windows/EditorInventionsList.cpp b/src/openrct2-ui/windows/EditorInventionsList.cpp index 46476a8d114f..5ed4648f1707 100644 --- a/src/openrct2-ui/windows/EditorInventionsList.cpp +++ b/src/openrct2-ui/windows/EditorInventionsList.cpp @@ -432,7 +432,7 @@ static void window_editor_inventions_list_scrollmousedown(rct_window* w, int32_t return; // Disallow picking up always-researched items - if (researchItem->rawValue < RESEARCHED_ITEMS_END_2 || research_item_is_always_researched(researchItem)) + if (research_item_is_always_researched(researchItem)) return; w->Invalidate(); @@ -485,8 +485,7 @@ static void window_editor_inventions_list_cursor( // Use the open hand as cursor for items that can be picked up researchItem = window_editor_inventions_list_get_item_from_scroll_y(scrollIndex, y); - if (researchItem != nullptr && researchItem->rawValue >= RESEARCHED_ITEMS_END_2 - && !research_item_is_always_researched(researchItem)) + if (researchItem != nullptr && !research_item_is_always_researched(researchItem)) { *cursorId = CURSOR_HAND_OPEN; } diff --git a/src/openrct2/management/Research.cpp b/src/openrct2/management/Research.cpp index c3b32f131415..7afa46c88683 100644 --- a/src/openrct2/management/Research.cpp +++ b/src/openrct2/management/Research.cpp @@ -759,7 +759,7 @@ void research_fix() rct_ride_entry* rideEntry = get_ride_entry(researchItem.entryIndex); if (rideEntry == nullptr) { - gResearchItemsInvented.erase(it); + it = gResearchItemsInvented.erase(it); } else { @@ -771,7 +771,7 @@ void research_fix() rct_scenery_group_entry* sceneryGroupEntry = get_scenery_group_entry(researchItem.rawValue); if (sceneryGroupEntry == nullptr) { - gResearchItemsInvented.erase(it); + it = gResearchItemsInvented.erase(it); } else { @@ -787,7 +787,7 @@ void research_fix() rct_ride_entry* rideEntry = get_ride_entry(researchItem.entryIndex); if (rideEntry == nullptr) { - gResearchItemsUninvented.erase(it); + it = gResearchItemsUninvented.erase(it); } else { @@ -799,7 +799,7 @@ void research_fix() rct_scenery_group_entry* sceneryGroupEntry = get_scenery_group_entry(researchItem.rawValue); if (sceneryGroupEntry == nullptr) { - gResearchItemsUninvented.erase(it); + it = gResearchItemsUninvented.erase(it); } else { @@ -849,22 +849,16 @@ void research_fix() void research_items_make_all_unresearched() { - for (auto it = gResearchItemsInvented.begin(); it != gResearchItemsInvented.end();) - { - auto& researchItem = *it; - gResearchItemsUninvented.push_back(researchItem); - gResearchItemsInvented.erase(it); - } + gResearchItemsUninvented.insert( + gResearchItemsUninvented.end(), std::make_move_iterator(gResearchItemsInvented.begin()), + std::make_move_iterator(gResearchItemsInvented.end())); } void research_items_make_all_researched() { - for (auto it = gResearchItemsUninvented.begin(); it != gResearchItemsUninvented.end();) - { - auto& researchItem = *it; - gResearchItemsInvented.push_back(researchItem); - gResearchItemsUninvented.erase(it); - } + gResearchItemsInvented.insert( + gResearchItemsInvented.end(), std::make_move_iterator(gResearchItemsUninvented.begin()), + std::make_move_iterator(gResearchItemsUninvented.end())); } /** @@ -873,20 +867,7 @@ void research_items_make_all_researched() */ void research_items_shuffle() { - // Count non pre-researched items - size_t numNonResearchedItems = gResearchItemsUninvented.size(); - - // Shuffle list - for (size_t i = 0; i < numNonResearchedItems; i++) - { - size_t ri = util_rand() % numNonResearchedItems; - if (ri == i) - continue; - - ResearchItem researchItemTemp = gResearchItemsUninvented[i]; - gResearchItemsUninvented[i] = gResearchItemsUninvented[ri]; - gResearchItemsUninvented[ri] = researchItemTemp; - } + std::shuffle(std::begin(gResearchItemsUninvented), std::end(gResearchItemsUninvented), std::default_random_engine{}); } bool research_item_is_always_researched(const ResearchItem* researchItem) diff --git a/src/openrct2/management/Research.h b/src/openrct2/management/Research.h index 7776463da1d6..f222abbdf3b1 100644 --- a/src/openrct2/management/Research.h +++ b/src/openrct2/management/Research.h @@ -15,7 +15,6 @@ struct rct_ride_entry; -#pragma pack(push, 1) struct ResearchItem { // Bit 16 (0: scenery entry, 1: ride entry) @@ -36,8 +35,6 @@ struct ResearchItem bool Equals(const ResearchItem* otherItem) const; bool Exists() const; }; -assert_struct_size(ResearchItem, 5); -#pragma pack(pop) enum { From 984fd5e58aee804e84d8d972a7b19fecf1d3a97f Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 19 Jun 2019 22:58:04 +0200 Subject: [PATCH 07/10] Make EditorInventionsList a bit less buggy --- .../windows/EditorInventionsList.cpp | 76 ++++++++++++++----- src/openrct2/management/Research.cpp | 2 + 2 files changed, 57 insertions(+), 21 deletions(-) diff --git a/src/openrct2-ui/windows/EditorInventionsList.cpp b/src/openrct2-ui/windows/EditorInventionsList.cpp index 5ed4648f1707..0f655368ce0c 100644 --- a/src/openrct2-ui/windows/EditorInventionsList.cpp +++ b/src/openrct2-ui/windows/EditorInventionsList.cpp @@ -166,7 +166,7 @@ static constexpr const rct_string_id EditorInventionsResearchCategories[] = { // clang-format on static void window_editor_inventions_list_drag_open(ResearchItem* researchItem); -static void move_research_item(ResearchItem* beforeItem); +static void move_research_item(ResearchItem* beforeItem, int32_t scrollIndex); /** * @@ -196,26 +196,56 @@ static void research_rides_setup() * * rct2: 0x006855E7 */ -static void move_research_item(ResearchItem* beforeItem) +static void move_research_item(ResearchItem* beforeItem, int32_t scrollIndex) { research_remove(&_editorInventionsListDraggedItem); - bool foundBeforeItem = false; - - for (size_t i = 0; i < gResearchItemsInvented.size() && !foundBeforeItem; i++) + if (scrollIndex == 0) { - if (beforeItem == nullptr || gResearchItemsInvented[i].Equals(beforeItem)) + if (gResearchItemsInvented.empty()) + { + gResearchItemsInvented.push_back(_editorInventionsListDraggedItem); + } + else { - gResearchItemsInvented.insert((gResearchItemsInvented.begin() + i + 1), _editorInventionsListDraggedItem); - foundBeforeItem = true; + bool placed = false; + for (size_t i = 0; i < gResearchItemsInvented.size() && !placed; i++) + { + if (beforeItem == nullptr || gResearchItemsInvented[i].Equals(beforeItem)) + { + gResearchItemsInvented.insert((gResearchItemsInvented.begin() + i), _editorInventionsListDraggedItem); + placed = true; + } + } + if (!placed) + { + // Still not found? Append to end of list. + gResearchItemsInvented.push_back(_editorInventionsListDraggedItem); + } } + } - for (size_t i = 0; i < gResearchItemsUninvented.size() && !foundBeforeItem; i++) + else if (scrollIndex == 1) { - if (beforeItem == nullptr || gResearchItemsUninvented[i].Equals(beforeItem)) + if (gResearchItemsUninvented.empty()) { - gResearchItemsUninvented.insert((gResearchItemsUninvented.begin() + i + 1), _editorInventionsListDraggedItem); - foundBeforeItem = true; + gResearchItemsUninvented.push_back(_editorInventionsListDraggedItem); + } + else + { + bool placed = false; + for (size_t i = 0; i < gResearchItemsUninvented.size() && !placed; i++) + { + if (beforeItem == nullptr || gResearchItemsUninvented[i].Equals(beforeItem)) + { + gResearchItemsUninvented.insert((gResearchItemsUninvented.begin() + i), _editorInventionsListDraggedItem); + placed = true; + } + } + if (!placed) + { + gResearchItemsInvented.push_back(_editorInventionsListDraggedItem); + } } } @@ -265,7 +295,7 @@ static ResearchItem* window_editor_inventions_list_get_item_from_scroll_y_includ return &researchList.back(); } -static ResearchItem* get_research_item_at(int32_t x, int32_t y) +static ResearchItem* get_research_item_at(int32_t x, int32_t y, int32_t* outScrollId) { rct_window* w = window_find_by_class(WC_EDITOR_INVENTION_LIST); if (w != nullptr && w->x <= x && w->y < y && w->x + w->width > x && w->y + w->height > y) @@ -275,14 +305,14 @@ static ResearchItem* get_research_item_at(int32_t x, int32_t y) if (widgetIndex == WIDX_PRE_RESEARCHED_SCROLL || widgetIndex == WIDX_RESEARCH_ORDER_SCROLL) { gPressedWidget.widget_index = widgetIndex; - int32_t outX, outY, outScrollArea, outScrollId; - widget_scroll_get_part(w, widget, x, y, &outX, &outY, &outScrollArea, &outScrollId); + int32_t outX, outY, outScrollArea; + widget_scroll_get_part(w, widget, x, y, &outX, &outY, &outScrollArea, outScrollId); if (outScrollArea == SCROLL_PART_VIEW) { - outScrollId = outScrollId == 0 ? 0 : 1; + *outScrollId = *outScrollId == 0 ? 0 : 1; - int32_t scrollY = y - (w->y + widget->top) + w->scrolls[outScrollId].v_top + 5; - return window_editor_inventions_list_get_item_from_scroll_y_include_seps(outScrollId, scrollY); + int32_t scrollY = y - (w->y + widget->top) + w->scrolls[*outScrollId].v_top + 5; + return window_editor_inventions_list_get_item_from_scroll_y_include_seps(*outScrollId, scrollY); } } } @@ -771,7 +801,8 @@ static void window_editor_inventions_list_drag_cursor( rct_window* inventionListWindow = window_find_by_class(WC_EDITOR_INVENTION_LIST); if (inventionListWindow != nullptr) { - ResearchItem* researchItem = get_research_item_at(x, y); + int32_t scrollId; + ResearchItem* researchItem = get_research_item_at(x, y, &scrollId); if (researchItem != inventionListWindow->research_item) { inventionListWindow->Invalidate(); @@ -789,15 +820,18 @@ static void window_editor_inventions_list_drag_moved(rct_window* w, int32_t x, i { ResearchItem* researchItem; + int32_t scrollId; // Skip always researched items, so that the dragged item gets placed underneath them do { - researchItem = get_research_item_at(x, y); + researchItem = get_research_item_at(x, y, &scrollId); y += LIST_ROW_HEIGHT; } while (researchItem != nullptr && research_item_is_always_researched(researchItem)); if (researchItem != nullptr) - move_research_item(researchItem); + { + move_research_item(researchItem, scrollId); + } window_close(w); _editorInventionsListDraggedItem.rawValue = -1; diff --git a/src/openrct2/management/Research.cpp b/src/openrct2/management/Research.cpp index 7afa46c88683..3ec2d745b7ad 100644 --- a/src/openrct2/management/Research.cpp +++ b/src/openrct2/management/Research.cpp @@ -852,6 +852,7 @@ void research_items_make_all_unresearched() gResearchItemsUninvented.insert( gResearchItemsUninvented.end(), std::make_move_iterator(gResearchItemsInvented.begin()), std::make_move_iterator(gResearchItemsInvented.end())); + gResearchItemsInvented.clear(); } void research_items_make_all_researched() @@ -859,6 +860,7 @@ void research_items_make_all_researched() gResearchItemsInvented.insert( gResearchItemsInvented.end(), std::make_move_iterator(gResearchItemsUninvented.begin()), std::make_move_iterator(gResearchItemsUninvented.end())); + gResearchItemsUninvented.clear(); } /** From abe721b30843c78cc8ec3b2d446f8aa538ae040b Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 21 Aug 2019 21:46:03 +0200 Subject: [PATCH 08/10] Fix rebase errors and formatting --- src/openrct2-ui/windows/EditorInventionsList.cpp | 1 - src/openrct2/rct12/RCT12.h | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/openrct2-ui/windows/EditorInventionsList.cpp b/src/openrct2-ui/windows/EditorInventionsList.cpp index 0f655368ce0c..d25c3d9a51f8 100644 --- a/src/openrct2-ui/windows/EditorInventionsList.cpp +++ b/src/openrct2-ui/windows/EditorInventionsList.cpp @@ -223,7 +223,6 @@ static void move_research_item(ResearchItem* beforeItem, int32_t scrollIndex) gResearchItemsInvented.push_back(_editorInventionsListDraggedItem); } } - } else if (scrollIndex == 1) { diff --git a/src/openrct2/rct12/RCT12.h b/src/openrct2/rct12/RCT12.h index bfcbce33d4ac..4f2a8f7d6ae5 100644 --- a/src/openrct2/rct12/RCT12.h +++ b/src/openrct2/rct12/RCT12.h @@ -49,7 +49,6 @@ constexpr uint16_t const RCT12_MAX_INVERSIONS = 31; constexpr uint16_t const RCT12_MAX_GOLF_HOLES = 31; constexpr uint16_t const RCT12_MAX_HELICES = 31; -<<<<<<< HEAD enum class RCT12TrackDesignVersion : uint8_t { TD4, @@ -57,14 +56,13 @@ enum class RCT12TrackDesignVersion : uint8_t TD6, unknown }; -======= + // Everything before this point has been researched #define RCT12_RESEARCHED_ITEMS_SEPARATOR (-1) // Everything before this point and after separator still requires research #define RCT12_RESEARCHED_ITEMS_END (-2) // Extra end of list entry. Leftover from RCT1. #define RCT12_RESEARCHED_ITEMS_END_2 (-3) ->>>>>>> 04e9e626d... Split off RCT12ResearchItem #pragma pack(push, 1) From ae8c93ca2ba87c2eb04bece89619b76c407988fa Mon Sep 17 00:00:00 2001 From: Ted John Date: Wed, 21 Aug 2019 22:02:12 +0100 Subject: [PATCH 09/10] Fix research list UI / dragging --- .../windows/EditorInventionsList.cpp | 68 +++++-------------- 1 file changed, 18 insertions(+), 50 deletions(-) diff --git a/src/openrct2-ui/windows/EditorInventionsList.cpp b/src/openrct2-ui/windows/EditorInventionsList.cpp index d25c3d9a51f8..320502476b76 100644 --- a/src/openrct2-ui/windows/EditorInventionsList.cpp +++ b/src/openrct2-ui/windows/EditorInventionsList.cpp @@ -198,62 +198,30 @@ static void research_rides_setup() */ static void move_research_item(ResearchItem* beforeItem, int32_t scrollIndex) { - research_remove(&_editorInventionsListDraggedItem); - - if (scrollIndex == 0) + auto w = window_find_by_class(WC_EDITOR_INVENTION_LIST); + if (w != nullptr) { - if (gResearchItemsInvented.empty()) - { - gResearchItemsInvented.push_back(_editorInventionsListDraggedItem); - } - else - { - bool placed = false; - for (size_t i = 0; i < gResearchItemsInvented.size() && !placed; i++) - { - if (beforeItem == nullptr || gResearchItemsInvented[i].Equals(beforeItem)) - { - gResearchItemsInvented.insert((gResearchItemsInvented.begin() + i), _editorInventionsListDraggedItem); - placed = true; - } - } - if (!placed) - { - // Still not found? Append to end of list. - gResearchItemsInvented.push_back(_editorInventionsListDraggedItem); - } - } + w->research_item = nullptr; + w->Invalidate(); } - else if (scrollIndex == 1) + + research_remove(&_editorInventionsListDraggedItem); + + auto& researchList = scrollIndex == 0 ? gResearchItemsInvented : gResearchItemsUninvented; + if (beforeItem != nullptr) { - if (gResearchItemsUninvented.empty()) - { - gResearchItemsUninvented.push_back(_editorInventionsListDraggedItem); - } - else + for (size_t i = 0; i < researchList.size(); i++) { - bool placed = false; - for (size_t i = 0; i < gResearchItemsUninvented.size() && !placed; i++) - { - if (beforeItem == nullptr || gResearchItemsUninvented[i].Equals(beforeItem)) - { - gResearchItemsUninvented.insert((gResearchItemsUninvented.begin() + i), _editorInventionsListDraggedItem); - placed = true; - } - } - if (!placed) + if (researchList[i].Equals(beforeItem)) { - gResearchItemsInvented.push_back(_editorInventionsListDraggedItem); + researchList.insert((researchList.begin() + i), _editorInventionsListDraggedItem); + return; } } } - rct_window* w = window_find_by_class(WC_EDITOR_INVENTION_LIST); - if (w != nullptr) - { - w->research_item = nullptr; - w->Invalidate(); - } + // Still not found? Append to end of list. + researchList.push_back(_editorInventionsListDraggedItem); } /** @@ -290,8 +258,7 @@ static ResearchItem* window_editor_inventions_list_get_item_from_scroll_y_includ return &researchItem; } } - - return &researchList.back(); + return nullptr; } static ResearchItem* get_research_item_at(int32_t x, int32_t y, int32_t* outScrollId) @@ -316,6 +283,7 @@ static ResearchItem* get_research_item_at(int32_t x, int32_t y, int32_t* outScro } } + *outScrollId = -1; return nullptr; } @@ -827,7 +795,7 @@ static void window_editor_inventions_list_drag_moved(rct_window* w, int32_t x, i y += LIST_ROW_HEIGHT; } while (researchItem != nullptr && research_item_is_always_researched(researchItem)); - if (researchItem != nullptr) + if (scrollId != -1) { move_research_item(researchItem, scrollId); } From ad96aa57859868014b3a6e256ef681513446e40e Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Fri, 23 Aug 2019 22:52:13 +0200 Subject: [PATCH 10/10] Fix bug introduced after empty vector check --- src/openrct2/management/Research.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/openrct2/management/Research.cpp b/src/openrct2/management/Research.cpp index 3ec2d745b7ad..467f2a637351 100644 --- a/src/openrct2/management/Research.cpp +++ b/src/openrct2/management/Research.cpp @@ -125,6 +125,16 @@ static void research_invalidate_related_windows() window_invalidate_by_class(WC_RESEARCH); } +static void research_mark_as_fully_completed() +{ + gResearchProgress = 0; + gResearchProgressStage = RESEARCH_STAGE_FINISHED_ALL; + research_invalidate_related_windows(); + // Reset funding to 0 if no more rides. + auto gameAction = ParkSetResearchFundingAction(gResearchPriorities, 0); + GameActions::Execute(&gameAction); +} + /** * * rct2: 0x00684BE5 @@ -133,6 +143,7 @@ static void research_next_design() { if (gResearchItemsUninvented.empty()) { + research_mark_as_fully_completed(); return; } @@ -153,12 +164,7 @@ static void research_next_design() } else { - gResearchProgress = 0; - gResearchProgressStage = RESEARCH_STAGE_FINISHED_ALL; - research_invalidate_related_windows(); - // Reset funding to 0 if no more rides. - auto gameAction = ParkSetResearchFundingAction(gResearchPriorities, 0); - GameActions::Execute(&gameAction); + research_mark_as_fully_completed(); return; } }