diff --git a/src/openrct2/object/ObjectList.cpp b/src/openrct2/object/ObjectList.cpp index 397bfaa7bc..bd5e35a15c 100644 --- a/src/openrct2/object/ObjectList.cpp +++ b/src/openrct2/object/ObjectList.cpp @@ -148,10 +148,12 @@ const ObjectEntryDescriptor& ObjectList::GetObject(ObjectType type, ObjectEntryI return placeholder; } -void ObjectList::Add(const ObjectEntryDescriptor& entry) +ObjectEntryIndex ObjectList::Add(const ObjectEntryDescriptor& entry) { auto& subList = GetList(entry.GetType()); + auto index = subList.size(); subList.push_back(entry); + return static_cast(index); } void ObjectList::SetObject(ObjectEntryIndex index, const ObjectEntryDescriptor& entry) diff --git a/src/openrct2/object/ObjectList.h b/src/openrct2/object/ObjectList.h index 6695420886..15307c6e87 100644 --- a/src/openrct2/object/ObjectList.h +++ b/src/openrct2/object/ObjectList.h @@ -19,7 +19,7 @@ private: std::vector> _subLists; public: - void Add(const ObjectEntryDescriptor& entry); + ObjectEntryIndex Add(const ObjectEntryDescriptor& entry); std::vector& GetList(ObjectType type); std::vector& GetList(ObjectType type) const; const ObjectEntryDescriptor& GetObject(ObjectType type, ObjectEntryIndex index) const; diff --git a/src/openrct2/park/Legacy.cpp b/src/openrct2/park/Legacy.cpp index afb3356b43..4c577e29c9 100644 --- a/src/openrct2/park/Legacy.cpp +++ b/src/openrct2/park/Legacy.cpp @@ -2248,30 +2248,27 @@ const RCT2::FootpathMapping* GetFootpathMapping(const ObjectEntryDescriptor& des void UpdateFootpathsFromMapping( ObjectEntryIndex* pathToSurfaceMap, ObjectEntryIndex* pathToQueueSurfaceMap, ObjectEntryIndex* pathToRailingsMap, - ObjectList& requiredObjects, ObjectEntryIndex& surfaceCount, ObjectEntryIndex& railingCount, ObjectEntryIndex entryIndex, - const RCT2::FootpathMapping* footpathMapping) + ObjectList& requiredObjects, ObjectEntryIndex entryIndex, const RCT2::FootpathMapping* footpathMapping) { auto surfaceIndex = requiredObjects.Find(ObjectType::footpathSurface, footpathMapping->NormalSurface); if (surfaceIndex == kObjectEntryIndexNull) { - requiredObjects.SetObject(ObjectType::footpathSurface, surfaceCount, footpathMapping->NormalSurface); - surfaceIndex = surfaceCount++; + surfaceIndex = requiredObjects.Add(ObjectEntryDescriptor(ObjectType::footpathSurface, footpathMapping->NormalSurface)); } pathToSurfaceMap[entryIndex] = surfaceIndex; - surfaceIndex = requiredObjects.Find(ObjectType::footpathSurface, footpathMapping->QueueSurface); - if (surfaceIndex == kObjectEntryIndexNull) + auto queueSurfaceIndex = requiredObjects.Find(ObjectType::footpathSurface, footpathMapping->QueueSurface); + if (queueSurfaceIndex == kObjectEntryIndexNull) { - requiredObjects.SetObject(ObjectType::footpathSurface, surfaceCount, footpathMapping->QueueSurface); - surfaceIndex = surfaceCount++; + queueSurfaceIndex = requiredObjects.Add( + ObjectEntryDescriptor(ObjectType::footpathSurface, footpathMapping->QueueSurface)); } - pathToQueueSurfaceMap[entryIndex] = surfaceIndex; + pathToQueueSurfaceMap[entryIndex] = queueSurfaceIndex; auto railingIndex = requiredObjects.Find(ObjectType::footpathRailings, footpathMapping->Railing); if (railingIndex == kObjectEntryIndexNull) { - requiredObjects.SetObject(ObjectType::footpathRailings, railingCount, footpathMapping->Railing); - railingIndex = railingCount++; + railingIndex = requiredObjects.Add(ObjectEntryDescriptor(ObjectType::footpathRailings, footpathMapping->Railing)); } pathToRailingsMap[entryIndex] = railingIndex; } diff --git a/src/openrct2/park/Legacy.h b/src/openrct2/park/Legacy.h index 54d857e324..809196d357 100644 --- a/src/openrct2/park/Legacy.h +++ b/src/openrct2/park/Legacy.h @@ -45,8 +45,7 @@ std::optional GetDATPathName(std::string_view newPathName); const OpenRCT2::RCT2::FootpathMapping* GetFootpathMapping(const ObjectEntryDescriptor& desc); void UpdateFootpathsFromMapping( ObjectEntryIndex* pathToSurfaceMap, ObjectEntryIndex* pathToQueueSurfaceMap, ObjectEntryIndex* pathToRailingsMap, - ObjectList& requiredObjects, ObjectEntryIndex& surfaceCount, ObjectEntryIndex& railingCount, ObjectEntryIndex entryIndex, - const OpenRCT2::RCT2::FootpathMapping* footpathMapping); + ObjectList& requiredObjects, ObjectEntryIndex entryIndex, const OpenRCT2::RCT2::FootpathMapping* footpathMapping); std::span GetLegacyPeepAnimationObjects(); void ConvertPeepAnimationTypeToObjects(OpenRCT2::GameState_t& gameState); diff --git a/src/openrct2/park/ParkFile.cpp b/src/openrct2/park/ParkFile.cpp index b2fa45831a..33178d2f6d 100644 --- a/src/openrct2/park/ParkFile.cpp +++ b/src/openrct2/park/ParkFile.cpp @@ -44,6 +44,7 @@ #include "../object/ObjectManager.h" #include "../object/ObjectRepository.h" #include "../peep/RideUseSystem.h" +#include "../rct2/RCT2.h" #include "../ride/RideManager.hpp" #include "../ride/ShopItem.h" #include "../ride/Vehicle.h" @@ -313,12 +314,14 @@ namespace OpenRCT2 const auto version = os.GetHeader().TargetVersion; ObjectList requiredObjects; + struct LegacyFootpathMapping + { + ObjectEntryIndex originalEntryIndex; + const RCT2::FootpathMapping& mapping; + }; + std::vector legacyPathMappings; os.ReadWriteChunk( - ParkFileChunkType::OBJECTS, - [&requiredObjects, pathToSurfaceMap, pathToQueueSurfaceMap, pathToRailingsMap, - version](OrcaStream::ChunkStream& cs) { - ObjectEntryIndex surfaceCount = 0; - ObjectEntryIndex railingsCount = 0; + ParkFileChunkType::OBJECTS, [&requiredObjects, version, &legacyPathMappings](OrcaStream::ChunkStream& cs) { auto numSubLists = cs.Read(); for (size_t i = 0; i < numSubLists; i++) { @@ -337,15 +340,12 @@ namespace OpenRCT2 RCTObjectEntry datEntry; cs.Read(&datEntry, sizeof(datEntry)); ObjectEntryDescriptor desc(datEntry); - if (version <= 2 && datEntry.GetType() == ObjectType::paths) + if (version < kFixedObsoleteFootpathsVersion && datEntry.GetType() == ObjectType::paths) { auto footpathMapping = GetFootpathMapping(desc); if (footpathMapping != nullptr) { - UpdateFootpathsFromMapping( - pathToSurfaceMap, pathToQueueSurfaceMap, pathToRailingsMap, requiredObjects, - surfaceCount, railingsCount, j, footpathMapping); - + legacyPathMappings.push_back(LegacyFootpathMapping{ j, *footpathMapping }); continue; } } @@ -392,10 +392,7 @@ namespace OpenRCT2 auto footpathMapping = GetFootpathMapping(desc); if (footpathMapping != nullptr) { - // We have surface objects for this footpath - UpdateFootpathsFromMapping( - pathToSurfaceMap, pathToQueueSurfaceMap, pathToRailingsMap, requiredObjects, - surfaceCount, railingsCount, j, footpathMapping); + legacyPathMappings.push_back(LegacyFootpathMapping{ j, *footpathMapping }); continue; } @@ -411,6 +408,13 @@ namespace OpenRCT2 } }); + for (const auto& mapping : legacyPathMappings) + { + UpdateFootpathsFromMapping( + pathToSurfaceMap, pathToQueueSurfaceMap, pathToRailingsMap, requiredObjects, mapping.originalEntryIndex, + &mapping.mapping); + } + if (version < kPeepNamesObjectsVersion) { AppendRequiredObjects( diff --git a/src/openrct2/park/ParkFile.h b/src/openrct2/park/ParkFile.h index 4799386e28..d432103f30 100644 --- a/src/openrct2/park/ParkFile.h +++ b/src/openrct2/park/ParkFile.h @@ -20,7 +20,7 @@ namespace OpenRCT2 struct GameState_t; // Current version that is saved. - constexpr uint32_t kParkFileCurrentVersion = 55; + constexpr uint32_t kParkFileCurrentVersion = 56; // The minimum version that is forwards compatible with the current version. constexpr uint32_t kParkFileMinVersion = 55; @@ -53,6 +53,7 @@ namespace OpenRCT2 constexpr uint16_t kClimateObjectsVersion = 53; constexpr uint16_t kExtendedGoKartsVersion = 54; constexpr uint16_t kHigherInversionsHolesHelicesStatsVersion = 55; + constexpr uint16_t kFixedObsoleteFootpathsVersion = 56; } // namespace OpenRCT2 class ParkFileExporter