diff --git a/src/openrct2-ui/windows/EditorInventionsList.cpp b/src/openrct2-ui/windows/EditorInventionsList.cpp index 29d8c23520..8fbac799f8 100644 --- a/src/openrct2-ui/windows/EditorInventionsList.cpp +++ b/src/openrct2-ui/windows/EditorInventionsList.cpp @@ -311,7 +311,7 @@ rct_window* window_editor_inventions_list_open() window_init_scroll_widgets(w); w->selected_tab = 0; w->research_item = nullptr; - _editorInventionsListDraggedItem.rawValue = RESEARCH_ITEM_NULL; + _editorInventionsListDraggedItem.SetNull(); w->min_width = WW; w->min_height = WH; @@ -396,7 +396,7 @@ static void window_editor_inventions_list_update(rct_window* w) if (window_find_by_class(WC_EDITOR_INVENTION_LIST_DRAG) != nullptr) return; - _editorInventionsListDraggedItem.rawValue = RESEARCH_ITEM_NULL; + _editorInventionsListDraggedItem.SetNull(); w->Invalidate(); } @@ -808,7 +808,7 @@ static void window_editor_inventions_list_drag_moved(rct_window* w, const Screen } window_close(w); - _editorInventionsListDraggedItem.rawValue = RESEARCH_ITEM_NULL; + _editorInventionsListDraggedItem.SetNull(); window_invalidate_by_class(WC_EDITOR_INVENTION_LIST); } diff --git a/src/openrct2/management/NewsItem.cpp b/src/openrct2/management/NewsItem.cpp index 3a5e4db65f..396acf93e7 100644 --- a/src/openrct2/management/NewsItem.cpp +++ b/src/openrct2/management/NewsItem.cpp @@ -354,7 +354,7 @@ void news_item_open_subject(int32_t type, int32_t subject) break; case NEWS_ITEM_RESEARCH: { - auto item = ResearchItem(subject, 0); + auto item = ResearchItem(subject, 0, 0); if (item.type == RESEARCH_ENTRY_TYPE_RIDE) { auto intent = Intent(INTENT_ACTION_NEW_RIDE_OF_TYPE); diff --git a/src/openrct2/management/Research.cpp b/src/openrct2/management/Research.cpp index f8552ccbe4..83cf547146 100644 --- a/src/openrct2/management/Research.cpp +++ b/src/openrct2/management/Research.cpp @@ -540,8 +540,12 @@ bool research_insert_ride_entry(uint8_t rideType, ObjectEntryIndex entryIndex, u { if (rideType != RIDE_TYPE_NULL) { - research_insert( - { static_cast(RESEARCH_ENTRY_RIDE_MASK | (rideType << 8) | entryIndex), category }, researched); + ResearchItem tmpItem = {}; + tmpItem.type = RESEARCH_ENTRY_TYPE_RIDE; + tmpItem.baseRideType = rideType; + tmpItem.entryIndex = entryIndex; + tmpItem.category = category; + research_insert(tmpItem, researched); return true; } @@ -560,7 +564,11 @@ void research_insert_ride_entry(ObjectEntryIndex entryIndex, bool researched) void research_insert_scenery_group_entry(ObjectEntryIndex entryIndex, bool researched) { - research_insert({ entryIndex, RESEARCH_CATEGORY_SCENERY_GROUP }, researched); + ResearchItem tmpItem = {}; + tmpItem.type = RESEARCH_ENTRY_TYPE_SCENERY; + tmpItem.entryIndex = entryIndex; + tmpItem.category = RESEARCH_CATEGORY_SCENERY_GROUP; + research_insert(tmpItem, researched); } bool ride_type_is_invented(uint32_t rideType) @@ -895,7 +903,12 @@ bool ResearchItem::IsAlwaysResearched() const bool ResearchItem::IsNull() const { - return rawValue == RESEARCH_ITEM_NULL; + return entryIndex == OBJECT_ENTRY_INDEX_NULL; +} + +void ResearchItem::SetNull() +{ + entryIndex = OBJECT_ENTRY_INDEX_NULL; } bool ResearchItem::Equals(const ResearchItem* otherItem) const diff --git a/src/openrct2/management/Research.h b/src/openrct2/management/Research.h index f21b705c80..0b27d855e1 100644 --- a/src/openrct2/management/Research.h +++ b/src/openrct2/management/Research.h @@ -19,32 +19,72 @@ struct rct_ride_entry; struct ResearchItem { - // Bit 16 (0: scenery entry, 1: ride entry) union { uint32_t rawValue; struct { - uint8_t entryIndex; + ObjectEntryIndex entryIndex; uint8_t baseRideType; uint8_t type; // 0: scenery entry, 1: ride entry - uint8_t flags; }; }; + uint8_t flags; uint8_t category; bool IsNull() const; + void SetNull(); bool Equals(const ResearchItem* otherItem) const; bool Exists() const; bool IsAlwaysResearched() const; rct_string_id GetName() const; ResearchItem() = default; - constexpr ResearchItem(uint32_t _rawValue, int32_t _category) + constexpr ResearchItem(uint32_t _rawValue, uint8_t _flags, uint8_t _category) : rawValue(_rawValue) + , flags(_flags) , category(_category) { } + + RCT12ResearchItem ToRCT12ResearchItem() const + { + RCT12ResearchItem retItem = {}; + if (IsNull()) + { + retItem.rawValue = RCT12_RESEARCHED_ITEMS_SEPARATOR; + } + else + { + retItem.entryIndex = OpenRCT2EntryIndexToRCTEntryIndex(entryIndex); + retItem.baseRideType = baseRideType; + retItem.type = type; + retItem.flags = flags; + retItem.category = category; + } + + return retItem; + } + + ResearchItem(const RCT12ResearchItem& oldResearchItem) + { + if (oldResearchItem.IsInventedEndMarker() || oldResearchItem.IsUninventedEndMarker() + || oldResearchItem.IsRandomEndMarker()) + { + rawValue = 0; + flags = 0; + category = 0; + SetNull(); + } + else + { + entryIndex = RCTEntryIndexToOpenRCT2EntryIndex(oldResearchItem.entryIndex); + baseRideType = oldResearchItem.baseRideType; + type = oldResearchItem.type; + flags = oldResearchItem.flags; + category = oldResearchItem.category; + } + } }; enum @@ -64,8 +104,6 @@ enum #define MAX_RESEARCH_ITEMS 500 -#define RESEARCH_ENTRY_RIDE_MASK 0x10000 - enum { RESEARCH_FUNDING_NONE, @@ -85,7 +123,7 @@ enum RESEARCH_STAGE_FINISHED_ALL }; -enum +enum : uint8_t { RESEARCH_CATEGORY_TRANSPORT, RESEARCH_CATEGORY_GENTLE, diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index c479aee42d..8b5dcb0969 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -2548,7 +2548,7 @@ private: ResearchItem tmpResearchItem = {}; ConvertResearchEntry(&tmpResearchItem, researchItem, researchType); - dst->Assoc = static_cast(tmpResearchItem.rawValue); + dst->Assoc = tmpResearchItem.rawValue; } else { @@ -2592,7 +2592,7 @@ private: void ConvertResearchEntry(ResearchItem* dst, uint8_t srcItem, uint8_t srcType) { - dst->rawValue = RESEARCH_ITEM_NULL; + dst->SetNull(); if (srcType == RCT1_RESEARCH_TYPE_RIDE) { auto entryIndex = _rideTypeToRideEntryMap[srcItem]; diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index b88a35d2a8..b675e93a36 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -246,7 +246,7 @@ void S6Exporter::Export() _s6.active_research_types = gResearchPriorities; _s6.research_progress_stage = gResearchProgressStage; if (gResearchLastItem.has_value()) - _s6.last_researched_item_subject = gResearchLastItem->rawValue; + _s6.last_researched_item_subject = gResearchLastItem->ToRCT12ResearchItem().rawValue; else _s6.last_researched_item_subject = RCT12_RESEARCHED_ITEMS_SEPARATOR; // pad_01357CF8 @@ -254,8 +254,9 @@ void S6Exporter::Export() if (gResearchNextItem.has_value()) { - _s6.next_research_item = gResearchNextItem->rawValue; - _s6.next_research_category = gResearchNextItem->category; + auto RCT2ResearchItem = gResearchNextItem->ToRCT12ResearchItem(); + _s6.next_research_item = RCT2ResearchItem.rawValue; + _s6.next_research_category = RCT2ResearchItem.category; } else { @@ -904,12 +905,12 @@ void S6Exporter::ExportResearchList() size_t i = 0; for (const auto& researchItem : gResearchItemsInvented) { - _s6.research_items[i++] = RCT12ResearchItem{ researchItem.rawValue, researchItem.category }; + _s6.research_items[i++] = researchItem.ToRCT12ResearchItem(); } _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++] = researchItem.ToRCT12ResearchItem(); } _s6.research_items[i++] = { RCT12_RESEARCHED_ITEMS_END, 0 }; _s6.research_items[i] = { RCT12_RESEARCHED_ITEMS_END_2, 0 }; diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 9349c0b556..820270f6f6 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -264,12 +264,13 @@ public: gResearchPriorities = _s6.active_research_types; gResearchProgressStage = _s6.research_progress_stage; if (_s6.last_researched_item_subject != RCT12_RESEARCHED_ITEMS_SEPARATOR) - gResearchLastItem = ResearchItem(_s6.last_researched_item_subject, RESEARCH_CATEGORY_TRANSPORT); + gResearchLastItem = ResearchItem( + RCT12ResearchItem{ _s6.last_researched_item_subject, RESEARCH_CATEGORY_TRANSPORT }); else gResearchLastItem = std::nullopt; // pad_01357CF8 if (_s6.next_research_item != RCT12_RESEARCHED_ITEMS_SEPARATOR) - gResearchNextItem = ResearchItem(_s6.next_research_item, _s6.next_research_category); + gResearchNextItem = ResearchItem(RCT12ResearchItem{ _s6.next_research_item, _s6.next_research_category }); else gResearchNextItem = std::nullopt; @@ -905,9 +906,9 @@ public: RCT12ResearchItem* ri = &_s6.research_items[i]; if (invented) - gResearchItemsInvented.push_back(ResearchItem{ ri->rawValue, ri->category }); + gResearchItemsInvented.push_back(ResearchItem(*ri)); else - gResearchItemsUninvented.push_back(ResearchItem{ ri->rawValue, ri->category }); + gResearchItemsUninvented.push_back(ResearchItem(*ri)); } }