mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2025-12-23 15:52:55 +01:00
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
This commit is contained in:
@@ -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")
|
||||
|
||||
@@ -48,8 +48,8 @@
|
||||
<TitleSequencesSha1>304d13a126c15bf2c86ff13b81a2f2cc1856ac8d</TitleSequencesSha1>
|
||||
<ObjectsUrl>https://github.com/OpenRCT2/objects/releases/download/v1.2.4/objects.zip</ObjectsUrl>
|
||||
<ObjectsSha1>c82605035f120188b7334a781a786ced9588e9af</ObjectsSha1>
|
||||
<ReplaysUrl>https://github.com/OpenRCT2/replays/releases/download/v0.0.60/replays.zip</ReplaysUrl>
|
||||
<ReplaysSha1>1EB460BB3C71BD21CCBE778BEF1E8CD593241A18</ReplaysSha1>
|
||||
<ReplaysUrl>https://github.com/OpenRCT2/replays/releases/download/v0.0.61/replays.zip</ReplaysUrl>
|
||||
<ReplaysSha1>18BFAD02A453CE0D5926C13A856546ED825AD0F1</ReplaysSha1>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<CoordsXYZ> GetNearestParkEntrance(const CoordsXY& loc)
|
||||
{
|
||||
uint8_t chosenEntrance = 0xFF;
|
||||
std::optional<CoordsXYZ> 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)
|
||||
|
||||
Reference in New Issue
Block a user