1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-06 06:32:56 +01:00

Only add RCT1 land objects to imported SV6 if they are used

This commit is contained in:
Duncan
2021-12-05 16:08:33 +00:00
committed by GitHub
parent 03749d186c
commit c01049a500
8 changed files with 181 additions and 95 deletions

View File

@@ -311,6 +311,7 @@
<ClInclude Include="platform\Crash.h" />
<ClInclude Include="platform\platform.h" />
<ClInclude Include="platform\Platform2.h" />
<ClInclude Include="rct12\EntryList.h" />
<ClInclude Include="rct12\Limits.h" />
<ClInclude Include="rct12\RCT12.h" />
<ClInclude Include="rct12\SawyerChunk.h" />

View File

@@ -45,6 +45,7 @@
#include "../object/ObjectManager.h"
#include "../object/ObjectRepository.h"
#include "../peep/RideUseSystem.h"
#include "../rct12/EntryList.h"
#include "../ride/RideData.h"
#include "../ride/Station.h"
#include "../ride/Track.h"
@@ -80,44 +81,6 @@ using namespace OpenRCT2;
namespace RCT1
{
class EntryList
{
private:
std::vector<std::string> _entries;
public:
size_t GetCount() const
{
return _entries.size();
}
const std::vector<std::string>& GetEntries() const
{
return _entries;
}
ObjectEntryIndex GetOrAddEntry(std::string_view identifier)
{
for (size_t i = 0; i < _entries.size(); i++)
{
if (_entries[i] == identifier)
{
return static_cast<ObjectEntryIndex>(i);
}
}
_entries.emplace_back(identifier);
return static_cast<ObjectEntryIndex>(_entries.size() - 1);
}
void AddRange(std::initializer_list<const char*> initializerList)
{
for (auto entry : initializerList)
{
GetOrAddEntry(entry);
}
}
};
class S4Importer final : public IParkImporter
{
private:
@@ -128,18 +91,18 @@ namespace RCT1
bool _isScenario = false;
// Lists of dynamic object entries
EntryList _rideEntries;
EntryList _smallSceneryEntries;
EntryList _largeSceneryEntries;
EntryList _wallEntries;
EntryList _pathEntries;
EntryList _pathAdditionEntries;
EntryList _sceneryGroupEntries;
EntryList _waterEntry;
EntryList _terrainSurfaceEntries;
EntryList _terrainEdgeEntries;
EntryList _footpathSurfaceEntries;
EntryList _footpathRailingsEntries;
RCT12::EntryList _rideEntries;
RCT12::EntryList _smallSceneryEntries;
RCT12::EntryList _largeSceneryEntries;
RCT12::EntryList _wallEntries;
RCT12::EntryList _pathEntries;
RCT12::EntryList _pathAdditionEntries;
RCT12::EntryList _sceneryGroupEntries;
RCT12::EntryList _waterEntry;
RCT12::EntryList _terrainSurfaceEntries;
RCT12::EntryList _terrainEdgeEntries;
RCT12::EntryList _footpathSurfaceEntries;
RCT12::EntryList _footpathRailingsEntries;
// Lookup tables for converting from RCT1 hard coded types to the new dynamic object entries
ObjectEntryIndex _rideTypeToRideEntryMap[EnumValue(RideType::Count)]{};
@@ -598,7 +561,7 @@ namespace RCT1
case ObjectType::Paths:
case ObjectType::PathBits:
{
EntryList* entries = GetEntryList(objectType);
RCT12::EntryList* entries = GetEntryList(objectType);
// Check if there are spare entries available
size_t maxEntries = static_cast<size_t>(object_entry_group_counts[EnumValue(objectType)]);
@@ -1484,7 +1447,7 @@ namespace RCT1
}
}
void AppendRequiredObjects(ObjectList& objectList, ObjectType objectType, const EntryList& entryList)
void AppendRequiredObjects(ObjectList& objectList, ObjectType objectType, const RCT12::EntryList& entryList)
{
AppendRequiredObjects(objectList, objectType, entryList.GetEntries());
}
@@ -2456,7 +2419,7 @@ namespace RCT1
}
}
EntryList* GetEntryList(ObjectType objectType)
RCT12::EntryList* GetEntryList(ObjectType objectType)
{
switch (objectType)
{

View File

@@ -0,0 +1,65 @@
/*****************************************************************************
* Copyright (c) 2014-2021 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#pragma once
#include <string>
#include <string_view>
#include <vector>
using ObjectEntryIndex = uint16_t;
namespace RCT12
{
class EntryList
{
private:
std::vector<std::string> _entries;
public:
size_t GetCount() const
{
return _entries.size();
}
const std::vector<std::string>& GetEntries() const
{
return _entries;
}
ObjectEntryIndex GetOrAddEntry(std::string_view identifier)
{
for (size_t i = 0; i < _entries.size(); i++)
{
if (_entries[i] == identifier)
{
return static_cast<ObjectEntryIndex>(i);
}
}
_entries.emplace_back(identifier);
return static_cast<ObjectEntryIndex>(_entries.size() - 1);
}
void AddRange(std::initializer_list<const char*> initializerList)
{
for (auto entry : initializerList)
{
GetOrAddEntry(entry);
}
}
template<uint32_t i> void AddRange(const std::string_view (&list)[i])
{
for (auto entry : list)
{
GetOrAddEntry(entry);
}
}
};
} // namespace RCT12

View File

@@ -22,6 +22,7 @@
#include "../world/Surface.h"
#include "../world/TileElement.h"
#include "../world/Wall.h"
#include "EntryList.h"
using namespace OpenRCT2;
@@ -889,46 +890,6 @@ std::optional<uint8_t> GetStyleFromMusicIdentifier(std::string_view identifier)
return std::nullopt;
}
void SetDefaultRCT2TerrainObjects(ObjectList& objectList)
{
// Surfaces
objectList.SetObject(ObjectType::TerrainSurface, 0, "rct2.terrain_surface.grass");
objectList.SetObject(ObjectType::TerrainSurface, 1, "rct2.terrain_surface.sand");
objectList.SetObject(ObjectType::TerrainSurface, 2, "rct2.terrain_surface.dirt");
objectList.SetObject(ObjectType::TerrainSurface, 3, "rct2.terrain_surface.rock");
objectList.SetObject(ObjectType::TerrainSurface, 4, "rct2.terrain_surface.martian");
objectList.SetObject(ObjectType::TerrainSurface, 5, "rct2.terrain_surface.chequerboard");
objectList.SetObject(ObjectType::TerrainSurface, 6, "rct2.terrain_surface.grass_clumps");
objectList.SetObject(ObjectType::TerrainSurface, 7, "rct2.terrain_surface.ice");
objectList.SetObject(ObjectType::TerrainSurface, 8, "rct2.terrain_surface.grid_red");
objectList.SetObject(ObjectType::TerrainSurface, 9, "rct2.terrain_surface.grid_yellow");
objectList.SetObject(ObjectType::TerrainSurface, 10, "rct2.terrain_surface.grid_purple");
objectList.SetObject(ObjectType::TerrainSurface, 11, "rct2.terrain_surface.grid_green");
objectList.SetObject(ObjectType::TerrainSurface, 12, "rct2.terrain_surface.sand_red");
objectList.SetObject(ObjectType::TerrainSurface, 13, "rct2.terrain_surface.sand_brown");
objectList.SetObject(ObjectType::TerrainSurface, 14, "rct1aa.terrain_surface.roof_red");
objectList.SetObject(ObjectType::TerrainSurface, 15, "rct1ll.terrain_surface.roof_grey");
objectList.SetObject(ObjectType::TerrainSurface, 16, "rct1ll.terrain_surface.rust");
objectList.SetObject(ObjectType::TerrainSurface, 17, "rct1ll.terrain_surface.wood");
// Edges
objectList.SetObject(ObjectType::TerrainEdge, 0, "rct2.terrain_edge.rock");
objectList.SetObject(ObjectType::TerrainEdge, 1, "rct2.terrain_edge.wood_red");
objectList.SetObject(ObjectType::TerrainEdge, 2, "rct2.terrain_edge.wood_black");
objectList.SetObject(ObjectType::TerrainEdge, 3, "rct2.terrain_edge.ice");
objectList.SetObject(ObjectType::TerrainEdge, 4, "rct1.terrain_edge.brick");
objectList.SetObject(ObjectType::TerrainEdge, 5, "rct1.terrain_edge.iron");
objectList.SetObject(ObjectType::TerrainEdge, 6, "rct1aa.terrain_edge.grey");
objectList.SetObject(ObjectType::TerrainEdge, 7, "rct1aa.terrain_edge.yellow");
objectList.SetObject(ObjectType::TerrainEdge, 8, "rct1aa.terrain_edge.red");
objectList.SetObject(ObjectType::TerrainEdge, 9, "rct1ll.terrain_edge.purple");
objectList.SetObject(ObjectType::TerrainEdge, 10, "rct1ll.terrain_edge.green");
objectList.SetObject(ObjectType::TerrainEdge, 11, "rct1ll.terrain_edge.stone_brown");
objectList.SetObject(ObjectType::TerrainEdge, 12, "rct1ll.terrain_edge.stone_grey");
objectList.SetObject(ObjectType::TerrainEdge, 13, "rct1ll.terrain_edge.skyscraper_a");
objectList.SetObject(ObjectType::TerrainEdge, 14, "rct1ll.terrain_edge.skyscraper_b");
}
void RCT12AddDefaultObjects(ObjectList& objectList)
{
// Stations
@@ -947,6 +908,21 @@ void RCT12AddDefaultObjects(ObjectList& objectList)
}
}
static void AppendRequiredObjects(ObjectList& objectList, ObjectType objectType, const std::vector<std::string>& objectNames)
{
for (const auto& objectName : objectNames)
{
auto descriptor = ObjectEntryDescriptor(objectName);
descriptor.Type = objectType;
objectList.Add(descriptor);
}
}
void AppendRequiredObjects(ObjectList& objectList, ObjectType objectType, const RCT12::EntryList& entryList)
{
AppendRequiredObjects(objectList, objectType, entryList.GetEntries());
}
money64 RCT12CompletedCompanyValueToOpenRCT2(money32 origValue)
{
if (origValue == RCT12_COMPANY_VALUE_ON_FAILED_OBJECTIVE)

View File

@@ -24,6 +24,10 @@ class ObjectList;
using track_type_t = uint16_t;
using RCT12TrackType = uint8_t;
namespace RCT12
{
class EntryList;
}
constexpr uint8_t RCT2_STRING_FORMAT_ARG_START = 123;
constexpr uint8_t RCT2_STRING_FORMAT_ARG_END = 141;
@@ -832,8 +836,8 @@ track_type_t RCT12FlatTrackTypeToOpenRCT2(RCT12TrackType origTrackType);
RCT12TrackType OpenRCT2FlatTrackTypeToRCT12(track_type_t origTrackType);
std::string_view GetStationIdentifierFromStyle(uint8_t style);
std::optional<uint8_t> GetStyleFromMusicIdentifier(std::string_view identifier);
void SetDefaultRCT2TerrainObjects(ObjectList& objectList);
void RCT12AddDefaultObjects(ObjectList& objectList);
void AppendRequiredObjects(ObjectList& objectList, ObjectType objectType, const RCT12::EntryList& entryList);
static constexpr money32 RCT12_COMPANY_VALUE_ON_FAILED_OBJECTIVE = 0x80000001;

View File

@@ -11,6 +11,7 @@
#include "../Context.h"
#include "../object/Object.h"
#include "../object/ObjectList.h"
#include "../object/ObjectManager.h"
#include "../ride/Ride.h"
#include "../ride/RideData.h"

View File

@@ -20,6 +20,7 @@
#include <vector>
struct rct_ride_entry;
class ObjectList;
enum class EditorStep : uint8_t;
namespace RCT2
@@ -1063,6 +1064,37 @@ namespace RCT2
const FootpathMapping* GetFootpathSurfaceId(
const ObjectEntryDescriptor& desc, bool ideallyLoaded = false, bool isQueue = false);
std::optional<rct_object_entry> GetBestObjectEntryForSurface(std::string_view surface, std::string_view railings);
static constexpr std::string_view DefaultTerrainSurfaces[] = {
"rct2.terrain_surface.grass", "rct2.terrain_surface.sand", "rct2.terrain_surface.dirt",
"rct2.terrain_surface.rock", "rct2.terrain_surface.martian", "rct2.terrain_surface.chequerboard",
"rct2.terrain_surface.grass_clumps", "rct2.terrain_surface.ice", "rct2.terrain_surface.grid_red",
"rct2.terrain_surface.grid_yellow", "rct2.terrain_surface.grid_purple", "rct2.terrain_surface.grid_green",
"rct2.terrain_surface.sand_red", "rct2.terrain_surface.sand_brown",
};
// Additional surface styles added to OpenRCT2 as a feature if RCT1 linked
static constexpr std::string_view OpenRCT2HybridTerrainSurfaces[] = {
"rct1aa.terrain_surface.roof_red",
"rct1ll.terrain_surface.roof_grey",
"rct1ll.terrain_surface.rust",
"rct1ll.terrain_surface.wood",
};
static constexpr std::string_view DefaultTerrainEdges[] = {
"rct2.terrain_edge.rock",
"rct2.terrain_edge.wood_red",
"rct2.terrain_edge.wood_black",
"rct2.terrain_edge.ice",
};
// Additional surface edges added to OpenRCT2 as a feature if RCT1 was linked
static constexpr std::string_view OpenRCT2HybridTerrainEdges[] = {
"rct1.terrain_edge.brick", "rct1.terrain_edge.iron", "rct1aa.terrain_edge.grey",
"rct1aa.terrain_edge.yellow", "rct1aa.terrain_edge.red", "rct1ll.terrain_edge.purple",
"rct1ll.terrain_edge.green", "rct1ll.terrain_edge.stone_brown", "rct1ll.terrain_edge.stone_grey",
"rct1ll.terrain_edge.skyscraper_a", "rct1ll.terrain_edge.skyscraper_b",
};
} // namespace RCT2
std::vector<uint8_t> DecryptSea(const fs::path& path);

View File

@@ -47,6 +47,7 @@
#include "../object/ObjectManager.h"
#include "../object/ObjectRepository.h"
#include "../peep/RideUseSystem.h"
#include "../rct12/EntryList.h"
#include "../rct12/RCT12.h"
#include "../rct12/SawyerChunkReader.h"
#include "../rct12/SawyerEncoding.h"
@@ -94,6 +95,8 @@ namespace RCT2
ObjectEntryIndex _pathToSurfaceMap[16];
ObjectEntryIndex _pathToQueueSurfaceMap[16];
ObjectEntryIndex _pathToRailingMap[16];
RCT12::EntryList _terrainSurfaceEntries;
RCT12::EntryList _terrainEdgeEntries;
public:
S6Importer(IObjectRepository& objectRepository)
@@ -492,6 +495,15 @@ namespace RCT2
ClearRestrictedScenery();
}
void AddDefaultEntries()
{
// Add default surfaces
_terrainSurfaceEntries.AddRange(DefaultTerrainSurfaces);
// Add default edges
_terrainEdgeEntries.AddRange(DefaultTerrainEdges);
}
void ConvertScenarioStringsToUTF8()
{
// Scenario details
@@ -1192,8 +1204,10 @@ namespace RCT2
auto src2 = src->AsSurface();
dst2->SetSlope(src2->GetSlope());
dst2->SetSurfaceStyle(src2->GetSurfaceStyle());
dst2->SetEdgeStyle(src2->GetEdgeStyle());
dst2->SetGrassLength(src2->GetGrassLength());
dst2->SetOwnership(src2->GetOwnership());
dst2->SetParkFences(src2->GetParkFences());
@@ -1732,7 +1746,37 @@ namespace RCT2
}
}
SetDefaultRCT2TerrainObjects(objectList);
// Add default rct2 terrain surfaces and edges
AddDefaultEntries();
// Find if any rct1 terrain surfaces or edges have been used
const bool hasRCT1Terrain = std::any_of(
std::begin(_s6.tile_elements), std::end(_s6.tile_elements), [](RCT12TileElement& tile) {
auto* surface = tile.AsSurface();
if (surface == nullptr)
{
return false;
}
if (surface->GetSurfaceStyle() >= std::size(RCT2::DefaultTerrainSurfaces))
{
return true;
}
if (surface->GetEdgeStyle() >= std::size(RCT2::DefaultTerrainEdges))
{
return true;
}
return false;
});
// If an rct1 surface or edge then load all the Hybrid surfaces and edges
if (hasRCT1Terrain)
{
_terrainSurfaceEntries.AddRange(OpenRCT2HybridTerrainSurfaces);
_terrainEdgeEntries.AddRange(OpenRCT2HybridTerrainEdges);
}
AppendRequiredObjects(objectList, ObjectType::TerrainSurface, _terrainSurfaceEntries);
AppendRequiredObjects(objectList, ObjectType::TerrainEdge, _terrainEdgeEntries);
RCT12AddDefaultObjects(objectList);
return objectList;
}