1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-18 12:33:17 +01:00

Improve track import of footpath surface

This commit is contained in:
Ted John
2021-04-22 21:55:04 +01:00
parent 9b91b305b4
commit 5cba4fe1a7
4 changed files with 134 additions and 102 deletions

View File

@@ -161,3 +161,26 @@ RCT12TrackType OpenRCT2TrackTypeToRCT2(track_type_t origTrackType)
// This function is safe to run this way round.
return OpenRCT2FlatTrackTypeToRCT12(origTrackType);
}
std::tuple<std::string_view, std::string_view, std::string_view> GetFootpathSurfaceId(const ObjectEntryDescriptor& desc)
{
auto name = desc.Entry.GetName();
if (name == "PATHASH ")
return { "rct2.pathsurface.ash", "rct2.pathsurface.queue.yellow", "rct2.railings.bambooblack" };
else if (name == "PATHCRZY")
return { "rct2.pathsurface.crazy", "rct2.pathsurface.queue.yellow", "rct2.railings.concrete" };
else if (name == "PATHDIRT")
return { "rct2.pathsurface.dirt", "rct2.pathsurface.queue.yellow", "rct2.railings.bamboobrown" };
else if (name == "PATHSPCE")
return { "rct2.pathsurface.space", "rct2.pathsurface.queue.red", "rct2.railings.space" };
else if (name == "ROAD ")
return { "rct2.pathsurface.road", "rct2.pathsurface.queue.blue", "rct2.railings.wood" };
else if (name == "TARMACB ")
return { "rct2.pathsurface.tarmac.brown", "rct2.pathsurface.queue.yellow", "rct2.railings.concrete" };
else if (name == "TARMACG ")
return { "rct2.pathsurface.tarmac.green", "rct2.pathsurface.queue.green", "rct2.railings.concretegreen" };
else if (name == "TARMAC ")
return { "rct2.pathsurface.tarmac", "rct2.pathsurface.queue.blue", "rct2.railings.wood" };
else
return {};
}

View File

@@ -16,6 +16,7 @@
#include "../ride/RideRatings.h"
#include "../ride/VehicleColour.h"
#include <tuple>
#include <vector>
constexpr const uint8_t RCT2_MAX_STAFF = 200;
@@ -802,3 +803,5 @@ RCT12TrackType OpenRCT2TrackTypeToRCT2(track_type_t origTrackType);
* Handles single and multi-byte strings.
*/
size_t GetRCT2StringBufferLen(const char* buffer, size_t maxBufferLen);
std::tuple<std::string_view, std::string_view, std::string_view> GetFootpathSurfaceId(const ObjectEntryDescriptor& desc);

View File

@@ -1649,29 +1649,6 @@ public:
RCT12AddDefaultObjects(objectList);
return objectList;
}
std::tuple<std::string_view, std::string_view, std::string_view> GetFootpathSurfaceId(const ObjectEntryDescriptor& desc)
{
auto name = desc.Entry.GetName();
if (name == "PATHASH ")
return { "rct2.pathsurface.ash", "rct2.pathsurface.queue.yellow", "rct2.railings.bambooblack" };
else if (name == "PATHCRZY")
return { "rct2.pathsurface.crazy", "rct2.pathsurface.queue.yellow", "rct2.railings.concrete" };
else if (name == "PATHDIRT")
return { "rct2.pathsurface.dirt", "rct2.pathsurface.queue.yellow", "rct2.railings.bamboobrown" };
else if (name == "PATHSPCE")
return { "rct2.pathsurface.space", "rct2.pathsurface.queue.red", "rct2.railings.space" };
else if (name == "ROAD ")
return { "rct2.pathsurface.road", "rct2.pathsurface.queue.blue", "rct2.railings.wood" };
else if (name == "TARMACB ")
return { "rct2.pathsurface.tarmac.brown", "rct2.pathsurface.queue.yellow", "rct2.railings.concrete" };
else if (name == "TARMACG ")
return { "rct2.pathsurface.tarmac.green", "rct2.pathsurface.queue.green", "rct2.railings.concretegreen" };
else if (name == "TARMAC ")
return { "rct2.pathsurface.tarmac", "rct2.pathsurface.queue.blue", "rct2.railings.wood" };
else
return {};
}
};
template<> void S6Importer::ImportEntity<Vehicle>(const RCT12SpriteBase& baseSrc)

