From 4e9d2ce76412ff79a35699e63c76c08c29333f82 Mon Sep 17 00:00:00 2001 From: Michael Steenbeek Date: Sun, 20 Jan 2019 21:38:38 +0100 Subject: [PATCH] Split footpath object into two internally --- src/openrct2-ui/windows/Footpath.cpp | 30 +-- src/openrct2/object/FootpathObject.cpp | 18 +- src/openrct2/object/FootpathObject.h | 12 + src/openrct2/paint/Supports.cpp | 4 +- src/openrct2/paint/Supports.h | 4 +- .../paint/tile_element/Paint.Entrance.cpp | 4 +- .../paint/tile_element/Paint.Path.cpp | 206 +++++++++--------- src/openrct2/rct1/RCT1.h | 8 + src/openrct2/rct1/S4Importer.cpp | 25 +++ src/openrct2/rct12/RCT12.cpp | 5 + src/openrct2/rct12/RCT12.h | 1 + src/openrct2/ride/TrackDesign.cpp | 8 +- src/openrct2/world/Footpath.cpp | 27 ++- src/openrct2/world/Footpath.h | 23 +- src/openrct2/world/TileElement.h | 5 +- 15 files changed, 244 insertions(+), 136 deletions(-) diff --git a/src/openrct2-ui/windows/Footpath.cpp b/src/openrct2-ui/windows/Footpath.cpp index d75d8b397e..57fb602eed 100644 --- a/src/openrct2-ui/windows/Footpath.cpp +++ b/src/openrct2-ui/windows/Footpath.cpp @@ -192,7 +192,7 @@ 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 - rct_footpath_entry* pathEntry = get_footpath_entry(gFootpathSelectedId); + PathSurfaceEntry* pathEntry = get_path_surface_entry(gFootpathSelectedId); if (pathEntry != nullptr && (pathEntry->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) && !gCheatsSandboxMode) { pathEntry = nullptr; @@ -374,7 +374,7 @@ static void window_footpath_dropdown(rct_window* w, rct_widgetindex widgetIndex, int32_t i = 0, j = 0; for (; i < MAX_PATH_OBJECTS; i++) { - rct_footpath_entry* pathType = get_footpath_entry(i); + PathSurfaceEntry* pathType = get_path_surface_entry(i); if (pathType == nullptr) { continue; @@ -563,7 +563,7 @@ static void window_footpath_update(rct_window* w) static void window_footpath_invalidate(rct_window* w) { int32_t selectedPath; - rct_footpath_entry* pathType; + PathSurfaceEntry* pathType; // Press / unpress footpath and queue type buttons w->pressed_widgets &= ~(1 << WIDX_FOOTPATH_TYPE); @@ -578,10 +578,9 @@ static void window_footpath_invalidate(rct_window* w) // Set footpath and queue type button images selectedPath = gFootpathSelectedId; - pathType = get_footpath_entry(selectedPath); + pathType = get_path_surface_entry(selectedPath); - // TODO: Should probably add constants for object sprites - int32_t pathImage = 71 + pathType->image; + int32_t pathImage = pathType->preview; // Editor-only paths might lack a queue image int32_t queueImage = (pathType->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR) ? pathImage : pathImage + 1; window_footpath_widgets[WIDX_FOOTPATH_TYPE].image = pathImage; @@ -612,11 +611,14 @@ static void window_footpath_paint(rct_window* w, rct_drawpixelinfo* dpi) int32_t image = ConstructionPreviewImages[slope][direction]; int32_t selectedPath = gFootpathSelectedId; - rct_footpath_entry* pathType = get_footpath_entry(selectedPath); - image += pathType->image; - if (gFootpathSelectedType != SELECTED_PATH_TYPE_NORMAL) + PathSurfaceEntry* pathType = get_path_surface_entry(selectedPath); + if (gFootpathSelectedType == SELECTED_PATH_TYPE_NORMAL) { - image += 51; + image += pathType->image; + } + else + { + image += pathType->queue_image; } // Draw construction image @@ -649,7 +651,7 @@ 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, numPathTypes, image; - rct_footpath_entry* pathType; + PathSurfaceEntry* pathType; numPathTypes = 0; // If the game is in sandbox mode, also show paths that are normally restricted to the scenario editor @@ -657,7 +659,7 @@ static void window_footpath_show_footpath_types_dialog(rct_window* w, rct_widget for (i = 0; i < MAX_PATH_OBJECTS; i++) { - pathType = get_footpath_entry(i); + pathType = get_path_surface_entry(i); if (pathType == nullptr) { continue; @@ -667,7 +669,7 @@ static void window_footpath_show_footpath_types_dialog(rct_window* w, rct_widget continue; } - image = pathType->image + 71; + image = pathType->preview; // 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)) { @@ -1238,7 +1240,7 @@ static bool footpath_select_default() int32_t footpathId = -1; for (int32_t i = 0; i < object_entry_group_counts[OBJECT_TYPE_PATHS]; i++) { - rct_footpath_entry* pathEntry = get_footpath_entry(i); + PathSurfaceEntry* pathEntry = get_path_surface_entry(i); if (pathEntry != nullptr) { footpathId = i; diff --git a/src/openrct2/object/FootpathObject.cpp b/src/openrct2/object/FootpathObject.cpp index e9fa6d7ec3..7216586912 100644 --- a/src/openrct2/object/FootpathObject.cpp +++ b/src/openrct2/object/FootpathObject.cpp @@ -39,6 +39,20 @@ void FootpathObject::Load() _legacyType.string_idx = language_allocate_object_string(GetName()); _legacyType.image = gfx_object_allocate_images(GetImageTable().GetImages(), GetImageTable().GetCount()); _legacyType.bridge_image = _legacyType.image + 109; + + _pathSurfaceEntry.string_idx = _legacyType.string_idx; + _pathSurfaceEntry.image = _legacyType.image; + _pathSurfaceEntry.queue_image = _legacyType.image + 51; + _pathSurfaceEntry.preview = _legacyType.image + 71; + _pathSurfaceEntry.flags = _legacyType.flags; + + _pathRailingsEntry.string_idx = _legacyType.string_idx; + _pathRailingsEntry.bridge_image = _legacyType.bridge_image; + _pathRailingsEntry.preview = _legacyType.image + 71; + _pathRailingsEntry.flags = _legacyType.flags; + _pathRailingsEntry.scrolling_mode = _legacyType.scrolling_mode; + _pathRailingsEntry.support_type = _legacyType.support_type; + _pathRailingsEntry.railings_image = _legacyType.image + 73; } void FootpathObject::Unload() @@ -54,8 +68,8 @@ void FootpathObject::DrawPreview(rct_drawpixelinfo* dpi, int32_t width, int32_t { int32_t x = width / 2; int32_t y = height / 2; - gfx_draw_sprite(dpi, _legacyType.image + 71, x - 49, y - 17, 0); - gfx_draw_sprite(dpi, _legacyType.image + 72, x + 4, y - 17, 0); + gfx_draw_sprite(dpi, _pathSurfaceEntry.preview, x - 49, y - 17, 0); + gfx_draw_sprite(dpi, _pathSurfaceEntry.preview + 1, x + 4, y - 17, 0); } static uint8_t ParseSupportType(const std::string& s) diff --git a/src/openrct2/object/FootpathObject.h b/src/openrct2/object/FootpathObject.h index d6391c6720..986962f94b 100644 --- a/src/openrct2/object/FootpathObject.h +++ b/src/openrct2/object/FootpathObject.h @@ -16,6 +16,8 @@ class FootpathObject final : public Object { private: rct_footpath_entry _legacyType = {}; + PathSurfaceEntry _pathSurfaceEntry = {}; + PathRailingsEntry _pathRailingsEntry = {}; public: explicit FootpathObject(const rct_object_entry& entry) @@ -28,6 +30,16 @@ public: return &_legacyType; } + PathSurfaceEntry* GetPathSurfaceEntry() + { + return &_pathSurfaceEntry; + } + + PathRailingsEntry* GetPathRailingsEntry() + { + return &_pathRailingsEntry; + } + void ReadLegacy(IReadObjectContext* context, IStream* stream) override; void ReadJson(IReadObjectContext* context, const json_t* root) override; void Load() override; diff --git a/src/openrct2/paint/Supports.cpp b/src/openrct2/paint/Supports.cpp index e2c3a841c7..b1938da17d 100644 --- a/src/openrct2/paint/Supports.cpp +++ b/src/openrct2/paint/Supports.cpp @@ -1083,7 +1083,7 @@ bool metal_b_supports_paint_setup( */ bool path_a_supports_paint_setup( paint_session* session, int32_t supportType, int32_t special, int32_t height, uint32_t imageColourFlags, - rct_footpath_entry* railingEntry, bool* underground) + PathRailingsEntry* railingEntry, bool* underground) { if (underground != nullptr) { @@ -1230,7 +1230,7 @@ bool path_a_supports_paint_setup( */ bool path_b_supports_paint_setup( paint_session* session, int32_t segment, int32_t special, int32_t height, uint32_t imageColourFlags, - rct_footpath_entry* railingEntry) + PathRailingsEntry* railingEntry) { support_height* supportSegments = session->SupportSegments; diff --git a/src/openrct2/paint/Supports.h b/src/openrct2/paint/Supports.h index 75b7e3a47f..6959b394e7 100644 --- a/src/openrct2/paint/Supports.h +++ b/src/openrct2/paint/Supports.h @@ -23,10 +23,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, - rct_footpath_entry* railingEntry, bool* underground); + PathRailingsEntry* railingEntry, bool* underground); bool path_b_supports_paint_setup( paint_session* session, int32_t supportType, int32_t special, int32_t height, uint32_t imageColourFlags, - rct_footpath_entry* railingEntry); + PathRailingsEntry* railingEntry); // 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 edcd01d769..65138eaace 100644 --- a/src/openrct2/paint/tile_element/Paint.Entrance.cpp +++ b/src/openrct2/paint/tile_element/Paint.Entrance.cpp @@ -234,12 +234,12 @@ 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->AsEntrance()->GetSequenceIndex(); - rct_footpath_entry* path_entry = nullptr; + PathSurfaceEntry* path_entry = 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_footpath_entry(tile_element->AsEntrance()->GetPathType()); + path_entry = get_path_surface_entry(tile_element->AsEntrance()->GetPathType()); rct_entrance_type* entrance; uint8_t di = ((direction / 2 + part_index / 2) & 1) ? 0x1A : 0x20; diff --git a/src/openrct2/paint/tile_element/Paint.Path.cpp b/src/openrct2/paint/tile_element/Paint.Path.cpp index 9fef67b038..a8ecdc9202 100644 --- a/src/openrct2/paint/tile_element/Paint.Path.cpp +++ b/src/openrct2/paint/tile_element/Paint.Path.cpp @@ -82,11 +82,11 @@ static constexpr const uint8_t byte_98D8A4[] = { // clang-format on void path_paint_box_support( - paint_session* session, const TileElement* tileElement, int32_t height, rct_footpath_entry* footpathEntry, - rct_footpath_entry* railingEntry, bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags); + paint_session* session, const TileElement* tileElement, int32_t height, PathSurfaceEntry* footpathEntry, + PathRailingsEntry* railingEntry, bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags); void path_paint_pole_support( - paint_session* session, const TileElement* tileElement, int16_t height, rct_footpath_entry* footpathEntry, - rct_footpath_entry* railingEntry, bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags); + paint_session* session, const TileElement* tileElement, int16_t height, PathSurfaceEntry* footpathEntry, + PathRailingsEntry* railingEntry, bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags); /* rct2: 0x006A5AE5 */ static void path_bit_lights_paint( @@ -322,8 +322,10 @@ static void path_bit_jumping_fountains_paint( */ static void sub_6A4101( paint_session* session, const TileElement* tile_element, uint16_t height, uint32_t connectedEdges, bool word_F3F038, - rct_footpath_entry* railingEntry, uint32_t base_image_id, uint32_t imageFlags) + PathRailingsEntry* railingEntry, uint32_t imageFlags) { + uint32_t base_image_id = railingEntry->railings_image | imageFlags; + if (tile_element->AsPath()->IsQueue()) { uint8_t local_ebp = connectedEdges & 0x0F; @@ -333,20 +335,20 @@ static void sub_6A4101( & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK) { case 0: - sub_98197C(session, 95 + base_image_id, 0, 4, 32, 1, 23, height, 0, 4, height + 2); - sub_98197C(session, 95 + base_image_id, 0, 28, 32, 1, 23, height, 0, 28, height + 2); + sub_98197C(session, 22 + base_image_id, 0, 4, 32, 1, 23, height, 0, 4, height + 2); + sub_98197C(session, 22 + base_image_id, 0, 28, 32, 1, 23, height, 0, 28, height + 2); break; case 1: - sub_98197C(session, 94 + base_image_id, 4, 0, 1, 32, 23, height, 4, 0, height + 2); - sub_98197C(session, 94 + base_image_id, 28, 0, 1, 32, 23, height, 28, 0, height + 2); + sub_98197C(session, 21 + base_image_id, 4, 0, 1, 32, 23, height, 4, 0, height + 2); + sub_98197C(session, 21 + base_image_id, 28, 0, 1, 32, 23, height, 28, 0, height + 2); break; case 2: - sub_98197C(session, 96 + base_image_id, 0, 4, 32, 1, 23, height, 0, 4, height + 2); - sub_98197C(session, 96 + base_image_id, 0, 28, 32, 1, 23, height, 0, 28, height + 2); + sub_98197C(session, 23 + base_image_id, 0, 4, 32, 1, 23, height, 0, 4, height + 2); + sub_98197C(session, 23 + base_image_id, 0, 28, 32, 1, 23, height, 0, 28, height + 2); break; case 3: - sub_98197C(session, 93 + base_image_id, 4, 0, 1, 32, 23, height, 4, 0, height + 2); - sub_98197C(session, 93 + base_image_id, 28, 0, 1, 32, 23, height, 28, 0, height + 2); + sub_98197C(session, 20 + base_image_id, 4, 0, 1, 32, 23, height, 4, 0, height + 2); + sub_98197C(session, 20 + base_image_id, 28, 0, 1, 32, 23, height, 28, 0, height + 2); break; } } @@ -355,52 +357,52 @@ static void sub_6A4101( switch (local_ebp) { case 1: - sub_98197C(session, 90 + base_image_id, 0, 4, 28, 1, 7, height, 0, 4, height + 2); - sub_98197C(session, 90 + base_image_id, 0, 28, 28, 1, 7, height, 0, 28, height + 2); + sub_98197C(session, 17 + base_image_id, 0, 4, 28, 1, 7, height, 0, 4, height + 2); + sub_98197C(session, 17 + base_image_id, 0, 28, 28, 1, 7, height, 0, 28, height + 2); break; case 2: - sub_98197C(session, 91 + base_image_id, 4, 0, 1, 28, 7, height, 4, 0, height + 2); - sub_98197C(session, 91 + base_image_id, 28, 0, 1, 28, 7, height, 28, 0, height + 2); + sub_98197C(session, 18 + base_image_id, 4, 0, 1, 28, 7, height, 4, 0, height + 2); + sub_98197C(session, 18 + base_image_id, 28, 0, 1, 28, 7, height, 28, 0, height + 2); break; case 3: - sub_98197C(session, 90 + base_image_id, 0, 4, 28, 1, 7, height, 0, 4, height + 2); + sub_98197C(session, 17 + base_image_id, 0, 4, 28, 1, 7, height, 0, 4, height + 2); sub_98197C( - session, 91 + base_image_id, 28, 0, 1, 28, 7, height, 28, 4, + session, 18 + base_image_id, 28, 0, 1, 28, 7, height, 28, 4, height + 2); // bound_box_offset_y seems to be a bug - sub_98197C(session, 98 + base_image_id, 0, 0, 4, 4, 7, height, 0, 28, height + 2); + sub_98197C(session, 25 + base_image_id, 0, 0, 4, 4, 7, height, 0, 28, height + 2); break; case 4: - sub_98197C(session, 92 + base_image_id, 0, 4, 28, 1, 7, height, 0, 4, height + 2); - sub_98197C(session, 92 + base_image_id, 0, 28, 28, 1, 7, height, 0, 28, height + 2); + sub_98197C(session, 19 + base_image_id, 0, 4, 28, 1, 7, height, 0, 4, height + 2); + sub_98197C(session, 19 + base_image_id, 0, 28, 28, 1, 7, height, 0, 28, height + 2); break; case 5: - sub_98197C(session, 88 + base_image_id, 0, 4, 32, 1, 7, height, 0, 4, height + 2); - sub_98197C(session, 88 + base_image_id, 0, 28, 32, 1, 7, height, 0, 28, height + 2); + sub_98197C(session, 15 + base_image_id, 0, 4, 32, 1, 7, height, 0, 4, height + 2); + sub_98197C(session, 15 + base_image_id, 0, 28, 32, 1, 7, height, 0, 28, height + 2); break; case 6: - sub_98197C(session, 91 + base_image_id, 4, 0, 1, 28, 7, height, 4, 0, height + 2); - sub_98197C(session, 92 + base_image_id, 0, 4, 28, 1, 7, height, 0, 4, height + 2); - sub_98197C(session, 99 + base_image_id, 0, 0, 4, 4, 7, height, 28, 28, height + 2); + sub_98197C(session, 18 + base_image_id, 4, 0, 1, 28, 7, height, 4, 0, height + 2); + sub_98197C(session, 19 + base_image_id, 0, 4, 28, 1, 7, height, 0, 4, height + 2); + sub_98197C(session, 26 + base_image_id, 0, 0, 4, 4, 7, height, 28, 28, height + 2); break; case 8: - sub_98197C(session, 89 + base_image_id, 4, 0, 1, 28, 7, height, 4, 0, height + 2); - sub_98197C(session, 89 + base_image_id, 28, 0, 1, 28, 7, height, 28, 0, height + 2); + sub_98197C(session, 16 + base_image_id, 4, 0, 1, 28, 7, height, 4, 0, height + 2); + sub_98197C(session, 16 + base_image_id, 28, 0, 1, 28, 7, height, 28, 0, height + 2); break; case 9: - sub_98197C(session, 89 + base_image_id, 28, 0, 1, 28, 7, height, 28, 0, height + 2); - sub_98197C(session, 90 + base_image_id, 0, 28, 28, 1, 7, height, 0, 28, height + 2); - sub_98197C(session, 97 + base_image_id, 0, 0, 4, 4, 7, height, 0, 0, height + 2); + sub_98197C(session, 16 + base_image_id, 28, 0, 1, 28, 7, height, 28, 0, height + 2); + sub_98197C(session, 17 + base_image_id, 0, 28, 28, 1, 7, height, 0, 28, height + 2); + sub_98197C(session, 24 + base_image_id, 0, 0, 4, 4, 7, height, 0, 0, height + 2); break; case 10: - sub_98197C(session, 87 + base_image_id, 4, 0, 1, 32, 7, height, 4, 0, height + 2); - sub_98197C(session, 87 + base_image_id, 28, 0, 1, 32, 7, height, 28, 0, height + 2); + sub_98197C(session, 14 + base_image_id, 4, 0, 1, 32, 7, height, 4, 0, height + 2); + sub_98197C(session, 14 + base_image_id, 28, 0, 1, 32, 7, height, 28, 0, height + 2); break; case 12: - sub_98197C(session, 89 + base_image_id, 4, 0, 1, 28, 7, height, 4, 0, height + 2); + sub_98197C(session, 16 + base_image_id, 4, 0, 1, 28, 7, height, 4, 0, height + 2); sub_98197C( - session, 92 + base_image_id, 0, 28, 28, 1, 7, height, 4, 28, + session, 19 + base_image_id, 0, 28, 28, 1, 7, height, 4, 28, height + 2); // bound_box_offset_x seems to be a bug - sub_98197C(session, 100 + base_image_id, 0, 0, 4, 4, 7, height, 28, 0, height + 2); + sub_98197C(session, 27 + base_image_id, 0, 0, 4, 4, 7, height, 28, 0, height + 2); break; default: // purposely left empty @@ -427,7 +429,7 @@ static void sub_6A4101( LocationXYZ16 boundBoxOffsets = { BannerBoundBoxes[direction][0].x, BannerBoundBoxes[direction][0].y, static_cast(height + 2) }; - uint32_t imageId = (direction << 1) + base_image_id + 101; + uint32_t imageId = (direction << 1) + base_image_id + 28; // Draw pole in the back sub_98197C(session, imageId, 0, 0, 1, 1, 21, height, boundBoxOffsets.x, boundBoxOffsets.y, boundBoxOffsets.z); @@ -498,20 +500,20 @@ static void sub_6A4101( & FOOTPATH_PROPERTIES_SLOPE_DIRECTION_MASK) { case 0: - sub_98197C(session, 81 + base_image_id, 0, 4, 32, 1, 23, height, 0, 4, height + 2); - sub_98197C(session, 81 + base_image_id, 0, 28, 32, 1, 23, height, 0, 28, height + 2); + sub_98197C(session, 8 + base_image_id, 0, 4, 32, 1, 23, height, 0, 4, height + 2); + sub_98197C(session, 8 + base_image_id, 0, 28, 32, 1, 23, height, 0, 28, height + 2); break; case 1: - sub_98197C(session, 80 + base_image_id, 4, 0, 1, 32, 23, height, 4, 0, height + 2); - sub_98197C(session, 80 + base_image_id, 28, 0, 1, 32, 23, height, 28, 0, height + 2); + sub_98197C(session, 7 + base_image_id, 4, 0, 1, 32, 23, height, 4, 0, height + 2); + sub_98197C(session, 7 + base_image_id, 28, 0, 1, 32, 23, height, 28, 0, height + 2); break; case 2: - sub_98197C(session, 82 + base_image_id, 0, 4, 32, 1, 23, height, 0, 4, height + 2); - sub_98197C(session, 82 + base_image_id, 0, 28, 32, 1, 23, height, 0, 28, height + 2); + sub_98197C(session, 9 + base_image_id, 0, 4, 32, 1, 23, height, 0, 4, height + 2); + sub_98197C(session, 9 + base_image_id, 0, 28, 32, 1, 23, height, 0, 28, height + 2); break; case 3: - sub_98197C(session, 79 + base_image_id, 4, 0, 1, 32, 23, height, 4, 0, height + 2); - sub_98197C(session, 79 + base_image_id, 28, 0, 1, 32, 23, height, 28, 0, height + 2); + sub_98197C(session, 6 + base_image_id, 4, 0, 1, 32, 23, height, 4, 0, height + 2); + sub_98197C(session, 6 + base_image_id, 28, 0, 1, 32, 23, height, 28, 0, height + 2); break; } } @@ -528,128 +530,128 @@ static void sub_6A4101( // purposely left empty break; case 1: - sub_98197C(session, 76 + base_image_id, 0, 4, 28, 1, 7, height, 0, 4, height + 2); - sub_98197C(session, 76 + base_image_id, 0, 28, 28, 1, 7, height, 0, 28, height + 2); + sub_98197C(session, 3 + base_image_id, 0, 4, 28, 1, 7, height, 0, 4, height + 2); + sub_98197C(session, 3 + base_image_id, 0, 28, 28, 1, 7, height, 0, 28, height + 2); break; case 2: - sub_98197C(session, 77 + base_image_id, 4, 0, 1, 28, 7, height, 4, 0, height + 2); - sub_98197C(session, 77 + base_image_id, 28, 0, 1, 28, 7, height, 28, 0, height + 2); + sub_98197C(session, 4 + base_image_id, 4, 0, 1, 28, 7, height, 4, 0, height + 2); + sub_98197C(session, 4 + base_image_id, 28, 0, 1, 28, 7, height, 28, 0, height + 2); break; case 4: - sub_98197C(session, 78 + base_image_id, 0, 4, 28, 1, 7, height, 0, 4, height + 2); - sub_98197C(session, 78 + base_image_id, 0, 28, 28, 1, 7, height, 0, 28, height + 2); + sub_98197C(session, 5 + base_image_id, 0, 4, 28, 1, 7, height, 0, 4, height + 2); + sub_98197C(session, 5 + base_image_id, 0, 28, 28, 1, 7, height, 0, 28, height + 2); break; case 5: - sub_98197C(session, 74 + base_image_id, 0, 4, 32, 1, 7, height, 0, 4, height + 2); - sub_98197C(session, 74 + base_image_id, 0, 28, 32, 1, 7, height, 0, 28, height + 2); + sub_98197C(session, 1 + base_image_id, 0, 4, 32, 1, 7, height, 0, 4, height + 2); + sub_98197C(session, 1 + base_image_id, 0, 28, 32, 1, 7, height, 0, 28, height + 2); break; case 8: - sub_98197C(session, 75 + base_image_id, 4, 0, 1, 28, 7, height, 4, 0, height + 2); - sub_98197C(session, 75 + base_image_id, 28, 0, 1, 28, 7, height, 28, 0, height + 2); + sub_98197C(session, 2 + base_image_id, 4, 0, 1, 28, 7, height, 4, 0, height + 2); + sub_98197C(session, 2 + base_image_id, 28, 0, 1, 28, 7, height, 28, 0, height + 2); break; case 10: - sub_98197C(session, 73 + base_image_id, 4, 0, 1, 32, 7, height, 4, 0, height + 2); - sub_98197C(session, 73 + base_image_id, 28, 0, 1, 32, 7, height, 28, 0, height + 2); + sub_98197C(session, 0 + base_image_id, 4, 0, 1, 32, 7, height, 4, 0, height + 2); + sub_98197C(session, 0 + base_image_id, 28, 0, 1, 32, 7, height, 28, 0, height + 2); break; case 3: - sub_98197C(session, 76 + base_image_id, 0, 4, 28, 1, 7, height, 0, 4, height + 2); + sub_98197C(session, 3 + base_image_id, 0, 4, 28, 1, 7, height, 0, 4, height + 2); sub_98197C( - session, 77 + base_image_id, 28, 0, 1, 28, 7, height, 28, 4, + session, 4 + base_image_id, 28, 0, 1, 28, 7, height, 28, 4, height + 2); // bound_box_offset_y seems to be a bug if (!(drawnCorners & FOOTPATH_CORNER_0)) { - sub_98197C(session, 84 + base_image_id, 0, 0, 4, 4, 7, height, 0, 28, height + 2); + sub_98197C(session, 11 + base_image_id, 0, 0, 4, 4, 7, height, 0, 28, height + 2); } break; case 6: - sub_98197C(session, 77 + base_image_id, 4, 0, 1, 28, 7, height, 4, 0, height + 2); - sub_98197C(session, 78 + base_image_id, 0, 4, 28, 1, 7, height, 0, 4, height + 2); + sub_98197C(session, 4 + base_image_id, 4, 0, 1, 28, 7, height, 4, 0, height + 2); + sub_98197C(session, 5 + base_image_id, 0, 4, 28, 1, 7, height, 0, 4, height + 2); if (!(drawnCorners & FOOTPATH_CORNER_1)) { - sub_98197C(session, 85 + base_image_id, 0, 0, 4, 4, 7, height, 28, 28, height + 2); + sub_98197C(session, 12 + base_image_id, 0, 0, 4, 4, 7, height, 28, 28, height + 2); } break; case 9: - sub_98197C(session, 75 + base_image_id, 28, 0, 1, 28, 7, height, 28, 0, height + 2); - sub_98197C(session, 76 + base_image_id, 0, 28, 28, 1, 7, height, 0, 28, height + 2); + sub_98197C(session, 2 + base_image_id, 28, 0, 1, 28, 7, height, 28, 0, height + 2); + sub_98197C(session, 3 + base_image_id, 0, 28, 28, 1, 7, height, 0, 28, height + 2); if (!(drawnCorners & FOOTPATH_CORNER_3)) { - sub_98197C(session, 83 + base_image_id, 0, 0, 4, 4, 7, height, 0, 0, height + 2); + sub_98197C(session, 10 + base_image_id, 0, 0, 4, 4, 7, height, 0, 0, height + 2); } break; case 12: - sub_98197C(session, 75 + base_image_id, 4, 0, 1, 28, 7, height, 4, 0, height + 2); + sub_98197C(session, 2 + base_image_id, 4, 0, 1, 28, 7, height, 4, 0, height + 2); sub_98197C( - session, 78 + base_image_id, 0, 28, 28, 1, 7, height, 4, 28, + session, 5 + base_image_id, 0, 28, 28, 1, 7, height, 4, 28, height + 2); // bound_box_offset_x seems to be a bug if (!(drawnCorners & FOOTPATH_CORNER_2)) { - sub_98197C(session, 86 + base_image_id, 0, 0, 4, 4, 7, height, 28, 0, height + 2); + sub_98197C(session, 13 + base_image_id, 0, 0, 4, 4, 7, height, 28, 0, height + 2); } break; case 7: - sub_98197C(session, 74 + base_image_id, 0, 4, 32, 1, 7, height, 0, 4, height + 2); + sub_98197C(session, 1 + base_image_id, 0, 4, 32, 1, 7, height, 0, 4, height + 2); if (!(drawnCorners & FOOTPATH_CORNER_0)) { - sub_98197C(session, 84 + base_image_id, 0, 0, 4, 4, 7, height, 0, 28, height + 2); + sub_98197C(session, 11 + base_image_id, 0, 0, 4, 4, 7, height, 0, 28, height + 2); } if (!(drawnCorners & FOOTPATH_CORNER_1)) { - sub_98197C(session, 85 + base_image_id, 0, 0, 4, 4, 7, height, 28, 28, height + 2); + sub_98197C(session, 12 + base_image_id, 0, 0, 4, 4, 7, height, 28, 28, height + 2); } break; case 13: - sub_98197C(session, 74 + base_image_id, 0, 28, 32, 1, 7, height, 0, 28, height + 2); + sub_98197C(session, 1 + base_image_id, 0, 28, 32, 1, 7, height, 0, 28, height + 2); if (!(drawnCorners & FOOTPATH_CORNER_2)) { - sub_98197C(session, 86 + base_image_id, 0, 0, 4, 4, 7, height, 28, 0, height + 2); + sub_98197C(session, 13 + base_image_id, 0, 0, 4, 4, 7, height, 28, 0, height + 2); } if (!(drawnCorners & FOOTPATH_CORNER_3)) { - sub_98197C(session, 83 + base_image_id, 0, 0, 4, 4, 7, height, 0, 0, height + 2); + sub_98197C(session, 10 + base_image_id, 0, 0, 4, 4, 7, height, 0, 0, height + 2); } break; case 14: - sub_98197C(session, 73 + base_image_id, 4, 0, 1, 32, 7, height, 4, 0, height + 2); + sub_98197C(session, 0 + base_image_id, 4, 0, 1, 32, 7, height, 4, 0, height + 2); if (!(drawnCorners & FOOTPATH_CORNER_1)) { - sub_98197C(session, 85 + base_image_id, 0, 0, 4, 4, 7, height, 28, 28, height + 2); + sub_98197C(session, 12 + base_image_id, 0, 0, 4, 4, 7, height, 28, 28, height + 2); } if (!(drawnCorners & FOOTPATH_CORNER_2)) { - sub_98197C(session, 86 + base_image_id, 0, 0, 4, 4, 7, height, 28, 0, height + 2); + sub_98197C(session, 13 + base_image_id, 0, 0, 4, 4, 7, height, 28, 0, height + 2); } break; case 11: - sub_98197C(session, 73 + base_image_id, 28, 0, 1, 32, 7, height, 28, 0, height + 2); + sub_98197C(session, 0 + base_image_id, 28, 0, 1, 32, 7, height, 28, 0, height + 2); if (!(drawnCorners & FOOTPATH_CORNER_0)) { - sub_98197C(session, 84 + base_image_id, 0, 0, 4, 4, 7, height, 0, 28, height + 2); + sub_98197C(session, 11 + base_image_id, 0, 0, 4, 4, 7, height, 0, 28, height + 2); } if (!(drawnCorners & FOOTPATH_CORNER_3)) { - sub_98197C(session, 83 + base_image_id, 0, 0, 4, 4, 7, height, 0, 0, height + 2); + sub_98197C(session, 10 + base_image_id, 0, 0, 4, 4, 7, height, 0, 0, height + 2); } break; case 15: if (!(drawnCorners & FOOTPATH_CORNER_0)) { - sub_98197C(session, 84 + base_image_id, 0, 0, 4, 4, 7, height, 0, 28, height + 2); + sub_98197C(session, 11 + base_image_id, 0, 0, 4, 4, 7, height, 0, 28, height + 2); } if (!(drawnCorners & FOOTPATH_CORNER_1)) { - sub_98197C(session, 85 + base_image_id, 0, 0, 4, 4, 7, height, 28, 28, height + 2); + sub_98197C(session, 12 + base_image_id, 0, 0, 4, 4, 7, height, 28, 28, height + 2); } if (!(drawnCorners & FOOTPATH_CORNER_2)) { - sub_98197C(session, 86 + base_image_id, 0, 0, 4, 4, 7, height, 28, 0, height + 2); + sub_98197C(session, 13 + base_image_id, 0, 0, 4, 4, 7, height, 28, 0, height + 2); } if (!(drawnCorners & FOOTPATH_CORNER_3)) { - sub_98197C(session, 83 + base_image_id, 0, 0, 4, 4, 7, height, 0, 0, height + 2); + sub_98197C(session, 10 + base_image_id, 0, 0, 4, 4, 7, height, 0, 0, height + 2); } break; } @@ -667,7 +669,7 @@ static void sub_6A4101( */ static void sub_6A3F61( paint_session* session, const TileElement* tile_element, uint16_t connectedEdges, uint16_t height, - rct_footpath_entry* railingEntry, uint32_t imageFlags, uint32_t sceneryImageFlags, bool word_F3F038) + PathRailingsEntry* railingEntry, uint32_t imageFlags, uint32_t sceneryImageFlags, bool word_F3F038) { // eax -- // ebx -- @@ -738,9 +740,7 @@ static void sub_6A3F61( // Redundant zoom-level check removed - sub_6A4101( - session, tile_element, height, connectedEdges, word_F3F038, railingEntry, railingEntry->image | imageFlags, - imageFlags); + sub_6A4101(session, tile_element, height, connectedEdges, word_F3F038, railingEntry, imageFlags); } // This is about tunnel drawing @@ -928,8 +928,8 @@ void path_paint(paint_session* session, uint16_t height, const TileElement* tile sub_98196C(session, imageId, 16, 16, 1, 1, 0, height2); } - rct_footpath_entry* footpathEntry = tile_element->AsPath()->GetPathEntry(); - rct_footpath_entry* railingEntry = tile_element->AsPath()->GetRailingEntry(); + PathSurfaceEntry* footpathEntry = tile_element->AsPath()->GetPathEntry(); + PathRailingsEntry* railingEntry = tile_element->AsPath()->GetRailingEntry(); if (footpathEntry != nullptr && railingEntry != nullptr) { @@ -980,8 +980,8 @@ void path_paint(paint_session* session, uint16_t height, const TileElement* tile } void path_paint_box_support( - paint_session* session, const TileElement* tileElement, int32_t height, rct_footpath_entry* footpathEntry, - rct_footpath_entry* railingEntry, bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags) + paint_session* session, const TileElement* tileElement, int32_t height, PathSurfaceEntry* footpathEntry, + PathRailingsEntry* railingEntry, bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags) { PathElement* pathElement = tileElement->AsPath(); @@ -1009,10 +1009,13 @@ void path_paint_box_support( imageId = byte_98D6E0[edi]; } - imageId += footpathEntry->image; if (pathElement->IsQueue()) { - imageId += 51; + imageId += footpathEntry->queue_image; + } + else + { + imageId += footpathEntry->image; } if (!session->DidPassSurface) @@ -1134,8 +1137,8 @@ void path_paint_box_support( } void path_paint_pole_support( - paint_session* session, const TileElement* tileElement, int16_t height, rct_footpath_entry* footpathEntry, - rct_footpath_entry* railingEntry, bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags) + paint_session* session, const TileElement* tileElement, int16_t height, PathSurfaceEntry* footpathEntry, + PathRailingsEntry* railingEntry, bool hasSupports, uint32_t imageFlags, uint32_t sceneryImageFlags) { PathElement* pathElement = tileElement->AsPath(); @@ -1162,10 +1165,13 @@ void path_paint_pole_support( imageId = byte_98D6E0[edi]; } - imageId += footpathEntry->image; if (pathElement->IsQueue()) { - imageId += 51; + imageId += footpathEntry->queue_image; + } + else + { + imageId += footpathEntry->image; } // Below Surface diff --git a/src/openrct2/rct1/RCT1.h b/src/openrct2/rct1/RCT1.h index 0aeacb419c..3aa5cbd709 100644 --- a/src/openrct2/rct1/RCT1.h +++ b/src/openrct2/rct1/RCT1.h @@ -1287,6 +1287,14 @@ enum RCT1_LANDSCAPE_DOOR_OPEN = 3, }; +enum +{ + RCT1_PATH_SUPPORT_TYPE_TRUSS, + RCT1_PATH_SUPPORT_TYPE_COATED_WOOD, + RCT1_PATH_SUPPORT_TYPE_SPACE, + RCT1_PATH_SUPPORT_TYPE_BAMBOO, +}; + void load_from_sv4(const char* path); void load_from_sc4(const char* path); diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index 484dd838a7..b8e3e858a2 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -2065,10 +2065,35 @@ private: dst2->flags &= ~(TILE_ELEMENT_FLAG_BROKEN | TILE_ELEMENT_FLAG_INDESTRUCTIBLE_TRACK_PIECE); dst2->SetPathEntryIndex(entryIndex); + dst2->SetShouldDrawPathOverSupports(true); if (RCT1::PathIsQueue(pathType)) { dst2->SetIsQueue(true); } + if (_gameVersion != FILE_VERSION_RCT1_LL) + { + dst2->SetRailingEntryIndex(0); + } + else + { + uint8_t 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); + } // Additions uint8_t additionType = dst2->GetAddition(); diff --git a/src/openrct2/rct12/RCT12.cpp b/src/openrct2/rct12/RCT12.cpp index 4a9d974160..190d00e0ae 100644 --- a/src/openrct2/rct12/RCT12.cpp +++ b/src/openrct2/rct12/RCT12.cpp @@ -155,6 +155,11 @@ uint8_t RCT12PathElement::GetRCT1PathType() const return pathType2; } +uint8_t RCT12PathElement::GetRCT1SupportType() const +{ + return (flags & 0b01100000) >> 5; +} + uint8_t RCT12TrackElement::GetTrackType() const { return trackType; diff --git a/src/openrct2/rct12/RCT12.h b/src/openrct2/rct12/RCT12.h index 8ffc1f8e8d..21b3e6b059 100644 --- a/src/openrct2/rct12/RCT12.h +++ b/src/openrct2/rct12/RCT12.h @@ -211,6 +211,7 @@ public: bool AdditionIsGhost() const; uint8_t GetAdditionStatus() const; uint8_t GetRCT1PathType() const; + uint8_t GetRCT1SupportType() const; }; assert_struct_size(RCT12PathElement, 8); struct RCT12TrackElement : RCT12TileElementBase diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index e7087fb3cc..c1ba4fd655 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -783,9 +783,9 @@ static int32_t track_design_place_scenery( } entry_index = 0; - for (rct_footpath_entry* path = get_footpath_entry(0); + for (PathSurfaceEntry* path = get_path_surface_entry(0); entry_index < object_entry_group_counts[OBJECT_TYPE_PATHS]; - path = get_footpath_entry(entry_index), entry_index++) + path = get_path_surface_entry(entry_index), entry_index++) { if (path == nullptr) { @@ -899,9 +899,9 @@ static int32_t track_design_place_scenery( } entry_index = 0; - for (rct_footpath_entry* path = get_footpath_entry(0); + for (PathSurfaceEntry* path = get_path_surface_entry(0); entry_index < object_entry_group_counts[OBJECT_TYPE_PATHS]; - path = get_footpath_entry(entry_index), entry_index++) + path = get_path_surface_entry(entry_index), entry_index++) { if (path == nullptr) { diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index 9b56365eee..c2ab41847d 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -16,6 +16,7 @@ #include "../localisation/Localisation.h" #include "../management/Finance.h" #include "../network/network.h" +#include "../object/FootpathObject.h" #include "../object/ObjectList.h" #include "../object/ObjectManager.h" #include "../paint/VirtualFloor.h" @@ -2103,14 +2104,14 @@ uint8_t PathElement::GetRailingEntryIndex() const return GetPathEntryIndex(); } -rct_footpath_entry* PathElement::GetPathEntry() const +PathSurfaceEntry* PathElement::GetPathEntry() const { - return get_footpath_entry(GetPathEntryIndex()); + return get_path_surface_entry(GetPathEntryIndex()); } -rct_footpath_entry* PathElement::GetRailingEntry() const +PathRailingsEntry* PathElement::GetRailingEntry() const { - return get_footpath_entry(GetRailingEntryIndex()); + return get_path_railings_entry(GetRailingEntryIndex()); } void PathElement::SetPathEntryIndex(uint8_t newEntryIndex) @@ -2687,14 +2688,26 @@ void footpath_remove_edges_at(int32_t x, int32_t y, TileElement* tileElement) tileElement->AsPath()->SetEdgesAndCorners(0); } -rct_footpath_entry* get_footpath_entry(int32_t entryIndex) +PathSurfaceEntry* get_path_surface_entry(int32_t entryIndex) { - rct_footpath_entry* result = nullptr; + PathSurfaceEntry* result = nullptr; auto& objMgr = OpenRCT2::GetContext()->GetObjectManager(); auto obj = objMgr.GetLoadedObject(OBJECT_TYPE_PATHS, entryIndex); if (obj != nullptr) { - result = (rct_footpath_entry*)obj->GetLegacyData(); + result = ((FootpathObject*)obj)->GetPathSurfaceEntry(); + } + return result; +} + +PathRailingsEntry* get_path_railings_entry(int32_t entryIndex) +{ + PathRailingsEntry* result = nullptr; + auto& objMgr = OpenRCT2::GetContext()->GetObjectManager(); + auto obj = objMgr.GetLoadedObject(OBJECT_TYPE_PATHS, entryIndex); + if (obj != nullptr) + { + result = ((FootpathObject*)obj)->GetPathRailingsEntry(); } return result; } diff --git a/src/openrct2/world/Footpath.h b/src/openrct2/world/Footpath.h index 1457a4a387..2c14ba4f20 100644 --- a/src/openrct2/world/Footpath.h +++ b/src/openrct2/world/Footpath.h @@ -36,6 +36,26 @@ struct rct_footpath_entry assert_struct_size(rct_footpath_entry, 13); #pragma pack(pop) +struct PathSurfaceEntry +{ + rct_string_id string_idx; + uint32_t image; + uint32_t queue_image; + uint32_t preview; + uint8_t flags; +}; + +struct PathRailingsEntry +{ + rct_string_id string_idx; + uint32_t preview; + uint32_t bridge_image; + uint32_t railings_image; + uint8_t support_type; + uint8_t flags; + uint8_t scrolling_mode; +}; + // Masks for values stored in TileElement.type enum { @@ -170,7 +190,8 @@ int32_t footpath_is_connected_to_map_edge(int32_t x, int32_t y, int32_t z, int32 void footpath_remove_edges_at(int32_t x, int32_t y, TileElement* tileElement); int32_t entrance_get_directions(const TileElement* tileElement); -rct_footpath_entry* get_footpath_entry(int32_t entryIndex); +PathSurfaceEntry* get_path_surface_entry(int32_t entryIndex); +PathRailingsEntry* get_path_railings_entry(int32_t 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 990a7e75df..cf974c05a8 100644 --- a/src/openrct2/world/TileElement.h +++ b/src/openrct2/world/TileElement.h @@ -11,6 +11,7 @@ #include "../common.h" #include "../ride/RideTypes.h" +#include "Footpath.h" #include "Location.hpp" struct rct_scenery_entry; @@ -178,11 +179,11 @@ private: public: uint8_t GetPathEntryIndex() const; - rct_footpath_entry* GetPathEntry() const; + PathSurfaceEntry* GetPathEntry() const; void SetPathEntryIndex(uint8_t newIndex); uint8_t GetRailingEntryIndex() const; - rct_footpath_entry* GetRailingEntry() const; + PathRailingsEntry* GetRailingEntry() const; void SetRailingEntryIndex(uint8_t newIndex); uint8_t GetQueueBannerDirection() const;