1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-15 11:03:00 +01:00

Refactor footpath placement functions

This commit is contained in:
Michael Steenbeek
2025-09-14 14:25:08 +02:00
committed by GitHub
parent 0e21f93359
commit 63a1c49db2
3 changed files with 70 additions and 75 deletions

View File

@@ -162,26 +162,6 @@ namespace OpenRCT2::Ui::Windows
#pragma endregion
/** rct2: 0x0098D8B4 */
static constexpr uint8_t DefaultPathSlope[] = {
0,
SLOPE_IS_IRREGULAR_FLAG,
SLOPE_IS_IRREGULAR_FLAG,
FOOTPATH_PROPERTIES_FLAG_IS_SLOPED | 2,
SLOPE_IS_IRREGULAR_FLAG,
SLOPE_IS_IRREGULAR_FLAG,
FOOTPATH_PROPERTIES_FLAG_IS_SLOPED | 3,
RAISE_FOOTPATH_FLAG,
SLOPE_IS_IRREGULAR_FLAG,
FOOTPATH_PROPERTIES_FLAG_IS_SLOPED | 1,
SLOPE_IS_IRREGULAR_FLAG,
RAISE_FOOTPATH_FLAG,
FOOTPATH_PROPERTIES_FLAG_IS_SLOPED | 0,
RAISE_FOOTPATH_FLAG,
RAISE_FOOTPATH_FLAG,
SLOPE_IS_IRREGULAR_FLAG,
};
/** rct2: 0x0098D7E0 */
static constexpr uint8_t ConstructionPreviewImages[][4] = {
{ 5, 10, 5, 10 }, // Flat
@@ -925,13 +905,13 @@ namespace OpenRCT2::Ui::Windows
return mapCoords.ToTileStart();
}
int32_t FootpathGetSlopeFromInfo(const InteractionInfo& info)
FootpathPlacementResult FootpathGetPlacementFromInfo(const InteractionInfo& info)
{
if (info.interactionType == ViewportInteractionItem::None || info.Element == nullptr)
{
gMapSelectFlags.unset(MapSelectFlag::enable);
FootpathUpdateProvisional();
return kTileSlopeFlat;
return {};
}
switch (info.interactionType)
@@ -941,7 +921,7 @@ namespace OpenRCT2::Ui::Windows
auto surfaceElement = info.Element->AsSurface();
if (surfaceElement != nullptr)
{
return DefaultPathSlope[surfaceElement->GetSlope() & kTileSlopeRaisedCornersMask];
return FootpathGetOnTerrainPlacement(*surfaceElement);
}
break;
}
@@ -955,7 +935,7 @@ namespace OpenRCT2::Ui::Windows
{
slope |= FOOTPATH_PROPERTIES_FLAG_IS_SLOPED;
}
return slope;
return { pathElement->GetBaseZ(), slope };
}
break;
}
@@ -963,41 +943,7 @@ namespace OpenRCT2::Ui::Windows
break;
}
return kTileSlopeFlat;
}
int32_t FootpathGetBaseZFromInfo(const InteractionInfo& info)
{
if (info.interactionType == ViewportInteractionItem::None || info.Element == nullptr)
{
return 0;
}
switch (info.interactionType)
{
case ViewportInteractionItem::Terrain:
{
auto surfaceElement = info.Element->AsSurface();
if (surfaceElement != nullptr)
{
return surfaceElement->GetBaseZ();
}
break;
}
case ViewportInteractionItem::Footpath:
{
auto pathElement = info.Element->AsPath();
if (pathElement != nullptr)
{
return pathElement->GetBaseZ();
}
break;
}
default:
break;
}
return 0;
return {};
}
/**
@@ -1038,20 +984,16 @@ namespace OpenRCT2::Ui::Windows
auto info = GetMapCoordinatesFromPos(
screenCoords, EnumsToFlags(ViewportInteractionItem::Terrain, ViewportInteractionItem::Footpath));
baseZ = FootpathGetBaseZFromInfo(info);
slope = FootpathGetSlopeFromInfo(info);
if (slope & RAISE_FOOTPATH_FLAG)
{
slope &= ~RAISE_FOOTPATH_FLAG;
baseZ += kPathHeightStep;
}
if (baseZ == 0)
auto result = FootpathGetPlacementFromInfo(info);
if (!result.isValid())
{
gMapSelectFlags.unset(MapSelectFlag::enable);
FootpathUpdateProvisional();
return;
}
baseZ = result.baseZ;
slope = result.slope;
}
// Set provisional path
@@ -1133,13 +1075,9 @@ namespace OpenRCT2::Ui::Windows
const auto info = GetMapCoordinatesFromPos(
screenCoords, EnumsToFlags(ViewportInteractionItem::Terrain, ViewportInteractionItem::Footpath));
slope = FootpathGetSlopeFromInfo(info);
baseZ = FootpathGetBaseZFromInfo(info);
if (slope & RAISE_FOOTPATH_FLAG)
{
slope &= ~RAISE_FOOTPATH_FLAG;
baseZ += kPathHeightStep;
}
auto result = FootpathGetPlacementFromInfo(info);
baseZ = result.baseZ;
slope = result.slope;
}
// Try and place path

View File

@@ -103,6 +103,26 @@ static constexpr uint8_t connected_path_count[] = {
4, // 0b1111
};
/** rct2: 0x0098D8B4 */
static constexpr uint8_t kDefaultPathSlope[] = {
0,
SLOPE_IS_IRREGULAR_FLAG,
SLOPE_IS_IRREGULAR_FLAG,
FOOTPATH_PROPERTIES_FLAG_IS_SLOPED | 2,
SLOPE_IS_IRREGULAR_FLAG,
SLOPE_IS_IRREGULAR_FLAG,
FOOTPATH_PROPERTIES_FLAG_IS_SLOPED | 3,
RAISE_FOOTPATH_FLAG,
SLOPE_IS_IRREGULAR_FLAG,
FOOTPATH_PROPERTIES_FLAG_IS_SLOPED | 1,
SLOPE_IS_IRREGULAR_FLAG,
RAISE_FOOTPATH_FLAG,
FOOTPATH_PROPERTIES_FLAG_IS_SLOPED | 0,
RAISE_FOOTPATH_FLAG,
RAISE_FOOTPATH_FLAG,
SLOPE_IS_IRREGULAR_FLAG,
};
static bool entrance_has_direction(const EntranceElement& entranceElement, int32_t direction)
{
return entranceElement.GetDirections() & (1 << (direction & 3));
@@ -2060,3 +2080,25 @@ bool FootpathIsZAndDirectionValid(const PathElement& pathElement, int32_t curren
}
return true;
}
FootpathPlacementResult FootpathGetOnTerrainPlacement(const TileCoordsXY& location)
{
auto* surfaceElement = MapGetSurfaceElementAt(location);
if (surfaceElement == nullptr)
return {};
return FootpathGetOnTerrainPlacement(*surfaceElement);
}
FootpathPlacementResult FootpathGetOnTerrainPlacement(const SurfaceElement& surfaceElement)
{
int32_t baseZ = surfaceElement.GetBaseZ();
uint8_t slope = kDefaultPathSlope[surfaceElement.GetSlope() & kTileSlopeRaisedCornersMask];
if (slope & RAISE_FOOTPATH_FLAG)
{
slope &= ~RAISE_FOOTPATH_FLAG;
baseZ += kPathHeightStep;
}
return { baseZ, slope };
}

View File

@@ -19,6 +19,7 @@ namespace OpenRCT2
class FootpathRailingsObject;
struct PathElement;
struct SurfaceElement;
struct TileElement;
} // namespace OpenRCT2
@@ -75,6 +76,17 @@ struct FootpathSelection
}
};
struct FootpathPlacementResult
{
int32_t baseZ{};
uint8_t slope{};
bool isValid()
{
return baseZ > 0;
}
};
enum
{
RAILING_ENTRY_FLAG_HAS_SUPPORT_BASE_SPRITE = (1 << 0),
@@ -157,3 +169,6 @@ const OpenRCT2::FootpathRailingsObject* GetPathRailingsEntry(OpenRCT2::ObjectEnt
void FootpathQueueChainReset();
void FootpathQueueChainPush(RideId rideIndex);
bool FootpathIsZAndDirectionValid(const OpenRCT2::PathElement& tileElement, int32_t currentZ, int32_t currentDirection);
FootpathPlacementResult FootpathGetOnTerrainPlacement(const TileCoordsXY& location);
FootpathPlacementResult FootpathGetOnTerrainPlacement(const OpenRCT2::SurfaceElement& surfaceElement);