Rework path surface and railings descriptor handling

This commit is contained in:
Gymnasiast 2021-09-05 18:44:43 +02:00
parent 2282f24404
commit 4cc717ccdb
No known key found for this signature in database
GPG Key ID: DBFFF47AB2CA3EDD
27 changed files with 250 additions and 237 deletions

View File

@ -18,6 +18,7 @@
#include <openrct2/actions/FootpathPlaceAction.h>
#include <openrct2/audio/audio.h>
#include <openrct2/localisation/Localisation.h>
#include <openrct2/object/FootpathObject.h>
#include <openrct2/object/ObjectLimits.h>
#include <openrct2/platform/platform.h>
#include <openrct2/sprites.h>
@ -187,14 +188,14 @@ static bool footpath_select_default();
rct_window* window_footpath_open()
{
// If a restricted path was selected when the game is no longer in Sandbox mode, reset it
PathSurfaceDescriptor* pathEntry = get_path_surface_entry(gFootpathSelectedId);
if (pathEntry != nullptr && (pathEntry->Flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) && !gCheatsSandboxMode)
const auto* legacyPathEntry = GetLegacyFootpathEntry(gFootpathSelectedId);
if (legacyPathEntry != nullptr && legacyPathEntry->GetPathSurfaceDescriptor().IsEditorOnly() && !gCheatsSandboxMode)
{
pathEntry = nullptr;
legacyPathEntry = nullptr;
}
// Select the default path if we don't have one
if (pathEntry == nullptr)
if (legacyPathEntry == nullptr)
{
if (!footpath_select_default())
{
@ -369,12 +370,12 @@ static void window_footpath_dropdown(rct_window* w, rct_widgetindex widgetIndex,
int32_t i = 0, j = 0;
for (; i < MAX_PATH_OBJECTS; i++)
{
PathSurfaceDescriptor* pathType = get_path_surface_entry(i);
if (pathType == nullptr)
{
const auto* legacyPathEntry = GetLegacyFootpathEntry(i);
if (legacyPathEntry == nullptr)
continue;
}
if ((pathType->Flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) && !showEditorPaths)
const PathSurfaceDescriptor& surfaceDescriptor = legacyPathEntry->GetPathSurfaceDescriptor();
if (surfaceDescriptor.IsEditorOnly() && !showEditorPaths)
{
continue;
}
@ -574,12 +575,11 @@ static void window_footpath_invalidate(rct_window* w)
// Set footpath and queue type button images
auto pathImage = static_cast<uint32_t>(SPR_NONE);
auto queueImage = static_cast<uint32_t>(SPR_NONE);
auto pathEntry = get_path_surface_entry(gFootpathSelectedId);
if (pathEntry != nullptr)
const auto* legacyPathEntry = GetLegacyFootpathEntry(gFootpathSelectedId);
if (legacyPathEntry != nullptr)
{
pathImage = pathEntry->PreviewImage;
// Editor-only paths might lack a queue image
queueImage = (pathEntry->Flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) ? pathImage : pathImage + 1;
pathImage = legacyPathEntry->GetPathSurfaceDescriptor().PreviewImage;
queueImage = legacyPathEntry->GetQueueSurfaceDescriptor().PreviewImage;
}
window_footpath_widgets[WIDX_FOOTPATH_TYPE].image = pathImage;
window_footpath_widgets[WIDX_QUEUELINE_TYPE].image = queueImage;
@ -609,9 +609,14 @@ static void window_footpath_paint(rct_window* w, rct_drawpixelinfo* dpi)
}
int32_t image = ConstructionPreviewImages[slope][direction];
int32_t selectedPath = gFootpathSelectedId + (MAX_PATH_OBJECTS * _footpathSelectedType);
PathSurfaceDescriptor* pathType = get_path_surface_entry(selectedPath);
image += pathType->Image;
const auto* legacyPathEntry = GetLegacyFootpathEntry(gFootpathSelectedId);
if (legacyPathEntry != nullptr)
{
if (_footpathSelectedType == SELECTED_PATH_TYPE_NORMAL)
image += legacyPathEntry->GetPathSurfaceDescriptor().Image;
else
image += legacyPathEntry->GetQueueSurfaceDescriptor().Image;
}
// Draw construction image
screenCoords = w->windowPos
@ -646,32 +651,28 @@ static void window_footpath_paint(rct_window* w, rct_drawpixelinfo* dpi)
*/
static void window_footpath_show_footpath_types_dialog(rct_window* w, rct_widget* widget, bool showQueues)
{
int32_t i, image;
PathSurfaceDescriptor* pathType;
uint32_t numPathTypes = 0;
// If the game is in sandbox mode, also show paths that are normally restricted to the scenario editor
bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode);
for (i = 0; i < MAX_PATH_OBJECTS; i++)
for (int32_t i = 0; i < MAX_PATH_OBJECTS; i++)
{
pathType = get_path_surface_entry(i);
if (pathType == nullptr)
{
continue;
}
if ((pathType->Flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) && !showEditorPaths)
const auto* legacyPathEntry = GetLegacyFootpathEntry(i);
if (legacyPathEntry == nullptr)
{
continue;
}
image = pathType->PreviewImage;
// Editor-only paths usually lack queue images. In this case, use the main path image
if (showQueues && !(pathType->Flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR))
const auto& surfaceDescriptor = (showQueues) ? legacyPathEntry->GetQueueSurfaceDescriptor()
: legacyPathEntry->GetPathSurfaceDescriptor();
if (surfaceDescriptor.IsEditorOnly() && !showEditorPaths)
{
image++;
continue;
}
const auto image = surfaceDescriptor.PreviewImage;
gDropdownItemsFormat[numPathTypes] = STR_NONE;
gDropdownItemsArgs[numPathTypes] = image;
numPathTypes++;
@ -1227,16 +1228,17 @@ static bool footpath_select_default()
int32_t footpathId = -1;
for (int32_t i = 0; i < object_entry_group_counts[EnumValue(ObjectType::Paths)]; i++)
{
PathSurfaceDescriptor* pathEntry = get_path_surface_entry(i);
if (pathEntry != nullptr)
{
footpathId = i;
const auto* footpathObject = GetLegacyFootpathEntry(i);
if (footpathObject == nullptr)
continue;
// Prioritise non-restricted path
if (!(pathEntry->Flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR))
{
break;
}
footpathId = i;
const PathSurfaceDescriptor& surfaceDescriptor = footpathObject->GetPathSurfaceDescriptor();
// Prioritise non-restricted path
if (!surfaceDescriptor.IsEditorOnly())
{
break;
}
}
if (footpathId == -1)

View File

@ -1886,7 +1886,7 @@ static void window_tile_inspector_paint(rct_window* w, rct_drawpixelinfo* dpi)
// Details
// Path name
auto ft = Formatter();
ft.Add<rct_string_id>(tileElement->AsPath()->GetSurfaceEntry()->Name);
ft.Add<rct_string_id>(tileElement->AsPath()->GetSurfaceDescriptor()->Name);
DrawTextBasic(dpi, screenCoords, STR_TILE_INSPECTOR_PATH_NAME, ft, { COLOUR_WHITE });
// Path addition

View File

@ -140,7 +140,7 @@ void setup_in_use_selection_flags()
case TILE_ELEMENT_TYPE_TRACK:
break;
case TILE_ELEMENT_TYPE_PATH:
type = iter.element->AsPath()->GetSurfaceEntryIndex();
type = iter.element->AsPath()->GetLegacyPathEntryIndex();
assert(type < object_entry_group_counts[EnumValue(ObjectType::Paths)]);
Editor::SetSelectedObject(ObjectType::Paths, type, OBJECT_SELECTION_FLAG_SELECTED);
@ -164,7 +164,7 @@ void setup_in_use_selection_flags()
Editor::SetSelectedObject(ObjectType::ParkEntrance, 0, OBJECT_SELECTION_FLAG_SELECTED);
type = iter.element->AsEntrance()->GetPathType();
type = iter.element->AsEntrance()->GetLegacyPathEntryIndex();
assert(type < object_entry_group_counts[EnumValue(ObjectType::Paths)]);
Editor::SetSelectedObject(ObjectType::Paths, type, OBJECT_SELECTION_FLAG_SELECTED);
break;

View File

@ -153,7 +153,7 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementUpdateQuery(PathElement* pa
{
const int32_t newFootpathType = (_type & (FOOTPATH_PROPERTIES_TYPE_MASK >> 4));
const bool newPathIsQueue = ((_type >> 7) == 1);
if (pathElement->GetSurfaceEntryIndex() != newFootpathType || pathElement->IsQueue() != newPathIsQueue)
if (pathElement->GetLegacyPathEntryIndex() != newFootpathType || pathElement->IsQueue() != newPathIsQueue)
{
res->Cost += MONEY(6, 00);
}
@ -169,7 +169,7 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementUpdateExecute(PathElement*
{
const int32_t newFootpathType = (_type & (FOOTPATH_PROPERTIES_TYPE_MASK >> 4));
const bool newPathIsQueue = ((_type >> 7) == 1);
if (pathElement->GetSurfaceEntryIndex() != newFootpathType || pathElement->IsQueue() != newPathIsQueue)
if (pathElement->GetLegacyPathEntryIndex() != newFootpathType || pathElement->IsQueue() != newPathIsQueue)
{
res->Cost += MONEY(6, 00);
}
@ -181,7 +181,7 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementUpdateExecute(PathElement*
footpath_remove_edges_at(_loc, reinterpret_cast<TileElement*>(pathElement));
}
pathElement->SetSurfaceEntryIndex(_type & ~FOOTPATH_ELEMENT_INSERT_QUEUE);
pathElement->SetLegacyPathEntryIndex(_type & ~FOOTPATH_ELEMENT_INSERT_QUEUE);
bool isQueue = _type & FOOTPATH_ELEMENT_INSERT_QUEUE;
pathElement->SetIsQueue(isQueue);
@ -238,7 +238,7 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementInsertQuery(GameActions::Re
{
entrancePath = true;
// Make the price the same as replacing a path
if (entranceElement->GetPathType() == (_type & 0xF))
if (entranceElement->GetLegacyPathEntryIndex() == (_type & 0xF))
entranceIsSamePath = true;
else
res->Cost -= MONEY(6, 00);
@ -304,7 +304,7 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementInsertExecute(GameActions::
{
entrancePath = true;
// Make the price the same as replacing a path
if (entranceElement->GetPathType() == (_type & 0xF))
if (entranceElement->GetLegacyPathEntryIndex() == (_type & 0xF))
entranceIsSamePath = true;
else
res->Cost -= MONEY(6, 00);
@ -339,7 +339,7 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementInsertExecute(GameActions::
if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && !entranceIsSamePath)
{
// Set the path type but make sure it's not a queue as that will not show up
entranceElement->SetPathType(_type & 0x7F);
entranceElement->SetLegacyPathEntryIndex(_type & 0x7F);
map_invalidate_tile_full(_loc);
}
}
@ -349,7 +349,7 @@ GameActions::Result::Ptr FootpathPlaceAction::ElementInsertExecute(GameActions::
Guard::Assert(pathElement != nullptr);
pathElement->SetClearanceZ(zHigh);
pathElement->SetSurfaceEntryIndex(_type & ~FOOTPATH_ELEMENT_INSERT_QUEUE);
pathElement->SetLegacyPathEntryIndex(_type & ~FOOTPATH_ELEMENT_INSERT_QUEUE);
pathElement->SetSlopeDirection(_slope & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK);
pathElement->SetSloped(_slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED);
pathElement->SetIsQueue(_type & FOOTPATH_ELEMENT_INSERT_QUEUE);

View File

@ -122,7 +122,7 @@ GameActions::Result::Ptr FootpathPlaceFromTrackAction::ElementInsertQuery(GameAc
{
entrancePath = true;
// Make the price the same as replacing a path
if (entranceElement->GetPathType() == (_type & 0xF))
if (entranceElement->GetLegacyPathEntryIndex() == (_type & 0xF))
entranceIsSamePath = true;
else
res->Cost -= MONEY(6, 00);
@ -189,7 +189,7 @@ GameActions::Result::Ptr FootpathPlaceFromTrackAction::ElementInsertExecute(Game
{
entrancePath = true;
// Make the price the same as replacing a path
if (entranceElement->GetPathType() == (_type & 0xF))
if (entranceElement->GetLegacyPathEntryIndex() == (_type & 0xF))
entranceIsSamePath = true;
else
res->Cost -= MONEY(6, 00);
@ -223,7 +223,7 @@ GameActions::Result::Ptr FootpathPlaceFromTrackAction::ElementInsertExecute(Game
if (!(GetFlags() & GAME_COMMAND_FLAG_GHOST) && !entranceIsSamePath)
{
// Set the path type but make sure it's not a queue as that will not show up
entranceElement->SetPathType(_type & 0x7F);
entranceElement->SetLegacyPathEntryIndex(_type & 0x7F);
map_invalidate_tile_full(_loc);
}
}
@ -233,7 +233,7 @@ GameActions::Result::Ptr FootpathPlaceFromTrackAction::ElementInsertExecute(Game
Guard::Assert(pathElement != nullptr);
pathElement->SetClearanceZ(zHigh);
pathElement->SetSurfaceEntryIndex(_type & ~FOOTPATH_ELEMENT_INSERT_QUEUE);
pathElement->SetLegacyPathEntryIndex(_type & ~FOOTPATH_ELEMENT_INSERT_QUEUE);
pathElement->SetSlopeDirection(_slope & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK);
pathElement->SetSloped(_slope & FOOTPATH_PROPERTIES_FLAG_IS_SLOPED);
pathElement->SetIsQueue(_type & FOOTPATH_ELEMENT_INSERT_QUEUE);

View File

@ -146,7 +146,7 @@ GameActions::Result::Ptr PlaceParkEntranceAction::Execute() const
entranceElement->SetDirection(_loc.direction);
entranceElement->SetSequenceIndex(index);
entranceElement->SetEntranceType(ENTRANCE_TYPE_PARK_ENTRANCE);
entranceElement->SetPathType(_pathType);
entranceElement->SetLegacyPathEntryIndex(_pathType);
if (!entranceElement->IsGhost())
{

View File

@ -40,23 +40,23 @@ void FootpathObject::Load()
_legacyType.image = gfx_object_allocate_images(GetImageTable().GetImages(), GetImageTable().GetCount());
_legacyType.bridge_image = _legacyType.image + 109;
_pathSurfaceEntry.Name = _legacyType.string_idx;
_pathSurfaceEntry.Image = _legacyType.image;
_pathSurfaceEntry.PreviewImage = _legacyType.GetPreviewImage();
_pathSurfaceEntry.Flags = _legacyType.flags;
_pathSurfaceDescriptor.Name = _legacyType.string_idx;
_pathSurfaceDescriptor.Image = _legacyType.image;
_pathSurfaceDescriptor.PreviewImage = _legacyType.GetPreviewImage();
_pathSurfaceDescriptor.Flags = _legacyType.flags;
_queueEntry.Name = _legacyType.string_idx;
_queueEntry.Image = _legacyType.GetQueueImage();
_queueEntry.PreviewImage = _legacyType.GetQueuePreviewImage();
_queueEntry.Flags = _legacyType.flags | FOOTPATH_ENTRY_FLAG_IS_QUEUE;
_queueSurfaceDescriptor.Name = _legacyType.string_idx;
_queueSurfaceDescriptor.Image = _legacyType.GetQueueImage();
_queueSurfaceDescriptor.PreviewImage = _legacyType.GetQueuePreviewImage();
_queueSurfaceDescriptor.Flags = _legacyType.flags | FOOTPATH_ENTRY_FLAG_IS_QUEUE;
_pathRailingsEntry.Name = _legacyType.string_idx;
_pathRailingsEntry.BridgeImage = _legacyType.bridge_image;
_pathRailingsEntry.PreviewImage = _legacyType.GetPreviewImage();
_pathRailingsEntry.Flags = _legacyType.flags;
_pathRailingsEntry.ScrollingMode = _legacyType.scrolling_mode;
_pathRailingsEntry.SupportType = _legacyType.support_type;
_pathRailingsEntry.RailingsImage = _legacyType.GetRailingsImage();
_pathRailingsDescriptor.Name = _legacyType.string_idx;
_pathRailingsDescriptor.BridgeImage = _legacyType.bridge_image;
_pathRailingsDescriptor.PreviewImage = _legacyType.GetPreviewImage();
_pathRailingsDescriptor.Flags = _legacyType.flags;
_pathRailingsDescriptor.ScrollingMode = _legacyType.scrolling_mode;
_pathRailingsDescriptor.SupportType = _legacyType.support_type;
_pathRailingsDescriptor.RailingsImage = _legacyType.GetRailingsImage();
}
void FootpathObject::Unload()
@ -71,8 +71,8 @@ void FootpathObject::Unload()
void FootpathObject::DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int32_t height) const
{
auto screenCoords = ScreenCoordsXY{ width / 2, height / 2 };
gfx_draw_sprite(dpi, _pathSurfaceEntry.PreviewImage, screenCoords - ScreenCoordsXY{ 49, 17 }, 0);
gfx_draw_sprite(dpi, _queueEntry.PreviewImage, screenCoords + ScreenCoordsXY{ 4, -17 }, 0);
gfx_draw_sprite(dpi, _pathSurfaceDescriptor.PreviewImage, screenCoords - ScreenCoordsXY{ 49, 17 }, 0);
gfx_draw_sprite(dpi, _queueSurfaceDescriptor.PreviewImage, screenCoords + ScreenCoordsXY{ 4, -17 }, 0);
}
static RailingEntrySupportType ParseSupportType(const std::string& s)

View File

@ -16,9 +16,9 @@ class FootpathObject final : public Object
{
private:
rct_footpath_entry _legacyType = {};
PathSurfaceDescriptor _pathSurfaceEntry = {};
PathSurfaceDescriptor _queueEntry = {};
PathRailingsDescriptor _pathRailingsEntry = {};
PathSurfaceDescriptor _pathSurfaceDescriptor = {};
PathSurfaceDescriptor _queueSurfaceDescriptor = {};
PathRailingsDescriptor _pathRailingsDescriptor = {};
public:
explicit FootpathObject(const rct_object_entry& entry)
@ -31,19 +31,19 @@ public:
return &_legacyType;
}
PathSurfaceDescriptor* GetPathSurfaceEntry()
const PathSurfaceDescriptor& GetPathSurfaceDescriptor() const
{
return &_pathSurfaceEntry;
return _pathSurfaceDescriptor;
}
PathSurfaceDescriptor* GetQueueEntry()
const PathSurfaceDescriptor& GetQueueSurfaceDescriptor() const
{
return &_queueEntry;
return _queueSurfaceDescriptor;
}
PathRailingsDescriptor* GetPathRailingsEntry()
const PathRailingsDescriptor& GetPathRailingsDescriptor() const
{
return &_pathRailingsEntry;
return _pathRailingsDescriptor;
}
void ReadLegacy(IReadObjectContext* context, OpenRCT2::IStream* stream) override;

View File

@ -24,6 +24,14 @@ void FootpathRailingsObject::Load()
BridgeImageId = PreviewImageId + 37;
RailingsImageId = PreviewImageId + 1;
}
_descriptor.Name = NameStringId;
_descriptor.BridgeImage = BridgeImageId;
_descriptor.PreviewImage = PreviewImageId;
_descriptor.Flags = Flags;
_descriptor.ScrollingMode = ScrollingMode;
_descriptor.SupportType = SupportType;
_descriptor.RailingsImage = RailingsImageId;
}
void FootpathRailingsObject::Unload()

View File

@ -23,6 +23,7 @@ public:
uint8_t Flags{};
uint8_t ScrollingMode{};
colour_t Colour{};
PathRailingsDescriptor _descriptor = {};
public:
explicit FootpathRailingsObject(const rct_object_entry& entry)
@ -36,6 +37,11 @@ public:
void DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int32_t height) const override;
const PathRailingsDescriptor& GetDescriptor() const
{
return _descriptor;
}
private:
RailingEntrySupportType ParseSupportType(std::string_view s);
};

View File

@ -24,6 +24,11 @@ void FootpathSurfaceObject::Load()
PreviewImageId = gfx_object_allocate_images(GetImageTable().GetImages(), GetImageTable().GetCount());
BaseImageId = PreviewImageId + 1;
}
_descriptor.Name = NameStringId;
_descriptor.Image = BaseImageId;
_descriptor.PreviewImage = PreviewImageId;
_descriptor.Flags = Flags;
}
void FootpathSurfaceObject::Unload()

View File

@ -19,6 +19,7 @@ public:
uint32_t PreviewImageId{};
uint32_t BaseImageId{};
uint8_t Flags{};
PathSurfaceDescriptor _descriptor = {};
public:
explicit FootpathSurfaceObject(const rct_object_entry& entry)
@ -33,4 +34,9 @@ public:
void DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int32_t height) const override;
void SetRepositoryItem(ObjectRepositoryItem* item) const override;
const PathSurfaceDescriptor& GetDescriptor() const
{
return _descriptor;
}
};

View File

@ -1161,14 +1161,14 @@ bool metal_b_supports_paint_setup(
* @param special (ax)
* @param height (dx)
* @param imageColourFlags (ebp)
* @param railingEntry (0x00F3EF6C)
* @param railingsDescriptor (0x00F3EF6C)
* @param[out] underground (Carry Flag)
*
* @return Whether supports were drawn
*/
bool path_a_supports_paint_setup(
paint_session* session, int32_t supportType, int32_t special, int32_t height, uint32_t imageColourFlags,
PathRailingsDescriptor* railingEntry, bool* underground)
const PathRailingsDescriptor* railingsDescriptor, bool* underground)
{
if (underground != nullptr)
{
@ -1202,7 +1202,7 @@ bool path_a_supports_paint_setup(
{
// save dx2
PaintAddImageAsParent(
session, (railingEntry->BridgeImage + 48) | imageColourFlags, { 0, 0, baseHeight - 2 }, { 32, 32, 0 });
session, (railingsDescriptor->BridgeImage + 48) | imageColourFlags, { 0, 0, baseHeight - 2 }, { 32, 32, 0 });
hasSupports = true;
}
else if (session->Support.slope & 0x10)
@ -1216,7 +1216,7 @@ bool path_a_supports_paint_setup(
}
uint32_t imageId = (supportType * 24) + word_97B3C4[session->Support.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK]
+ railingEntry->BridgeImage;
+ railingsDescriptor->BridgeImage;
PaintAddImageAsParent(
session, imageId | imageColourFlags, { 0, 0, baseHeight }, { 32, 32, 11 }, { 0, 0, baseHeight + 2 });
@ -1239,7 +1239,7 @@ bool path_a_supports_paint_setup(
}
uint32_t ebx = (supportType * 24) + word_97B3C4[session->Support.slope & TILE_ELEMENT_SURFACE_SLOPE_MASK]
+ railingEntry->BridgeImage;
+ railingsDescriptor->BridgeImage;
PaintAddImageAsParent(session, ebx | imageColourFlags, { 0, 0, baseHeight }, { 32, 32, 11 }, { 0, 0, baseHeight + 2 });
@ -1251,7 +1251,7 @@ bool path_a_supports_paint_setup(
{
if (baseHeight & 0x10 || heightSteps == 1 || baseHeight + 16 == session->WaterHeight)
{
uint32_t imageId = (supportType * 24) + railingEntry->BridgeImage + 23;
uint32_t imageId = (supportType * 24) + railingsDescriptor->BridgeImage + 23;
PaintAddImageAsParent(
session, imageId | imageColourFlags, { 0, 0, baseHeight }, { 32, 32, ((heightSteps == 1) ? 7 : 12) });
@ -1261,7 +1261,7 @@ bool path_a_supports_paint_setup(
}
else
{
uint32_t imageId = (supportType * 24) + railingEntry->BridgeImage + 22;
uint32_t imageId = (supportType * 24) + railingsDescriptor->BridgeImage + 22;
PaintAddImageAsParent(
session, imageId | imageColourFlags, { 0, 0, baseHeight }, { 32, 32, ((heightSteps == 2) ? 23 : 28) });
@ -1275,7 +1275,7 @@ bool path_a_supports_paint_setup(
{
uint16_t specialIndex = (special - 1) & 0xFFFF;
uint32_t imageId = railingEntry->BridgeImage + 55 + specialIndex;
uint32_t imageId = railingsDescriptor->BridgeImage + 55 + specialIndex;
const unk_supports_desc& supportsDesc = byte_98D8D4[specialIndex];
const unk_supports_desc_bound_box& boundBox = supportsDesc.bounding_box;
@ -1314,13 +1314,13 @@ bool path_a_supports_paint_setup(
* @param special (ax)
* @param height (dx)
* @param imageColourFlags (ebp)
* @param railingEntry (0x00F3EF6C)
* @param railingsDescriptor (0x00F3EF6C)
*
* @return Whether supports were drawn
*/
bool path_b_supports_paint_setup(
paint_session* session, int32_t segment, int32_t special, int32_t height, uint32_t imageColourFlags,
PathRailingsDescriptor* railingEntry)
const PathRailingsDescriptor* railingsDescriptor)
{
support_height* supportSegments = session->SupportSegments;
@ -1342,7 +1342,7 @@ bool path_b_supports_paint_setup(
uint16_t baseHeight;
if ((supportSegments[segment].slope & 0x20) || (height - supportSegments[segment].height < 6)
|| !(railingEntry->Flags & RAILING_ENTRY_FLAG_HAS_SUPPORT_BASE_SPRITE))
|| !(railingsDescriptor->Flags & RAILING_ENTRY_FLAG_HAS_SUPPORT_BASE_SPRITE))
{
baseHeight = supportSegments[segment].height;
}
@ -1352,7 +1352,7 @@ bool path_b_supports_paint_setup(
baseHeight = supportSegments[segment].height;
PaintAddImageAsParent(
session, (railingEntry->BridgeImage + 37 + imageOffset) | imageColourFlags,
session, (railingsDescriptor->BridgeImage + 37 + imageOffset) | imageColourFlags,
{ SupportBoundBoxes[segment].x, SupportBoundBoxes[segment].y, baseHeight }, { 0, 0, 5 });
baseHeight += 6;
}
@ -1371,7 +1371,7 @@ bool path_b_supports_paint_setup(
if (heightDiff > 0)
{
PaintAddImageAsParent(
session, (railingEntry->BridgeImage + 20 + (heightDiff - 1)) | imageColourFlags,
session, (railingsDescriptor->BridgeImage + 20 + (heightDiff - 1)) | imageColourFlags,
{ SupportBoundBoxes[segment], baseHeight }, { 0, 0, heightDiff - 1 });
}
@ -1404,7 +1404,7 @@ bool path_b_supports_paint_setup(
}
PaintAddImageAsParent(
session, (railingEntry->BridgeImage + 20 + (z - 1)) | imageColourFlags,
session, (railingsDescriptor->BridgeImage + 20 + (z - 1)) | imageColourFlags,
{ SupportBoundBoxes[segment], baseHeight }, { 0, 0, (z - 1) });
baseHeight += z;
@ -1415,7 +1415,7 @@ bool path_b_supports_paint_setup(
break;
}
uint32_t imageId = railingEntry->BridgeImage + 20 + (z - 1);
uint32_t imageId = railingsDescriptor->BridgeImage + 20 + (z - 1);
if (z == 16)
{
imageId += 1;
@ -1449,7 +1449,7 @@ bool path_b_supports_paint_setup(
break;
}
uint32_t imageId = railingEntry->BridgeImage + 20 + (z - 1);
uint32_t imageId = railingsDescriptor->BridgeImage + 20 + (z - 1);
PaintAddImageAsParent(
session, imageId | imageColourFlags, { SupportBoundBoxes[segment], baseHeight }, { 0, 0, 0 },
{ SupportBoundBoxes[segment], baseHeight });

View File

@ -24,10 +24,10 @@ bool metal_b_supports_paint_setup(
paint_session* session, uint8_t supportType, uint8_t segment, int32_t special, int32_t height, uint32_t imageColourFlags);
bool path_a_supports_paint_setup(
paint_session* session, int32_t supportType, int32_t special, int32_t height, uint32_t imageColourFlags,
PathRailingsDescriptor* railingEntry, bool* underground);
const PathRailingsDescriptor* railingsDescriptor, bool* underground);
bool path_b_supports_paint_setup(
paint_session* session, int32_t supportType, int32_t special, int32_t height, uint32_t imageColourFlags,
PathRailingsDescriptor* railingEntry);
const PathRailingsDescriptor* railingsDescriptor);
// There are 13 types of metal supports. A graphic showing all of them is available here:
// https://cloud.githubusercontent.com/assets/737603/19420485/7eaba28e-93ec-11e6-83cb-03190accc094.png

View File

@ -245,12 +245,14 @@ static void park_entrance_paint(paint_session* session, uint8_t direction, int32
// Index to which part of the entrance
// Middle, left, right
uint8_t part_index = tile_element.GetSequenceIndex();
PathSurfaceDescriptor* path_entry = nullptr;
const PathSurfaceDescriptor* surfaceDescriptor = nullptr;
// The left and right of the park entrance often have this set to 127.
// So only attempt to get the footpath type if we're dealing with the middle bit of the entrance.
if (part_index == 0)
path_entry = get_path_surface_entry(tile_element.GetPathType());
{
surfaceDescriptor = tile_element.GetPathSurfaceDescriptor();
}
rct_entrance_type* entrance;
uint8_t di = ((direction / 2 + part_index / 2) & 1) ? 0x1A : 0x20;
@ -258,9 +260,9 @@ static void park_entrance_paint(paint_session* session, uint8_t direction, int32
switch (part_index)
{
case 0:
if (path_entry != nullptr)
if (surfaceDescriptor != nullptr)
{
image_id = (path_entry->Image + 5 * (1 + (direction & 1))) | ghost_id;
image_id = (surfaceDescriptor->Image + 5 * (1 + (direction & 1))) | ghost_id;
PaintAddImageAsParent(session, image_id, { 0, 0, height }, { 32, 0x1C, 0 }, { 0, 2, height });
}

View File

@ -86,11 +86,11 @@ static constexpr const uint8_t byte_98D8A4[] = {
// clang-format on
void path_paint_box_support(
paint_session* session, const PathElement& pathElement, int32_t height, PathSurfaceDescriptor* footpathEntry,
PathRailingsDescriptor* railingEntry, bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags);
paint_session* session, const PathElement& pathElement, int32_t height, const PathSurfaceDescriptor* footpathEntry,
const PathRailingsDescriptor* railingEntry, bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags);
void path_paint_pole_support(
paint_session* session, const PathElement& pathElement, int16_t height, PathSurfaceDescriptor* footpathEntry,
PathRailingsDescriptor* railingEntry, bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags);
paint_session* session, const PathElement& pathElement, int16_t height, const PathSurfaceDescriptor* surfaceDescriptor,
const PathRailingsDescriptor* railingsDescriptor, bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags);
/* rct2: 0x006A5AE5 */
static void path_bit_lights_paint(
@ -326,9 +326,9 @@ static void path_bit_jumping_fountains_paint(
*/
static void sub_6A4101(
paint_session* session, const PathElement& pathElement, uint16_t height, uint32_t connectedEdges, bool word_F3F038,
PathRailingsDescriptor* railingEntry, uint32_t imageFlags)
const PathRailingsDescriptor* railingsDescriptor, uint32_t imageFlags)
{
uint32_t base_image_id = railingEntry->RailingsImage | imageFlags;
uint32_t base_image_id = railingsDescriptor->RailingsImage | imageFlags;
if (pathElement.IsQueue())
{
@ -447,7 +447,7 @@ static void sub_6A4101(
auto ride = get_ride(pathElement.GetRideIndex());
if (direction < 2 && ride != nullptr && imageFlags == 0)
{
uint16_t scrollingMode = railingEntry->ScrollingMode;
uint16_t scrollingMode = railingsDescriptor->ScrollingMode;
scrollingMode += direction;
auto ft = Formatter();
@ -663,13 +663,13 @@ static void sub_6A4101(
* @param pathElement (esp[0])
* @param connectedEdges (bp) (relative to the camera's rotation)
* @param height (dx)
* @param railingEntry (0x00F3EF6C)
* @param railingsDescriptor (0x00F3EF6C)
* @param imageFlags (0x00F3EF70)
* @param sceneryImageFlags (0x00F3EF74)
*/
static void sub_6A3F61(
paint_session* session, const PathElement& pathElement, uint16_t connectedEdges, uint16_t height,
PathRailingsDescriptor* railingEntry, uint32_t imageFlags, uint32_t sceneryImageFlags, bool word_F3F038)
const PathRailingsDescriptor* railingsDescriptor, uint32_t imageFlags, uint32_t sceneryImageFlags, bool word_F3F038)
{
// eax --
// ebx --
@ -749,7 +749,7 @@ static void sub_6A3F61(
// Redundant zoom-level check removed
if (paintScenery)
sub_6A4101(session, pathElement, height, connectedEdges, word_F3F038, railingEntry, imageFlags);
sub_6A4101(session, pathElement, height, connectedEdges, word_F3F038, railingsDescriptor, imageFlags);
}
// This is about tunnel drawing
@ -943,20 +943,22 @@ void PaintPath(paint_session* session, uint16_t height, const PathElement& tileE
PaintAddImageAsParent(session, imageId, { 16, 16, heightMarkerBaseZ }, { 1, 1, 0 });
}
PathSurfaceDescriptor* footpathEntry = tileElement.GetSurfaceEntry();
PathRailingsDescriptor* railingEntry = tileElement.GetRailingEntry();
const PathSurfaceDescriptor* surfaceDescriptor = tileElement.GetSurfaceDescriptor();
const PathRailingsDescriptor* railingsDescriptor = tileElement.GetRailingsDescriptor();
if (footpathEntry != nullptr && railingEntry != nullptr)
if (surfaceDescriptor != nullptr && railingsDescriptor != nullptr)
{
if (railingEntry->SupportType == RailingEntrySupportType::Pole)
if (railingsDescriptor->SupportType == RailingEntrySupportType::Pole)
{
path_paint_pole_support(
session, tileElement, height, footpathEntry, railingEntry, hasSupports, imageFlags, sceneryImageFlags);
session, tileElement, height, surfaceDescriptor, railingsDescriptor, hasSupports, imageFlags,
sceneryImageFlags);
}
else
{
path_paint_box_support(
session, tileElement, height, footpathEntry, railingEntry, hasSupports, imageFlags, sceneryImageFlags);
session, tileElement, height, surfaceDescriptor, railingsDescriptor, hasSupports, imageFlags,
sceneryImageFlags);
}
}
@ -993,8 +995,8 @@ void PaintPath(paint_session* session, uint16_t height, const PathElement& tileE
}
void path_paint_box_support(
paint_session* session, const PathElement& pathElement, int32_t height, PathSurfaceDescriptor* footpathEntry,
PathRailingsDescriptor* railingEntry, bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags)
paint_session* session, const PathElement& pathElement, int32_t height, const PathSurfaceDescriptor* footpathEntry,
const PathRailingsDescriptor* railingEntry, bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags)
{
// Rol edges around rotation
uint8_t edges = ((pathElement.GetEdges() << session->CurrentRotation) & 0xF)
@ -1139,8 +1141,8 @@ void path_paint_box_support(
}
void path_paint_pole_support(
paint_session* session, const PathElement& pathElement, int16_t height, PathSurfaceDescriptor* footpathEntry,
PathRailingsDescriptor* railingEntry, bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags)
paint_session* session, const PathElement& pathElement, int16_t height, const PathSurfaceDescriptor* surfaceDescriptor,
const PathRailingsDescriptor* railingsDescriptor, bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags)
{
// Rol edges around rotation
uint8_t edges = ((pathElement.GetEdges() << session->CurrentRotation) & 0xF)
@ -1165,7 +1167,7 @@ void path_paint_pole_support(
imageId = byte_98D6E0[edi];
}
imageId += footpathEntry->Image;
imageId += surfaceDescriptor->Image;
// Below Surface
if (!session->DidPassSurface)
@ -1202,11 +1204,11 @@ void path_paint_pole_support(
{
bridgeImage = ((pathElement.GetSlopeDirection() + session->CurrentRotation)
& FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK)
+ railingEntry->BridgeImage + 16;
+ railingsDescriptor->BridgeImage + 16;
}
else
{
bridgeImage = edges + railingEntry->BridgeImage;
bridgeImage = edges + railingsDescriptor->BridgeImage;
bridgeImage |= imageFlags;
}
@ -1223,7 +1225,8 @@ void path_paint_pole_support(
}
}
sub_6A3F61(session, pathElement, edi, height, railingEntry, imageFlags, sceneryImageFlags, hasSupports); // TODO: arguments
sub_6A3F61(
session, pathElement, edi, height, railingsDescriptor, imageFlags, sceneryImageFlags, hasSupports); // TODO: arguments
uint16_t ax = 0;
if (pathElement.IsSloped())
@ -1242,7 +1245,7 @@ void path_paint_pole_support(
{
if (!(edges & (1 << i)))
{
path_b_supports_paint_setup(session, supports[i], ax, height, imageFlags, railingEntry);
path_b_supports_paint_setup(session, supports[i], ax, height, imageFlags, railingsDescriptor);
}
}

View File

@ -1599,36 +1599,13 @@ namespace RCT1
dst2->SetIsBroken(false);
dst2->SetIsBlockedByVehicle(false);
dst2->SetSurfaceEntryIndex(entryIndex);
dst2->SetLegacyPathEntryIndex(entryIndex);
dst2->SetShouldDrawPathOverSupports(true);
if (RCT1::PathIsQueue(pathType))
{
dst2->SetIsQueue(true);
}
if (_gameVersion != FILE_VERSION_RCT1_LL)
{
dst2->SetRailingEntryIndex(0);
}
else
{
ObjectEntryIndex railingsEntryIndex;
switch (src2->GetRCT1SupportType())
{
case RCT1_PATH_SUPPORT_TYPE_COATED_WOOD:
railingsEntryIndex = 3;
break;
case RCT1_PATH_SUPPORT_TYPE_SPACE:
railingsEntryIndex = 4;
break;
case RCT1_PATH_SUPPORT_TYPE_BAMBOO:
railingsEntryIndex = 5;
break;
case RCT1_PATH_SUPPORT_TYPE_TRUSS:
default:
railingsEntryIndex = 0;
}
dst2->SetRailingEntryIndex(railingsEntryIndex);
}
// TODO: Set railings type
// Additions
ObjectEntryIndex additionType = dst2->GetAddition();
@ -1743,7 +1720,7 @@ namespace RCT1
pathType = RCT1_FOOTPATH_TYPE_TARMAC_GRAY;
}
auto entryIndex = _pathTypeToEntryMap[pathType];
dst2->SetPathType(entryIndex & 0x7F);
dst2->SetLegacyPathEntryIndex(entryIndex & 0x7F);
}
return 1;

View File

@ -1798,7 +1798,7 @@ void S6Exporter::ExportTileElement(RCT12TileElement* dst, const TileElement* src
auto dst2 = dst->AsPath();
auto src2 = src->AsPath();
dst2->SetPathEntryIndex(src2->GetSurfaceEntryIndex());
dst2->SetPathEntryIndex(src2->GetLegacyPathEntryIndex());
dst2->SetQueueBannerDirection(src2->GetQueueBannerDirection());
dst2->SetSloped(src2->IsSloped());
dst2->SetSlopeDirection(src2->GetSlopeDirection());
@ -1889,7 +1889,7 @@ void S6Exporter::ExportTileElement(RCT12TileElement* dst, const TileElement* src
dst2->SetRideIndex(OpenRCT2RideIdToRCT12RideId(src2->GetRideIndex()));
dst2->SetStationIndex(src2->GetStationIndex());
dst2->SetSequenceIndex(src2->GetSequenceIndex());
dst2->SetPathType(src2->GetPathType());
dst2->SetPathType(src2->GetLegacyPathEntryIndex());
break;
}

View File

@ -1167,7 +1167,7 @@ public:
auto dst2 = dst->AsPath();
auto src2 = src->AsPath();
dst2->SetSurfaceEntryIndex(src2->GetEntryIndex());
dst2->SetLegacyPathEntryIndex(src2->GetEntryIndex());
dst2->SetQueueBannerDirection(src2->GetQueueBannerDirection());
dst2->SetSloped(src2->IsSloped());
dst2->SetSlopeDirection(src2->GetSlopeDirection());
@ -1257,7 +1257,7 @@ public:
dst2->SetRideIndex(RCT12RideIdToOpenRCT2RideId(src2->GetRideIndex()));
dst2->SetStationIndex(src2->GetStationIndex());
dst2->SetSequenceIndex(src2->GetSequenceIndex());
dst2->SetPathType(src2->GetPathType());
dst2->SetLegacyPathEntryIndex(src2->GetPathType());
break;
}

View File

@ -591,7 +591,7 @@ static void ride_ratings_score_close_proximity(RideRatingUpdateState& state, Til
break;
case TILE_ELEMENT_TYPE_PATH:
// Bonus for normal path
if (tileElement->AsPath()->GetSurfaceEntryIndex() != 0)
if (tileElement->AsPath()->GetLegacyPathEntryIndex() != 0)
{
if (tileElement->GetClearanceZ() == inputTileElement->GetBaseZ())
{

View File

@ -39,6 +39,7 @@
#include "../localisation/StringIds.h"
#include "../management/Finance.h"
#include "../network/network.h"
#include "../object/FootpathObject.h"
#include "../object/ObjectList.h"
#include "../object/ObjectManager.h"
#include "../object/ObjectRepository.h"
@ -874,15 +875,15 @@ static bool TrackDesignPlaceSceneryElementGetEntry(
}
entry_index = 0;
for (PathSurfaceDescriptor* path = get_path_surface_entry(0);
entry_index < object_entry_group_counts[EnumValue(ObjectType::Paths)];
path = get_path_surface_entry(entry_index), entry_index++)
for (; entry_index < object_entry_group_counts[EnumValue(ObjectType::Paths)]; entry_index++)
{
if (path == nullptr)
const auto* legacyPathEntry = GetLegacyFootpathEntry(entry_index);
if (legacyPathEntry == nullptr)
{
return true;
}
if (path->Flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR)
const auto& surfaceDescriptor = legacyPathEntry->GetPathSurfaceDescriptor();
if (surfaceDescriptor.IsEditorOnly())
{
return true;
}

View File

@ -296,7 +296,7 @@ static void track_design_save_add_wall(const CoordsXY& loc, WallElement* wallEle
static void track_design_save_add_footpath(const CoordsXY& loc, PathElement* pathElement)
{
int32_t entryType = pathElement->GetSurfaceEntryIndex();
int32_t entryType = pathElement->GetLegacyPathEntryIndex();
auto entry = object_entry_get_object(ObjectType::Paths, entryType);
uint8_t flags = 0;
@ -473,7 +473,7 @@ static void track_design_save_remove_wall(const CoordsXY& loc, WallElement* wall
static void track_design_save_remove_footpath(const CoordsXY& loc, PathElement* pathElement)
{
int32_t entryType = pathElement->GetSurfaceEntryIndex();
int32_t entryType = pathElement->GetLegacyPathEntryIndex();
auto entry = object_entry_get_object(ObjectType::Paths, entryType);
uint8_t flags = 0;

View File

@ -713,7 +713,7 @@ namespace OpenRCT2::Scripting
case TILE_ELEMENT_TYPE_PATH:
{
auto el = _element->AsPath();
duk_push_int(ctx, el->GetSurfaceEntryIndex());
duk_push_int(ctx, el->GetLegacyPathEntryIndex());
break;
}
case TILE_ELEMENT_TYPE_SMALL_SCENERY:
@ -756,7 +756,7 @@ namespace OpenRCT2::Scripting
case TILE_ELEMENT_TYPE_PATH:
{
auto el = _element->AsPath();
el->SetSurfaceEntryIndex(value & 0xFF);
el->SetLegacyPathEntryIndex(value & 0xFF);
Invalidate();
break;
}
@ -1397,7 +1397,7 @@ namespace OpenRCT2::Scripting
auto ctx = GetContext()->GetScriptEngine().GetContext();
auto el = _element->AsEntrance();
if (el != nullptr)
duk_push_int(ctx, el->GetPathType());
duk_push_int(ctx, el->GetLegacyPathEntryIndex());
else
duk_push_null(ctx);
return DukValue::take_from_stack(ctx);
@ -1408,7 +1408,7 @@ namespace OpenRCT2::Scripting
auto el = _element->AsEntrance();
if (el != nullptr)
{
el->SetPathType(value);
el->SetLegacyPathEntryIndex(value);
Invalidate();
}
}

View File

@ -18,6 +18,7 @@
#include "../localisation/StringIds.h"
#include "../management/Finance.h"
#include "../network/network.h"
#include "../object/FootpathObject.h"
#include "../ride/Station.h"
#include "../ride/Track.h"
#include "Footpath.h"
@ -254,12 +255,21 @@ void EntranceElement::SetSequenceIndex(uint8_t newSequenceIndex)
SequenceIndex |= (newSequenceIndex & 0xF);
}
PathSurfaceIndex EntranceElement::GetPathType() const
ObjectEntryIndex EntranceElement::GetLegacyPathEntryIndex() const
{
return PathType;
}
void EntranceElement::SetPathType(PathSurfaceIndex newPathType)
void EntranceElement::SetLegacyPathEntryIndex(ObjectEntryIndex newPathType)
{
PathType = newPathType;
}
const PathSurfaceDescriptor* EntranceElement::GetPathSurfaceDescriptor() const
{
const auto* legacyPathEntry = GetLegacyFootpathEntry(PathType);
if (legacyPathEntry == nullptr)
return nullptr;
return &legacyPathEntry->GetPathSurfaceDescriptor();
}

View File

@ -1642,39 +1642,42 @@ void PathElement::SetAdditionIsGhost(bool isGhost)
Flags2 |= FOOTPATH_ELEMENT_FLAGS2_ADDITION_IS_GHOST;
}
PathSurfaceIndex PathElement::GetSurfaceEntryIndex() const
ObjectEntryIndex PathElement::GetLegacyPathEntryIndex() const
{
return SurfaceIndex;
}
PathRailingsIndex PathElement::GetRailingEntryIndex() const
const FootpathObject* PathElement::GetLegacyPathEntry() const
{
return GetSurfaceEntryIndex();
return GetLegacyFootpathEntry(GetLegacyPathEntryIndex());
}
PathSurfaceDescriptor* PathElement::GetSurfaceEntry() const
const PathSurfaceDescriptor* PathElement::GetSurfaceDescriptor() const
{
if (!IsQueue())
return get_path_surface_entry(GetSurfaceEntryIndex());
else
return get_path_surface_entry(GetSurfaceEntryIndex() + MAX_PATH_OBJECTS);
const auto* legacyPathEntry = GetLegacyPathEntry();
if (legacyPathEntry == nullptr)
return nullptr;
if (IsQueue())
return &legacyPathEntry->GetQueueSurfaceDescriptor();
return &legacyPathEntry->GetPathSurfaceDescriptor();
}
PathRailingsDescriptor* PathElement::GetRailingEntry() const
const PathRailingsDescriptor* PathElement::GetRailingsDescriptor() const
{
return get_path_railings_entry(GetRailingEntryIndex());
const auto* legacyPathEntry = GetLegacyPathEntry();
if (legacyPathEntry == nullptr)
return nullptr;
return &legacyPathEntry->GetPathRailingsDescriptor();
}
void PathElement::SetSurfaceEntryIndex(PathSurfaceIndex newIndex)
void PathElement::SetLegacyPathEntryIndex(ObjectEntryIndex newIndex)
{
SurfaceIndex = newIndex & ~FOOTPATH_ELEMENT_INSERT_QUEUE;
}
void PathElement::SetRailingEntryIndex(PathRailingsIndex newEntryIndex)
{
log_verbose("Setting railing entry index to %d", newEntryIndex);
}
uint8_t PathElement::GetQueueBannerDirection() const
{
return ((type & FOOTPATH_ELEMENT_TYPE_DIRECTION_MASK) >> 6);
@ -1688,7 +1691,7 @@ void PathElement::SetQueueBannerDirection(uint8_t direction)
bool PathElement::ShouldDrawPathOverSupports() const
{
return (GetRailingEntry()->Flags & RAILING_ENTRY_FLAG_DRAW_PATH_OVER_SUPPORTS);
return (GetRailingsDescriptor()->Flags & RAILING_ENTRY_FLAG_DRAW_PATH_OVER_SUPPORTS);
}
void PathElement::SetShouldDrawPathOverSupports(bool on)
@ -2247,32 +2250,15 @@ void footpath_remove_edges_at(const CoordsXY& footpathPos, TileElement* tileElem
tileElement->AsPath()->SetEdgesAndCorners(0);
}
PathSurfaceDescriptor* get_path_surface_entry(PathSurfaceIndex entryIndex)
const FootpathObject* GetLegacyFootpathEntry(ObjectEntryIndex entryIndex)
{
PathSurfaceDescriptor* result = nullptr;
auto& objMgr = OpenRCT2::GetContext()->GetObjectManager();
// TODO: Change when moving to the new save format.
auto obj = objMgr.GetLoadedObject(ObjectType::Paths, entryIndex % MAX_PATH_OBJECTS);
if (obj != nullptr)
{
if (entryIndex < MAX_PATH_OBJECTS)
result = (static_cast<FootpathObject*>(obj))->GetPathSurfaceEntry();
else
result = (static_cast<FootpathObject*>(obj))->GetQueueEntry();
}
return result;
}
PathRailingsDescriptor* get_path_railings_entry(PathRailingsIndex entryIndex)
{
PathRailingsDescriptor* result = nullptr;
auto& objMgr = OpenRCT2::GetContext()->GetObjectManager();
auto obj = objMgr.GetLoadedObject(ObjectType::Paths, entryIndex);
if (obj != nullptr)
{
result = (static_cast<FootpathObject*>(obj))->GetPathRailingsEntry();
}
return result;
if (obj == nullptr)
return nullptr;
const FootpathObject* footpathObject = (static_cast<FootpathObject*>(obj));
return footpathObject;
}
ride_id_t PathElement::GetRideIndex() const

View File

@ -27,11 +27,7 @@ constexpr auto PATH_CLEARANCE = 4 * COORDS_Z_STEP;
#define FOOTPATH_ELEMENT_INSERT_QUEUE 0x80
using PathSurfaceIndex = uint16_t;
constexpr PathSurfaceIndex PATH_SURFACE_INDEX_NULL = static_cast<PathSurfaceIndex>(-1);
using PathRailingsIndex = uint8_t;
constexpr PathRailingsIndex PATH_RAILINGS_INDEX_NULL = static_cast<PathRailingsIndex>(-1);
class FootpathObject;
enum class RailingEntrySupportType : uint8_t
{
@ -40,6 +36,13 @@ enum class RailingEntrySupportType : uint8_t
Count
};
enum
{
FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR = (1 << 2),
FOOTPATH_ENTRY_FLAG_IS_QUEUE = (1 << 3),
FOOTPATH_ENTRY_FLAG_NO_SLOPE_RAILINGS = (1 << 4),
};
#pragma pack(push, 1)
struct rct_footpath_entry
{
@ -60,6 +63,12 @@ struct rct_footpath_entry
}
constexpr uint32_t GetQueuePreviewImage() const
{
// Editor-only paths usually lack queue images. In this case, use the main path image.
if (flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR)
{
return GetPreviewImage();
}
return image + 72;
}
constexpr uint32_t GetRailingsImage() const
@ -76,6 +85,11 @@ struct PathSurfaceDescriptor
uint32_t Image;
uint32_t PreviewImage;
uint8_t Flags;
inline constexpr bool IsEditorOnly() const
{
return Flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR;
}
};
struct PathRailingsDescriptor
@ -130,13 +144,6 @@ enum
FOOTPATH_ELEMENT_FLAGS2_ADDITION_IS_BROKEN = (1 << 4),
};
enum
{
FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR = (1 << 2),
FOOTPATH_ENTRY_FLAG_IS_QUEUE = (1 << 3),
FOOTPATH_ENTRY_FLAG_NO_SLOPE_RAILINGS = (1 << 4),
};
enum
{
RAILING_ENTRY_FLAG_HAS_SUPPORT_BASE_SPRITE = (1 << 0),
@ -215,8 +222,7 @@ bool footpath_is_blocked_by_vehicle(const TileCoordsXYZ& position);
int32_t footpath_is_connected_to_map_edge(const CoordsXYZ& footpathPos, int32_t direction, int32_t flags);
void footpath_remove_edges_at(const CoordsXY& footpathPos, TileElement* tileElement);
PathSurfaceDescriptor* get_path_surface_entry(PathSurfaceIndex entryIndex);
PathRailingsDescriptor* get_path_railings_entry(PathRailingsIndex entryIndex);
const FootpathObject* GetLegacyFootpathEntry(ObjectEntryIndex entryIndex);
void footpath_queue_chain_reset();
void footpath_queue_chain_push(ride_id_t rideIndex);

View File

@ -260,10 +260,10 @@ struct PathElement : TileElementBase
static constexpr TileElementType ElementType = TileElementType::Path;
private:
PathSurfaceIndex SurfaceIndex; // 5
ObjectEntryIndex SurfaceIndex; // 5
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-private-field"
PathRailingsIndex RailingsIndex; // 7
uint8_t RailingsIndex; // 7
#pragma clang diagnostic pop
uint8_t Additions; // 8 (0 means no addition)
uint8_t EdgesAndCorners; // 9 (edges in lower 4 bits, corners in upper 4)
@ -281,13 +281,12 @@ private:
#pragma clang diagnostic pop
public:
PathSurfaceIndex GetSurfaceEntryIndex() const;
PathSurfaceDescriptor* GetSurfaceEntry() const;
void SetSurfaceEntryIndex(PathSurfaceIndex newIndex);
ObjectEntryIndex GetLegacyPathEntryIndex() const;
const FootpathObject* GetLegacyPathEntry() const;
void SetLegacyPathEntryIndex(ObjectEntryIndex newIndex);
PathRailingsIndex GetRailingEntryIndex() const;
PathRailingsDescriptor* GetRailingEntry() const;
void SetRailingEntryIndex(PathRailingsIndex newIndex);
const PathSurfaceDescriptor* GetSurfaceDescriptor() const;
const PathRailingsDescriptor* GetRailingsDescriptor() const;
uint8_t GetQueueBannerDirection() const;
void SetQueueBannerDirection(uint8_t direction);
@ -569,7 +568,7 @@ private:
uint8_t entranceType; // 5
uint8_t SequenceIndex; // 6. Only uses the lower nibble.
uint8_t StationIndex; // 7
PathSurfaceIndex PathType; // 8
ObjectEntryIndex PathType; // 8
ride_id_t rideIndex; // 9
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-private-field"
@ -589,8 +588,10 @@ public:
uint8_t GetSequenceIndex() const;
void SetSequenceIndex(uint8_t newSequenceIndex);
PathSurfaceIndex GetPathType() const;
void SetPathType(PathSurfaceIndex newPathType);
ObjectEntryIndex GetLegacyPathEntryIndex() const;
void SetLegacyPathEntryIndex(ObjectEntryIndex newPathType);
const PathSurfaceDescriptor* GetPathSurfaceDescriptor() const;
int32_t GetDirections() const;
};