From 542eb873fc6365bd09dc645523b62f5a23bf5677 Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Fri, 11 Sep 2020 23:45:25 -0400 Subject: [PATCH 1/3] Consolidate pathfinding code Consolidate all the guest pathfinding code from Peep.cpp into GuestPathfinding.cpp, and make a dedicated header for GuestPathfinding to help make it easier to see what the actual public interface is to the pathfinding system. --- OpenRCT2.xcodeproj/project.pbxproj | 2 + src/openrct2/libopenrct2.vcxproj | 1 + src/openrct2/peep/Guest.cpp | 1 + src/openrct2/peep/GuestPathfinding.cpp | 91 +++++++++++++++++++++++++ src/openrct2/peep/GuestPathfinding.h | 45 +++++++++++++ src/openrct2/peep/Peep.cpp | 93 +------------------------- src/openrct2/peep/Peep.h | 24 ------- src/openrct2/peep/Staff.cpp | 1 + test/tests/Pathfinding.cpp | 1 + 9 files changed, 144 insertions(+), 115 deletions(-) create mode 100644 src/openrct2/peep/GuestPathfinding.h diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index d4ce0feeda..8758952a1c 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -976,6 +976,7 @@ 4CFE4E871F950164005243C2 /* TrackData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackData.h; sourceTree = ""; }; 4CFE4E8E1F9625B0005243C2 /* Track.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Track.cpp; sourceTree = ""; }; 4CFE4E8F1F9625B0005243C2 /* Track.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Track.h; sourceTree = ""; }; + 51160A24250C7A15002029F6 /* GuestPathfinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GuestPathfinding.h; sourceTree = ""; }; 6341F4DF2400AA0E0052902B /* Drawing.Sprite.RLE.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Drawing.Sprite.RLE.cpp; sourceTree = ""; }; 6341F4E02400AA0F0052902B /* Drawing.Sprite.BMP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Drawing.Sprite.BMP.cpp; sourceTree = ""; }; 6341F4E32400AA1C0052902B /* ZoomLevel.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ZoomLevel.hpp; sourceTree = ""; }; @@ -3099,6 +3100,7 @@ F76C84531EC4E7CC00FA49E2 /* peep */ = { isa = PBXGroup; children = ( + 51160A24250C7A15002029F6 /* GuestPathfinding.h */, 9346F9D6208A191900C77D91 /* Guest.cpp */, 9346F9D7208A191900C77D91 /* GuestPathfinding.cpp */, 4CFE4E7B1F90A3F1005243C2 /* Peep.cpp */, diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index 0fac581d2b..71ee53303d 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -276,6 +276,7 @@ + diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index b078aa4aeb..a85bb9366b 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -36,6 +36,7 @@ #include "../world/Scenery.h" #include "../world/Sprite.h" #include "../world/Surface.h" +#include "GuestPathfinding.h" #include "Peep.h" #include "Staff.h" diff --git a/src/openrct2/peep/GuestPathfinding.cpp b/src/openrct2/peep/GuestPathfinding.cpp index 9878eb894c..57f17e95db 100644 --- a/src/openrct2/peep/GuestPathfinding.cpp +++ b/src/openrct2/peep/GuestPathfinding.cpp @@ -7,6 +7,8 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ +#include "GuestPathfinding.h" + #include "../core/Guard.hpp" #include "../ride/RideData.h" #include "../ride/Station.h" @@ -26,6 +28,17 @@ static int8_t _peepPathFindMaxJunctions; static int32_t _peepPathFindTilesChecked; static uint8_t _peepPathFindFewestNumSteps; +TileCoordsXYZ gPeepPathFindGoalPosition; +bool gPeepPathFindIgnoreForeignQueues; +ride_id_t gPeepPathFindQueueRideIndex; + +#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 +// Use to guard calls to log messages +bool gPathFindDebug = false; +// Use to put the peep name in the log message +utf8 gPathFindDebugPeepName[256]; +#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 + static int32_t guest_surface_path_finding(Peep* peep); /* A junction history for the peep pathfinding heuristic search @@ -2217,3 +2230,81 @@ int32_t guest_path_finding(Guest* peep) #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 return peep_move_one_tile(direction, peep); } + +bool is_valid_path_z_and_direction(TileElement* tileElement, int32_t currentZ, int32_t currentDirection) +{ + if (tileElement->AsPath()->IsSloped()) + { + int32_t slopeDirection = tileElement->AsPath()->GetSlopeDirection(); + if (slopeDirection == currentDirection) + { + if (currentZ != tileElement->base_height) + return false; + } + else + { + slopeDirection = direction_reverse(slopeDirection); + if (slopeDirection != currentDirection) + return false; + if (currentZ != tileElement->base_height + 2) + return false; + } + } + else + { + if (currentZ != tileElement->base_height) + return false; + } + return true; +} + +/** + * + * rct2: 0x0069A98C + */ +void peep_reset_pathfind_goal(Peep* peep) +{ +#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 + if (gPathFindDebug) + { + log_info("Resetting PathfindGoal for %s", gPathFindDebugPeepName); + } +#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 + + peep->PathfindGoal.x = 0xFF; + peep->PathfindGoal.y = 0xFF; + peep->PathfindGoal.z = 0xFF; + peep->PathfindGoal.direction = INVALID_DIRECTION; +} + +#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 +void pathfind_logging_enable([[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)); + + /* 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) + { + 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 + * string comparison with a compile time hardcoded name. */ + else + { + gPathFindDebug = strcmp(gPathFindDebugPeepName, "Mechanic Debug") == 0; + } +# endif // defined(PATHFIND_DEBUG) && PATHFIND_DEBUG +} + +void pathfind_logging_disable() +{ +# if defined(PATHFIND_DEBUG) && PATHFIND_DEBUG + gPathFindDebug = false; +# endif // defined(PATHFIND_DEBUG) && PATHFIND_DEBUG +} +#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 diff --git a/src/openrct2/peep/GuestPathfinding.h b/src/openrct2/peep/GuestPathfinding.h new file mode 100644 index 0000000000..d6e1312efc --- /dev/null +++ b/src/openrct2/peep/GuestPathfinding.h @@ -0,0 +1,45 @@ +/***************************************************************************** + * Copyright (c) 2014-2020 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#ifndef _GUESTPATHFINDING_H_ +#define _GUESTPATHFINDING_H_ + +#include "../common.h" +#include "../ride/RideTypes.h" +#include "../world/Location.hpp" + +struct Peep; +struct Guest; +struct TileElement; + +extern TileCoordsXYZ gPeepPathFindGoalPosition; +extern bool gPeepPathFindIgnoreForeignQueues; +extern ride_id_t gPeepPathFindQueueRideIndex; + +Direction peep_pathfind_choose_direction(const TileCoordsXYZ& loc, Peep* peep); +void peep_reset_pathfind_goal(Peep* peep); + +bool is_valid_path_z_and_direction(TileElement* tileElement, int32_t currentZ, int32_t currentDirection); + +int32_t guest_path_finding(Guest* peep); + +#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 pathfind_logging_enable(Peep* peep); +void pathfind_logging_disable(); +#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 + +#endif diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index 87673c5912..c1998b2fb3 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -44,17 +44,13 @@ #include "../world/SmallScenery.h" #include "../world/Sprite.h" #include "../world/Surface.h" +#include "GuestPathfinding.h" #include "Staff.h" #include #include #include -#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 -bool gPathFindDebug = false; -utf8 gPathFindDebugPeepName[256]; -#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - uint8_t gGuestChangeModifier; uint32_t gNumGuestsInPark; uint32_t gNumGuestsInParkLastWeek; @@ -69,10 +65,6 @@ uint32_t gNextGuestNumber; uint8_t gPeepWarningThrottle[16]; -TileCoordsXYZ gPeepPathFindGoalPosition; -bool gPeepPathFindIgnoreForeignQueues; -ride_id_t gPeepPathFindQueueRideIndex; - static uint8_t _unk_F1AEF0; static TileElement* _peepRideEntranceExitElement; @@ -1715,10 +1707,7 @@ Peep* Peep::Generate(const CoordsXYZ& coords) peep->CashInPocket = cash; peep->CashSpent = 0; peep->TimeInPark = -1; - peep->PathfindGoal.x = 0xFF; - peep->PathfindGoal.y = 0xFF; - peep->PathfindGoal.z = 0xFF; - peep->PathfindGoal.direction = INVALID_DIRECTION; + peep_reset_pathfind_goal(peep); peep->ItemStandardFlags = 0; peep->ItemExtraFlags = 0; peep->GuestHeadingToRideId = RIDE_ID_NULL; @@ -2954,33 +2943,6 @@ static bool peep_interact_with_shop(Peep* peep, const CoordsXYE& coords) return true; } -bool is_valid_path_z_and_direction(TileElement* tileElement, int32_t currentZ, int32_t currentDirection) -{ - if (tileElement->AsPath()->IsSloped()) - { - int32_t slopeDirection = tileElement->AsPath()->GetSlopeDirection(); - if (slopeDirection == currentDirection) - { - if (currentZ != tileElement->base_height) - return false; - } - else - { - slopeDirection = direction_reverse(slopeDirection); - if (slopeDirection != currentDirection) - return false; - if (currentZ != tileElement->base_height + 2) - return false; - } - } - else - { - if (currentZ != tileElement->base_height) - return false; - } - return true; -} - void Peep::PerformNextAction(uint8_t& pathing_result) { TileElement* tmpTile; @@ -3140,25 +3102,6 @@ void Peep::PerformNextAction(uint8_t& pathing_result, TileElement*& tile_result) peep_return_to_centre_of_tile(this); } -/** - * - * rct2: 0x0069A98C - */ -void peep_reset_pathfind_goal(Peep* peep) -{ -#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - if (gPathFindDebug) - { - log_info("Resetting PathfindGoal for %s", gPathFindDebugPeepName); - } -#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - - peep->PathfindGoal.x = 0xFF; - peep->PathfindGoal.y = 0xFF; - peep->PathfindGoal.z = 0xFF; - peep->PathfindGoal.direction = INVALID_DIRECTION; -} - /** * Gets the height including the bit depending on how far up the slope the peep * is. @@ -3266,38 +3209,6 @@ void peep_update_names(bool realNames) gfx_invalidate_screen(); } -#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 -void pathfind_logging_enable([[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)); - - /* 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) - { - 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 - * string comparison with a compile time hardcoded name. */ - else - { - gPathFindDebug = strcmp(gPathFindDebugPeepName, "Mechanic Debug") == 0; - } -# endif // defined(PATHFIND_DEBUG) && PATHFIND_DEBUG -} - -void pathfind_logging_disable() -{ -# if defined(PATHFIND_DEBUG) && PATHFIND_DEBUG - gPathFindDebug = false; -# endif // defined(PATHFIND_DEBUG) && PATHFIND_DEBUG -} -#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - void increment_guests_in_park() { if (gNumGuestsInPark < UINT32_MAX) diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index 66d7d46442..87e645fa86 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -1026,10 +1026,6 @@ extern uint32_t gNextGuestNumber; extern uint8_t gPeepWarningThrottle[16]; -extern TileCoordsXYZ gPeepPathFindGoalPosition; -extern bool gPeepPathFindIgnoreForeignQueues; -extern ride_id_t gPeepPathFindQueueRideIndex; - Peep* try_get_guest(uint16_t spriteIndex); int32_t peep_get_staff_count(); bool peep_can_be_picked_up(Peep* peep); @@ -1057,26 +1053,6 @@ void peep_update_names(bool realNames); void guest_set_name(uint16_t spriteIndex, const char* name); -Direction peep_pathfind_choose_direction(const TileCoordsXYZ& loc, Peep* peep); -void peep_reset_pathfind_goal(Peep* peep); - -bool is_valid_path_z_and_direction(TileElement* tileElement, int32_t currentZ, int32_t currentDirection); -int32_t guest_path_finding(Guest* peep); - -#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. -// Some variables used for the path finding debugging. -extern bool gPathFindDebug; // Use to guard calls to log messages -extern utf8 gPathFindDebugPeepName[256]; // Use to put the peep name in the log message - -// The following calls set the above two variables for a peep. -// ... when PATHFIND_DEBUG is 1 (nonzero) -void pathfind_logging_enable(Peep* peep); -void pathfind_logging_disable(); -#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - void increment_guests_in_park(); void increment_guests_heading_for_park(); void decrement_guests_in_park(); diff --git a/src/openrct2/peep/Staff.cpp b/src/openrct2/peep/Staff.cpp index 99cf4118d8..4e305ff4cf 100644 --- a/src/openrct2/peep/Staff.cpp +++ b/src/openrct2/peep/Staff.cpp @@ -37,6 +37,7 @@ #include "../world/SmallScenery.h" #include "../world/Sprite.h" #include "../world/Surface.h" +#include "GuestPathfinding.h" #include "Peep.h" #include diff --git a/test/tests/Pathfinding.cpp b/test/tests/Pathfinding.cpp index 8d1c9825bf..7dcdc9be71 100644 --- a/test/tests/Pathfinding.cpp +++ b/test/tests/Pathfinding.cpp @@ -1,5 +1,6 @@ #include "TestData.h" #include "openrct2/core/StringReader.hpp" +#include "openrct2/peep/GuestPathfinding.h" #include "openrct2/peep/Peep.h" #include "openrct2/ride/Station.h" #include "openrct2/scenario/Scenario.h" From 4a20ed38a8441da73a0844de5330f91c25d1b8d5 Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Sat, 12 Sep 2020 01:11:56 -0400 Subject: [PATCH 2/3] Document public API for pathfinder Add comments explaining the externally-visible points in the pathfinding code. --- src/openrct2/peep/GuestPathfinding.h | 29 +++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/openrct2/peep/GuestPathfinding.h b/src/openrct2/peep/GuestPathfinding.h index d6e1312efc..990463e972 100644 --- a/src/openrct2/peep/GuestPathfinding.h +++ b/src/openrct2/peep/GuestPathfinding.h @@ -18,15 +18,42 @@ 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; -extern bool gPeepPathFindIgnoreForeignQueues; + +// 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. extern ride_id_t gPeepPathFindQueueRideIndex; +// Furthermore, staff members don't care about this stuff; even if they are e.g. a mechanic headed +// to a particular ride, they have no issues with walking over queues for other rides to get there. +// This bool controls that behaviour - if true, the peep will not path over queues for rides other +// than their target ride, and if false, they will treat it like a regular path. +// +// In practice, if this is false, gPeepPathFindQueueRideIndex is always RIDE_ID_NULL. +extern bool gPeepPathFindIgnoreForeignQueues; + +// 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. Direction peep_pathfind_choose_direction(const TileCoordsXYZ& loc, Peep* peep); + +// Reset the peep's stored goal, which means they will forget any stored pathfinding history +// on the next choose_direction call. void peep_reset_pathfind_goal(Peep* peep); +// Test whether the given tile can be walked onto, if the peep is currently at height currentZ and +// moving in direction currentDirection. bool is_valid_path_z_and_direction(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. +// +// Returns 0 if the guest has successfully had a new destination set up, nonzero otherwise. int32_t guest_path_finding(Guest* peep); #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 From b57ed85098d4be6eb1bb8a402e908bc149ba2428 Mon Sep 17 00:00:00 2001 From: Richard Fine Date: Wed, 16 Sep 2020 20:22:36 -0400 Subject: [PATCH 3/3] Fixes from review feedback --- src/openrct2/peep/Guest.cpp | 8 ++--- src/openrct2/peep/GuestPathfinding.cpp | 44 +++++++++++++------------- src/openrct2/peep/GuestPathfinding.h | 15 +++------ src/openrct2/peep/Peep.cpp | 2 +- src/openrct2/peep/Peep.h | 4 +++ src/openrct2/peep/Staff.cpp | 12 +++---- 6 files changed, 41 insertions(+), 44 deletions(-) diff --git a/src/openrct2/peep/Guest.cpp b/src/openrct2/peep/Guest.cpp index a85bb9366b..f90aac737a 100644 --- a/src/openrct2/peep/Guest.cpp +++ b/src/openrct2/peep/Guest.cpp @@ -1677,7 +1677,7 @@ loc_69B221: UmbrellaColour = ride->track_colour[0].main; if (shopItem == SHOP_ITEM_MAP) - peep_reset_pathfind_goal(this); + ResetPathfindGoal(); uint16_t consumptionTime = item_consumption_time[shopItem]; TimeToConsume = std::min((TimeToConsume + consumptionTime), 255); @@ -1814,7 +1814,7 @@ void Guest::OnExitRide(ride_id_t rideIndex) { GuestHeadingToRideId = rideIndex; GuestIsLostCountdown = 200; - peep_reset_pathfind_goal(this); + ResetPathfindGoal(); WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_ACTION; } @@ -1877,7 +1877,7 @@ void Guest::PickRideToGoOn() // Head to that ride GuestHeadingToRideId = ride->id; GuestIsLostCountdown = 200; - peep_reset_pathfind_goal(this); + ResetPathfindGoal(); WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_ACTION; // Make peep look at their map if they have one @@ -3254,7 +3254,7 @@ template static void peep_head_for_nearest_ride(Guest* peep, bool co // Head to that ride peep->GuestHeadingToRideId = closestRide->id; peep->GuestIsLostCountdown = 200; - peep_reset_pathfind_goal(peep); + peep->ResetPathfindGoal(); peep->WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_ACTION; peep->TimeLost = 0; } diff --git a/src/openrct2/peep/GuestPathfinding.cpp b/src/openrct2/peep/GuestPathfinding.cpp index 57f17e95db..ca827d2153 100644 --- a/src/openrct2/peep/GuestPathfinding.cpp +++ b/src/openrct2/peep/GuestPathfinding.cpp @@ -255,7 +255,7 @@ static uint8_t footpath_element_next_in_direction(TileCoordsXYZ loc, PathElement continue; if (nextTileElement->GetType() != TILE_ELEMENT_TYPE_PATH) continue; - if (!is_valid_path_z_and_direction(nextTileElement, loc.z, chosenDirection)) + if (!IsValidPathZAndDirection(nextTileElement, loc.z, chosenDirection)) continue; if (nextTileElement->AsPath()->IsWide()) return PATH_SEARCH_WIDE; @@ -348,7 +348,7 @@ static uint8_t footpath_element_dest_in_dir( } break; case TILE_ELEMENT_TYPE_PATH: - if (!is_valid_path_z_and_direction(tileElement, loc.z, chosenDirection)) + if (!IsValidPathZAndDirection(tileElement, loc.z, chosenDirection)) continue; if (tileElement->AsPath()->IsWide()) return PATH_SEARCH_WIDE; @@ -776,7 +776,7 @@ static void peep_pathfind_heuristic_search( * queue path. * Otherwise, peeps walk on path tiles to get to the goal. */ - if (!is_valid_path_z_and_direction(tileElement, loc.z, test_edge)) + if (!IsValidPathZAndDirection(tileElement, loc.z, test_edge)) continue; // Path may be sloped, so set z to path base height. @@ -1739,13 +1739,13 @@ static int32_t guest_path_find_park_entrance(Peep* peep, uint8_t edges) gPeepPathFindQueueRideIndex = RIDE_ID_NULL; #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - pathfind_logging_enable(peep); + PathfindLoggingEnable(peep); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 Direction chosenDirection = peep_pathfind_choose_direction(TileCoordsXYZ{ peep->NextLoc }, peep); #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - pathfind_logging_disable(); + PathfindLoggingDisable(); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 if (chosenDirection == INVALID_DIRECTION) @@ -1942,7 +1942,7 @@ static StationIndex guest_pathfinding_select_random_station( int32_t guest_path_finding(Guest* peep) { #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - pathfind_logging_enable(peep); + PathfindLoggingEnable(peep); if (gPathFindDebug) { log_info("Starting guest_path_finding for %s", gPathFindDebugPeepName); @@ -2019,7 +2019,7 @@ int32_t guest_path_finding(Guest* peep) "Completed guest_path_finding for %s - taking only direction available: %d.", gPathFindDebugPeepName, direction); } - pathfind_logging_disable(); + PathfindLoggingDisable(); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 return peep_move_one_tile(direction, peep); } @@ -2035,7 +2035,7 @@ int32_t guest_path_finding(Guest* peep) { log_info("Completed guest_path_finding for %s - peep is outside the park.", gPathFindDebugPeepName); } - pathfind_logging_disable(); + PathfindLoggingDisable(); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 switch (peep->State) { @@ -2105,7 +2105,7 @@ int32_t guest_path_finding(Guest* peep) { log_info("Completed guest_path_finding for %s - peep is leaving the park.", gPathFindDebugPeepName); } - pathfind_logging_disable(); + PathfindLoggingDisable(); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 return guest_path_find_park_entrance(peep, edges); } @@ -2117,7 +2117,7 @@ int32_t guest_path_finding(Guest* peep) { log_info("Completed guest_path_finding for %s - peep is aimless.", gPathFindDebugPeepName); } - pathfind_logging_disable(); + PathfindLoggingDisable(); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 return guest_path_find_aimless(peep, edges); } @@ -2133,7 +2133,7 @@ int32_t guest_path_finding(Guest* peep) log_info( "Completed guest_path_finding for %s - peep is heading to closed ride == aimless.", gPathFindDebugPeepName); } - pathfind_logging_disable(); + PathfindLoggingDisable(); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 return guest_path_find_aimless(peep, edges); } @@ -2209,14 +2209,14 @@ int32_t guest_path_finding(Guest* peep) * 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_reset_pathfind_goal(peep); + peep->ResetPathfindGoal(); #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 if (gPathFindDebug) { log_info("Completed guest_path_finding for %s - failed to choose a direction == aimless.", gPathFindDebugPeepName); } - pathfind_logging_disable(); + PathfindLoggingDisable(); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 return guest_path_find_aimless(peep, edges); @@ -2226,12 +2226,12 @@ int32_t guest_path_finding(Guest* peep) { log_info("Completed guest_path_finding for %s - direction chosen: %d.", gPathFindDebugPeepName, direction); } - pathfind_logging_disable(); + PathfindLoggingDisable(); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 return peep_move_one_tile(direction, peep); } -bool is_valid_path_z_and_direction(TileElement* tileElement, int32_t currentZ, int32_t currentDirection) +bool IsValidPathZAndDirection(TileElement* tileElement, int32_t currentZ, int32_t currentDirection) { if (tileElement->AsPath()->IsSloped()) { @@ -2262,7 +2262,7 @@ bool is_valid_path_z_and_direction(TileElement* tileElement, int32_t currentZ, i * * rct2: 0x0069A98C */ -void peep_reset_pathfind_goal(Peep* peep) +void Peep::ResetPathfindGoal() { #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 if (gPathFindDebug) @@ -2271,14 +2271,14 @@ void peep_reset_pathfind_goal(Peep* peep) } #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - peep->PathfindGoal.x = 0xFF; - peep->PathfindGoal.y = 0xFF; - peep->PathfindGoal.z = 0xFF; - peep->PathfindGoal.direction = INVALID_DIRECTION; + PathfindGoal.x = 0xFF; + PathfindGoal.y = 0xFF; + PathfindGoal.z = 0xFF; + PathfindGoal.direction = INVALID_DIRECTION; } #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 -void pathfind_logging_enable([[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. */ @@ -2301,7 +2301,7 @@ void pathfind_logging_enable([[maybe_unused]] Peep* peep) # endif // defined(PATHFIND_DEBUG) && PATHFIND_DEBUG } -void pathfind_logging_disable() +void PathfindLoggingDisable() { # if defined(PATHFIND_DEBUG) && PATHFIND_DEBUG gPathFindDebug = false; diff --git a/src/openrct2/peep/GuestPathfinding.h b/src/openrct2/peep/GuestPathfinding.h index 990463e972..7804e2de60 100644 --- a/src/openrct2/peep/GuestPathfinding.h +++ b/src/openrct2/peep/GuestPathfinding.h @@ -7,8 +7,7 @@ * OpenRCT2 is licensed under the GNU General Public License version 3. *****************************************************************************/ -#ifndef _GUESTPATHFINDING_H_ -#define _GUESTPATHFINDING_H_ +#pragma once #include "../common.h" #include "../ride/RideTypes.h" @@ -42,13 +41,9 @@ extern bool gPeepPathFindIgnoreForeignQueues; // the direction the peep should walk in from the current tile. Direction peep_pathfind_choose_direction(const TileCoordsXYZ& loc, Peep* peep); -// Reset the peep's stored goal, which means they will forget any stored pathfinding history -// on the next choose_direction call. -void peep_reset_pathfind_goal(Peep* peep); - // Test whether the given tile can be walked onto, if the peep is currently at height currentZ and // moving in direction currentDirection. -bool is_valid_path_z_and_direction(TileElement* tileElement, int32_t currentZ, int32_t currentDirection); +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. @@ -65,8 +60,6 @@ int32_t guest_path_finding(Guest* peep); // 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 pathfind_logging_enable(Peep* peep); -void pathfind_logging_disable(); +void PathfindLoggingEnable(Peep* peep); +void PathfindLoggingDisable(); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - -#endif diff --git a/src/openrct2/peep/Peep.cpp b/src/openrct2/peep/Peep.cpp index c1998b2fb3..1d4147b5dd 100644 --- a/src/openrct2/peep/Peep.cpp +++ b/src/openrct2/peep/Peep.cpp @@ -1707,7 +1707,7 @@ Peep* Peep::Generate(const CoordsXYZ& coords) peep->CashInPocket = cash; peep->CashSpent = 0; peep->TimeInPark = -1; - peep_reset_pathfind_goal(peep); + peep->ResetPathfindGoal(); peep->ItemStandardFlags = 0; peep->ItemExtraFlags = 0; peep->GuestHeadingToRideId = RIDE_ID_NULL; diff --git a/src/openrct2/peep/Peep.h b/src/openrct2/peep/Peep.h index 87e645fa86..f69273b884 100644 --- a/src/openrct2/peep/Peep.h +++ b/src/openrct2/peep/Peep.h @@ -800,6 +800,10 @@ public: // Peep std::string GetName() const; bool SetName(const std::string_view& value); + // Reset the peep's stored goal, which means they will forget any stored pathfinding history + // on the next peep_pathfind_choose_direction call. + void ResetPathfindGoal(); + // TODO: Make these private again when done refactoring public: // Peep bool CheckForPath(); diff --git a/src/openrct2/peep/Staff.cpp b/src/openrct2/peep/Staff.cpp index 4e305ff4cf..64d4bc3d86 100644 --- a/src/openrct2/peep/Staff.cpp +++ b/src/openrct2/peep/Staff.cpp @@ -283,7 +283,7 @@ bool staff_can_ignore_wide_flag(Peep* staff, const CoordsXYZ& staffPos, TileElem } /* test_element is a path */ - if (!is_valid_path_z_and_direction(test_element, adjacPos.z / COORDS_Z_STEP, adjac_dir)) + if (!IsValidPathZAndDirection(test_element, adjacPos.z / COORDS_Z_STEP, adjac_dir)) continue; /* test_element is a connected path */ @@ -857,13 +857,13 @@ static uint8_t staff_mechanic_direction_path(Peep* peep, uint8_t validDirections gPeepPathFindQueueRideIndex = RIDE_ID_NULL; #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - pathfind_logging_enable(peep); + PathfindLoggingEnable(peep); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 Direction pathfindDirection = peep_pathfind_choose_direction(TileCoordsXYZ{ peep->NextLoc }, peep); #if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 - pathfind_logging_disable(); + PathfindLoggingDisable(); #endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1 if (pathfindDirection == INVALID_DIRECTION) @@ -874,7 +874,7 @@ static uint8_t staff_mechanic_direction_path(Peep* peep, uint8_t validDirections * 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_reset_pathfind_goal(peep); + peep->ResetPathfindGoal(); return staff_mechanic_direction_path_rand(peep, pathDirections); } @@ -1437,7 +1437,7 @@ void Staff::UpdateHeadingToInspect() if (SubState == 0) { MechanicTimeSinceCall = 0; - peep_reset_pathfind_goal(this); + ResetPathfindGoal(); SubState = 2; } @@ -1547,7 +1547,7 @@ void Staff::UpdateAnswering() SubState = 2; peep_window_state_update(this); MechanicTimeSinceCall = 0; - peep_reset_pathfind_goal(this); + ResetPathfindGoal(); return; } UpdateAction();