Fix #7006: Use RTDs for determining ride category

This commit is contained in:
Gymnasiast 2020-04-30 12:58:20 +02:00
parent 505ac0f1a0
commit 6cdee9db93
No known key found for this signature in database
GPG Key ID: DBFFF47AB2CA3EDD
8 changed files with 58 additions and 69 deletions

View File

@ -10,6 +10,7 @@
- Change: [#11449] Remove complete circuit requirement from Air Powered Vertical Coaster (for RCT1 parity). - 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: [#1148] Research funding dropdown not shown in finances window.
- Fix: [#6119] Advertising campaign for ride window not updated properly (original bug). - 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: [#11072] Land and water tools working out of bounds (original bug).
- Fix: [#11259] Custom JSON object breaks saves. - Fix: [#11259] Custom JSON object breaks saves.
- Fix: [#11290] Perform funds checking for all peeps entering a ride. - Fix: [#11290] Perform funds checking for all peeps entering a ride.

View File

@ -1293,7 +1293,8 @@ static void editor_load_selected_objects()
{ {
rct_ride_entry* rideEntry = get_ride_entry(entryIndex); rct_ride_entry* rideEntry = get_ride_entry(entryIndex);
uint8_t rideType = ride_entry_get_first_non_null_ride_type(rideEntry); 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) else if (objectType == OBJECT_TYPE_SCENERY_GROUP)
{ {

View File

@ -1094,7 +1094,8 @@ 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++) for (int32_t j = 0; j < MAX_RIDE_TYPES_PER_RIDE_ENTRY; j++)
{ {
rideType = rideEntry->ride_type[j]; rideType = rideEntry->ride_type[j];
research_insert_ride_entry(rideType, groupIndex, rideEntry->category[0], true); uint8_t category = RideTypeDescriptors[rideType].Category;
research_insert_ride_entry(rideType, groupIndex, category, true);
} }
gSilentResearch = true; gSilentResearch = true;

View File

@ -488,7 +488,11 @@ void research_populate_list_random()
int32_t researched = (scenario_rand() & 0xFF) > 128; int32_t researched = (scenario_rand() & 0xFF) > 128;
for (auto rideType : rideEntry->ride_type) 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);
}
} }
} }
@ -521,10 +525,13 @@ bool research_insert_ride_entry(uint8_t rideType, ObjectEntryIndex entryIndex, u
void research_insert_ride_entry(ObjectEntryIndex entryIndex, bool researched) void research_insert_ride_entry(ObjectEntryIndex entryIndex, bool researched)
{ {
rct_ride_entry* rideEntry = get_ride_entry(entryIndex); rct_ride_entry* rideEntry = get_ride_entry(entryIndex);
uint8_t category = rideEntry->category[0];
for (auto rideType : rideEntry->ride_type) 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);
}
} }
} }

View File

@ -60,9 +60,8 @@ void RideObject::ReadLegacy(IReadObjectContext* context, IStream* stream)
_legacyType.intensity_multiplier = stream->ReadValue<int8_t>(); _legacyType.intensity_multiplier = stream->ReadValue<int8_t>();
_legacyType.nausea_multiplier = stream->ReadValue<int8_t>(); _legacyType.nausea_multiplier = stream->ReadValue<int8_t>();
_legacyType.max_height = stream->ReadValue<uint8_t>(); _legacyType.max_height = stream->ReadValue<uint8_t>();
_legacyType.enabledTrackPieces = stream->ReadValue<uint64_t>(); // Skipping a uint64_t for the enabled track pieces and two uint8_ts for the categories.
_legacyType.category[0] = stream->ReadValue<uint8_t>(); stream->Seek(10, STREAM_SEEK_CURRENT);
_legacyType.category[1] = stream->ReadValue<uint8_t>();
_legacyType.shop_item = stream->ReadValue<uint8_t>(); _legacyType.shop_item = stream->ReadValue<uint8_t>();
_legacyType.shop_item_secondary = stream->ReadValue<uint8_t>(); _legacyType.shop_item_secondary = stream->ReadValue<uint8_t>();
@ -382,32 +381,32 @@ std::string RideObject::GetCapacity() const
void RideObject::SetRepositoryItem(ObjectRepositoryItem* item) 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++) for (int32_t i = 0; i < RCT2_MAX_RIDE_TYPES_PER_RIDE_ENTRY; i++)
{ {
item->RideInfo.RideType[i] = _legacyType.ride_type[i]; item->RideInfo.RideType[i] = _legacyType.ride_type[i];
} }
for (int32_t i = 0; i < RCT2_MAX_CATEGORIES_PER_RIDE; 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 = 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);
// Determines the ride group. Will fall back to 0 if there is none found. // Determines the ride group. Will fall back to 0 if there is none found.
uint8_t rideGroupIndex = 0; 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 the ride group is nullptr, the track type does not have ride groups.
if (rideGroup != nullptr) if (rideGroup != nullptr)
{ {
for (uint8_t i = rideGroupIndex + 1; i < MAX_RIDE_GROUPS_PER_RIDE_TYPE; i++) 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) if (irg != nullptr)
{ {
@ -547,17 +546,6 @@ void RideObject::ReadJson(IReadObjectContext* context, const json_t* root)
_legacyType.ride_type[i] = rideType; _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"); _legacyType.max_height = ObjectJsonHelpers::GetInteger(properties, "maxHeight");
// This needs to be set for both shops/facilities _and_ regular rides. // This needs to be set for both shops/facilities _and_ regular rides.

View File

@ -2603,11 +2603,12 @@ private:
if (rideEntry != nullptr) if (rideEntry != nullptr)
{ {
auto rideType = ride_entry_get_first_non_null_ride_type(rideEntry);
dst->entryIndex = entryIndex; dst->entryIndex = entryIndex;
dst->baseRideType = ride_entry_get_first_non_null_ride_type(rideEntry); dst->baseRideType = rideType;
dst->type = RESEARCH_ENTRY_TYPE_RIDE; dst->type = RESEARCH_ENTRY_TYPE_RIDE;
dst->flags = 0; dst->flags = 0;
dst->category = rideEntry->category[0]; dst->category = RideTypeDescriptors[rideType].Category;
} }
} }
} }
@ -2621,11 +2622,12 @@ private:
if (rideEntry != nullptr) if (rideEntry != nullptr)
{ {
auto rideType = ride_entry_get_first_non_null_ride_type(rideEntry);
dst->entryIndex = entryIndex; dst->entryIndex = entryIndex;
dst->baseRideType = ride_entry_get_first_non_null_ride_type(rideEntry); dst->baseRideType = rideType;
dst->type = RESEARCH_ENTRY_TYPE_RIDE; dst->type = RESEARCH_ENTRY_TYPE_RIDE;
dst->flags = 0; dst->flags = 0;
dst->category = rideEntry->category[0]; dst->category = RideTypeDescriptors[rideType].Category;
} }
} }
} }

