Pathfinding cleanup (#21407)

* Eliminate unnecessary abstraction for path finding

* Pass the goal to ChooseDirection instead of using globals

* Remove gPeepPathFindGoalPosition and pass it by parameter instead

* Remove _peepPathFindIsStaff and make ignoring banners explicit

* Code style and naming fixups

* Apply clang-format

* Add comment specifying to why it does not ignore banners

* Apply review comments
This commit is contained in:
Matt 2024-02-22 21:52:01 +02:00 committed by GitHub
parent fdbdbd405f
commit 9d9f0af0cd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 2065 additions and 2114 deletions

View File

@ -70,8 +70,6 @@ uint8_t gGuestChangeModifier;
uint8_t gPeepWarningThrottle[16];
std::unique_ptr<GuestPathfinding> gGuestPathfinder = std::make_unique<OriginalPathfinding>();
static uint8_t _unk_F1AEF0;
static TileElement* _peepRideEntranceExitElement;
@ -2393,7 +2391,7 @@ void Peep::PerformNextAction(uint8_t& pathing_result, TileElement*& tile_result)
if (guest != nullptr)
{
result = gGuestPathfinder->CalculateNextDestination(*guest);
result = PathFinding::CalculateNextDestination(*guest);
}
else
{
@ -2853,3 +2851,20 @@ void Peep::Paint(PaintSession& session, int32_t imageDirection) const
}
}
}
/**
*
* rct2: 0x0069A98C
*/
void Peep::ResetPathfindGoal()
{
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
if (_pathFindDebug)
{
LOG_INFO("Resetting PathfindGoal for %s", _pathFindDebugPeepName);
}
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
PathfindGoal.SetNull();
PathfindGoal.direction = INVALID_DIRECTION;
}

View File

