From 4cc717ccdbece7d193a9c9e1e2ed1bd6e74e22bd Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Sun, 5 Sep 2021 18:44:43 +0200 Subject: [PATCH] Rework path surface and railings descriptor handling --- src/openrct2-ui/windows/Footpath.cpp | 82 ++++++++++--------- src/openrct2-ui/windows/TileInspector.cpp | 2 +- src/openrct2/EditorObjectSelectionSession.cpp | 4 +- src/openrct2/actions/FootpathPlaceAction.cpp | 14 ++-- .../actions/FootpathPlaceFromTrackAction.cpp | 8 +- .../actions/PlaceParkEntranceAction.cpp | 2 +- src/openrct2/object/FootpathObject.cpp | 34 ++++---- src/openrct2/object/FootpathObject.h | 18 ++-- .../object/FootpathRailingsObject.cpp | 8 ++ src/openrct2/object/FootpathRailingsObject.h | 6 ++ src/openrct2/object/FootpathSurfaceObject.cpp | 5 ++ src/openrct2/object/FootpathSurfaceObject.h | 6 ++ src/openrct2/paint/Supports.cpp | 32 ++++---- src/openrct2/paint/Supports.h | 4 +- .../paint/tile_element/Paint.Entrance.cpp | 10 ++- .../paint/tile_element/Paint.Path.cpp | 53 ++++++------ src/openrct2/rct1/S4Importer.cpp | 29 +------ src/openrct2/rct2/S6Exporter.cpp | 4 +- src/openrct2/rct2/S6Importer.cpp | 4 +- src/openrct2/ride/RideRatings.cpp | 2 +- src/openrct2/ride/TrackDesign.cpp | 11 +-- src/openrct2/ride/TrackDesignSave.cpp | 4 +- .../bindings/world/ScTileElement.cpp | 8 +- src/openrct2/world/Entrance.cpp | 14 +++- src/openrct2/world/Footpath.cpp | 66 ++++++--------- src/openrct2/world/Footpath.h | 34 ++++---- src/openrct2/world/TileElement.h | 23 +++--- 27 files changed, 250 insertions(+), 237 deletions(-) diff --git a/src/openrct2-ui/windows/Footpath.cpp b/src/openrct2-ui/windows/Footpath.cpp index dfb6508ac3..1cdd7ba637 100644 --- a/src/openrct2-ui/windows/Footpath.cpp +++ b/src/openrct2-ui/windows/Footpath.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -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(SPR_NONE); auto queueImage = static_cast(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) diff --git a/src/openrct2-ui/windows/TileInspector.cpp b/src/openrct2-ui/windows/TileInspector.cpp index b1f8042bc6..bfadeab869 100644 --- a/src/openrct2-ui/windows/TileInspector.cpp +++ b/src/openrct2-ui/windows/TileInspector.cpp @@ -1886,7 +1886,7 @@ static void window_tile_inspector_paint(rct_window* w, rct_drawpixelinfo* dpi) // Details // Path name auto ft = Formatter(); - ft.Add(tileElement->AsPath()->GetSurfaceEntry()->Name); + ft.Add(tileElement->AsPath()->GetSurfaceDescriptor()->Name); DrawTextBasic(dpi, screenCoords, STR_TILE_INSPECTOR_PATH_NAME, ft, { COLOUR_WHITE }); // Path addition diff --git a/src/openrct2/EditorObjectSelectionSession.cpp b/src/openrct2/EditorObjectSelectionSession.cpp index 687233c39f..622262fe06 100644 --- a/src/openrct2/EditorObjectSelectionSession.cpp +++ b/src/openrct2/EditorObjectSelectionSession.cpp @@ -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; diff --git a/src/openrct2/actions/FootpathPlaceAction.cpp b/src/openrct2/actions/FootpathPlaceAction.cpp index 6124336ffd..b294f1ee2a 100644 --- a/src/openrct2/actions/FootpathPlaceAction.cpp +++ b/src/openrct2/actions/FootpathPlaceAction.cpp @@ -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(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); diff --git a/src/openrct2/actions/FootpathPlaceFromTrackAction.cpp b/src/openrct2/actions/FootpathPlaceFromTrackAction.cpp index 80249c155f..0c73ba201d 100644 --- a/src/openrct2/actions/FootpathPlaceFromTrackAction.cpp +++ b/src/openrct2/actions/FootpathPlaceFromTrackAction.cpp @@ -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); diff --git a/src/openrct2/actions/PlaceParkEntranceAction.cpp b/src/openrct2/actions/PlaceParkEntranceAction.cpp index 8b4e3db1d2..72c9d102b8 100644 --- a/src/openrct2/actions/PlaceParkEntranceAction.cpp +++ b/src/openrct2/actions/PlaceParkEntranceAction.cpp @@ -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()) { diff --git a/src/openrct2/object/FootpathObject.cpp b/src/openrct2/object/FootpathObject.cpp index 26c5961cf9..17df28d69c 100644 --- a/src/openrct2/object/FootpathObject.cpp +++ b/src/openrct2/object/FootpathObject.cpp @@ -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) diff --git a/src/openrct2/object/FootpathObject.h b/src/openrct2/object/FootpathObject.h index 52af3a2ae9..5d481cec80 100644 --- a/src/openrct2/object/FootpathObject.h +++ b/src/openrct2/object/FootpathObject.h @@ -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; diff --git a/src/openrct2/object/FootpathRailingsObject.cpp b/src/openrct2/object/FootpathRailingsObject.cpp index ee16825968..70b742339f 100644 --- a/src/openrct2/object/FootpathRailingsObject.cpp +++ b/src/openrct2/object/FootpathRailingsObject.cpp @@ -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() diff --git a/src/openrct2/object/FootpathRailingsObject.h b/src/openrct2/object/FootpathRailingsObject.h index 2b61ec9255..205ebebd8f 100644 --- a/src/openrct2/object/FootpathRailingsObject.h +++ b/src/openrct2/object/FootpathRailingsObject.h @@ -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); }; diff --git a/src/openrct2/object/FootpathSurfaceObject.cpp b/src/openrct2/object/FootpathSurfaceObject.cpp index 66b89b6727..bb20157c11 100644 --- a/src/openrct2/object/FootpathSurfaceObject.cpp +++ b/src/openrct2/object/FootpathSurfaceObject.cpp @@ -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() diff --git a/src/openrct2/object/FootpathSurfaceObject.h b/src/openrct2/object/FootpathSurfaceObject.h index 7d5ca8c6d7..fd23e06a81 100644 --- a/src/openrct2/object/FootpathSurfaceObject.h +++ b/src/openrct2/object/FootpathSurfaceObject.h @@ -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; + } }; diff --git a/src/openrct2/paint/Supports.cpp b/src/openrct2/paint/Supports.cpp index 7c73be108b..ed60fe98ef 100644 --- a/src/openrct2/paint/Supports.cpp +++ b/src/openrct2/paint/Supports.cpp @@ -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 }); diff --git a/src/openrct2/paint/Supports.h b/src/openrct2/paint/Supports.h index 3131df3e03..3e8ff8fb57 100644 --- a/src/openrct2/paint/Supports.h +++ b/src/openrct2/paint/Supports.h @@ -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 diff --git a/src/openrct2/paint/tile_element/Paint.Entrance.cpp b/src/openrct2/paint/tile_element/Paint.Entrance.cpp index fb4dbdd63f..7b0ab9c16d 100644 --- a/src/openrct2/paint/tile_element/Paint.Entrance.cpp +++ b/src/openrct2/paint/tile_element/Paint.Entrance.cpp @@ -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 }); } diff --git a/src/openrct2/paint/tile_element/Paint.Path.cpp b/src/openrct2/paint/tile_element/Paint.Path.cpp index 939f66a857..711dc7b32a 100644 --- a/src/openrct2/paint/tile_element/Paint.Path.cpp +++ b/src/openrct2/paint/tile_element/Paint.Path.cpp @@ -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); } } diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index ac1555b2d6..efcdeb95d3 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -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; diff --git a/src/openrct2/rct2/S6Exporter.cpp b/src/openrct2/rct2/S6Exporter.cpp index 6f3e4b0168..c8394c5fd0 100644 --- a/src/openrct2/rct2/S6Exporter.cpp +++ b/src/openrct2/rct2/S6Exporter.cpp @@ -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; } diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 708d6e404e..3a7d792448 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -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; } diff --git a/src/openrct2/ride/RideRatings.cpp b/src/openrct2/ride/RideRatings.cpp index 58265bbbb9..308a2f6528 100644 --- a/src/openrct2/ride/RideRatings.cpp +++ b/src/openrct2/ride/RideRatings.cpp @@ -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()) { diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index 2deca96b0a..33bf8c9732 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -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; } diff --git a/src/openrct2/ride/TrackDesignSave.cpp b/src/openrct2/ride/TrackDesignSave.cpp index cf3dde9395..a345852212 100644 --- a/src/openrct2/ride/TrackDesignSave.cpp +++ b/src/openrct2/ride/TrackDesignSave.cpp @@ -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; diff --git a/src/openrct2/scripting/bindings/world/ScTileElement.cpp b/src/openrct2/scripting/bindings/world/ScTileElement.cpp index 40251c55a4..1cc7aadbfb 100644 --- a/src/openrct2/scripting/bindings/world/ScTileElement.cpp +++ b/src/openrct2/scripting/bindings/world/ScTileElement.cpp @@ -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(); } } diff --git a/src/openrct2/world/Entrance.cpp b/src/openrct2/world/Entrance.cpp index 73b3e17c08..00131be3ec 100644 --- a/src/openrct2/world/Entrance.cpp +++ b/src/openrct2/world/Entrance.cpp @@ -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(); +} diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index 398dc4f8a0..fe59e4e6d1 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -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(obj))->GetPathSurfaceEntry(); - else - result = (static_cast(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(obj))->GetPathRailingsEntry(); - } - return result; + if (obj == nullptr) + return nullptr; + + const FootpathObject* footpathObject = (static_cast(obj)); + return footpathObject; } ride_id_t PathElement::GetRideIndex() const diff --git a/src/openrct2/world/Footpath.h b/src/openrct2/world/Footpath.h index 3c6ec98ace..1dc6e10f2a 100644 --- a/src/openrct2/world/Footpath.h +++ b/src/openrct2/world/Footpath.h @@ -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(-1); - -using PathRailingsIndex = uint8_t; -constexpr PathRailingsIndex PATH_RAILINGS_INDEX_NULL = static_cast(-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); diff --git a/src/openrct2/world/TileElement.h b/src/openrct2/world/TileElement.h index 008b21be4a..b683684571 100644 --- a/src/openrct2/world/TileElement.h +++ b/src/openrct2/world/TileElement.h @@ -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; };