From 019ed54a481be61c104c9688e45f4e18f9facd46 Mon Sep 17 00:00:00 2001 From: Artem Yanenko Date: Sat, 2 Jul 2022 16:02:27 +0200 Subject: [PATCH] Fix #17377: Park entrance can be placed without path in Scenario Editor --- distribution/changelog.txt | 1 + src/openrct2-ui/windows/Footpath.cpp | 136 --------------------------- src/openrct2-ui/windows/Map.cpp | 1 + src/openrct2/world/Footpath.cpp | 135 ++++++++++++++++++++++++++ src/openrct2/world/Footpath.h | 1 + 5 files changed, 138 insertions(+), 136 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index 4a8e485406..b3ff96f6b5 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -46,6 +46,7 @@ - Fix: [#17337] Air Powered Vertical Coaster trains not imported properly when loading RCT1 parks. - Fix: [#17346] Surface height markers are concealed by sprites of same surface. - Fix: [#17369] [Plugin] ‘Car.travelBy()’ moves other cars as well. +- Fix: [#17377] When building the park entrance before opening the Footpaths window, the path will be invisible. - Fix: [#17381] Air Powered Vertical Coaster stat penalty is wrong. - Fix: [#17433] Wrong T-shirt colours for guests on a Twist ride. - Fix: [#17450] Ducks can swim on three-corners-up land tile. diff --git a/src/openrct2-ui/windows/Footpath.cpp b/src/openrct2-ui/windows/Footpath.cpp index 2e7714b970..8eb02bad3b 100644 --- a/src/openrct2-ui/windows/Footpath.cpp +++ b/src/openrct2-ui/windows/Footpath.cpp @@ -184,7 +184,6 @@ static void WindowFootpathConstruct(); static void WindowFootpathRemove(); static void WindowFootpathSetEnabledAndPressedWidgets(); static void FootpathGetNextPathInfo(ObjectEntryIndex* type, CoordsXYZ& footpathLoc, int32_t* slope); -static bool FootpathSelectDefault(); /** * @@ -1367,141 +1366,6 @@ static void FootpathGetNextPathInfo(ObjectEntryIndex* type, CoordsXYZ& footpathL } } -static ObjectEntryIndex FootpathGetDefaultSurface(bool queue) -{ - bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode); - for (ObjectEntryIndex i = 0; i < MAX_FOOTPATH_SURFACE_OBJECTS; i++) - { - auto pathEntry = GetPathSurfaceEntry(i); - if (pathEntry != nullptr) - { - if (!showEditorPaths && (pathEntry->Flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR)) - { - continue; - } - if (queue == ((pathEntry->Flags & FOOTPATH_ENTRY_FLAG_IS_QUEUE) != 0)) - { - return i; - } - } - } - return OBJECT_ENTRY_INDEX_NULL; -} - -static ObjectEntryIndex FootpathGetDefaultRailings() -{ - for (ObjectEntryIndex i = 0; i < MAX_FOOTPATH_RAILINGS_OBJECTS; i++) - { - const auto* railingEntry = GetPathRailingsEntry(i); - if (railingEntry != nullptr) - { - return i; - } - } - return OBJECT_ENTRY_INDEX_NULL; -} - -static bool FootpathIsSurfaceEntryOkay(ObjectEntryIndex index, bool queue) -{ - auto pathEntry = GetPathSurfaceEntry(index); - if (pathEntry != nullptr) - { - bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode); - if (!showEditorPaths && (pathEntry->Flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR)) - { - return false; - } - if (queue == ((pathEntry->Flags & FOOTPATH_ENTRY_FLAG_IS_QUEUE) != 0)) - { - return true; - } - } - return false; -} - -static bool FootpathIsLegacyPathEntryOkay(ObjectEntryIndex index) -{ - bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode); - auto& objManager = OpenRCT2::GetContext()->GetObjectManager(); - auto footpathObj = static_cast(objManager.GetLoadedObject(ObjectType::Paths, index)); - if (footpathObj != nullptr) - { - auto pathEntry = reinterpret_cast(footpathObj->GetLegacyData()); - return showEditorPaths || !(pathEntry->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR); - } - return false; -} - -static ObjectEntryIndex FootpathGetDefaultLegacyPath() -{ - for (ObjectEntryIndex i = 0; i < MAX_PATH_OBJECTS; i++) - { - if (FootpathIsLegacyPathEntryOkay(i)) - { - return i; - } - } - return OBJECT_ENTRY_INDEX_NULL; -} - -static bool FootpathSelectDefault() -{ - // Select default footpath - auto surfaceIndex = FootpathGetDefaultSurface(false); - if (FootpathIsSurfaceEntryOkay(gFootpathSelection.NormalSurface, false)) - { - surfaceIndex = gFootpathSelection.NormalSurface; - } - - // Select default queue - auto queueIndex = FootpathGetDefaultSurface(true); - if (FootpathIsSurfaceEntryOkay(gFootpathSelection.QueueSurface, true)) - { - queueIndex = gFootpathSelection.QueueSurface; - } - - // Select default railing - auto railingIndex = FootpathGetDefaultRailings(); - const auto* railingEntry = GetPathRailingsEntry(gFootpathSelection.Railings); - if (railingEntry != nullptr) - { - railingIndex = gFootpathSelection.Railings; - } - - // Select default legacy path - auto legacyPathIndex = FootpathGetDefaultLegacyPath(); - if (gFootpathSelection.LegacyPath != OBJECT_ENTRY_INDEX_NULL) - { - if (FootpathIsLegacyPathEntryOkay(gFootpathSelection.LegacyPath)) - { - // Keep legacy path selected - legacyPathIndex = gFootpathSelection.LegacyPath; - } - else - { - // Reset legacy path, we default to a surface (if there are any) - gFootpathSelection.LegacyPath = OBJECT_ENTRY_INDEX_NULL; - } - } - - if (surfaceIndex == OBJECT_ENTRY_INDEX_NULL) - { - if (legacyPathIndex == OBJECT_ENTRY_INDEX_NULL) - { - // No surfaces or legacy paths available - return false; - } - - // No surfaces available, so default to legacy path - gFootpathSelection.LegacyPath = legacyPathIndex; - } - - gFootpathSelection.NormalSurface = surfaceIndex; - gFootpathSelection.QueueSurface = queueIndex; - gFootpathSelection.Railings = railingIndex; - return true; -} - static PathConstructFlags FootpathCreateConstructFlags(ObjectEntryIndex& type) { PathConstructFlags pathConstructFlags = 0; diff --git a/src/openrct2-ui/windows/Map.cpp b/src/openrct2-ui/windows/Map.cpp index c4d1dbcdb4..49eb151a09 100644 --- a/src/openrct2-ui/windows/Map.cpp +++ b/src/openrct2-ui/windows/Map.cpp @@ -159,6 +159,7 @@ public: InitMap(); gWindowSceneryRotation = 0; CentreMapOnViewPoint(); + FootpathSelectDefault(); // Reset land rights tool size _landRightsToolSize = 1; diff --git a/src/openrct2/world/Footpath.cpp b/src/openrct2/world/Footpath.cpp index 0c775a63fb..5b26d8b554 100644 --- a/src/openrct2/world/Footpath.cpp +++ b/src/openrct2/world/Footpath.cpp @@ -2353,6 +2353,141 @@ void footpath_remove_edges_at(const CoordsXY& footpathPos, TileElement* tileElem tileElement->AsPath()->SetEdgesAndCorners(0); } +static ObjectEntryIndex FootpathGetDefaultSurface(bool queue) +{ + bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode); + for (ObjectEntryIndex i = 0; i < MAX_FOOTPATH_SURFACE_OBJECTS; i++) + { + auto pathEntry = GetPathSurfaceEntry(i); + if (pathEntry != nullptr) + { + if (!showEditorPaths && (pathEntry->Flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR)) + { + continue; + } + if (queue == ((pathEntry->Flags & FOOTPATH_ENTRY_FLAG_IS_QUEUE) != 0)) + { + return i; + } + } + } + return OBJECT_ENTRY_INDEX_NULL; +} + +static bool FootpathIsSurfaceEntryOkay(ObjectEntryIndex index, bool queue) +{ + auto pathEntry = GetPathSurfaceEntry(index); + if (pathEntry != nullptr) + { + bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode); + if (!showEditorPaths && (pathEntry->Flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR)) + { + return false; + } + if (queue == ((pathEntry->Flags & FOOTPATH_ENTRY_FLAG_IS_QUEUE) != 0)) + { + return true; + } + } + return false; +} + +static ObjectEntryIndex FootpathGetDefaultRailings() +{ + for (ObjectEntryIndex i = 0; i < MAX_FOOTPATH_RAILINGS_OBJECTS; i++) + { + const auto* railingEntry = GetPathRailingsEntry(i); + if (railingEntry != nullptr) + { + return i; + } + } + return OBJECT_ENTRY_INDEX_NULL; +} + +static bool FootpathIsLegacyPathEntryOkay(ObjectEntryIndex index) +{ + bool showEditorPaths = ((gScreenFlags & SCREEN_FLAGS_SCENARIO_EDITOR) || gCheatsSandboxMode); + auto& objManager = OpenRCT2::GetContext()->GetObjectManager(); + auto footpathObj = static_cast(objManager.GetLoadedObject(ObjectType::Paths, index)); + if (footpathObj != nullptr) + { + auto pathEntry = reinterpret_cast(footpathObj->GetLegacyData()); + return showEditorPaths || !(pathEntry->flags & FOOTPATH_ENTRY_FLAG_SHOW_ONLY_IN_SCENARIO_EDITOR); + } + return false; +} + +static ObjectEntryIndex FootpathGetDefaultLegacyPath() +{ + for (ObjectEntryIndex i = 0; i < MAX_PATH_OBJECTS; i++) + { + if (FootpathIsLegacyPathEntryOkay(i)) + { + return i; + } + } + return OBJECT_ENTRY_INDEX_NULL; +} + +bool FootpathSelectDefault() +{ + // Select default footpath + auto surfaceIndex = FootpathGetDefaultSurface(false); + if (FootpathIsSurfaceEntryOkay(gFootpathSelection.NormalSurface, false)) + { + surfaceIndex = gFootpathSelection.NormalSurface; + } + + // Select default queue + auto queueIndex = FootpathGetDefaultSurface(true); + if (FootpathIsSurfaceEntryOkay(gFootpathSelection.QueueSurface, true)) + { + queueIndex = gFootpathSelection.QueueSurface; + } + + // Select default railing + auto railingIndex = FootpathGetDefaultRailings(); + const auto* railingEntry = GetPathRailingsEntry(gFootpathSelection.Railings); + if (railingEntry != nullptr) + { + railingIndex = gFootpathSelection.Railings; + } + + // Select default legacy path + auto legacyPathIndex = FootpathGetDefaultLegacyPath(); + if (gFootpathSelection.LegacyPath != OBJECT_ENTRY_INDEX_NULL) + { + if (FootpathIsLegacyPathEntryOkay(gFootpathSelection.LegacyPath)) + { + // Keep legacy path selected + legacyPathIndex = gFootpathSelection.LegacyPath; + } + else + { + // Reset legacy path, we default to a surface (if there are any) + gFootpathSelection.LegacyPath = OBJECT_ENTRY_INDEX_NULL; + } + } + + if (surfaceIndex == OBJECT_ENTRY_INDEX_NULL) + { + if (legacyPathIndex == OBJECT_ENTRY_INDEX_NULL) + { + // No surfaces or legacy paths available + return false; + } + + // No surfaces available, so default to legacy path + gFootpathSelection.LegacyPath = legacyPathIndex; + } + + gFootpathSelection.NormalSurface = surfaceIndex; + gFootpathSelection.QueueSurface = queueIndex; + gFootpathSelection.Railings = railingIndex; + return true; +} + const FootpathObject* GetLegacyFootpathEntry(ObjectEntryIndex entryIndex) { auto& objMgr = OpenRCT2::GetContext()->GetObjectManager(); diff --git a/src/openrct2/world/Footpath.h b/src/openrct2/world/Footpath.h index 5400b23ed5..a8f6732148 100644 --- a/src/openrct2/world/Footpath.h +++ b/src/openrct2/world/Footpath.h @@ -253,6 +253,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); +bool FootpathSelectDefault(); const FootpathObject* GetLegacyFootpathEntry(ObjectEntryIndex entryIndex); const FootpathSurfaceObject* GetPathSurfaceEntry(ObjectEntryIndex entryIndex); const FootpathRailingsObject* GetPathRailingsEntry(ObjectEntryIndex entryIndex);