diff --git a/CMakeLists.txt b/CMakeLists.txt
index fc8e92e457..37810899e0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -44,8 +44,8 @@ set(TITLE_SEQUENCE_SHA1 "304d13a126c15bf2c86ff13b81a2f2cc1856ac8d")
set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v1.0.18/objects.zip")
set(OBJECTS_SHA1 "4a3c32a0251c3babe014844f2c683fc32138b3f2")
-set(REPLAYS_URL "https://github.com/OpenRCT2/replays/releases/download/v0.0.21/replays.zip")
-set(REPLAYS_SHA1 "23BF9B52D2D0BDBAF7E2DE4F35ED53F6A416539D")
+set(REPLAYS_URL "https://github.com/OpenRCT2/replays/releases/download/v0.0.22/replays.zip")
+set(REPLAYS_SHA1 "7591db0a3842a7ac44fcbfbff9a573c9cb3ddc56")
option(FORCE32 "Force 32-bit build. It will add `-m32` to compiler flags.")
option(WITH_TESTS "Build tests")
diff --git a/distribution/changelog.txt b/distribution/changelog.txt
index a39f4f5f4f..65eef8d885 100644
--- a/distribution/changelog.txt
+++ b/distribution/changelog.txt
@@ -6,6 +6,7 @@
- Fix: [#12895] Mechanics are called to repair rides that have already been fixed.
- Fix: [#13334] Uninitialised variables in CustomTabDesc.
- Fix: [#13342] Rename tabChange to onTabChange in WindowDesc interface.
+- Fix: [#13409] Clamp peep distances from path centers.
- Improved: [#12917] Changed peep movement so that they stay more spread out over the full width of single tile paths.
- Removed: [#13423] Built-in explode guests cheat (replaced by plug-in).
diff --git a/openrct2.proj b/openrct2.proj
index 2b4478a78e..8ddc9c7e6a 100644
--- a/openrct2.proj
+++ b/openrct2.proj
@@ -48,8 +48,8 @@
304d13a126c15bf2c86ff13b81a2f2cc1856ac8d
https://github.com/OpenRCT2/objects/releases/download/v1.0.18/objects.zip
4a3c32a0251c3babe014844f2c683fc32138b3f2
- https://github.com/OpenRCT2/replays/releases/download/v0.0.21/replays.zip
- 23BF9B52D2D0BDBAF7E2DE4F35ED53F6A416539D
+ https://github.com/OpenRCT2/replays/releases/download/v0.0.22/replays.zip
+ 7591db0a3842a7ac44fcbfbff9a573c9cb3ddc56
diff --git a/src/openrct2/peep/GuestPathfinding.cpp b/src/openrct2/peep/GuestPathfinding.cpp
index dc1ba42c82..38301308cc 100644
--- a/src/openrct2/peep/GuestPathfinding.cpp
+++ b/src/openrct2/peep/GuestPathfinding.cpp
@@ -148,18 +148,27 @@ static int32_t peep_move_one_tile(Direction direction, Peep* peep)
//
// What we want instead is to apply that randomness in the direction they are walking ONLY, and keep their
// other coordinate constant.
+ //
+ // However, we have also seen some situations where guests end up too far from the center of paths. We've
+ // not identified exactly what causes this yet, but to limit the impact of it, we don't just keep the other
+ // coordinate constant, but instead clamp it to an acceptable range. This brings in 'outlier' guests from
+ // the edges of the path, while allowing guests who are already in an acceptable position to stay there.
int8_t offset = (scenario_rand() & 7) - 3;
if (direction == 0 || direction == 2)
{
- // Peep is moving along X, so apply the offset to the X position of the destination and keep their current Y
+ // Peep is moving along X, so apply the offset to the X position of the destination and clamp their current Y
peep->DestinationX += offset;
- peep->DestinationY = peep->y;
+ const uint16_t centerLine = (peep->y & 0xFFE0) + COORDS_XY_HALF_TILE;
+ peep->DestinationY = std::clamp(
+ peep->y, static_cast(centerLine - 3), static_cast(centerLine + 3));
}
else
{
- // Peep is moving along Y, so apply the offset to the Y position of the destination and keep their current X
- peep->DestinationX = peep->x;
+ // Peep is moving along Y, so apply the offset to the Y position of the destination and clamp their current X
+ const uint16_t centerLine = (peep->x & 0xFFE0) + COORDS_XY_HALF_TILE;
+ peep->DestinationX = std::clamp(
+ peep->x, static_cast(centerLine - 3), static_cast(centerLine + 3));
peep->DestinationY += offset;
}
}