View File

@ -7509,15 +7509,8 @@ void fix_invalid_vehicle_sprite_sizes()
bool ride_entry_has_category(const rct_ride_entry* rideEntry, uint8_t category) bool ride_entry_has_category(const rct_ride_entry* rideEntry, uint8_t category)
{ {
for (int32_t i = 0; i < MAX_CATEGORIES_PER_RIDE; i++) auto rideType = ride_entry_get_first_non_null_ride_type(rideEntry);
{ return RideTypeDescriptors[rideType].Category == category;
if (rideEntry->category[i] == category)
{
return true;
}
}
return false;
} }
int32_t ride_get_entry_index(int32_t rideType, int32_t rideSubType) int32_t ride_get_entry_index(int32_t rideType, int32_t rideSubType)

View File

@ -94,40 +94,36 @@ assert_struct_size(rct_ride_name, 4);
/** /**
* Ride type structure. * Ride type structure.
* size: unknown
*/ */
struct rct_ride_entry struct rct_ride_entry
{ {
rct_ride_name naming; rct_ride_name naming;
uint32_t images_offset; // 0x004. The first three images are previews. They correspond to the ride_type[] array. // The first three images are previews. They correspond to the ride_type[] array.
uint32_t flags; // 0x008 uint32_t images_offset;
uint8_t ride_type[RCT2_MAX_RIDE_TYPES_PER_RIDE_ENTRY]; // 0x00C uint32_t flags;
uint8_t min_cars_in_train; // 0x00F uint8_t ride_type[RCT2_MAX_RIDE_TYPES_PER_RIDE_ENTRY];
uint8_t max_cars_in_train; // 0x010 uint8_t min_cars_in_train;
uint8_t cars_per_flat_ride; // 0x011 uint8_t max_cars_in_train;
uint8_t cars_per_flat_ride;
// Number of cars that can't hold passengers // Number of cars that can't hold passengers
uint8_t zero_cars; // 0x012 uint8_t zero_cars;
// The index to the vehicle type displayed in // The index to the vehicle type displayed in the vehicle tab.
// the vehicle tab. uint8_t tab_vehicle;
uint8_t tab_vehicle; // 0x013 uint8_t default_vehicle;
uint8_t default_vehicle; // 0x014 // Convert from first - fourth vehicle to vehicle structure
// Convert from first - fourth vehicle to uint8_t front_vehicle;
// vehicle structure uint8_t second_vehicle;
uint8_t front_vehicle; // 0x015 uint8_t rear_vehicle;
uint8_t second_vehicle; // 0x016 uint8_t third_vehicle;
uint8_t rear_vehicle; // 0x017 uint8_t pad_019;
uint8_t third_vehicle; // 0x018 rct_ride_entry_vehicle vehicles[RCT2_MAX_VEHICLES_PER_RIDE_ENTRY];
uint8_t pad_019; // 0x019 vehicle_colour_preset_list* vehicle_preset_list;
rct_ride_entry_vehicle vehicles[RCT2_MAX_VEHICLES_PER_RIDE_ENTRY]; // 0x01A int8_t excitement_multiplier;
vehicle_colour_preset_list* vehicle_preset_list; // 0x1AE int8_t intensity_multiplier;
int8_t excitement_multiplier; // 0x1B2 int8_t nausea_multiplier;
int8_t intensity_multiplier; // 0x1B3 uint8_t max_height;
int8_t nausea_multiplier; // 0x1B4 uint8_t shop_item;
uint8_t max_height; // 0x1B5 uint8_t shop_item_secondary;
uint64_t enabledTrackPieces; // 0x1B6
uint8_t category[RCT2_MAX_CATEGORIES_PER_RIDE]; // 0x1BE
uint8_t shop_item; // 0x1C0
uint8_t shop_item_secondary; // 0x1C1
rct_string_id capacity; rct_string_id capacity;
void* obj; void* obj;