From 56c4240d776d6f470269d95e7ac00e94ec2616e3 Mon Sep 17 00:00:00 2001 From: Duncan Date: Sat, 11 Dec 2021 16:03:59 +0000 Subject: [PATCH] Make Parkfile Pathfinding Deterministic (#16147) * Rename path find functions and use sub function * Modify leaving park logic to not use park entrance index * Remove ChosenParkEntrance from peep struct * Refactor GetNearestParkEntrance Removed the index as its pointless. Fixed function to use CoordsXY * Increment network version * Update replays --- CMakeLists.txt | 4 +- openrct2.proj | 4 +- src/openrct2/entity/Peep.h | 6 +-- src/openrct2/network/NetworkBase.cpp | 2 +- src/openrct2/peep/GuestPathfinding.cpp | 63 +++++++++++--------------- 5 files changed, 32 insertions(+), 47 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c88b53a36b..6f2345bbc6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,9 +65,9 @@ set(OBJECTS_VERSION "1.2.4") set(OBJECTS_URL "https://github.com/OpenRCT2/objects/releases/download/v${OBJECTS_VERSION}/objects.zip") set(OBJECTS_SHA1 "c82605035f120188b7334a781a786ced9588e9af") -set(REPLAYS_VERSION "0.0.60") +set(REPLAYS_VERSION "0.0.61") set(REPLAYS_URL "https://github.com/OpenRCT2/replays/releases/download/v${REPLAYS_VERSION}/replays.zip") -set(REPLAYS_SHA1 "1EB460BB3C71BD21CCBE778BEF1E8CD593241A18") +set(REPLAYS_SHA1 "18BFAD02A453CE0D5926C13A856546ED825AD0F1") option(FORCE32 "Force 32-bit build. It will add `-m32` to compiler flags.") option(WITH_TESTS "Build tests") diff --git a/openrct2.proj b/openrct2.proj index ac81e980a6..9cc44cc738 100644 --- a/openrct2.proj +++ b/openrct2.proj @@ -48,8 +48,8 @@ 304d13a126c15bf2c86ff13b81a2f2cc1856ac8d https://github.com/OpenRCT2/objects/releases/download/v1.2.4/objects.zip c82605035f120188b7334a781a786ced9588e9af - https://github.com/OpenRCT2/replays/releases/download/v0.0.60/replays.zip - 1EB460BB3C71BD21CCBE778BEF1E8CD593241A18 + https://github.com/OpenRCT2/replays/releases/download/v0.0.61/replays.zip + 18BFAD02A453CE0D5926C13A856546ED825AD0F1 diff --git a/src/openrct2/entity/Peep.h b/src/openrct2/entity/Peep.h index f87367aefe..7bbf1bcd87 100644 --- a/src/openrct2/entity/Peep.h +++ b/src/openrct2/entity/Peep.h @@ -331,11 +331,7 @@ struct Peep : EntityBase uint8_t EnergyTarget; uint8_t Mass; uint8_t WindowInvalidateFlags; - union - { - ride_id_t CurrentRide; - ParkEntranceIndex ChosenParkEntrance; - }; + ride_id_t CurrentRide; StationIndex CurrentRideStation; uint8_t CurrentTrain; union diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index d210eac02d..423d455d71 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -40,7 +40,7 @@ // This string specifies which version of network stream current build uses. // It is used for making sure only compatible builds get connected, even within // single OpenRCT2 version. -#define NETWORK_STREAM_VERSION "4" +#define NETWORK_STREAM_VERSION "5" #define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION static Peep* _pickup_peep = nullptr; diff --git a/src/openrct2/peep/GuestPathfinding.cpp b/src/openrct2/peep/GuestPathfinding.cpp index 682fa2d0e2..e3af1f5405 100644 --- a/src/openrct2/peep/GuestPathfinding.cpp +++ b/src/openrct2/peep/GuestPathfinding.cpp @@ -1631,20 +1631,18 @@ Direction peep_pathfind_choose_direction(const TileCoordsXYZ& loc, Peep* peep) * @param y y coordinate of location * @return Index of gParkEntrance (or 0xFF if no park entrances exist). */ -static uint8_t get_nearest_park_entrance_index(uint16_t x, uint16_t y) +static std::optional GetNearestParkEntrance(const CoordsXY& loc) { - uint8_t chosenEntrance = 0xFF; + std::optional chosenEntrance = std::nullopt; uint16_t nearestDist = 0xFFFF; - uint8_t i = 0; for (const auto& parkEntrance : gParkEntrances) { - auto dist = abs(parkEntrance.x - x) + abs(parkEntrance.y - y); + auto dist = abs(parkEntrance.x - loc.x) + abs(parkEntrance.y - loc.y); if (dist < nearestDist) { nearestDist = dist; - chosenEntrance = i; + chosenEntrance = parkEntrance; } - i++; } return chosenEntrance; } @@ -1653,16 +1651,16 @@ static uint8_t get_nearest_park_entrance_index(uint16_t x, uint16_t y) * * rct2: 0x006952C0 */ -static int32_t guest_path_find_entering_park(Peep* peep, uint8_t edges) +static int32_t GuestPathFindParkEntranceEntering(Peep* peep, uint8_t edges) { // Send peeps to the nearest park entrance. - uint8_t chosenEntrance = get_nearest_park_entrance_index(peep->NextLoc.x, peep->NextLoc.y); + auto chosenEntrance = GetNearestParkEntrance(peep->NextLoc); // If no defined park entrances are found, walk aimlessly. - if (chosenEntrance == 0xFF) + if (!chosenEntrance.has_value()) return guest_path_find_aimless(peep, edges); - gPeepPathFindGoalPosition = TileCoordsXYZ(gParkEntrances[chosenEntrance]); + gPeepPathFindGoalPosition = TileCoordsXYZ(chosenEntrance.value()); gPeepPathFindIgnoreForeignQueues = true; gPeepPathFindQueueRideIndex = RIDE_ID_NULL; @@ -1702,7 +1700,7 @@ static uint8_t get_nearest_peep_spawn_index(uint16_t x, uint16_t y) * * rct2: 0x0069536C */ -static int32_t guest_path_find_leaving_park(Peep* peep, uint8_t edges) +static int32_t GuestPathFindPeepSpawn(Peep* peep, uint8_t edges) { // Send peeps to the nearest spawn point. uint8_t chosenSpawn = get_nearest_peep_spawn_index(peep->NextLoc.x, peep->NextLoc.y); @@ -1733,41 +1731,32 @@ static int32_t guest_path_find_leaving_park(Peep* peep, uint8_t edges) * * rct2: 0x00695161 */ -static int32_t guest_path_find_park_entrance(Peep* peep, uint8_t edges) +static int32_t GuestPathFindParkEntranceLeaving(Peep* peep, uint8_t edges) { - // If entrance no longer exists, choose a new one - if ((peep->PeepFlags & PEEP_FLAGS_PARK_ENTRANCE_CHOSEN) && peep->ChosenParkEntrance.ToUnderlying() >= gParkEntrances.size()) + TileCoordsXYZ entranceGoal{}; + if (peep->PeepFlags & PEEP_FLAGS_PARK_ENTRANCE_CHOSEN) { - peep->ChosenParkEntrance = ParkEntranceIndex::GetNull(); - peep->PeepFlags &= ~(PEEP_FLAGS_PARK_ENTRANCE_CHOSEN); + entranceGoal = peep->PathfindGoal; + auto* entranceElement = map_get_park_entrance_element_at(entranceGoal.ToCoordsXYZ(), false); + // If entrance no longer exists, choose a new one + if (entranceElement == nullptr) + { + peep->PeepFlags &= ~(PEEP_FLAGS_PARK_ENTRANCE_CHOSEN); + } } if (!(peep->PeepFlags & PEEP_FLAGS_PARK_ENTRANCE_CHOSEN)) { - auto chosenEntrance = ParkEntranceIndex::GetNull(); - uint16_t nearestDist = 0xFFFF; - uint8_t entranceNum = 0; - for (const auto& entrance : gParkEntrances) - { - uint16_t dist = abs(entrance.x - peep->NextLoc.x) + abs(entrance.y - peep->NextLoc.y); - if (dist < nearestDist) - { - nearestDist = dist; - chosenEntrance = ParkEntranceIndex::FromUnderlying(entranceNum); - } - entranceNum++; - } + auto chosenEntrance = GetNearestParkEntrance(peep->NextLoc); - if (chosenEntrance.IsNull()) + if (!chosenEntrance.has_value()) return guest_path_find_aimless(peep, edges); - peep->ChosenParkEntrance = chosenEntrance; peep->PeepFlags |= PEEP_FLAGS_PARK_ENTRANCE_CHOSEN; + entranceGoal = TileCoordsXYZ(*chosenEntrance); } - const auto& entrance = gParkEntrances[peep->ChosenParkEntrance.ToUnderlying()]; - - gPeepPathFindGoalPosition = TileCoordsXYZ(entrance); + gPeepPathFindGoalPosition = entranceGoal; gPeepPathFindIgnoreForeignQueues = true; gPeepPathFindQueueRideIndex = RIDE_ID_NULL; @@ -2073,9 +2062,9 @@ int32_t guest_path_finding(Guest* peep) switch (peep->State) { case PeepState::EnteringPark: - return guest_path_find_entering_park(peep, edges); + return GuestPathFindParkEntranceEntering(peep, edges); case PeepState::LeavingPark: - return guest_path_find_leaving_park(peep, edges); + return GuestPathFindPeepSpawn(peep, edges); default: return guest_path_find_aimless(peep, edges); } @@ -2140,7 +2129,7 @@ int32_t guest_path_finding(Guest* peep) } PathfindLoggingDisable(); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - return guest_path_find_park_entrance(peep, edges); + return GuestPathFindParkEntranceLeaving(peep, edges); } if (peep->GuestHeadingToRideId == RIDE_ID_NULL)