1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-18 04:23:20 +01:00

Work on RCT1 path import

This commit is contained in:
Ted John
2021-04-12 19:41:34 +01:00
parent 0a8f810e5d
commit ef6d8a6e69
13 changed files with 693 additions and 691 deletions

View File

@@ -94,7 +94,7 @@ rct_window* window_install_track_open(const utf8* path)
log_error("Failed to load track (ride type null): %s", path);
return nullptr;
}
if (object_manager_load_object(&_trackDesign->vehicle_object) == nullptr)
if (object_manager_load_object(&_trackDesign->vehicle_object.Entry) == nullptr)
{
log_error("Failed to load track (vehicle load fail): %s", path);
return nullptr;
@@ -242,7 +242,7 @@ static void window_install_track_paint(rct_window* w, rct_drawpixelinfo* dpi)
{
auto ft = Formatter();
const auto* objectEntry = object_manager_load_object(&td6->vehicle_object);
const auto* objectEntry = object_manager_load_object(&td6->vehicle_object.Entry);
if (objectEntry != nullptr)
{
auto groupIndex = object_manager_get_loaded_object_entry_index(objectEntry);

View File

@@ -87,7 +87,7 @@ GameActions::Result::Ptr TrackDesignAction::Query() const
return MakeResult(GameActions::Status::InvalidParameters);
}
const rct_object_entry* rideEntryObject = &_td.vehicle_object;
const rct_object_entry* rideEntryObject = &_td.vehicle_object.Entry;
ObjectType entryType;
ObjectEntryIndex entryIndex;
@@ -150,7 +150,7 @@ GameActions::Result::Ptr TrackDesignAction::Execute() const
res->Position.z = _loc.z;
res->Expenditure = ExpenditureType::RideConstruction;
const rct_object_entry* rideEntryObject = &_td.vehicle_object;
const rct_object_entry* rideEntryObject = &_td.vehicle_object.Entry;
ObjectType entryType;
ObjectEntryIndex entryIndex;

View File

@@ -414,7 +414,15 @@ private:
bool AddItem(const ObjectRepositoryItem& item)
{
auto conflict = FindObject(&item.ObjectEntry);
const ObjectRepositoryItem* conflict{};
if (item.ObjectEntry.name[0] != '\0')
{
conflict = FindObject(&item.ObjectEntry);
}
if (conflict == nullptr)
{
conflict = FindObject(item.Identifier);
}
if (conflict == nullptr)
{
size_t index = _items.size();

View File

@@ -69,7 +69,7 @@ using namespace OpenRCT2;
class EntryList
{
private:
std::vector<const char*> _entries;
std::vector<std::string> _entries;
public:
size_t GetCount() const
@@ -77,20 +77,22 @@ public:
return _entries.size();
}
const std::vector<const char*>& GetEntries() const
const std::vector<std::string>& GetEntries() const
{
return _entries;
}
ObjectEntryIndex GetOrAddEntry(const char* entryName)
ObjectEntryIndex GetOrAddEntry(std::string_view identifier)
{
auto entryIndex = Collections::IndexOf(_entries, entryName, true);
if (entryIndex == SIZE_MAX)
for (size_t i = 0; i < _entries.size(); i++)
{
entryIndex = _entries.size();
_entries.push_back(entryName);
if (_entries[i] == identifier)
{
return static_cast<ObjectEntryIndex>(i);
}
}
return static_cast<ObjectEntryIndex>(entryIndex);
_entries.emplace_back(identifier);
return static_cast<ObjectEntryIndex>(_entries.size() - 1);
}
void AddRange(std::initializer_list<const char*> initializerList)
@@ -387,25 +389,16 @@ private:
{
// Add default scenery groups
_sceneryGroupEntries.AddRange({
"SCGTREES",
"SCGSHRUB",
"SCGGARDN",
"SCGFENCE",
"SCGWALLS",
"SCGPATHX",
"rct2.scgtrees",
"rct2.scgshrub",
"rct2.scggardn",
"rct2.scgfence",
"rct2.scgwalls",
"rct2.scgpathx",
});
// Add default footpaths
_pathEntries.AddRange({
"TARMAC ",
"TARMACG ",
"TARMACB ",
"PATHCRZY",
"PATHSPCE",
"PATHDIRT",
"PATHASH ",
"ROAD ",
});
_pathEntries.AddRange({ "rct1.path.tarmac", "rct1.path.dirt", "rct1.path.crazy", "rct1.path.tile.pink" });
}
void AddAvailableEntriesFromResearchList()
@@ -519,11 +512,11 @@ private:
if (sceneryTheme != 0 && _sceneryThemeTypeToEntryMap[sceneryTheme] == OBJECT_ENTRY_INDEX_NULL)
continue;
std::vector<const char*> objects = RCT1::GetSceneryObjects(sceneryTheme);
for (const char* objectName : objects)
auto objects = RCT1::GetSceneryObjects(sceneryTheme);
for (auto objectName : objects)
{
auto& objectRepository = OpenRCT2::GetContext()->GetObjectRepository();
auto foundObject = objectRepository.FindObjectLegacy(objectName);
auto foundObject = objectRepository.FindObject(objectName);
if (foundObject != nullptr)
{
ObjectType objectType = foundObject->ObjectEntry.GetType();
@@ -556,8 +549,7 @@ private:
void AddEntryForWater()
{
const char* entryName;
std::string_view entryName;
if (_gameVersion < FILE_VERSION_RCT1_LL)
{
entryName = RCT1::GetWaterObject(RCT1_WATER_CYAN);
@@ -566,7 +558,6 @@ private:
{
entryName = RCT1::GetWaterObject(_s4.water_colour);
}
_waterEntry.GetOrAddEntry(entryName);
}
@@ -575,8 +566,8 @@ private:
assert(rideType < std::size(_rideTypeToRideEntryMap));
if (_rideTypeToRideEntryMap[rideType] == OBJECT_ENTRY_INDEX_NULL)
{
const char* entryName = RCT1::GetRideTypeObject(rideType);
if (!String::Equals(entryName, " "))
auto entryName = RCT1::GetRideTypeObject(rideType);
if (!entryName.empty())
{
auto entryIndex = _rideEntries.GetOrAddEntry(entryName);
_rideTypeToRideEntryMap[rideType] = entryIndex;
@@ -589,8 +580,8 @@ private:
assert(vehicleType < std::size(_vehicleTypeToRideEntryMap));
if (_vehicleTypeToRideEntryMap[vehicleType] == OBJECT_ENTRY_INDEX_NULL)
{
const char* entryName = RCT1::GetVehicleObject(vehicleType);
if (!String::Equals(entryName, " "))
auto entryName = RCT1::GetVehicleObject(vehicleType);
if (!entryName.empty())
{
auto entryIndex = _rideEntries.GetOrAddEntry(entryName);
_vehicleTypeToRideEntryMap[vehicleType] = entryIndex;
@@ -606,7 +597,7 @@ private:
assert(smallSceneryType < std::size(_smallSceneryTypeToEntryMap));
if (_smallSceneryTypeToEntryMap[smallSceneryType] == OBJECT_ENTRY_INDEX_NULL)
{
const char* entryName = RCT1::GetSmallSceneryObject(smallSceneryType);
auto entryName = RCT1::GetSmallSceneryObject(smallSceneryType);
auto entryIndex = _smallSceneryEntries.GetOrAddEntry(entryName);
_smallSceneryTypeToEntryMap[smallSceneryType] = entryIndex;
@@ -618,7 +609,7 @@ private:
assert(largeSceneryType < std::size(_largeSceneryTypeToEntryMap));
if (_largeSceneryTypeToEntryMap[largeSceneryType] == OBJECT_ENTRY_INDEX_NULL)
{
const char* entryName = RCT1::GetLargeSceneryObject(largeSceneryType);
auto entryName = RCT1::GetLargeSceneryObject(largeSceneryType);
auto entryIndex = _largeSceneryEntries.GetOrAddEntry(entryName);
_largeSceneryTypeToEntryMap[largeSceneryType] = entryIndex;
@@ -630,7 +621,7 @@ private:
assert(wallType < std::size(_wallTypeToEntryMap));
if (_wallTypeToEntryMap[wallType] == OBJECT_ENTRY_INDEX_NULL)
{
const char* entryName = RCT1::GetWallObject(wallType);
auto entryName = RCT1::GetWallObject(wallType);
auto entryIndex = _wallEntries.GetOrAddEntry(entryName);
_wallTypeToEntryMap[wallType] = entryIndex;
@@ -642,10 +633,10 @@ private:
assert(pathType < std::size(_pathTypeToEntryMap));
if (_pathTypeToEntryMap[pathType] == OBJECT_ENTRY_INDEX_NULL)
{
const char* entryName = RCT1::GetPathObject(pathType);
if (!String::Equals(entryName, " "))
auto identifier = RCT1::GetPathObject(pathType);
if (!identifier.empty())
{
auto entryIndex = _pathEntries.GetOrAddEntry(entryName);
auto entryIndex = _pathEntries.GetOrAddEntry(identifier);
_pathTypeToEntryMap[pathType] = entryIndex;
}
}
@@ -661,7 +652,7 @@ private:
uint8_t normalisedPathAdditionType = RCT1::NormalisePathAddition(pathAdditionType);
if (_pathAdditionTypeToEntryMap[normalisedPathAdditionType] == OBJECT_ENTRY_INDEX_NULL)
{
const char* entryName = RCT1::GetPathAddtionObject(normalisedPathAdditionType);
auto entryName = RCT1::GetPathAddtionObject(normalisedPathAdditionType);
auto entryIndex = _pathAdditionEntries.GetOrAddEntry(entryName);
_pathAdditionTypeToEntryMap[normalisedPathAdditionType] = entryIndex;
@@ -680,7 +671,7 @@ private:
}
else
{
const char* entryName = RCT1::GetSceneryGroupObject(sceneryThemeType);
auto entryName = RCT1::GetSceneryGroupObject(sceneryThemeType);
if (_sceneryGroupEntries.GetCount() >= MAX_SCENERY_GROUP_OBJECTS)
{
Console::WriteLine("Warning: More than %d (max scenery groups) in RCT1 park.", MAX_SCENERY_GROUP_OBJECTS);
@@ -1509,14 +1500,13 @@ private:
AppendRequiredObjects(objectList, objectType, entryList.GetEntries());
}
void AppendRequiredObjects(ObjectList& objectList, ObjectType objectType, const std::vector<const char*>& objectNames)
void AppendRequiredObjects(ObjectList& objectList, ObjectType objectType, const std::vector<std::string>& objectNames)
{
for (const auto objectName : objectNames)
for (const auto& objectName : objectNames)
{
rct_object_entry entry{};
entry.flags = ((static_cast<uint8_t>(ObjectSourceGame::RCT2) << 4) & 0xF0) | (EnumValue(objectType) & 0x0F);
entry.SetName(objectName);
objectList.Add(ObjectEntryDescriptor(entry));
auto descriptor = ObjectEntryDescriptor(objectName);
descriptor.Type = objectType;
objectList.Add(descriptor);
}
}
@@ -1532,18 +1522,18 @@ private:
AppendRequiredObjects(result, ObjectType::SceneryGroup, _sceneryGroupEntries);
AppendRequiredObjects(
result, ObjectType::Banners,
std::vector<const char*>({
"BN1 ",
"BN2 ",
"BN3 ",
"BN4 ",
"BN5 ",
"BN6 ",
"BN7 ",
"BN8 ",
"BN9 ",
std::vector<std::string>({
"rct2.bn1",
"rct2.bn2",
"rct2.bn3",
"rct2.bn4",
"rct2.bn5",
"rct2.bn6",
"rct2.bn7",
"rct2.bn8",
"rct2.bn9",
}));
AppendRequiredObjects(result, ObjectType::ParkEntrance, std::vector<const char*>({ "PKENT1 " }));
AppendRequiredObjects(result, ObjectType::ParkEntrance, std::vector<std::string>({ "rct2.pkent1" }));
AppendRequiredObjects(result, ObjectType::Water, _waterEntry);
RCT12AddDefaultObjects(result);
return result;

View File

@@ -147,20 +147,17 @@ private:
}
// Convert RCT1 vehicle type to RCT2 vehicle type. Initialise with a string consisting of 8 spaces.
rct_object_entry vehicleObject = { 0x80, " " };
std::string_view vehicleObject;
if (td4Base.type == RIDE_TYPE_MAZE)
{
const char* vehObjName = RCT1::GetRideTypeObject(td4Base.type);
assert(vehObjName != nullptr);
std::memcpy(vehicleObject.name, vehObjName, std::min(String::SizeOf(vehObjName), static_cast<size_t>(8)));
vehicleObject = RCT1::GetRideTypeObject(td4Base.type);
}
else
{
const char* vehObjName = RCT1::GetVehicleObject(td4Base.vehicle_type);
assert(vehObjName != nullptr);
std::memcpy(vehicleObject.name, vehObjName, std::min(String::SizeOf(vehObjName), static_cast<size_t>(8)));
vehicleObject = RCT1::GetVehicleObject(td4Base.vehicle_type);
}
std::memcpy(&td->vehicle_object, &vehicleObject, sizeof(rct_object_entry));
assert(!vehicleObject.empty());
td->vehicle_object = ObjectEntryDescriptor(vehicleObject);
td->vehicle_type = td4Base.vehicle_type;
td->flags = td4Base.flags;

File diff suppressed because it is too large Load Diff

View File

@@ -33,15 +33,15 @@ namespace RCT1
uint8_t NormalisePathAddition(uint8_t pathAdditionType);
uint8_t GetVehicleSubEntryIndex(uint8_t vehicleSubEntry);
const char* GetRideTypeObject(uint8_t rideType);
const char* GetVehicleObject(uint8_t vehicleType);
const char* GetSmallSceneryObject(uint8_t smallSceneryType);
const char* GetLargeSceneryObject(uint8_t largeSceneryType);
const char* GetWallObject(uint8_t wallType);
const char* GetPathObject(uint8_t pathType);
const char* GetPathAddtionObject(uint8_t pathAdditionType);
const char* GetSceneryGroupObject(uint8_t sceneryGroupType);
const char* GetWaterObject(uint8_t waterType);
std::string_view GetRideTypeObject(uint8_t rideType);
std::string_view GetVehicleObject(uint8_t vehicleType);
std::string_view GetSmallSceneryObject(uint8_t smallSceneryType);
std::string_view GetLargeSceneryObject(uint8_t largeSceneryType);
std::string_view GetWallObject(uint8_t wallType);
std::string_view GetPathObject(uint8_t pathType);
std::string_view GetPathAddtionObject(uint8_t pathAdditionType);
std::string_view GetSceneryGroupObject(uint8_t sceneryGroupType);
std::string_view GetWaterObject(uint8_t waterType);
const std::vector<const char*> GetSceneryObjects(uint8_t sceneryType);
} // namespace RCT1

View File

@@ -1440,4 +1440,11 @@ void RCT12AddDefaultObjects(ObjectList& objectList)
objectList.SetObject(ObjectType::Music, static_cast<ObjectEntryIndex>(i), _musicStyles[i]);
}
}
// Path railings
objectList.SetObject(ObjectType::FootpathRailings, 0, "rct2.railings.wood");
objectList.SetObject(ObjectType::FootpathRailings, 1, "rct2.railings.concrete");
objectList.SetObject(ObjectType::FootpathRailings, 2, "rct2.railings.space");
objectList.SetObject(ObjectType::FootpathRailings, 3, "rct2.railings.black");
objectList.SetObject(ObjectType::FootpathRailings, 4, "rct2.railings.brown");
}

View File

@@ -80,7 +80,7 @@ bool T6Exporter::SaveTrack(OpenRCT2::IStream* stream)
tempStream.WriteArray(_trackDesign->track_rail_colour, RCT12_NUM_COLOUR_SCHEMES);
tempStream.WriteArray(_trackDesign->track_support_colour, RCT12_NUM_COLOUR_SCHEMES);
tempStream.WriteValue<uint32_t>(_trackDesign->flags2);
tempStream.Write(&_trackDesign->vehicle_object, sizeof(rct_object_entry));
tempStream.Write(&_trackDesign->vehicle_object.Entry, sizeof(rct_object_entry));
tempStream.WriteValue<uint8_t>(_trackDesign->space_required_x);
tempStream.WriteValue<uint8_t>(_trackDesign->space_required_y);
tempStream.WriteArray(_trackDesign->vehicle_additional_colour, RCT2_MAX_CARS_PER_TRAIN);

View File

@@ -128,7 +128,7 @@ public:
td->track_support_colour[i] = td6.track_support_colour[i];
}
td->flags2 = td6.flags2;
td->vehicle_object = td6.vehicle_object;
td->vehicle_object = ObjectEntryDescriptor(td6.vehicle_object);
td->space_required_x = td6.space_required_x;
td->space_required_y = td6.space_required_y;
td->lift_hill_speed = td6.lift_hill_speed_num_circuits & 0b00011111;
@@ -224,7 +224,7 @@ public:
if (RCT2RideTypeNeedsConversion(td->type))
{
std::scoped_lock<std::mutex> lock(_objectLookupMutex);
auto rawObject = object_repository_load_object(&td->vehicle_object);
auto rawObject = object_repository_load_object(&td->vehicle_object.Entry);
if (rawObject != nullptr)
{
const auto* rideEntry = static_cast<const rct_ride_entry*>(

View File

@@ -94,7 +94,7 @@ rct_string_id TrackDesign::CreateTrackDesign(const Ride& ride)
// Note we are only copying rct_object_entry in size and
// not the extended as we don't need the chunk size.
std::memcpy(&vehicle_object, object->GetObjectEntry(), sizeof(rct_object_entry));
vehicle_object = ObjectEntryDescriptor(*object->GetObjectEntry());
ride_mode = ride.mode;
colour_scheme = ride.colour_scheme_type & 3;
@@ -590,7 +590,7 @@ void TrackDesign::Serialise(DataSerialiser& stream)
stream << DS_TAG(track_rail_colour);
stream << DS_TAG(track_support_colour);
stream << DS_TAG(flags2);
stream << DS_TAG(vehicle_object);
stream << DS_TAG(vehicle_object.Entry);
stream << DS_TAG(space_required_x);
stream << DS_TAG(space_required_y);
stream << DS_TAG(vehicle_additional_colour);
@@ -630,7 +630,7 @@ static void track_design_load_scenery_objects(TrackDesign* td6)
object_manager_unload_all_objects();
// Load ride object
rct_object_entry* rideEntry = &td6->vehicle_object;
rct_object_entry* rideEntry = &td6->vehicle_object.Entry;
object_manager_load_object(rideEntry);
// Load scenery objects
@@ -1870,7 +1870,7 @@ static bool track_design_place_preview(TrackDesign* td6, money32* cost, Ride** o
ObjectType entry_type;
ObjectEntryIndex entry_index;
if (!find_object_in_entry_group(&td6->vehicle_object, &entry_type, &entry_index))
if (!find_object_in_entry_group(&td6->vehicle_object.Entry, &entry_type, &entry_index))
{
entry_index = OBJECT_ENTRY_INDEX_NULL;
}
@@ -1944,7 +1944,7 @@ static bool track_design_place_preview(TrackDesign* td6, money32* cost, Ride** o
if (resultCost != MONEY32_UNDEFINED)
{
if (!find_object_in_entry_group(&td6->vehicle_object, &entry_type, &entry_index))
if (!find_object_in_entry_group(&td6->vehicle_object.Entry, &entry_type, &entry_index))
{
*flags |= TRACK_DESIGN_FLAG_VEHICLE_UNAVAILABLE;
}

View File

@@ -115,7 +115,7 @@ struct TrackDesign
uint8_t track_rail_colour[RCT12_NUM_COLOUR_SCHEMES];
uint8_t track_support_colour[RCT12_NUM_COLOUR_SCHEMES];
uint32_t flags2;
rct_object_entry vehicle_object;
ObjectEntryDescriptor vehicle_object;
uint8_t space_required_x;
uint8_t space_required_y;
uint8_t vehicle_additional_colour[RCT2_MAX_CARS_PER_TRAIN];

View File

@@ -82,7 +82,7 @@ public:
item.Name = GetNameFromTrackPath(path);
item.Path = path;
item.RideType = td6->type;
item.ObjectEntry = std::string(td6->vehicle_object.name, 8);
item.ObjectEntry = std::string(td6->vehicle_object.Entry.name, 8);
item.Flags = 0;
if (IsTrackReadOnly(path))
{