diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 712dc83e5b..f621d671f9 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -10,6 +10,7 @@ - Change: [#11449] Remove complete circuit requirement from Air Powered Vertical Coaster (for RCT1 parity). - Fix: [#1148] Research funding dropdown not shown in finances window. - Fix: [#6119] Advertising campaign for ride window not updated properly (original bug). +- Fix: [#7006] Submarine Ride is in the wrong research group. - Fix: [#11072] Land and water tools working out of bounds (original bug). - Fix: [#11259] Custom JSON object breaks saves. - Fix: [#11290] Perform funds checking for all peeps entering a ride. 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-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index 1838abc86c..a7378fb392 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -1293,7 +1293,8 @@ static void editor_load_selected_objects() { rct_ride_entry* rideEntry = get_ride_entry(entryIndex); uint8_t rideType = ride_entry_get_first_non_null_ride_type(rideEntry); - research_insert_ride_entry(rideType, entryIndex, rideEntry->category[0], true); + uint8_t category = RideTypeDescriptors[rideType].Category; + research_insert_ride_entry(rideType, entryIndex, category, true); } else if (objectType == OBJECT_TYPE_SCENERY_GROUP) { diff --git a/src/openrct2/interface/InteractiveConsole.cpp b/src/openrct2/interface/InteractiveConsole.cpp index 164b5b93d2..a23c4eee9d 100644 --- a/src/openrct2/interface/InteractiveConsole.cpp +++ b/src/openrct2/interface/InteractiveConsole.cpp @@ -1094,7 +1094,11 @@ static int32_t cc_load_object(InteractiveConsole& console, const arguments_t& ar for (int32_t j = 0; j < MAX_RIDE_TYPES_PER_RIDE_ENTRY; j++) { rideType = rideEntry->ride_type[j]; - research_insert_ride_entry(rideType, groupIndex, rideEntry->category[0], true); + if (rideType != RIDE_TYPE_NULL) + { + uint8_t category = RideTypeDescriptors[rideType].Category; + research_insert_ride_entry(rideType, groupIndex, category, true); + } } gSilentResearch = true; diff --git a/src/openrct2/management/NewsItem.cpp b/src/openrct2/management/NewsItem.cpp index 5c04535d4b..917c6baf1c 100644 --- a/src/openrct2/management/NewsItem.cpp +++ b/src/openrct2/management/NewsItem.cpp @@ -379,7 +379,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..7a4539f0c0 100644 --- a/src/openrct2/management/Research.cpp +++ b/src/openrct2/management/Research.cpp @@ -488,7 +488,11 @@ void research_populate_list_random() int32_t researched = (scenario_rand() & 0xFF) > 128; for (auto rideType : rideEntry->ride_type) { - research_insert_ride_entry(rideType, i, rideEntry->category[0], researched); + if (rideType != RIDE_TYPE_NULL) + { + uint8_t category = RideTypeDescriptors[rideType].Category; + research_insert_ride_entry(rideType, i, category, researched); + } } } @@ -506,42 +510,12 @@ void research_populate_list_random() } } -void research_populate_list_researched() -{ - // Rides - for (int32_t i = 0; i < MAX_RIDE_OBJECTS; i++) - { - rct_ride_entry* rideEntry = get_ride_entry(i); - if (rideEntry == nullptr) - { - continue; - } - - for (auto rideType : rideEntry->ride_type) - { - research_insert_ride_entry(rideType, i, rideEntry->category[0], true); - } - } - - // Scenery - for (uint32_t i = 0; i < MAX_SCENERY_GROUP_OBJECTS; i++) - { - rct_scenery_group_entry* sceneryGroupEntry = get_scenery_group_entry(i); - if (sceneryGroupEntry == nullptr) - { - continue; - } - - research_insert_scenery_group_entry(i, true); - } -} - bool research_insert_ride_entry(uint8_t rideType, ObjectEntryIndex entryIndex, uint8_t category, bool researched) { - if (rideType != RIDE_TYPE_NULL) + if (rideType != RIDE_TYPE_NULL && entryIndex != OBJECT_ENTRY_INDEX_NULL) { - research_insert( - { static_cast(RESEARCH_ENTRY_RIDE_MASK | (rideType << 8) | entryIndex), category }, researched); + auto tmpItem = ResearchItem(RESEARCH_ENTRY_TYPE_RIDE, entryIndex, rideType, category, 0); + research_insert(tmpItem, researched); return true; } @@ -551,16 +525,26 @@ bool research_insert_ride_entry(uint8_t rideType, ObjectEntryIndex entryIndex, u void research_insert_ride_entry(ObjectEntryIndex entryIndex, bool researched) { rct_ride_entry* rideEntry = get_ride_entry(entryIndex); - uint8_t category = rideEntry->category[0]; for (auto rideType : rideEntry->ride_type) { - research_insert_ride_entry(rideType, entryIndex, category, researched); + if (rideType != RIDE_TYPE_NULL) + { + uint8_t category = RideTypeDescriptors[rideType].Category; + research_insert_ride_entry(rideType, entryIndex, category, researched); + } } } -void research_insert_scenery_group_entry(ObjectEntryIndex entryIndex, bool researched) +bool research_insert_scenery_group_entry(ObjectEntryIndex entryIndex, bool researched) { - research_insert({ entryIndex, RESEARCH_CATEGORY_SCENERY_GROUP }, researched); + if (entryIndex != OBJECT_ENTRY_INDEX_NULL) + { + auto tmpItem = ResearchItem( + RESEARCH_ENTRY_TYPE_SCENERY, entryIndex, RIDE_TYPE_NULL, RESEARCH_CATEGORY_SCENERY_GROUP, 0); + research_insert(tmpItem, researched); + return true; + } + return false; } bool ride_type_is_invented(uint32_t rideType) @@ -895,7 +879,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..2ff01d3211 100644 --- a/src/openrct2/management/Research.h +++ b/src/openrct2/management/Research.h @@ -19,32 +19,80 @@ 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 _category, uint8_t _flags) : rawValue(_rawValue) + , flags(_flags) , category(_category) { } + ResearchItem(uint8_t _type, ObjectEntryIndex _entryIndex, uint8_t _baseRideType, uint8_t _category, uint8_t _flags) + : entryIndex(_entryIndex) + , baseRideType(_baseRideType) + , type(_type) + , 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 +112,6 @@ enum #define MAX_RESEARCH_ITEMS 500 -#define RESEARCH_ENTRY_RIDE_MASK 0x10000 - enum { RESEARCH_FUNDING_NONE, @@ -85,7 +131,7 @@ enum RESEARCH_STAGE_FINISHED_ALL }; -enum +enum : uint8_t { RESEARCH_CATEGORY_TRANSPORT, RESEARCH_CATEGORY_GENTLE, @@ -115,7 +161,6 @@ void research_update_uncompleted_types(); void research_update(); void research_reset_current_item(); void research_populate_list_random(); -void research_populate_list_researched(); void research_finish_item(ResearchItem* researchItem); void research_insert(ResearchItem item, bool researched); @@ -123,7 +168,7 @@ void research_remove(ResearchItem* researchItem); bool research_insert_ride_entry(uint8_t rideType, ObjectEntryIndex entryIndex, uint8_t category, bool researched); void research_insert_ride_entry(ObjectEntryIndex entryIndex, bool researched); -void research_insert_scenery_group_entry(ObjectEntryIndex entryIndex, bool researched); +bool research_insert_scenery_group_entry(ObjectEntryIndex entryIndex, bool researched); void ride_type_set_invented(uint32_t rideType); void ride_entry_set_invented(int32_t rideEntryIndex); diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index ed3a7d6c38..8303d82120 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -32,7 +32,7 @@ // This string specifies which version of network stream current build uses. // It is used for making sure only compatible builds get connected, even within // single OpenRCT2 version. -#define NETWORK_STREAM_VERSION "9" +#define NETWORK_STREAM_VERSION "11" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; diff --git a/src/openrct2/object/RideObject.cpp b/src/openrct2/object/RideObject.cpp index e450a73ef2..2e0745f9fb 100644 --- a/src/openrct2/object/RideObject.cpp +++ b/src/openrct2/object/RideObject.cpp @@ -60,9 +60,8 @@ void RideObject::ReadLegacy(IReadObjectContext* context, IStream* stream) _legacyType.intensity_multiplier = stream->ReadValue(); _legacyType.nausea_multiplier = stream->ReadValue(); _legacyType.max_height = stream->ReadValue(); - _legacyType.enabledTrackPieces = stream->ReadValue(); - _legacyType.category[0] = stream->ReadValue(); - _legacyType.category[1] = stream->ReadValue(); + // Skipping a uint64_t for the enabled track pieces and two uint8_ts for the categories. + stream->Seek(10, STREAM_SEEK_CURRENT); _legacyType.shop_item = stream->ReadValue(); _legacyType.shop_item_secondary = stream->ReadValue(); @@ -382,32 +381,32 @@ std::string RideObject::GetCapacity() const void RideObject::SetRepositoryItem(ObjectRepositoryItem* item) const { + // Find the first non-null ride type, to be used when checking the ride group and determining the category. + uint8_t firstRideType = ride_entry_get_first_non_null_ride_type(&_legacyType); + uint8_t category = RideTypeDescriptors[firstRideType].Category; + for (int32_t i = 0; i < RCT2_MAX_RIDE_TYPES_PER_RIDE_ENTRY; i++) { item->RideInfo.RideType[i] = _legacyType.ride_type[i]; } for (int32_t i = 0; i < RCT2_MAX_CATEGORIES_PER_RIDE; i++) { - item->RideInfo.RideCategory[i] = _legacyType.category[i]; + item->RideInfo.RideCategory[i] = category; } - uint8_t flags = 0; - item->RideInfo.RideFlags = flags; - - // Find the first non-null ride type, to be used when checking the ride group - uint8_t rideTypeIdx = ride_entry_get_first_non_null_ride_type(&_legacyType); + item->RideInfo.RideFlags = 0; // Determines the ride group. Will fall back to 0 if there is none found. uint8_t rideGroupIndex = 0; - const RideGroup* rideGroup = RideGroupManager::GetRideGroup(rideTypeIdx, &_legacyType); + const RideGroup* rideGroup = RideGroupManager::GetRideGroup(firstRideType, &_legacyType); // If the ride group is nullptr, the track type does not have ride groups. if (rideGroup != nullptr) { for (uint8_t i = rideGroupIndex + 1; i < MAX_RIDE_GROUPS_PER_RIDE_TYPE; i++) { - const RideGroup* irg = RideGroupManager::RideGroupFind(rideTypeIdx, i); + const RideGroup* irg = RideGroupManager::RideGroupFind(firstRideType, i); if (irg != nullptr) { @@ -547,17 +546,6 @@ void RideObject::ReadJson(IReadObjectContext* context, const json_t* root) _legacyType.ride_type[i] = rideType; } - auto rideCategories = ObjectJsonHelpers::GetJsonStringArray(json_object_get(properties, "category")); - if (rideCategories.size() >= 1) - { - _legacyType.category[0] = ParseRideCategory(rideCategories[0]); - _legacyType.category[1] = _legacyType.category[0]; - } - if (rideCategories.size() >= 2) - { - _legacyType.category[1] = ParseRideCategory(rideCategories[1]); - } - _legacyType.max_height = ObjectJsonHelpers::GetInteger(properties, "maxHeight"); // This needs to be set for both shops/facilities _and_ regular rides. diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index c479aee42d..519a67c9ac 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]; @@ -2603,11 +2603,12 @@ private: if (rideEntry != nullptr) { + auto rideType = ride_entry_get_first_non_null_ride_type(rideEntry); dst->entryIndex = entryIndex; - dst->baseRideType = ride_entry_get_first_non_null_ride_type(rideEntry); + dst->baseRideType = rideType; dst->type = RESEARCH_ENTRY_TYPE_RIDE; dst->flags = 0; - dst->category = rideEntry->category[0]; + dst->category = RideTypeDescriptors[rideType].Category; } } } @@ -2621,11 +2622,12 @@ private: if (rideEntry != nullptr) { + auto rideType = ride_entry_get_first_non_null_ride_type(rideEntry); dst->entryIndex = entryIndex; - dst->baseRideType = ride_entry_get_first_non_null_ride_type(rideEntry); + dst->baseRideType = rideType; dst->type = RESEARCH_ENTRY_TYPE_RIDE; dst->flags = 0; - dst->category = rideEntry->category[0]; + dst->category = RideTypeDescriptors[rideType].Category; } } } 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)); } } diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 5d32811d6f..40e7b24593 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -7509,15 +7509,8 @@ void fix_invalid_vehicle_sprite_sizes() bool ride_entry_has_category(const rct_ride_entry* rideEntry, uint8_t category) { - for (int32_t i = 0; i < MAX_CATEGORIES_PER_RIDE; i++) - { - if (rideEntry->category[i] == category) - { - return true; - } - } - - return false; + auto rideType = ride_entry_get_first_non_null_ride_type(rideEntry); + return RideTypeDescriptors[rideType].Category == category; } int32_t ride_get_entry_index(int32_t rideType, int32_t rideSubType) diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 55f9329ded..884abbcac8 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -94,40 +94,36 @@ assert_struct_size(rct_ride_name, 4); /** * Ride type structure. - * size: unknown */ struct rct_ride_entry { rct_ride_name naming; - uint32_t images_offset; // 0x004. The first three images are previews. They correspond to the ride_type[] array. - uint32_t flags; // 0x008 - uint8_t ride_type[RCT2_MAX_RIDE_TYPES_PER_RIDE_ENTRY]; // 0x00C - uint8_t min_cars_in_train; // 0x00F - uint8_t max_cars_in_train; // 0x010 - uint8_t cars_per_flat_ride; // 0x011 + // The first three images are previews. They correspond to the ride_type[] array. + uint32_t images_offset; + uint32_t flags; + uint8_t ride_type[RCT2_MAX_RIDE_TYPES_PER_RIDE_ENTRY]; + uint8_t min_cars_in_train; + uint8_t max_cars_in_train; + uint8_t cars_per_flat_ride; // Number of cars that can't hold passengers - uint8_t zero_cars; // 0x012 - // The index to the vehicle type displayed in - // the vehicle tab. - uint8_t tab_vehicle; // 0x013 - uint8_t default_vehicle; // 0x014 - // Convert from first - fourth vehicle to - // vehicle structure - uint8_t front_vehicle; // 0x015 - uint8_t second_vehicle; // 0x016 - uint8_t rear_vehicle; // 0x017 - uint8_t third_vehicle; // 0x018 - uint8_t pad_019; // 0x019 - rct_ride_entry_vehicle vehicles[RCT2_MAX_VEHICLES_PER_RIDE_ENTRY]; // 0x01A - vehicle_colour_preset_list* vehicle_preset_list; // 0x1AE - int8_t excitement_multiplier; // 0x1B2 - int8_t intensity_multiplier; // 0x1B3 - int8_t nausea_multiplier; // 0x1B4 - uint8_t max_height; // 0x1B5 - uint64_t enabledTrackPieces; // 0x1B6 - uint8_t category[RCT2_MAX_CATEGORIES_PER_RIDE]; // 0x1BE - uint8_t shop_item; // 0x1C0 - uint8_t shop_item_secondary; // 0x1C1 + uint8_t zero_cars; + // The index to the vehicle type displayed in the vehicle tab. + uint8_t tab_vehicle; + uint8_t default_vehicle; + // Convert from first - fourth vehicle to vehicle structure + uint8_t front_vehicle; + uint8_t second_vehicle; + uint8_t rear_vehicle; + uint8_t third_vehicle; + uint8_t pad_019; + rct_ride_entry_vehicle vehicles[RCT2_MAX_VEHICLES_PER_RIDE_ENTRY]; + vehicle_colour_preset_list* vehicle_preset_list; + int8_t excitement_multiplier; + int8_t intensity_multiplier; + int8_t nausea_multiplier; + uint8_t max_height; + uint8_t shop_item; + uint8_t shop_item_secondary; rct_string_id capacity; void* obj;