@ -183,7 +183,7 @@ bool Staff::CanIgnoreWideFlag(const CoordsXYZ& staffPos, TileElement* path) cons
}
/* test_element is a path */
if (!GuestPathfinding::IsValidPathZAndDirection(test_element, adjacPos.z / COORDS_Z_STEP, adjac_dir))
if (!PathFinding::IsValidPathZAndDirection(test_element, adjacPos.z / COORDS_Z_STEP, adjac_dir))
continue;
/* test_element is a connected path */
@ -713,10 +713,6 @@ Direction Staff::MechanicDirectionPath(uint8_t validDirections, PathElement* pat
}
}
gPeepPathFindGoalPosition.x = location.x;
gPeepPathFindGoalPosition.y = location.y;
gPeepPathFindGoalPosition.z = location.z;
gPeepPathFindIgnoreForeignQueues = false;
gPeepPathFindQueueRideIndex = RideId::GetNull();
@ -724,7 +720,8 @@ Direction Staff::MechanicDirectionPath(uint8_t validDirections, PathElement* pat
PathfindLoggingEnable(*this);
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
Direction pathfindDirection = gGuestPathfinder->ChooseDirection(TileCoordsXYZ{ NextLoc }, *this);
const auto goalPos = TileCoordsXYZ{ location };
Direction pathfindDirection = PathFinding::ChooseDirection(TileCoordsXYZ{ NextLoc }, goalPos, *this);
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
PathfindLoggingDisable();

File diff suppressed because it is too large Load Diff

View File

@ -19,13 +19,6 @@ struct Peep;
struct Guest;
struct TileElement;
// The tile position of the place the peep is trying to get to (park entrance/exit, ride
// entrance/exit, or the end of the queue line for a ride).
//
// This gets copied into Peep::PathfindGoal. The two separate variables are needed because
// when the goal changes the peep's pathfind history needs to be reset.
extern TileCoordsXYZ gPeepPathFindGoalPosition;
// When the heuristic pathfinder is examining neighboring tiles, one possibility is that it finds a
// queue tile; furthermore, this queue tile may or may not be for the ride that the peep is trying
// to get to, if any. This first var is used to store the ride that the peep is currently headed to.
@ -39,68 +32,31 @@ extern RideId gPeepPathFindQueueRideIndex;
// In practice, if this is false, gPeepPathFindQueueRideIndex is always RIDE_ID_NULL.
extern bool gPeepPathFindIgnoreForeignQueues;
class GuestPathfinding
namespace OpenRCT2::PathFinding
{
public:
virtual ~GuestPathfinding() = default;
Direction ChooseDirection(const TileCoordsXYZ& loc, const TileCoordsXYZ& goal, Peep& peep);
/**
* Given a peep 'peep' at tile 'loc', who is trying to get to 'gPeepPathFindGoalPosition', decide the direction the peep
* should walk in from the current tile.
*
* @param loc Reference to the peep's current tile location
* @param peep Reference to the current peep struct
* @return The direction the peep should walk in
*/
virtual Direction ChooseDirection(const TileCoordsXYZ& loc, Peep& peep) = 0;
int32_t CalculateNextDestination(Guest& peep);
/**
* Test whether the given tile can be walked onto, if the peep is currently at height currentZ and
* moving in direction currentDirection
*
* @param tileElement A pointer to the tile that is being tested
* @param currentZ The height coord the peep is at
* @param currentDirection The direction the peep is facing in
* @return True if the given tile can be walked onto, false otherwise
*/
static bool IsValidPathZAndDirection(TileElement* tileElement, int32_t currentZ, int32_t currentDirection);
/**
* Overall guest pathfinding AI. Sets up Peep::DestinationX/DestinationY (which they move to in a
* straight line, no pathfinding). Called whenever the guest has arrived at their previously set destination.
*
* @param peep A reference to a guest struct
* @returns 0 if the guest has successfully had a new destination set up, nonzero otherwise.
*/
virtual int32_t CalculateNextDestination(Guest& peep) = 0;
};
class OriginalPathfinding final : public GuestPathfinding
{
public:
Direction ChooseDirection(const TileCoordsXYZ& loc, Peep& peep) final override;
int32_t CalculateNextDestination(Guest& peep) final override;
private:
int32_t GuestPathFindParkEntranceEntering(Peep& peep, uint8_t edges);
int32_t GuestPathFindPeepSpawn(Peep& peep, uint8_t edges);
int32_t GuestPathFindParkEntranceLeaving(Peep& peep, uint8_t edges);
};
extern std::unique_ptr<GuestPathfinding> gGuestPathfinder;
bool IsValidPathZAndDirection(TileElement* tileElement, int32_t currentZ, int32_t currentDirection);
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
# define PATHFIND_DEBUG \
0 // Set to 0 to disable pathfinding debugging;
// Set to 1 to enable pathfinding debugging.
// When PATHFIND_DEBUG is 1 (nonzero):
// The following calls configure debug logging for the given peep
// If they're a guest, pathfinding will be logged if they have PEEP_FLAGS_TRACKING set
// If they're staff, pathfinding will be logged if their name is "Mechanic Debug"
void PathfindLoggingEnable(Peep& peep);
void PathfindLoggingDisable();
// When PATHFIND_DEBUG is 1 (nonzero):
// The following calls configure debug logging for the given peep
// If they're a guest, pathfinding will be logged if they have PEEP_FLAGS_TRACKING set
// If they're staff, pathfinding will be logged if their name is "Mechanic Debug"
void PathfindLoggingEnable(Peep& peep);
void PathfindLoggingDisable();
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
}; // namespace OpenRCT2::PathFinding

View File

@ -85,8 +85,7 @@ protected:
// Pick the direction the peep should initially move in, given the goal position.
// This will also store the goal position and initialize pathfinding data for the peep.
gPeepPathFindGoalPosition = goal;
const Direction moveDir = gGuestPathfinder->ChooseDirection(*pos, *peep);
const Direction moveDir = PathFinding::ChooseDirection(*pos, goal, *peep);
if (moveDir == INVALID_DIRECTION)
{
// Couldn't determine a direction to move off in