diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 4ca30c12c1..a442c1697f 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -122,6 +122,8 @@ private: EntryList _pathAdditionEntries; EntryList _sceneryGroupEntries; EntryList _waterEntry; + EntryList _terrainSurfaceEntries; + EntryList _terrainEdgeEntries; EntryList _footpathSurfaceEntries; EntryList _footpathRailingsEntries; @@ -134,6 +136,8 @@ private: ObjectEntryIndex _pathTypeToEntryMap[24]{}; ObjectEntryIndex _pathAdditionTypeToEntryMap[16]{}; ObjectEntryIndex _sceneryThemeTypeToEntryMap[24]{}; + ObjectEntryIndex _terrainSurfaceTypeToEntryMap[16]{}; + ObjectEntryIndex _terrainEdgeTypeToEntryMap[16]{}; ObjectEntryIndex _footpathSurfaceTypeToEntryMap[32]{}; ObjectEntryIndex _footpathRailingsTypeToEntryMap[4]{}; @@ -377,6 +381,8 @@ private: std::fill(std::begin(_pathTypeToEntryMap), std::end(_pathTypeToEntryMap), OBJECT_ENTRY_INDEX_NULL); std::fill(std::begin(_pathAdditionTypeToEntryMap), std::end(_pathAdditionTypeToEntryMap), OBJECT_ENTRY_INDEX_NULL); std::fill(std::begin(_sceneryThemeTypeToEntryMap), std::end(_sceneryThemeTypeToEntryMap), OBJECT_ENTRY_INDEX_NULL); + std::fill(std::begin(_terrainSurfaceTypeToEntryMap), std::end(_terrainSurfaceTypeToEntryMap), OBJECT_ENTRY_INDEX_NULL); + std::fill(std::begin(_terrainEdgeTypeToEntryMap), std::end(_terrainEdgeTypeToEntryMap), OBJECT_ENTRY_INDEX_NULL); std::fill( std::begin(_footpathSurfaceTypeToEntryMap), std::end(_footpathSurfaceTypeToEntryMap), OBJECT_ENTRY_INDEX_NULL); std::fill( @@ -419,6 +425,21 @@ private: _footpathRailingsEntries.AddRange( { "rct2.railings.wood", "rct1.ll.railings.space", "rct1.ll.railings.bamboo", "rct2.railings.concrete" }); + + // Add default surfaces + _terrainSurfaceEntries.AddRange({ "rct2.surface.grass", "rct2.surface.sand", "rct2.surface.dirt", "rct2.surface.rock", + "rct2.surface.martian", "rct2.surface.chequerboard", "rct2.surface.grassclumps", + "rct2.surface.ice", "rct2.surface.gridred", "rct2.surface.gridyellow", + "rct2.surface.gridpurple", "rct2.surface.gridgreen", "rct2.surface.sandred", + "rct2.surface.sandbrown", "rct1.aa.surface.roofred", "rct1.ll.surface.roofgrey", + "rct1.ll.surface.rust", "rct1.ll.surface.wood" }); + + // Add default edges + _terrainEdgeEntries.AddRange({ "rct2.edge.rock", "rct2.edge.woodred", "rct2.edge.woodblack", "rct2.edge.ice", + "rct1.edge.brick", "rct1.edge.iron", "rct1.aa.edge.grey", "rct1.aa.edge.yellow", + "rct1.aa.edge.red", "rct1.ll.edge.purple", "rct1.ll.edge.green", + "rct1.ll.edge.stonebrown", "rct1.ll.edge.stonegrey", "rct1.ll.edge.skyscrapera", + "rct1.ll.edge.skyscraperb" }); } void AddAvailableEntriesFromResearchList() @@ -473,6 +494,15 @@ private: { switch (tileElement->GetType()) { + case TILE_ELEMENT_TYPE_SURFACE: + { + auto surfaceEl = tileElement->AsSurface(); + auto surfaceStyle = surfaceEl->GetSurfaceStyle(); + auto edgeStyle = surfaceEl->GetEdgeStyle(); + AddEntryForTerrainSurface(surfaceStyle); + AddEntryForTerrainEdge(edgeStyle); + break; + } case TILE_ELEMENT_TYPE_PATH: { uint8_t pathType = tileElement->AsPath()->GetRCT1PathType(); @@ -711,6 +741,34 @@ private: } } + void AddEntryForTerrainSurface(ObjectEntryIndex terrainSurfaceType) + { + assert(terrainSurfaceType < std::size(_terrainSurfaceTypeToEntryMap)); + if (_terrainSurfaceTypeToEntryMap[terrainSurfaceType] == OBJECT_ENTRY_INDEX_NULL) + { + auto identifier = RCT1::GetTerrainSurfaceObject(terrainSurfaceType); + if (!identifier.empty()) + { + auto entryIndex = _terrainSurfaceEntries.GetOrAddEntry(identifier); + _terrainSurfaceTypeToEntryMap[terrainSurfaceType] = entryIndex; + } + } + } + + void AddEntryForTerrainEdge(ObjectEntryIndex terrainEdgeType) + { + assert(terrainEdgeType < std::size(_terrainEdgeTypeToEntryMap)); + if (_terrainEdgeTypeToEntryMap[terrainEdgeType] == OBJECT_ENTRY_INDEX_NULL) + { + auto identifier = RCT1::GetTerrainEdgeObject(terrainEdgeType); + if (!identifier.empty()) + { + auto entryIndex = _terrainEdgeEntries.GetOrAddEntry(identifier); + _terrainEdgeTypeToEntryMap[terrainEdgeType] = entryIndex; + } + } + } + void AddEntryForFootpathRailings(ObjectEntryIndex railingsType) { assert(railingsType < std::size(_footpathRailingsTypeToEntryMap)); @@ -1455,6 +1513,8 @@ private: })); AppendRequiredObjects(result, ObjectType::ParkEntrance, std::vector({ "rct2.pkent1" })); AppendRequiredObjects(result, ObjectType::Water, _waterEntry); + AppendRequiredObjects(result, ObjectType::TerrainSurface, _terrainSurfaceEntries); + AppendRequiredObjects(result, ObjectType::TerrainEdge, _terrainEdgeEntries); AppendRequiredObjects(result, ObjectType::FootpathSurface, _footpathSurfaceEntries); AppendRequiredObjects(result, ObjectType::FootpathRailings, _footpathRailingsEntries); RCT12AddDefaultObjects(result); @@ -1532,9 +1592,12 @@ private: auto dst2 = dst->AsSurface(); auto src2 = src->AsSurface(); + auto surfaceStyle = _terrainSurfaceTypeToEntryMap[src2->GetSurfaceStyle()]; + auto edgeStyle = _terrainEdgeTypeToEntryMap[src2->GetEdgeStyle()]; + dst2->SetSlope(src2->GetSlope()); - dst2->SetSurfaceStyle(RCT1::GetTerrain(src2->GetSurfaceStyle())); - dst2->SetEdgeStyle(RCT1::GetTerrainEdge(src2->GetEdgeStyle())); + dst2->SetSurfaceStyle(surfaceStyle); + dst2->SetEdgeStyle(edgeStyle); dst2->SetGrassLength(src2->GetGrassLength()); dst2->SetOwnership(src2->GetOwnership()); dst2->SetParkFences(src2->GetParkFences()); diff --git a/src/openrct2/rct1/Tables.cpp b/src/openrct2/rct1/Tables.cpp index c6de909ecc..213fc92bc7 100644 --- a/src/openrct2/rct1/Tables.cpp +++ b/src/openrct2/rct1/Tables.cpp @@ -116,7 +116,7 @@ namespace RCT1 return map[rct1SpriteType]; } - ObjectEntryIndex GetTerrain(uint8_t terrainSurface) + std::string_view GetTerrainSurfaceObject(uint8_t terrainSurface) { static constexpr std::string_view map[RCT1_NUM_TERRAIN_SURFACES] = { @@ -137,16 +137,10 @@ namespace RCT1 "rct2.surface.gridpurple", "rct2.surface.gridgreen", }; - std::string selectedSurface = "rct2.surface.grass"; - if (terrainSurface < std::size(map)) - { - selectedSurface = map[terrainSurface]; - } - - return object_manager_get_loaded_object_entry_index(ObjectEntryDescriptor(selectedSurface)); + return terrainSurface < std::size(map) ? map[terrainSurface] : map[0]; } - ObjectEntryIndex GetTerrainEdge(uint8_t terrainEdge) + std::string_view GetTerrainEdgeObject(uint8_t terrainEdge) { static constexpr std::string_view map[RCT1_NUM_TERRAIN_EDGES] = { @@ -166,13 +160,7 @@ namespace RCT1 "rct1.ll.edge.skyscrapera", "rct1.ll.edge.skyscraperb", }; - std::string selectedEdge = "rct2.edge.rock"; - if (terrainEdge < std::size(map)) - { - selectedEdge = map[terrainEdge]; - } - - return object_manager_get_loaded_object_entry_index(ObjectEntryDescriptor(selectedEdge)); + return terrainEdge < std::size(map) ? map[terrainEdge] : map[0]; } uint8_t GetRideType(uint8_t rideType, uint8_t vehicleType) diff --git a/src/openrct2/rct1/Tables.h b/src/openrct2/rct1/Tables.h index c77c84cf55..e72bef6a67 100644 --- a/src/openrct2/rct1/Tables.h +++ b/src/openrct2/rct1/Tables.h @@ -23,8 +23,6 @@ namespace RCT1 colour_t GetColour(colour_t colour); PeepSpriteType GetPeepSpriteType(uint8_t rct1SpriteType); - ObjectEntryIndex GetTerrain(uint8_t terrain); - ObjectEntryIndex GetTerrainEdge(uint8_t terrainEdge); uint8_t GetRideType(uint8_t rideType, uint8_t vehicleType); RCT1VehicleColourSchemeCopyDescriptor GetColourSchemeCopyDescriptor(uint8_t vehicleType); @@ -43,6 +41,8 @@ namespace RCT1 std::string_view GetFootpathRailingsObject(uint8_t footpathRailingsType); std::string_view GetSceneryGroupObject(uint8_t sceneryGroupType); std::string_view GetWaterObject(uint8_t waterType); + std::string_view GetTerrainSurfaceObject(uint8_t terrain); + std::string_view GetTerrainEdgeObject(uint8_t terrainEdge); const std::vector GetSceneryObjects(uint8_t sceneryType); } // namespace RCT1 diff --git a/src/openrct2/rct12/RCT12.cpp b/src/openrct2/rct12/RCT12.cpp index 6306746c6c..4f18ad03c9 100644 --- a/src/openrct2/rct12/RCT12.cpp +++ b/src/openrct2/rct12/RCT12.cpp @@ -1387,7 +1387,7 @@ std::optional GetStyleFromMusicIdentifier(std::string_view identifier) return {}; } -void RCT12AddDefaultObjects(ObjectList& objectList) +void SetDefaultRCT2TerrainObjects(ObjectList& objectList) { // Surfaces objectList.SetObject(ObjectType::TerrainSurface, 0, "rct2.surface.grass"); @@ -1425,7 +1425,10 @@ void RCT12AddDefaultObjects(ObjectList& objectList) objectList.SetObject(ObjectType::TerrainEdge, 12, "rct1.ll.edge.stonegrey"); objectList.SetObject(ObjectType::TerrainEdge, 13, "rct1.ll.edge.skyscrapera"); objectList.SetObject(ObjectType::TerrainEdge, 14, "rct1.ll.edge.skyscraperb"); +} +void RCT12AddDefaultObjects(ObjectList& objectList) +{ // Stations for (size_t i = 0; i < std::size(_stationStyles); i++) { diff --git a/src/openrct2/rct12/RCT12.h b/src/openrct2/rct12/RCT12.h index 2e9f1a7613..0aae72915c 100644 --- a/src/openrct2/rct12/RCT12.h +++ b/src/openrct2/rct12/RCT12.h @@ -936,4 +936,5 @@ track_type_t RCT12FlatTrackTypeToOpenRCT2(RCT12TrackType origTrackType); RCT12TrackType OpenRCT2FlatTrackTypeToRCT12(track_type_t origTrackType); std::string_view GetStationIdentifierFromStyle(uint8_t style); std::optional GetStyleFromMusicIdentifier(std::string_view identifier); +void SetDefaultRCT2TerrainObjects(ObjectList& objectList); void RCT12AddDefaultObjects(ObjectList& objectList); diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 84bab6fec8..7690ef85fe 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -1549,6 +1549,7 @@ public: } } + SetDefaultRCT2TerrainObjects(objectList); RCT12AddDefaultObjects(objectList); return objectList; }