View File

@@ -654,6 +654,106 @@ static void track_design_load_scenery_objects(TrackDesign* td6)
}
}
struct TrackSceneryEntry
{
ObjectType Type = ObjectType::None;
ObjectEntryIndex Index = OBJECT_ENTRY_INDEX_NULL;
ObjectEntryIndex SecondaryIndex = OBJECT_ENTRY_INDEX_NULL; // For footpath railing
};
static ObjectEntryIndex TrackDesignGetDefaultSurfaceIndex(bool isQueue)
{
for (ObjectEntryIndex i = 0; i < MAX_FOOTPATH_SURFACE_OBJECTS; i++)
{
auto footpathSurfaceObj = get_path_surface_entry(i);
if (footpathSurfaceObj != nullptr)
{
if (footpathSurfaceObj->Flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR)
{
continue;
}
if (isQueue != ((footpathSurfaceObj->Flags & FOOTPATH_ENTRY_FLAG_IS_QUEUE) != 0))
{
continue;
}
return i;
}
}
return OBJECT_ENTRY_INDEX_NULL;
}
static ObjectEntryIndex TrackDesignGetDefaultRailingIndex()
{
for (ObjectEntryIndex i = 0; i < MAX_FOOTPATH_RAILINGS_OBJECTS; i++)
{
auto footpathRailingsObj = get_path_railings_entry(i);
if (footpathRailingsObj != nullptr)
{
return i;
}
}
return OBJECT_ENTRY_INDEX_NULL;
}
static std::optional<TrackSceneryEntry> TrackDesignPlaceSceneryElementGetEntry(const TrackDesignSceneryElement& scenery)
{
TrackSceneryEntry result;
auto& objectMgr = OpenRCT2::GetContext()->GetObjectManager();
if (scenery.scenery_object.GetType() == ObjectType::Paths)
{
auto [normal, queue, railings] = GetFootpathSurfaceId(scenery.scenery_object);
if (normal.empty() && queue.empty() && railings.empty())
{
// Check if legacy path object is loaded
auto obj = objectMgr.GetLoadedObject(scenery.scenery_object);
if (obj != nullptr)
{
result.Type = obj->GetObjectType();
result.Index = objectMgr.GetLoadedObjectEntryIndex(obj);
}
else
{
result.Type = ObjectType::FootpathSurface;
}
}
else
{
result.Type = ObjectType::FootpathSurface;
result.Index = objectMgr.GetLoadedObjectEntryIndex(ObjectEntryDescriptor(scenery.IsQueue() ? queue : normal));
result.SecondaryIndex = objectMgr.GetLoadedObjectEntryIndex(ObjectEntryDescriptor(railings));
}
if (result.Index == OBJECT_ENTRY_INDEX_NULL)
result.Index = TrackDesignGetDefaultSurfaceIndex(false);
if (result.SecondaryIndex == OBJECT_ENTRY_INDEX_NULL)
result.SecondaryIndex = TrackDesignGetDefaultRailingIndex();
if (result.Index == OBJECT_ENTRY_INDEX_NULL || result.SecondaryIndex == OBJECT_ENTRY_INDEX_NULL)
{
_trackDesignPlaceStateSceneryUnavailable = true;
return {};
}
}
else
{
auto obj = objectMgr.GetLoadedObject(scenery.scenery_object);
if (obj != nullptr)
{
result.Type = obj->GetObjectType();
result.Index = objectMgr.GetLoadedObjectEntryIndex(obj);
}
else
{
_trackDesignPlaceStateSceneryUnavailable = true;
return {};
}
}
return result;
}
/**
*
* rct2: 0x006D247A
@@ -663,10 +763,11 @@ static void track_design_mirror_scenery(TrackDesign* td6)
auto& objectMgr = OpenRCT2::GetContext()->GetObjectManager();
for (auto& scenery : td6->scenery_elements)
{
auto obj = objectMgr.GetLoadedObject(scenery.scenery_object);
if (obj == nullptr)
auto entryInfo = TrackDesignPlaceSceneryElementGetEntry(scenery);
if (!entryInfo)
continue;
auto obj = objectMgr.GetLoadedObject(entryInfo->Type, entryInfo->Index);
switch (obj->GetObjectType())
{
case ObjectType::LargeScenery:
@@ -746,6 +847,7 @@ static void track_design_mirror_scenery(TrackDesign* td6)
break;
}
case ObjectType::Paths:
case ObjectType::FootpathSurface:
{
scenery.y = -scenery.y;
@@ -856,83 +958,6 @@ static void track_design_update_max_min_coordinates(const CoordsXYZ& coords)
std::max(_trackPreviewMax.z, coords.z) };
}
struct TrackSceneryEntry
{
ObjectType Type = ObjectType::None;
ObjectEntryIndex Index = OBJECT_ENTRY_INDEX_NULL;
ObjectEntryIndex SecondaryIndex = OBJECT_ENTRY_INDEX_NULL; // For footpath railing
};
static std::optional<TrackSceneryEntry> TrackDesignPlaceSceneryElementGetEntry(const TrackDesignSceneryElement& scenery)
{
TrackSceneryEntry result;
auto& objectMgr = OpenRCT2::GetContext()->GetObjectManager();
auto obj = objectMgr.GetLoadedObject(scenery.scenery_object);
if (obj != nullptr)
{
result.Type = obj->GetObjectType();
result.Index = objectMgr.GetLoadedObjectEntryIndex(obj);
}
else
{
// Find a fallback footpath
result.Type = scenery.scenery_object.GetType();
if (result.Type != ObjectType::Paths)
{
// Unsupported object type
_trackDesignPlaceStateSceneryUnavailable = true;
return {};
}
if (gScreenFlags & SCREEN_FLAGS_TRACK_DESIGNER)
{
// Don't bother with fallback with track designer
_trackDesignPlaceStateSceneryUnavailable = true;
return {};
}
// Find a default footpath surface to use
auto isQueue = scenery.IsQueue();
for (ObjectEntryIndex i = 0; i < MAX_FOOTPATH_SURFACE_OBJECTS; i++)
{
auto footpathSurfaceObj = get_path_surface_entry(i);
if (footpathSurfaceObj != nullptr)
{
if (footpathSurfaceObj->Flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR)
{
continue;
}
if (isQueue != ((footpathSurfaceObj->Flags & FOOTPATH_ENTRY_FLAG_IS_QUEUE) != 0))
{
continue;
}
result.Index = i;
break;
}
}
// Find a default railing to use
for (ObjectEntryIndex i = 0; i < MAX_FOOTPATH_RAILINGS_OBJECTS; i++)
{
auto footpathRailingsObj = get_path_railings_entry(i);
if (footpathRailingsObj != nullptr)
{
result.SecondaryIndex = i;
break;
}
}
if (result.Index == OBJECT_ENTRY_INDEX_NULL || result.SecondaryIndex == OBJECT_ENTRY_INDEX_NULL)
{
_trackDesignPlaceStateSceneryUnavailable = true;
return {};
}
}
return result;
}
static bool TrackDesignPlaceSceneryElementRemoveGhost(
CoordsXY mapCoord, const TrackDesignSceneryElement& scenery, uint8_t rotation, int32_t originZ)
{
@@ -979,6 +1004,7 @@ static bool TrackDesignPlaceSceneryElementRemoveGhost(
ga = std::make_unique<WallRemoveAction>(CoordsXYZD{ mapCoord.x, mapCoord.y, z, sceneryRotation });
break;
case ObjectType::Paths:
case ObjectType::FootpathSurface:
ga = std::make_unique<FootpathRemoveAction>(CoordsXYZ{ mapCoord.x, mapCoord.y, z });
break;
default:
@@ -1175,6 +1201,7 @@ static bool TrackDesignPlaceSceneryElement(
break;
}
case ObjectType::Paths:
case ObjectType::FootpathSurface:
if (_trackDesignPlaceOperation == PTD_OPERATION_GET_PLACE_Z)
{
return true;
@@ -1215,6 +1242,8 @@ static bool TrackDesignPlaceSceneryElement(
PathConstructFlags constructFlags = 0;
if (isQueue)
constructFlags |= PathConstructFlag::IsQueue;
if (entryInfo->Type == ObjectType::Paths)
constructFlags |= PathConstructFlag::IsPathObject;
auto footpathPlaceAction = FootpathPlaceFromTrackAction(
{ mapCoord.x, mapCoord.y, z * COORDS_Z_STEP }, slope, entryInfo->Index, entryInfo->SecondaryIndex,
edges, constructFlags);