From 79f3e28b0776e1142cf253447b105db990e521f0 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 5 Oct 2022 20:13:11 +0200 Subject: [PATCH 1/2] Fix #18204: Crash opening New Ride window with invalid highlight --- src/openrct2-ui/windows/NewRide.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/openrct2-ui/windows/NewRide.cpp b/src/openrct2-ui/windows/NewRide.cpp index 36f02d0c69..042745fda3 100644 --- a/src/openrct2-ui/windows/NewRide.cpp +++ b/src/openrct2-ui/windows/NewRide.cpp @@ -989,7 +989,9 @@ void WindowNewRideFocus(RideSelection rideItem) } rct_ride_entry* rideEntry = get_ride_entry(rideItem.EntryIndex); - auto rideTypeIndex = ride_entry_get_first_non_null_ride_type(rideEntry); + if (rideEntry == nullptr) + return; + auto rideTypeIndex = ride_entry_get_first_non_null_ride_type(rideEntry); w->SetPage(GetRideTypeDescriptor(rideTypeIndex).Category); } From 33f5fed0e286074f194723c240c35c2ff9745c63 Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Wed, 5 Oct 2022 20:16:46 +0200 Subject: [PATCH 2/2] Make GetFirstNonNullRideType() member function --- .../windows/EditorObjectSelection.cpp | 4 ++-- src/openrct2-ui/windows/NewRide.cpp | 2 +- src/openrct2/management/Research.cpp | 2 +- src/openrct2/object/RideObject.cpp | 2 +- src/openrct2/rct1/S4Importer.cpp | 4 ++-- src/openrct2/rct2/S6Importer.cpp | 2 +- src/openrct2/ride/Ride.cpp | 18 +----------------- src/openrct2/ride/Ride.h | 3 +-- src/openrct2/ride/RideEntry.h | 12 ++++++++++++ 9 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index ca57501f8b..193398d350 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -1508,7 +1508,7 @@ private: ; rct_ride_entry* ride_entry = get_ride_entry(entry_index); - auto rideType = ride_entry_get_first_non_null_ride_type(ride_entry); + auto rideType = ride_entry->GetFirstNonNullRideType(); auto intent = Intent(WindowClass::TrackDesignList); intent.putExtra(INTENT_EXTRA_RIDE_TYPE, rideType); @@ -1589,7 +1589,7 @@ void EditorLoadSelectedObjects() if (objectType == ObjectType::Ride) { rct_ride_entry* rideEntry = get_ride_entry(entryIndex); - auto rideType = ride_entry_get_first_non_null_ride_type(rideEntry); + auto rideType = rideEntry->GetFirstNonNullRideType(); ResearchCategory category = static_cast(GetRideTypeDescriptor(rideType).Category); research_insert_ride_entry(rideType, entryIndex, category, true); } diff --git a/src/openrct2-ui/windows/NewRide.cpp b/src/openrct2-ui/windows/NewRide.cpp index 042745fda3..73e0b82175 100644 --- a/src/openrct2-ui/windows/NewRide.cpp +++ b/src/openrct2-ui/windows/NewRide.cpp @@ -992,6 +992,6 @@ void WindowNewRideFocus(RideSelection rideItem) if (rideEntry == nullptr) return; - auto rideTypeIndex = ride_entry_get_first_non_null_ride_type(rideEntry); + auto rideTypeIndex = rideEntry->GetFirstNonNullRideType(); w->SetPage(GetRideTypeDescriptor(rideTypeIndex).Category); } diff --git a/src/openrct2/management/Research.cpp b/src/openrct2/management/Research.cpp index b2b72c7664..a1686f2a76 100644 --- a/src/openrct2/management/Research.cpp +++ b/src/openrct2/management/Research.cpp @@ -208,7 +208,7 @@ void research_finish_item(ResearchItem* researchItem) if (!RideTypeIsValid(base_ride_type)) { log_warning("Invalid ride type: %d", base_ride_type); - base_ride_type = ride_entry_get_first_non_null_ride_type(rideEntry); + base_ride_type = rideEntry->GetFirstNonNullRideType(); } StringId availabilityString; diff --git a/src/openrct2/object/RideObject.cpp b/src/openrct2/object/RideObject.cpp index 86e9db6bc6..5987bef18b 100644 --- a/src/openrct2/object/RideObject.cpp +++ b/src/openrct2/object/RideObject.cpp @@ -326,7 +326,7 @@ ImageIndex RideObject::GetPreviewImage(ride_type_t type) 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); + auto firstRideType = _legacyType.GetFirstNonNullRideType(); uint8_t category = GetRideTypeDescriptor(firstRideType).Category; for (int32_t i = 0; i < RCT2::ObjectLimits::MaxRideTypesPerRideEntry; i++) diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 7d995d7952..cfd4cb5651 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -2229,7 +2229,7 @@ namespace RCT1 if (rideEntry != nullptr) { - auto rideType = ride_entry_get_first_non_null_ride_type(rideEntry); + auto rideType = rideEntry->GetFirstNonNullRideType(); dst->entryIndex = entryIndex; dst->baseRideType = rideType; dst->type = Research::EntryType::Ride; @@ -2248,7 +2248,7 @@ namespace RCT1 if (rideEntry != nullptr) { - auto rideType = ride_entry_get_first_non_null_ride_type(rideEntry); + auto rideType = rideEntry->GetFirstNonNullRideType(); dst->entryIndex = entryIndex; dst->baseRideType = rideType; dst->type = Research::EntryType::Ride; diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index f6a7bb693b..be10b5f011 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -751,7 +751,7 @@ namespace RCT2 ObjectEntryIndex originalRideType = src->type; if (rideEntry != nullptr) { - originalRideType = ride_entry_get_first_non_null_ride_type(rideEntry); + originalRideType = rideEntry->GetFirstNonNullRideType(); } const auto isFlatRide = GetRideTypeDescriptor(originalRideType).HasFlag(RIDE_TYPE_FLAG_FLAT_RIDE); _isFlatRide.set(static_cast(index), isFlatRide); diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 53dee2314c..625fc905cf 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -5515,22 +5515,6 @@ bool ride_has_ratings(const Ride* ride) return ride->excitement != RIDE_RATING_UNDEFINED; } -/** - * Searches for a non-null ride type in a ride entry. - * If none is found, it will still return RIDE_TYPE_NULL. - */ -ride_type_t ride_entry_get_first_non_null_ride_type(const rct_ride_entry* rideEntry) -{ - for (uint8_t i = 0; i < RCT2::ObjectLimits::MaxRideTypesPerRideEntry; i++) - { - if (rideEntry->ride_type[i] != RIDE_TYPE_NULL) - { - return rideEntry->ride_type[i]; - } - } - return RIDE_TYPE_NULL; -} - int32_t get_booster_speed(ride_type_t rideType, int32_t rawSpeed) { int8_t shiftFactor = GetRideTypeDescriptor(rideType).OperatingSettings.BoosterSpeedFactor; @@ -5582,7 +5566,7 @@ void fix_invalid_vehicle_sprite_sizes() bool ride_entry_has_category(const rct_ride_entry* rideEntry, uint8_t category) { - auto rideType = ride_entry_get_first_non_null_ride_type(rideEntry); + auto rideType = rideEntry->GetFirstNonNullRideType(); return GetRideTypeDescriptor(rideType).Category == category; } diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index 3950ec1317..f8915405f0 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -18,6 +18,7 @@ #include "../rct2/Limits.h" #include "../world/Map.h" #include "RideColour.h" +#include "RideEntry.h" #include "RideRatings.h" #include "RideTypes.h" #include "Track.h" @@ -39,7 +40,6 @@ struct Vehicle; struct rct_ride_entry; struct ResultWithMessage; -#define RIDE_TYPE_NULL 255 #define RIDE_ADJACENCY_CHECK_DISTANCE 5 constexpr uint8_t TUNE_ID_NULL = 0xFF; @@ -1088,7 +1088,6 @@ bool ride_has_adjacent_station(Ride* ride); bool ride_has_station_shelter(Ride* ride); bool ride_has_ratings(const Ride* ride); -ride_type_t ride_entry_get_first_non_null_ride_type(const rct_ride_entry* rideEntry); int32_t get_booster_speed(ride_type_t rideType, int32_t rawSpeed); void fix_invalid_vehicle_sprite_sizes(); bool ride_entry_has_category(const rct_ride_entry* rideEntry, uint8_t category); diff --git a/src/openrct2/ride/RideEntry.h b/src/openrct2/ride/RideEntry.h index 112331e274..8efbc8305f 100644 --- a/src/openrct2/ride/RideEntry.h +++ b/src/openrct2/ride/RideEntry.h @@ -20,6 +20,7 @@ // Set to 255 on all tracked ride entries static uint8_t constexpr NoFlatRideCars = 0xFF; +static ride_type_t constexpr RIDE_TYPE_NULL = 0xFF; struct RideNaming { @@ -86,6 +87,17 @@ struct rct_ride_entry { return GetCar(DefaultCar); } + + ride_type_t GetFirstNonNullRideType() const + { + for (const auto& currentRideType : ride_type) + { + if (currentRideType != RIDE_TYPE_NULL) + return currentRideType; + } + + return RIDE_TYPE_NULL; + } }; void set_vehicle_type_image_max_sizes(CarEntry* vehicle_type, int32_t num_images);