mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-27 00:34:46 +01:00
Implement requested changes
- Change the GuestPathfinder object to a smart pointer - Improved function signatures - Added javadoc comments to the abstract base class - Converted pointers to references in pathfinding function calls
This commit is contained in:
@@ -43,7 +43,7 @@ static bool _pathFindDebug = false;
|
||||
static utf8 _pathFindDebugPeepName[256];
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
|
||||
static int32_t guest_surface_path_finding(Peep* peep);
|
||||
static int32_t guest_surface_path_finding(Peep& peep);
|
||||
|
||||
/* A junction history for the peep pathfinding heuristic search
|
||||
* The magic number 16 is the largest value returned by
|
||||
@@ -124,10 +124,10 @@ static int32_t path_get_permitted_edges(PathElement* pathElement)
|
||||
*
|
||||
* rct2: 0x0069524E
|
||||
*/
|
||||
static int32_t peep_move_one_tile(Direction direction, Peep* peep)
|
||||
static int32_t peep_move_one_tile(Direction direction, Peep& peep)
|
||||
{
|
||||
assert(direction_valid(direction));
|
||||
auto newTile = CoordsXY{ CoordsXY{ peep->NextLoc } + CoordsDirectionDelta[direction] }.ToTileCentre();
|
||||
auto newTile = CoordsXY{ CoordsXY{ peep.NextLoc } + CoordsDirectionDelta[direction] }.ToTileCentre();
|
||||
|
||||
if (newTile.x >= MAXIMUM_MAP_SIZE_BIG || newTile.y >= MAXIMUM_MAP_SIZE_BIG)
|
||||
{
|
||||
@@ -135,8 +135,8 @@ static int32_t peep_move_one_tile(Direction direction, Peep* peep)
|
||||
return guest_surface_path_finding(peep);
|
||||
}
|
||||
|
||||
peep->PeepDirection = direction;
|
||||
if (peep->State != PeepState::Queuing)
|
||||
peep.PeepDirection = direction;
|
||||
if (peep.State != PeepState::Queuing)
|
||||
{
|
||||
// When peeps are walking along a path, we would like them to be spread out across the width of the path,
|
||||
// instead of all walking along the exact centre line of the path.
|
||||
@@ -159,19 +159,19 @@ static int32_t peep_move_one_tile(Direction direction, Peep* peep)
|
||||
if (direction == 0 || direction == 2)
|
||||
{
|
||||
// Peep is moving along X, so apply the offset to the X position of the destination and clamp their current Y
|
||||
const int32_t centreLine = (peep->y & 0xFFE0) + COORDS_XY_HALF_TILE;
|
||||
const int32_t centreLine = (peep.y & 0xFFE0) + COORDS_XY_HALF_TILE;
|
||||
newTile.x += offset;
|
||||
newTile.y = std::clamp<int32_t>(peep->y, centreLine - 3, centreLine + 3);
|
||||
newTile.y = std::clamp<int32_t>(peep.y, centreLine - 3, centreLine + 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Peep is moving along Y, so apply the offset to the Y position of the destination and clamp their current X
|
||||
const int32_t centreLine = (peep->x & 0xFFE0) + COORDS_XY_HALF_TILE;
|
||||
newTile.x = std::clamp<int32_t>(peep->x, centreLine - 3, centreLine + 3);
|
||||
const int32_t centreLine = (peep.x & 0xFFE0) + COORDS_XY_HALF_TILE;
|
||||
newTile.x = std::clamp<int32_t>(peep.x, centreLine - 3, centreLine + 3);
|
||||
newTile.y += offset;
|
||||
}
|
||||
}
|
||||
peep->SetDestination(newTile, 2);
|
||||
peep.SetDestination(newTile, 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -180,9 +180,9 @@ static int32_t peep_move_one_tile(Direction direction, Peep* peep)
|
||||
*
|
||||
* rct2: 0x00694C41
|
||||
*/
|
||||
static int32_t guest_surface_path_finding(Peep* peep)
|
||||
static int32_t guest_surface_path_finding(Peep& peep)
|
||||
{
|
||||
auto pathPos = CoordsXYRangedZ{ peep->NextLoc, peep->NextLoc.z, peep->NextLoc.z + PATH_CLEARANCE };
|
||||
auto pathPos = CoordsXYRangedZ{ peep.NextLoc, peep.NextLoc.z, peep.NextLoc.z + PATH_CLEARANCE };
|
||||
Direction randDirection = scenario_rand() & 3;
|
||||
|
||||
if (!fence_in_the_way(pathPos, randDirection))
|
||||
@@ -208,8 +208,8 @@ static int32_t guest_surface_path_finding(Peep* peep)
|
||||
}
|
||||
randDirection &= 3;
|
||||
|
||||
pathPos.x = peep->NextLoc.x;
|
||||
pathPos.y = peep->NextLoc.y;
|
||||
pathPos.x = peep.NextLoc.x;
|
||||
pathPos.y = peep.NextLoc.y;
|
||||
if (!fence_in_the_way(pathPos, randDirection))
|
||||
{
|
||||
pathPos.x += CoordsDirectionDelta[randDirection].x;
|
||||
@@ -228,8 +228,8 @@ static int32_t guest_surface_path_finding(Peep* peep)
|
||||
randDirection -= 2;
|
||||
randDirection &= 3;
|
||||
|
||||
pathPos.x = peep->NextLoc.x;
|
||||
pathPos.y = peep->NextLoc.y;
|
||||
pathPos.x = peep.NextLoc.x;
|
||||
pathPos.y = peep.NextLoc.y;
|
||||
if (!fence_in_the_way(pathPos, randDirection))
|
||||
{
|
||||
pathPos.x += CoordsDirectionDelta[randDirection].x;
|
||||
@@ -460,14 +460,14 @@ static uint8_t footpath_element_destination_in_direction(
|
||||
*
|
||||
* rct2: 0x00695225
|
||||
*/
|
||||
static int32_t guest_path_find_aimless(Peep* peep, uint8_t edges)
|
||||
static int32_t guest_path_find_aimless(Peep& peep, uint8_t edges)
|
||||
{
|
||||
if (scenario_rand() & 1)
|
||||
{
|
||||
// If possible go straight
|
||||
if (edges & (1 << peep->PeepDirection))
|
||||
if (edges & (1 << peep.PeepDirection))
|
||||
{
|
||||
return peep_move_one_tile(peep->PeepDirection, peep);
|
||||
return peep_move_one_tile(peep.PeepDirection, peep);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -486,21 +486,21 @@ static int32_t guest_path_find_aimless(Peep* peep, uint8_t edges)
|
||||
*
|
||||
* rct2: 0x0069A60A
|
||||
*/
|
||||
static uint8_t peep_pathfind_get_max_number_junctions(Peep* peep)
|
||||
static uint8_t peep_pathfind_get_max_number_junctions(Peep& peep)
|
||||
{
|
||||
if (peep->Is<Staff>())
|
||||
if (peep.Is<Staff>())
|
||||
return 8;
|
||||
|
||||
// PEEP_FLAGS_2? It's cleared here but not set anywhere!
|
||||
if ((peep->PeepFlags & PEEP_FLAGS_2))
|
||||
if ((peep.PeepFlags & PEEP_FLAGS_2))
|
||||
{
|
||||
if ((scenario_rand() & 0xFFFF) <= 7281)
|
||||
peep->PeepFlags &= ~PEEP_FLAGS_2;
|
||||
peep.PeepFlags &= ~PEEP_FLAGS_2;
|
||||
|
||||
return 8;
|
||||
}
|
||||
|
||||
auto* guest = peep->As<Guest>();
|
||||
auto* guest = peep.As<Guest>();
|
||||
if (guest == nullptr)
|
||||
return 8;
|
||||
|
||||
@@ -687,7 +687,7 @@ static constexpr const char* pathSearchToString(uint8_t pathFindSearchResult)
|
||||
* rct2: 0x0069A997
|
||||
*/
|
||||
static void peep_pathfind_heuristic_search(
|
||||
TileCoordsXYZ loc, Peep* peep, TileElement* currentTileElement, bool inPatrolArea, uint8_t counter, uint16_t* endScore,
|
||||
TileCoordsXYZ loc, Peep& peep, TileElement* currentTileElement, bool inPatrolArea, uint8_t counter, uint16_t* endScore,
|
||||
Direction test_edge, uint8_t* endJunctions, TileCoordsXYZ junctionList[16], uint8_t directionList[16],
|
||||
TileCoordsXYZ* endXYZ, uint8_t* endSteps)
|
||||
{
|
||||
@@ -696,7 +696,7 @@ static void peep_pathfind_heuristic_search(
|
||||
bool currentElementIsWide = currentTileElement->AsPath()->IsWide();
|
||||
if (currentElementIsWide)
|
||||
{
|
||||
const Staff* staff = peep->As<Staff>();
|
||||
const Staff* staff = peep.As<Staff>();
|
||||
if (staff != nullptr && staff->CanIgnoreWideFlag(loc.ToCoordsXYZ(), currentTileElement))
|
||||
currentElementIsWide = false;
|
||||
}
|
||||
@@ -721,7 +721,7 @@ static void peep_pathfind_heuristic_search(
|
||||
}
|
||||
|
||||
bool nextInPatrolArea = inPatrolArea;
|
||||
auto* staff = peep->As<Staff>();
|
||||
auto* staff = peep.As<Staff>();
|
||||
if (staff != nullptr && staff->IsMechanic())
|
||||
{
|
||||
nextInPatrolArea = staff->IsLocationInPatrol(loc.ToCoordsXY());
|
||||
@@ -1075,14 +1075,14 @@ static void peep_pathfind_heuristic_search(
|
||||
/* First check if going through the junction would be
|
||||
* a loop. If so, the current search path ends here.
|
||||
* Path finding loop detection can take advantage of both the
|
||||
* peep->PathfindHistory - loops through remembered junctions
|
||||
* peep.PathfindHistory - loops through remembered junctions
|
||||
* the peep has already passed through getting to its
|
||||
* current position while on the way to its current goal;
|
||||
* _peepPathFindHistory - loops in the current search path. */
|
||||
bool pathLoop = false;
|
||||
/* Check the peep->PathfindHistory to see if this junction has
|
||||
/* Check the peep.PathfindHistory to see if this junction has
|
||||
* already been visited by the peep while heading for this goal. */
|
||||
for (auto& pathfindHistory : peep->PathfindHistory)
|
||||
for (auto& pathfindHistory : peep.PathfindHistory)
|
||||
{
|
||||
if (pathfindHistory == loc)
|
||||
{
|
||||
@@ -1261,7 +1261,7 @@ static void peep_pathfind_heuristic_search(
|
||||
*
|
||||
* rct2: 0x0069A5F0
|
||||
*/
|
||||
Direction OriginalPathfinding::peep_pathfind_choose_direction(const TileCoordsXYZ& loc, Peep* peep)
|
||||
Direction OriginalPathfinding::ChooseDirection(const TileCoordsXYZ& loc, Peep& peep)
|
||||
{
|
||||
PROFILED_FUNCTION();
|
||||
|
||||
@@ -1270,9 +1270,9 @@ Direction OriginalPathfinding::peep_pathfind_choose_direction(const TileCoordsXY
|
||||
|
||||
/* The max number of tiles to check - a whole-search limit.
|
||||
* Mainly to limit the performance impact of the path finding. */
|
||||
int32_t maxTilesChecked = (peep->Is<Staff>()) ? 50000 : 15000;
|
||||
int32_t maxTilesChecked = (peep.Is<Staff>()) ? 50000 : 15000;
|
||||
// Used to allow walking through no entry banners
|
||||
_peepPathFindIsStaff = peep->Is<Staff>();
|
||||
_peepPathFindIsStaff = peep.Is<Staff>();
|
||||
|
||||
TileCoordsXYZ goal = gPeepPathFindGoalPosition;
|
||||
|
||||
@@ -1322,7 +1322,7 @@ Direction OriginalPathfinding::peep_pathfind_choose_direction(const TileCoordsXY
|
||||
}
|
||||
|
||||
/* Check if this path element is a thin junction.
|
||||
* Only 'thin' junctions are remembered in peep->PathfindHistory.
|
||||
* Only 'thin' junctions are remembered in peep.PathfindHistory.
|
||||
* NO attempt is made to merge the overlaid path elements and
|
||||
* check if the combination is 'thin'!
|
||||
* The junction is considered 'thin' simply if any of the
|
||||
@@ -1338,9 +1338,9 @@ Direction OriginalPathfinding::peep_pathfind_choose_direction(const TileCoordsXY
|
||||
|
||||
permitted_edges &= 0xF;
|
||||
uint8_t edges = permitted_edges;
|
||||
if (isThin && peep->PathfindGoal == goal)
|
||||
if (isThin && peep.PathfindGoal == goal)
|
||||
{
|
||||
/* Use of peep->PathfindHistory[]:
|
||||
/* Use of peep.PathfindHistory[]:
|
||||
* When walking to a goal, the peep PathfindHistory stores
|
||||
* the last 4 thin junctions that the peep walked through.
|
||||
* For each of these 4 thin junctions the peep remembers
|
||||
@@ -1355,7 +1355,7 @@ Direction OriginalPathfinding::peep_pathfind_choose_direction(const TileCoordsXY
|
||||
/* If the peep remembers walking through this junction
|
||||
* previously while heading for its goal, retrieve the
|
||||
* directions it has not yet tried. */
|
||||
for (auto& pathfindHistory : peep->PathfindHistory)
|
||||
for (auto& pathfindHistory : peep.PathfindHistory)
|
||||
{
|
||||
if (pathfindHistory == loc)
|
||||
{
|
||||
@@ -1405,15 +1405,15 @@ Direction OriginalPathfinding::peep_pathfind_choose_direction(const TileCoordsXY
|
||||
|
||||
/* If this is a new goal for the peep. Store it and reset the peep's
|
||||
* PathfindHistory. */
|
||||
if (!direction_valid(peep->PathfindGoal.direction) || peep->PathfindGoal != goal)
|
||||
if (!direction_valid(peep.PathfindGoal.direction) || peep.PathfindGoal != goal)
|
||||
{
|
||||
peep->PathfindGoal = { goal, 0 };
|
||||
peep.PathfindGoal = { goal, 0 };
|
||||
|
||||
// Clear pathfinding history
|
||||
TileCoordsXYZD nullPos;
|
||||
nullPos.SetNull();
|
||||
|
||||
std::fill(std::begin(peep->PathfindHistory), std::end(peep->PathfindHistory), nullPos);
|
||||
std::fill(std::begin(peep.PathfindHistory), std::end(peep.PathfindHistory), nullPos);
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (_pathFindDebug)
|
||||
{
|
||||
@@ -1504,13 +1504,13 @@ Direction OriginalPathfinding::peep_pathfind_choose_direction(const TileCoordsXY
|
||||
uint8_t endDirectionList[16] = { 0 };
|
||||
|
||||
bool inPatrolArea = false;
|
||||
auto* staff = peep->As<Staff>();
|
||||
auto* staff = peep.As<Staff>();
|
||||
if (staff != nullptr && staff->IsMechanic())
|
||||
{
|
||||
/* Mechanics are the only staff type that
|
||||
* pathfind to a destination. Determine if the
|
||||
* mechanic is in their patrol area. */
|
||||
inPatrolArea = staff->IsLocationInPatrol(peep->NextLoc);
|
||||
inPatrolArea = staff->IsLocationInPatrol(peep.NextLoc);
|
||||
}
|
||||
|
||||
#if defined(DEBUG_LEVEL_2) && DEBUG_LEVEL_2
|
||||
@@ -1592,20 +1592,20 @@ Direction OriginalPathfinding::peep_pathfind_choose_direction(const TileCoordsXY
|
||||
{
|
||||
for (int32_t i = 0; i < 4; ++i)
|
||||
{
|
||||
if (peep->PathfindHistory[i] == loc)
|
||||
if (peep.PathfindHistory[i] == loc)
|
||||
{
|
||||
/* Peep remembers this junction, so remove the
|
||||
* chosen_edge from those left to try. */
|
||||
peep->PathfindHistory[i].direction &= ~(1 << chosen_edge);
|
||||
peep.PathfindHistory[i].direction &= ~(1 << chosen_edge);
|
||||
/* Also remove the edge through which the peep
|
||||
* entered the junction from those left to try. */
|
||||
peep->PathfindHistory[i].direction &= ~(1 << direction_reverse(peep->PeepDirection));
|
||||
peep.PathfindHistory[i].direction &= ~(1 << direction_reverse(peep.PeepDirection));
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (_pathFindDebug)
|
||||
{
|
||||
log_verbose(
|
||||
"Updating existing pf_history (in index: %d) for %d,%d,%d without entry edge %d & exit edge %d.", i,
|
||||
loc.x, loc.y, loc.z, direction_reverse(peep->PeepDirection), chosen_edge);
|
||||
loc.x, loc.y, loc.z, direction_reverse(peep.PeepDirection), chosen_edge);
|
||||
}
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
return chosen_edge;
|
||||
@@ -1614,20 +1614,20 @@ Direction OriginalPathfinding::peep_pathfind_choose_direction(const TileCoordsXY
|
||||
|
||||
/* Peep does not remember this junction, so forget a junction
|
||||
* and remember this junction. */
|
||||
int32_t i = peep->PathfindGoal.direction++;
|
||||
peep->PathfindGoal.direction &= 3;
|
||||
peep->PathfindHistory[i] = { loc, permitted_edges };
|
||||
int32_t i = peep.PathfindGoal.direction++;
|
||||
peep.PathfindGoal.direction &= 3;
|
||||
peep.PathfindHistory[i] = { loc, permitted_edges };
|
||||
/* Remove the chosen_edge from those left to try. */
|
||||
peep->PathfindHistory[i].direction &= ~(1 << chosen_edge);
|
||||
peep.PathfindHistory[i].direction &= ~(1 << chosen_edge);
|
||||
/* Also remove the edge through which the peep
|
||||
* entered the junction from those left to try. */
|
||||
peep->PathfindHistory[i].direction &= ~(1 << direction_reverse(peep->PeepDirection));
|
||||
peep.PathfindHistory[i].direction &= ~(1 << direction_reverse(peep.PeepDirection));
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (_pathFindDebug)
|
||||
{
|
||||
log_verbose(
|
||||
"Storing new pf_history (in index: %d) for %d,%d,%d without entry edge %d & exit edge %d.", i, loc.x, loc.y,
|
||||
loc.z, direction_reverse(peep->PeepDirection), chosen_edge);
|
||||
loc.z, direction_reverse(peep.PeepDirection), chosen_edge);
|
||||
}
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
}
|
||||
@@ -1661,10 +1661,10 @@ static std::optional<CoordsXYZ> GetNearestParkEntrance(const CoordsXY& loc)
|
||||
*
|
||||
* rct2: 0x006952C0
|
||||
*/
|
||||
int32_t OriginalPathfinding::GuestPathFindParkEntranceEntering(Peep* peep, uint8_t edges)
|
||||
int32_t OriginalPathfinding::GuestPathFindParkEntranceEntering(Peep& peep, uint8_t edges)
|
||||
{
|
||||
// Send peeps to the nearest park entrance.
|
||||
auto chosenEntrance = GetNearestParkEntrance(peep->NextLoc);
|
||||
auto chosenEntrance = GetNearestParkEntrance(peep.NextLoc);
|
||||
|
||||
// If no defined park entrances are found, walk aimlessly.
|
||||
if (!chosenEntrance.has_value())
|
||||
@@ -1674,7 +1674,7 @@ int32_t OriginalPathfinding::GuestPathFindParkEntranceEntering(Peep* peep, uint8
|
||||
gPeepPathFindIgnoreForeignQueues = true;
|
||||
gPeepPathFindQueueRideIndex = RideId::GetNull();
|
||||
|
||||
Direction chosenDirection = peep_pathfind_choose_direction(TileCoordsXYZ{ peep->NextLoc }, peep);
|
||||
Direction chosenDirection = ChooseDirection(TileCoordsXYZ{ peep.NextLoc }, peep);
|
||||
|
||||
if (chosenDirection == INVALID_DIRECTION)
|
||||
return guest_path_find_aimless(peep, edges);
|
||||
@@ -1710,10 +1710,10 @@ static uint8_t get_nearest_peep_spawn_index(uint16_t x, uint16_t y)
|
||||
*
|
||||
* rct2: 0x0069536C
|
||||
*/
|
||||
int32_t OriginalPathfinding::GuestPathFindPeepSpawn(Peep* peep, uint8_t edges)
|
||||
int32_t OriginalPathfinding::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);
|
||||
uint8_t chosenSpawn = get_nearest_peep_spawn_index(peep.NextLoc.x, peep.NextLoc.y);
|
||||
|
||||
// If no defined spawns were found, walk aimlessly.
|
||||
if (chosenSpawn == 0xFF)
|
||||
@@ -1723,14 +1723,14 @@ int32_t OriginalPathfinding::GuestPathFindPeepSpawn(Peep* peep, uint8_t edges)
|
||||
Direction direction = peepSpawnLoc.direction;
|
||||
|
||||
gPeepPathFindGoalPosition = TileCoordsXYZ(peepSpawnLoc);
|
||||
if (peepSpawnLoc.x == peep->NextLoc.x && peepSpawnLoc.y == peep->NextLoc.y)
|
||||
if (peepSpawnLoc.x == peep.NextLoc.x && peepSpawnLoc.y == peep.NextLoc.y)
|
||||
{
|
||||
return peep_move_one_tile(direction, peep);
|
||||
}
|
||||
|
||||
gPeepPathFindIgnoreForeignQueues = true;
|
||||
gPeepPathFindQueueRideIndex = RideId::GetNull();
|
||||
direction = peep_pathfind_choose_direction(TileCoordsXYZ{ peep->NextLoc }, peep);
|
||||
direction = ChooseDirection(TileCoordsXYZ{ peep.NextLoc }, peep);
|
||||
if (direction == INVALID_DIRECTION)
|
||||
return guest_path_find_aimless(peep, edges);
|
||||
|
||||
@@ -1741,28 +1741,28 @@ int32_t OriginalPathfinding::GuestPathFindPeepSpawn(Peep* peep, uint8_t edges)
|
||||
*
|
||||
* rct2: 0x00695161
|
||||
*/
|
||||
int32_t OriginalPathfinding::GuestPathFindParkEntranceLeaving(Peep* peep, uint8_t edges)
|
||||
int32_t OriginalPathfinding::GuestPathFindParkEntranceLeaving(Peep& peep, uint8_t edges)
|
||||
{
|
||||
TileCoordsXYZ entranceGoal{};
|
||||
if (peep->PeepFlags & PEEP_FLAGS_PARK_ENTRANCE_CHOSEN)
|
||||
if (peep.PeepFlags & PEEP_FLAGS_PARK_ENTRANCE_CHOSEN)
|
||||
{
|
||||
entranceGoal = peep->PathfindGoal;
|
||||
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);
|
||||
peep.PeepFlags &= ~(PEEP_FLAGS_PARK_ENTRANCE_CHOSEN);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(peep->PeepFlags & PEEP_FLAGS_PARK_ENTRANCE_CHOSEN))
|
||||
if (!(peep.PeepFlags & PEEP_FLAGS_PARK_ENTRANCE_CHOSEN))
|
||||
{
|
||||
auto chosenEntrance = GetNearestParkEntrance(peep->NextLoc);
|
||||
auto chosenEntrance = GetNearestParkEntrance(peep.NextLoc);
|
||||
|
||||
if (!chosenEntrance.has_value())
|
||||
return guest_path_find_aimless(peep, edges);
|
||||
|
||||
peep->PeepFlags |= PEEP_FLAGS_PARK_ENTRANCE_CHOSEN;
|
||||
peep.PeepFlags |= PEEP_FLAGS_PARK_ENTRANCE_CHOSEN;
|
||||
entranceGoal = TileCoordsXYZ(*chosenEntrance);
|
||||
}
|
||||
|
||||
@@ -1774,7 +1774,7 @@ int32_t OriginalPathfinding::GuestPathFindParkEntranceLeaving(Peep* peep, uint8_
|
||||
PathfindLoggingEnable(peep);
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
|
||||
Direction chosenDirection = peep_pathfind_choose_direction(TileCoordsXYZ{ peep->NextLoc }, peep);
|
||||
Direction chosenDirection = ChooseDirection(TileCoordsXYZ{ peep.NextLoc }, peep);
|
||||
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
PathfindLoggingDisable();
|
||||
@@ -1942,9 +1942,9 @@ static void get_ride_queue_end(TileCoordsXYZ& loc)
|
||||
* appropriate.
|
||||
*/
|
||||
static StationIndex guest_pathfinding_select_random_station(
|
||||
const Guest* guest, int32_t numEntranceStations, BitSet<OpenRCT2::Limits::MaxStationsPerRide>& entranceStations)
|
||||
const Guest& guest, int32_t numEntranceStations, BitSet<OpenRCT2::Limits::MaxStationsPerRide>& entranceStations)
|
||||
{
|
||||
int32_t select = guest->GuestNumRides % numEntranceStations;
|
||||
int32_t select = guest.GuestNumRides % numEntranceStations;
|
||||
while (select > 0)
|
||||
{
|
||||
for (StationIndex::UnderlyingType i = 0; i < OpenRCT2::Limits::MaxStationsPerRide; i++)
|
||||
@@ -1971,22 +1971,22 @@ static StationIndex guest_pathfinding_select_random_station(
|
||||
*
|
||||
* rct2: 0x00694C35
|
||||
*/
|
||||
int32_t OriginalPathfinding::guest_path_finding(Guest* peep)
|
||||
int32_t OriginalPathfinding::CalculateNextDestination(Guest& peep)
|
||||
{
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
PathfindLoggingEnable(peep);
|
||||
if (_pathFindDebug)
|
||||
{
|
||||
log_info("Starting guest_path_finding for %s", _pathFindDebugPeepName);
|
||||
log_info("Starting CalculateNextDestination for %s", _pathFindDebugPeepName);
|
||||
}
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
|
||||
if (peep->GetNextIsSurface())
|
||||
if (peep.GetNextIsSurface())
|
||||
{
|
||||
return guest_surface_path_finding(peep);
|
||||
}
|
||||
|
||||
TileCoordsXYZ loc{ peep->NextLoc };
|
||||
TileCoordsXYZ loc{ peep.NextLoc };
|
||||
|
||||
auto* pathElement = map_get_path_element_at(loc);
|
||||
if (pathElement == nullptr)
|
||||
@@ -2002,7 +2002,7 @@ int32_t OriginalPathfinding::guest_path_finding(Guest* peep)
|
||||
return guest_surface_path_finding(peep);
|
||||
}
|
||||
|
||||
if (!peep->OutsideOfPark && peep->HeadingForRideOrParkExit())
|
||||
if (!peep.OutsideOfPark && peep.HeadingForRideOrParkExit())
|
||||
{
|
||||
/* If this tileElement is adjacent to any non-wide paths,
|
||||
* remove all of the edges to wide paths. */
|
||||
@@ -2024,14 +2024,14 @@ int32_t OriginalPathfinding::guest_path_finding(Guest* peep)
|
||||
edges = adjustedEdges;
|
||||
}
|
||||
|
||||
int32_t direction = direction_reverse(peep->PeepDirection);
|
||||
int32_t direction = direction_reverse(peep.PeepDirection);
|
||||
// Check if in a dead end (i.e. only edge is where the peep came from)
|
||||
if (!(edges & ~(1 << direction)))
|
||||
{
|
||||
// In a dead end. Check if peep is lost, etc.
|
||||
peep->CheckIfLost();
|
||||
peep->CheckCantFindRide();
|
||||
peep->CheckCantFindExit();
|
||||
peep.CheckIfLost();
|
||||
peep.CheckCantFindRide();
|
||||
peep.CheckCantFindExit();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2048,7 +2048,7 @@ int32_t OriginalPathfinding::guest_path_finding(Guest* peep)
|
||||
if (_pathFindDebug)
|
||||
{
|
||||
log_info(
|
||||
"Completed guest_path_finding for %s - taking only direction available: %d.", _pathFindDebugPeepName,
|
||||
"Completed CalculateNextDestination for %s - taking only direction available: %d.", _pathFindDebugPeepName,
|
||||
direction);
|
||||
}
|
||||
PathfindLoggingDisable();
|
||||
@@ -2060,16 +2060,16 @@ int32_t OriginalPathfinding::guest_path_finding(Guest* peep)
|
||||
|
||||
// Peep is outside the park.
|
||||
// loc_694F19:
|
||||
if (peep->OutsideOfPark)
|
||||
if (peep.OutsideOfPark)
|
||||
{
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (_pathFindDebug)
|
||||
{
|
||||
log_info("Completed guest_path_finding for %s - peep is outside the park.", _pathFindDebugPeepName);
|
||||
log_info("Completed CalculateNextDestination for %s - peep is outside the park.", _pathFindDebugPeepName);
|
||||
}
|
||||
PathfindLoggingDisable();
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
switch (peep->State)
|
||||
switch (peep.State)
|
||||
{
|
||||
case PeepState::EnteringPark:
|
||||
return GuestPathFindParkEntranceEntering(peep, edges);
|
||||
@@ -2086,7 +2086,7 @@ int32_t OriginalPathfinding::guest_path_finding(Guest* peep)
|
||||
* In principle, peeps with food are not paying as much attention to
|
||||
* where they are going and are consequently more like to walk up
|
||||
* dead end paths, paths to ride exits, etc. */
|
||||
if (!peep->HasFoodOrDrink() && (scenario_rand() & 0xFFFF) >= 2184)
|
||||
if (!peep.HasFoodOrDrink() && (scenario_rand() & 0xFFFF) >= 2184)
|
||||
{
|
||||
uint8_t adjustedEdges = edges;
|
||||
for (Direction chosenDirection : ALL_DIRECTIONS)
|
||||
@@ -2113,41 +2113,41 @@ int32_t OriginalPathfinding::guest_path_finding(Guest* peep)
|
||||
/* If there are still multiple directions to choose from,
|
||||
* peeps with maps will randomly read the map: probability of doing so
|
||||
* is much higher when heading for a ride or the park exit. */
|
||||
if (peep->HasItem(ShopItem::Map))
|
||||
if (peep.HasItem(ShopItem::Map))
|
||||
{
|
||||
// If at least 2 directions consult map
|
||||
if (bitcount(edges) >= 2)
|
||||
{
|
||||
uint16_t probability = 1638;
|
||||
if (peep->HeadingForRideOrParkExit())
|
||||
if (peep.HeadingForRideOrParkExit())
|
||||
{
|
||||
probability = 9362;
|
||||
}
|
||||
if ((scenario_rand() & 0xFFFF) < probability)
|
||||
{
|
||||
peep->ReadMap();
|
||||
peep.ReadMap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (peep->PeepFlags & PEEP_FLAGS_LEAVING_PARK)
|
||||
if (peep.PeepFlags & PEEP_FLAGS_LEAVING_PARK)
|
||||
{
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (_pathFindDebug)
|
||||
{
|
||||
log_info("Completed guest_path_finding for %s - peep is leaving the park.", _pathFindDebugPeepName);
|
||||
log_info("Completed CalculateNextDestination for %s - peep is leaving the park.", _pathFindDebugPeepName);
|
||||
}
|
||||
PathfindLoggingDisable();
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
return GuestPathFindParkEntranceLeaving(peep, edges);
|
||||
}
|
||||
|
||||
if (peep->GuestHeadingToRideId.IsNull())
|
||||
if (peep.GuestHeadingToRideId.IsNull())
|
||||
{
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (_pathFindDebug)
|
||||
{
|
||||
log_info("Completed guest_path_finding for %s - peep is aimless.", _pathFindDebugPeepName);
|
||||
log_info("Completed CalculateNextDestination for %s - peep is aimless.", _pathFindDebugPeepName);
|
||||
}
|
||||
PathfindLoggingDisable();
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
@@ -2155,7 +2155,7 @@ int32_t OriginalPathfinding::guest_path_finding(Guest* peep)
|
||||
}
|
||||
|
||||
// Peep is heading for a ride.
|
||||
RideId rideIndex = peep->GuestHeadingToRideId;
|
||||
RideId rideIndex = peep.GuestHeadingToRideId;
|
||||
auto ride = get_ride(rideIndex);
|
||||
if (ride == nullptr || ride->status != RideStatus::Open)
|
||||
{
|
||||
@@ -2163,7 +2163,8 @@ int32_t OriginalPathfinding::guest_path_finding(Guest* peep)
|
||||
if (_pathFindDebug)
|
||||
{
|
||||
log_info(
|
||||
"Completed guest_path_finding for %s - peep is heading to closed ride == aimless.", _pathFindDebugPeepName);
|
||||
"Completed CalculateNextDestination for %s - peep is heading to closed ride == aimless.",
|
||||
_pathFindDebugPeepName);
|
||||
}
|
||||
PathfindLoggingDisable();
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
@@ -2194,7 +2195,7 @@ int32_t OriginalPathfinding::guest_path_finding(Guest* peep)
|
||||
entranceStations[stationIndex.ToUnderlying()] = true;
|
||||
|
||||
TileCoordsXYZD entranceLocation = station.Entrance;
|
||||
auto score = CalculateHeuristicPathingScore(entranceLocation, TileCoordsXYZ{ peep->NextLoc });
|
||||
auto score = CalculateHeuristicPathingScore(entranceLocation, TileCoordsXYZ{ peep.NextLoc });
|
||||
if (score < bestScore)
|
||||
{
|
||||
bestScore = score;
|
||||
@@ -2234,22 +2235,23 @@ int32_t OriginalPathfinding::guest_path_finding(Guest* peep)
|
||||
gPeepPathFindGoalPosition = loc;
|
||||
gPeepPathFindIgnoreForeignQueues = true;
|
||||
|
||||
direction = peep_pathfind_choose_direction(TileCoordsXYZ{ peep->NextLoc }, peep);
|
||||
direction = ChooseDirection(TileCoordsXYZ{ peep.NextLoc }, peep);
|
||||
|
||||
if (direction == INVALID_DIRECTION)
|
||||
{
|
||||
/* Heuristic search failed for all directions.
|
||||
* Reset the PathfindGoal - this means that the PathfindHistory
|
||||
* will be reset in the next call to peep_pathfind_choose_direction().
|
||||
* will be reset in the next call to ChooseDirection().
|
||||
* This lets the heuristic search "try again" in case the player has
|
||||
* edited the path layout or the mechanic was already stuck in the
|
||||
* save game (e.g. with a worse version of the pathfinding). */
|
||||
peep->ResetPathfindGoal();
|
||||
peep.ResetPathfindGoal();
|
||||
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (_pathFindDebug)
|
||||
{
|
||||
log_info("Completed guest_path_finding for %s - failed to choose a direction == aimless.", _pathFindDebugPeepName);
|
||||
log_info(
|
||||
"Completed CalculateNextDestination for %s - failed to choose a direction == aimless.", _pathFindDebugPeepName);
|
||||
}
|
||||
PathfindLoggingDisable();
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
@@ -2259,7 +2261,7 @@ int32_t OriginalPathfinding::guest_path_finding(Guest* peep)
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (_pathFindDebug)
|
||||
{
|
||||
log_info("Completed guest_path_finding for %s - direction chosen: %d.", _pathFindDebugPeepName, direction);
|
||||
log_info("Completed CalculateNextDestination for %s - direction chosen: %d.", _pathFindDebugPeepName, direction);
|
||||
}
|
||||
PathfindLoggingDisable();
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
@@ -2311,18 +2313,18 @@ void Peep::ResetPathfindGoal()
|
||||
}
|
||||
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
void PathfindLoggingEnable([[maybe_unused]] Peep* peep)
|
||||
void PathfindLoggingEnable([[maybe_unused]] Peep& peep)
|
||||
{
|
||||
# if defined(PATHFIND_DEBUG) && PATHFIND_DEBUG
|
||||
/* Determine if the pathfinding debugging is wanted for this peep. */
|
||||
format_string(gPathFindDebugPeepName, sizeof(gPathFindDebugPeepName), peep->name_string_idx, &(peep->Id));
|
||||
format_string(gPathFindDebugPeepName, sizeof(gPathFindDebugPeepName), peep.name_string_idx, &(peep.Id));
|
||||
|
||||
/* For guests, use the existing PEEP_FLAGS_TRACKING flag to
|
||||
* determine for which guest(s) the pathfinding debugging will
|
||||
* be output for. */
|
||||
if (peep->type == PEEP_TYPE_GUEST)
|
||||
if (peep.type == PEEP_TYPE_GUEST)
|
||||
{
|
||||
gPathFindDebug = peep->PeepFlags & PEEP_FLAGS_TRACKING;
|
||||
gPathFindDebug = peep.PeepFlags & PEEP_FLAGS_TRACKING;
|
||||
}
|
||||
/* For staff, there is no tracking button (any other similar
|
||||
* suitable existing mechanism?), so fall back to a crude
|
||||
|
||||
Reference in New Issue
Block a user