Fix #14482: Rides with Crooked House hack sometimes misbehave

This commit is contained in:
Gymnasiast 2021-10-20 23:13:01 +02:00
parent a4ed1cb6ce
commit 815d09a431
No known key found for this signature in database
GPG Key ID: DBFFF47AB2CA3EDD
4 changed files with 32 additions and 5 deletions

View File

@ -13,6 +13,7 @@
- Fix: [#13465] Creating a scenario based on a won save game results in a scenario thats instantly won.
- Fix: [#13912] “Dome park” no longer renders dome correctly.
- Fix: [#14316] Closing the Track Designs Manager window causes broken state.
- Fix: [#14482, #15258] Rides with invisibility hacks sometimes behave incorrectly.
- Fix: [#14649] ImageImporter incorrectly remaps colours outside the RCT2 palette.
- Fix: [#14667] “Extreme Hawaiian Island” has unpurchaseable land tiles (original bug).
- Fix: [#14741] Crash when exiting OpenRCT2 on macOS.

View File

@ -140,9 +140,9 @@ bool RCT2TrackTypeIsBooster(uint8_t rideType, uint16_t trackType)
&& trackType == TrackElemType::Booster;
}
track_type_t RCT2TrackTypeToOpenRCT2(RCT12TrackType origTrackType, uint8_t rideType)
track_type_t RCT2TrackTypeToOpenRCT2(RCT12TrackType origTrackType, uint8_t rideType, bool convertFlat)
{
if (GetRideTypeDescriptor(rideType).HasFlag(RIDE_TYPE_FLAG_FLAT_RIDE))
if (convertFlat && GetRideTypeDescriptor(rideType).HasFlag(RIDE_TYPE_FLAG_FLAT_RIDE))
return RCT12FlatTrackTypeToOpenRCT2(origTrackType);
if (origTrackType == TrackElemType::RotationControlToggleAlias && !RCT2TrackTypeIsBooster(rideType, origTrackType))
return TrackElemType::RotationControlToggle;

View File

@ -1069,7 +1069,7 @@ ObjectEntryIndex RCT2RideTypeToOpenRCT2RideType(uint8_t rct2RideType, const rct_
bool RCT2TrackTypeIsBooster(uint8_t rideType, uint16_t trackType);
bool RCT2RideTypeNeedsConversion(uint8_t rct2RideType);
uint8_t OpenRCT2RideTypeToRCT2RideType(ObjectEntryIndex openrct2Type);
track_type_t RCT2TrackTypeToOpenRCT2(RCT12TrackType origTrackType, uint8_t rideType);
track_type_t RCT2TrackTypeToOpenRCT2(RCT12TrackType origTrackType, uint8_t rideType, bool convertFlat = true);
RCT12TrackType OpenRCT2TrackTypeToRCT2(track_type_t origTrackType);
/**

View File

@ -86,6 +86,7 @@ private:
rct_s6_data _s6{};
uint8_t _gameVersion = 0;
bool _isSV7 = false;
std::bitset<RCT12_MAX_RIDES_IN_PARK> _isFlatRide{};
public:
S6Importer(IObjectRepository& objectRepository)
@ -234,6 +235,7 @@ public:
scenario_rand_seed(_s6.scenario_srand_0, _s6.scenario_srand_1);
DetermineFlatRideStatus();
ImportTileElements();
ImportEntities();
@ -544,6 +546,29 @@ public:
}
}
void DetermineFlatRideStatus()
{
for (uint8_t index = 0; index < RCT12_MAX_RIDES_IN_PARK; index++)
{
auto src = &_s6.rides[index];
if (src->type == RIDE_TYPE_NULL)
continue;
auto subtype = RCTEntryIndexToOpenRCT2EntryIndex(src->subtype);
auto* rideEntry = get_ride_entry(subtype);
// This code is needed to detect hacks where a tracked ride has been made invisible
// by setting its ride type to a flat ride.
ObjectEntryIndex originalRideType = src->type;
if (rideEntry != nullptr)
{
originalRideType = ride_entry_get_first_non_null_ride_type(rideEntry);
}
const auto isFlatRide = GetRideTypeDescriptor(originalRideType).HasFlag(RIDE_TYPE_FLAG_FLAT_RIDE);
_isFlatRide.set(static_cast<size_t>(index), isFlatRide);
}
}
void ImportRide(Ride* dst, const rct2_ride* src, const ride_id_t rideIndex)
{
*dst = {};
@ -860,7 +885,8 @@ public:
dst.CurrentRide = RCT12RideIdToOpenRCT2RideId(src.current_ride);
dst.State = src.state;
if (src.current_ride < RCT12_MAX_RIDES_IN_PARK && _s6.rides[src.current_ride].type < std::size(RideTypeDescriptors))
dst.ProximityTrackType = RCT2TrackTypeToOpenRCT2(src.proximity_track_type, _s6.rides[src.current_ride].type);
dst.ProximityTrackType = RCT2TrackTypeToOpenRCT2(
src.proximity_track_type, _s6.rides[src.current_ride].type, _isFlatRide[src.current_ride]);
else
dst.ProximityTrackType = 0xFF;
dst.ProximityBaseHeight = src.proximity_base_height;
@ -1203,7 +1229,7 @@ public:
auto rideType = _s6.rides[src2->GetRideIndex()].type;
track_type_t trackType = static_cast<track_type_t>(src2->GetTrackType());
dst2->SetTrackType(RCT2TrackTypeToOpenRCT2(trackType, rideType));
dst2->SetTrackType(RCT2TrackTypeToOpenRCT2(trackType, rideType, _isFlatRide[src2->GetRideIndex()]));
dst2->SetRideType(rideType);
dst2->SetSequenceIndex(src2->GetSequenceIndex());
dst2->SetRideIndex(RCT12RideIdToOpenRCT2RideId(src2->GetRideIndex()));