mirror of
https://github.com/OpenRCT2/OpenRCT2.git
synced 2025-01-23 19:02:04 -05:00
Merge pull request #12916 from richard-fine/pathfinding
Pathfinding cleanup
This commit is contained in:
commit
c72f547606
9 changed files with 192 additions and 139 deletions
|
@ -969,6 +969,7 @@
|
||||||
4CFE4E871F950164005243C2 /* TrackData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackData.h; sourceTree = "<group>"; };
|
4CFE4E871F950164005243C2 /* TrackData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrackData.h; sourceTree = "<group>"; };
|
||||||
4CFE4E8E1F9625B0005243C2 /* Track.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Track.cpp; sourceTree = "<group>"; };
|
4CFE4E8E1F9625B0005243C2 /* Track.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Track.cpp; sourceTree = "<group>"; };
|
||||||
4CFE4E8F1F9625B0005243C2 /* Track.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Track.h; sourceTree = "<group>"; };
|
4CFE4E8F1F9625B0005243C2 /* Track.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Track.h; sourceTree = "<group>"; };
|
||||||
|
51160A24250C7A15002029F6 /* GuestPathfinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GuestPathfinding.h; sourceTree = "<group>"; };
|
||||||
6341F4DF2400AA0E0052902B /* Drawing.Sprite.RLE.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Drawing.Sprite.RLE.cpp; sourceTree = "<group>"; };
|
6341F4DF2400AA0E0052902B /* Drawing.Sprite.RLE.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Drawing.Sprite.RLE.cpp; sourceTree = "<group>"; };
|
||||||
6341F4E02400AA0F0052902B /* Drawing.Sprite.BMP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Drawing.Sprite.BMP.cpp; sourceTree = "<group>"; };
|
6341F4E02400AA0F0052902B /* Drawing.Sprite.BMP.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Drawing.Sprite.BMP.cpp; sourceTree = "<group>"; };
|
||||||
6341F4E32400AA1C0052902B /* ZoomLevel.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ZoomLevel.hpp; sourceTree = "<group>"; };
|
6341F4E32400AA1C0052902B /* ZoomLevel.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ZoomLevel.hpp; sourceTree = "<group>"; };
|
||||||
|
@ -3093,6 +3094,7 @@
|
||||||
F76C84531EC4E7CC00FA49E2 /* peep */ = {
|
F76C84531EC4E7CC00FA49E2 /* peep */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
51160A24250C7A15002029F6 /* GuestPathfinding.h */,
|
||||||
9346F9D6208A191900C77D91 /* Guest.cpp */,
|
9346F9D6208A191900C77D91 /* Guest.cpp */,
|
||||||
9346F9D7208A191900C77D91 /* GuestPathfinding.cpp */,
|
9346F9D7208A191900C77D91 /* GuestPathfinding.cpp */,
|
||||||
4CFE4E7B1F90A3F1005243C2 /* Peep.cpp */,
|
4CFE4E7B1F90A3F1005243C2 /* Peep.cpp */,
|
||||||
|
|
|
@ -274,6 +274,7 @@
|
||||||
<ClInclude Include="paint\tile_element\Paint.TileElement.h" />
|
<ClInclude Include="paint\tile_element\Paint.TileElement.h" />
|
||||||
<ClInclude Include="paint\VirtualFloor.h" />
|
<ClInclude Include="paint\VirtualFloor.h" />
|
||||||
<ClInclude Include="ParkImporter.h" />
|
<ClInclude Include="ParkImporter.h" />
|
||||||
|
<ClInclude Include="peep\GuestPathfinding.h" />
|
||||||
<ClInclude Include="peep\Peep.h" />
|
<ClInclude Include="peep\Peep.h" />
|
||||||
<ClInclude Include="peep\Staff.h" />
|
<ClInclude Include="peep\Staff.h" />
|
||||||
<ClInclude Include="PlatformEnvironment.h" />
|
<ClInclude Include="PlatformEnvironment.h" />
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "../world/Scenery.h"
|
#include "../world/Scenery.h"
|
||||||
#include "../world/Sprite.h"
|
#include "../world/Sprite.h"
|
||||||
#include "../world/Surface.h"
|
#include "../world/Surface.h"
|
||||||
|
#include "GuestPathfinding.h"
|
||||||
#include "Peep.h"
|
#include "Peep.h"
|
||||||
#include "Staff.h"
|
#include "Staff.h"
|
||||||
|
|
||||||
|
@ -1674,7 +1675,7 @@ loc_69B221:
|
||||||
UmbrellaColour = ride->track_colour[0].main;
|
UmbrellaColour = ride->track_colour[0].main;
|
||||||
|
|
||||||
if (shopItem == SHOP_ITEM_MAP)
|
if (shopItem == SHOP_ITEM_MAP)
|
||||||
peep_reset_pathfind_goal(this);
|
ResetPathfindGoal();
|
||||||
|
|
||||||
uint16_t consumptionTime = item_consumption_time[shopItem];
|
uint16_t consumptionTime = item_consumption_time[shopItem];
|
||||||
TimeToConsume = std::min((TimeToConsume + consumptionTime), 255);
|
TimeToConsume = std::min((TimeToConsume + consumptionTime), 255);
|
||||||
|
@ -1811,7 +1812,7 @@ void Guest::OnExitRide(ride_id_t rideIndex)
|
||||||
{
|
{
|
||||||
GuestHeadingToRideId = rideIndex;
|
GuestHeadingToRideId = rideIndex;
|
||||||
GuestIsLostCountdown = 200;
|
GuestIsLostCountdown = 200;
|
||||||
peep_reset_pathfind_goal(this);
|
ResetPathfindGoal();
|
||||||
WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_ACTION;
|
WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_ACTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1874,7 +1875,7 @@ void Guest::PickRideToGoOn()
|
||||||
// Head to that ride
|
// Head to that ride
|
||||||
GuestHeadingToRideId = ride->id;
|
GuestHeadingToRideId = ride->id;
|
||||||
GuestIsLostCountdown = 200;
|
GuestIsLostCountdown = 200;
|
||||||
peep_reset_pathfind_goal(this);
|
ResetPathfindGoal();
|
||||||
WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_ACTION;
|
WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_ACTION;
|
||||||
|
|
||||||
// Make peep look at their map if they have one
|
// Make peep look at their map if they have one
|
||||||
|
@ -3251,7 +3252,7 @@ template<typename T> static void peep_head_for_nearest_ride(Guest* peep, bool co
|
||||||
// Head to that ride
|
// Head to that ride
|
||||||
peep->GuestHeadingToRideId = closestRide->id;
|
peep->GuestHeadingToRideId = closestRide->id;
|
||||||
peep->GuestIsLostCountdown = 200;
|
peep->GuestIsLostCountdown = 200;
|
||||||
peep_reset_pathfind_goal(peep);
|
peep->ResetPathfindGoal();
|
||||||
peep->WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_ACTION;
|
peep->WindowInvalidateFlags |= PEEP_INVALIDATE_PEEP_ACTION;
|
||||||
peep->TimeLost = 0;
|
peep->TimeLost = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "GuestPathfinding.h"
|
||||||
|
|
||||||
#include "../core/Guard.hpp"
|
#include "../core/Guard.hpp"
|
||||||
#include "../ride/RideData.h"
|
#include "../ride/RideData.h"
|
||||||
#include "../ride/Station.h"
|
#include "../ride/Station.h"
|
||||||
|
@ -26,6 +28,17 @@ static int8_t _peepPathFindMaxJunctions;
|
||||||
static int32_t _peepPathFindTilesChecked;
|
static int32_t _peepPathFindTilesChecked;
|
||||||
static uint8_t _peepPathFindFewestNumSteps;
|
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);
|
static int32_t guest_surface_path_finding(Peep* peep);
|
||||||
|
|
||||||
/* A junction history for the peep pathfinding heuristic search
|
/* A junction history for the peep pathfinding heuristic search
|
||||||
|
@ -242,7 +255,7 @@ static uint8_t footpath_element_next_in_direction(TileCoordsXYZ loc, PathElement
|
||||||
continue;
|
continue;
|
||||||
if (nextTileElement->GetType() != TILE_ELEMENT_TYPE_PATH)
|
if (nextTileElement->GetType() != TILE_ELEMENT_TYPE_PATH)
|
||||||
continue;
|
continue;
|
||||||
if (!is_valid_path_z_and_direction(nextTileElement, loc.z, chosenDirection))
|
if (!IsValidPathZAndDirection(nextTileElement, loc.z, chosenDirection))
|
||||||
continue;
|
continue;
|
||||||
if (nextTileElement->AsPath()->IsWide())
|
if (nextTileElement->AsPath()->IsWide())
|
||||||
return PATH_SEARCH_WIDE;
|
return PATH_SEARCH_WIDE;
|
||||||
|
@ -335,7 +348,7 @@ static uint8_t footpath_element_dest_in_dir(
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TILE_ELEMENT_TYPE_PATH:
|
case TILE_ELEMENT_TYPE_PATH:
|
||||||
if (!is_valid_path_z_and_direction(tileElement, loc.z, chosenDirection))
|
if (!IsValidPathZAndDirection(tileElement, loc.z, chosenDirection))
|
||||||
continue;
|
continue;
|
||||||
if (tileElement->AsPath()->IsWide())
|
if (tileElement->AsPath()->IsWide())
|
||||||
return PATH_SEARCH_WIDE;
|
return PATH_SEARCH_WIDE;
|
||||||
|
@ -763,7 +776,7 @@ static void peep_pathfind_heuristic_search(
|
||||||
* queue path.
|
* queue path.
|
||||||
* Otherwise, peeps walk on path tiles to get to the goal. */
|
* 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;
|
continue;
|
||||||
|
|
||||||
// Path may be sloped, so set z to path base height.
|
// Path may be sloped, so set z to path base height.
|
||||||
|
@ -1726,13 +1739,13 @@ static int32_t guest_path_find_park_entrance(Peep* peep, uint8_t edges)
|
||||||
gPeepPathFindQueueRideIndex = RIDE_ID_NULL;
|
gPeepPathFindQueueRideIndex = RIDE_ID_NULL;
|
||||||
|
|
||||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||||
pathfind_logging_enable(peep);
|
PathfindLoggingEnable(peep);
|
||||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||||
|
|
||||||
Direction chosenDirection = peep_pathfind_choose_direction(TileCoordsXYZ{ peep->NextLoc }, peep);
|
Direction chosenDirection = peep_pathfind_choose_direction(TileCoordsXYZ{ peep->NextLoc }, peep);
|
||||||
|
|
||||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||||
pathfind_logging_disable();
|
PathfindLoggingDisable();
|
||||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||||
|
|
||||||
if (chosenDirection == INVALID_DIRECTION)
|
if (chosenDirection == INVALID_DIRECTION)
|
||||||
|
@ -1929,7 +1942,7 @@ static StationIndex guest_pathfinding_select_random_station(
|
||||||
int32_t guest_path_finding(Guest* peep)
|
int32_t guest_path_finding(Guest* peep)
|
||||||
{
|
{
|
||||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||||
pathfind_logging_enable(peep);
|
PathfindLoggingEnable(peep);
|
||||||
if (gPathFindDebug)
|
if (gPathFindDebug)
|
||||||
{
|
{
|
||||||
log_info("Starting guest_path_finding for %s", gPathFindDebugPeepName);
|
log_info("Starting guest_path_finding for %s", gPathFindDebugPeepName);
|
||||||
|
@ -2006,7 +2019,7 @@ int32_t guest_path_finding(Guest* peep)
|
||||||
"Completed guest_path_finding for %s - taking only direction available: %d.", gPathFindDebugPeepName,
|
"Completed guest_path_finding for %s - taking only direction available: %d.", gPathFindDebugPeepName,
|
||||||
direction);
|
direction);
|
||||||
}
|
}
|
||||||
pathfind_logging_disable();
|
PathfindLoggingDisable();
|
||||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||||
return peep_move_one_tile(direction, peep);
|
return peep_move_one_tile(direction, peep);
|
||||||
}
|
}
|
||||||
|
@ -2022,7 +2035,7 @@ int32_t guest_path_finding(Guest* peep)
|
||||||
{
|
{
|
||||||
log_info("Completed guest_path_finding for %s - peep is outside the park.", gPathFindDebugPeepName);
|
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
|
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||||
switch (peep->State)
|
switch (peep->State)
|
||||||
{
|
{
|
||||||
|
@ -2092,7 +2105,7 @@ int32_t guest_path_finding(Guest* peep)
|
||||||
{
|
{
|
||||||
log_info("Completed guest_path_finding for %s - peep is leaving the park.", gPathFindDebugPeepName);
|
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
|
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||||
return guest_path_find_park_entrance(peep, edges);
|
return guest_path_find_park_entrance(peep, edges);
|
||||||
}
|
}
|
||||||
|
@ -2104,7 +2117,7 @@ int32_t guest_path_finding(Guest* peep)
|
||||||
{
|
{
|
||||||
log_info("Completed guest_path_finding for %s - peep is aimless.", gPathFindDebugPeepName);
|
log_info("Completed guest_path_finding for %s - peep is aimless.", gPathFindDebugPeepName);
|
||||||
}
|
}
|
||||||
pathfind_logging_disable();
|
PathfindLoggingDisable();
|
||||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||||
return guest_path_find_aimless(peep, edges);
|
return guest_path_find_aimless(peep, edges);
|
||||||
}
|
}
|
||||||
|
@ -2120,7 +2133,7 @@ int32_t guest_path_finding(Guest* peep)
|
||||||
log_info(
|
log_info(
|
||||||
"Completed guest_path_finding for %s - peep is heading to closed ride == aimless.", gPathFindDebugPeepName);
|
"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
|
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||||
return guest_path_find_aimless(peep, edges);
|
return guest_path_find_aimless(peep, edges);
|
||||||
}
|
}
|
||||||
|
@ -2196,14 +2209,14 @@ int32_t guest_path_finding(Guest* peep)
|
||||||
* This lets the heuristic search "try again" in case the player has
|
* This lets the heuristic search "try again" in case the player has
|
||||||
* edited the path layout or the mechanic was already stuck in the
|
* edited the path layout or the mechanic was already stuck in the
|
||||||
* save game (e.g. with a worse version of the pathfinding). */
|
* 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 defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||||
if (gPathFindDebug)
|
if (gPathFindDebug)
|
||||||
{
|
{
|
||||||
log_info("Completed guest_path_finding for %s - failed to choose a direction == aimless.", gPathFindDebugPeepName);
|
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
|
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||||
|
|
||||||
return guest_path_find_aimless(peep, edges);
|
return guest_path_find_aimless(peep, edges);
|
||||||
|
@ -2213,7 +2226,85 @@ int32_t guest_path_finding(Guest* peep)
|
||||||
{
|
{
|
||||||
log_info("Completed guest_path_finding for %s - direction chosen: %d.", gPathFindDebugPeepName, direction);
|
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
|
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||||
return peep_move_one_tile(direction, peep);
|
return peep_move_one_tile(direction, peep);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsValidPathZAndDirection(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::ResetPathfindGoal()
|
||||||
|
{
|
||||||
|
#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
|
||||||
|
|
||||||
|
PathfindGoal.x = 0xFF;
|
||||||
|
PathfindGoal.y = 0xFF;
|
||||||
|
PathfindGoal.z = 0xFF;
|
||||||
|
PathfindGoal.direction = INVALID_DIRECTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||||
|
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));
|
||||||
|
|
||||||
|
/* 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 PathfindLoggingDisable()
|
||||||
|
{
|
||||||
|
# if defined(PATHFIND_DEBUG) && PATHFIND_DEBUG
|
||||||
|
gPathFindDebug = false;
|
||||||
|
# endif // defined(PATHFIND_DEBUG) && PATHFIND_DEBUG
|
||||||
|
}
|
||||||
|
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||||
|
|
65
src/openrct2/peep/GuestPathfinding.h
Normal file
65
src/openrct2/peep/GuestPathfinding.h
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
* 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../common.h"
|
||||||
|
#include "../ride/RideTypes.h"
|
||||||
|
#include "../world/Location.hpp"
|
||||||
|
|
||||||
|
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.
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Test whether the given tile can be walked onto, if the peep is currently at height currentZ and
|
||||||
|
// moving in direction 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.
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
# 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();
|
||||||
|
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
|
@ -44,17 +44,13 @@
|
||||||
#include "../world/SmallScenery.h"
|
#include "../world/SmallScenery.h"
|
||||||
#include "../world/Sprite.h"
|
#include "../world/Sprite.h"
|
||||||
#include "../world/Surface.h"
|
#include "../world/Surface.h"
|
||||||
|
#include "GuestPathfinding.h"
|
||||||
#include "Staff.h"
|
#include "Staff.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
#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;
|
uint8_t gGuestChangeModifier;
|
||||||
uint32_t gNumGuestsInPark;
|
uint32_t gNumGuestsInPark;
|
||||||
uint32_t gNumGuestsInParkLastWeek;
|
uint32_t gNumGuestsInParkLastWeek;
|
||||||
|
@ -69,10 +65,6 @@ uint32_t gNextGuestNumber;
|
||||||
|
|
||||||
uint8_t gPeepWarningThrottle[16];
|
uint8_t gPeepWarningThrottle[16];
|
||||||
|
|
||||||
TileCoordsXYZ gPeepPathFindGoalPosition;
|
|
||||||
bool gPeepPathFindIgnoreForeignQueues;
|
|
||||||
ride_id_t gPeepPathFindQueueRideIndex;
|
|
||||||
|
|
||||||
static uint8_t _unk_F1AEF0;
|
static uint8_t _unk_F1AEF0;
|
||||||
static TileElement* _peepRideEntranceExitElement;
|
static TileElement* _peepRideEntranceExitElement;
|
||||||
|
|
||||||
|
@ -1715,10 +1707,7 @@ Peep* Peep::Generate(const CoordsXYZ& coords)
|
||||||
peep->CashInPocket = cash;
|
peep->CashInPocket = cash;
|
||||||
peep->CashSpent = 0;
|
peep->CashSpent = 0;
|
||||||
peep->TimeInPark = -1;
|
peep->TimeInPark = -1;
|
||||||
peep->PathfindGoal.x = 0xFF;
|
peep->ResetPathfindGoal();
|
||||||
peep->PathfindGoal.y = 0xFF;
|
|
||||||
peep->PathfindGoal.z = 0xFF;
|
|
||||||
peep->PathfindGoal.direction = INVALID_DIRECTION;
|
|
||||||
peep->ItemStandardFlags = 0;
|
peep->ItemStandardFlags = 0;
|
||||||
peep->ItemExtraFlags = 0;
|
peep->ItemExtraFlags = 0;
|
||||||
peep->GuestHeadingToRideId = RIDE_ID_NULL;
|
peep->GuestHeadingToRideId = RIDE_ID_NULL;
|
||||||
|
@ -2953,33 +2942,6 @@ static bool peep_interact_with_shop(Peep* peep, const CoordsXYE& coords)
|
||||||
return true;
|
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)
|
void Peep::PerformNextAction(uint8_t& pathing_result)
|
||||||
{
|
{
|
||||||
TileElement* tmpTile;
|
TileElement* tmpTile;
|
||||||
|
@ -3139,25 +3101,6 @@ void Peep::PerformNextAction(uint8_t& pathing_result, TileElement*& tile_result)
|
||||||
peep_return_to_centre_of_tile(this);
|
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
|
* Gets the height including the bit depending on how far up the slope the peep
|
||||||
* is.
|
* is.
|
||||||
|
@ -3263,38 +3206,6 @@ void peep_update_names(bool realNames)
|
||||||
gfx_invalidate_screen();
|
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()
|
void increment_guests_in_park()
|
||||||
{
|
{
|
||||||
if (gNumGuestsInPark < UINT32_MAX)
|
if (gNumGuestsInPark < UINT32_MAX)
|
||||||
|
|
|
@ -804,6 +804,10 @@ public: // Peep
|
||||||
std::string GetName() const;
|
std::string GetName() const;
|
||||||
bool SetName(const std::string_view& value);
|
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
|
// TODO: Make these private again when done refactoring
|
||||||
public: // Peep
|
public: // Peep
|
||||||
bool CheckForPath();
|
bool CheckForPath();
|
||||||
|
@ -1030,10 +1034,6 @@ extern uint32_t gNextGuestNumber;
|
||||||
|
|
||||||
extern uint8_t gPeepWarningThrottle[16];
|
extern uint8_t gPeepWarningThrottle[16];
|
||||||
|
|
||||||
extern TileCoordsXYZ gPeepPathFindGoalPosition;
|
|
||||||
extern bool gPeepPathFindIgnoreForeignQueues;
|
|
||||||
extern ride_id_t gPeepPathFindQueueRideIndex;
|
|
||||||
|
|
||||||
Peep* try_get_guest(uint16_t spriteIndex);
|
Peep* try_get_guest(uint16_t spriteIndex);
|
||||||
int32_t peep_get_staff_count();
|
int32_t peep_get_staff_count();
|
||||||
bool peep_can_be_picked_up(Peep* peep);
|
bool peep_can_be_picked_up(Peep* peep);
|
||||||
|
@ -1058,26 +1058,6 @@ void peep_update_names(bool realNames);
|
||||||
|
|
||||||
void guest_set_name(uint16_t spriteIndex, const char* name);
|
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_in_park();
|
||||||
void increment_guests_heading_for_park();
|
void increment_guests_heading_for_park();
|
||||||
void decrement_guests_in_park();
|
void decrement_guests_in_park();
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "../world/SmallScenery.h"
|
#include "../world/SmallScenery.h"
|
||||||
#include "../world/Sprite.h"
|
#include "../world/Sprite.h"
|
||||||
#include "../world/Surface.h"
|
#include "../world/Surface.h"
|
||||||
|
#include "GuestPathfinding.h"
|
||||||
#include "Peep.h"
|
#include "Peep.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -282,7 +283,7 @@ bool staff_can_ignore_wide_flag(Peep* staff, const CoordsXYZ& staffPos, TileElem
|
||||||
}
|
}
|
||||||
|
|
||||||
/* test_element is a path */
|
/* 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;
|
continue;
|
||||||
|
|
||||||
/* test_element is a connected path */
|
/* test_element is a connected path */
|
||||||
|
@ -856,13 +857,13 @@ static uint8_t staff_mechanic_direction_path(Peep* peep, uint8_t validDirections
|
||||||
gPeepPathFindQueueRideIndex = RIDE_ID_NULL;
|
gPeepPathFindQueueRideIndex = RIDE_ID_NULL;
|
||||||
|
|
||||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||||
pathfind_logging_enable(peep);
|
PathfindLoggingEnable(peep);
|
||||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||||
|
|
||||||
Direction pathfindDirection = peep_pathfind_choose_direction(TileCoordsXYZ{ peep->NextLoc }, peep);
|
Direction pathfindDirection = peep_pathfind_choose_direction(TileCoordsXYZ{ peep->NextLoc }, peep);
|
||||||
|
|
||||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||||
pathfind_logging_disable();
|
PathfindLoggingDisable();
|
||||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||||
|
|
||||||
if (pathfindDirection == INVALID_DIRECTION)
|
if (pathfindDirection == INVALID_DIRECTION)
|
||||||
|
@ -873,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
|
* This lets the heuristic search "try again" in case the player has
|
||||||
* edited the path layout or the mechanic was already stuck in the
|
* edited the path layout or the mechanic was already stuck in the
|
||||||
* save game (e.g. with a worse version of the pathfinding). */
|
* 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);
|
return staff_mechanic_direction_path_rand(peep, pathDirections);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1436,7 +1437,7 @@ void Staff::UpdateHeadingToInspect()
|
||||||
if (SubState == 0)
|
if (SubState == 0)
|
||||||
{
|
{
|
||||||
MechanicTimeSinceCall = 0;
|
MechanicTimeSinceCall = 0;
|
||||||
peep_reset_pathfind_goal(this);
|
ResetPathfindGoal();
|
||||||
SubState = 2;
|
SubState = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1546,7 +1547,7 @@ void Staff::UpdateAnswering()
|
||||||
SubState = 2;
|
SubState = 2;
|
||||||
peep_window_state_update(this);
|
peep_window_state_update(this);
|
||||||
MechanicTimeSinceCall = 0;
|
MechanicTimeSinceCall = 0;
|
||||||
peep_reset_pathfind_goal(this);
|
ResetPathfindGoal();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
UpdateAction();
|
UpdateAction();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "TestData.h"
|
#include "TestData.h"
|
||||||
#include "openrct2/core/StringReader.hpp"
|
#include "openrct2/core/StringReader.hpp"
|
||||||
|
#include "openrct2/peep/GuestPathfinding.h"
|
||||||
#include "openrct2/peep/Peep.h"
|
#include "openrct2/peep/Peep.h"
|
||||||
#include "openrct2/ride/Station.h"
|
#include "openrct2/ride/Station.h"
|
||||||
#include "openrct2/scenario/Scenario.h"
|
#include "openrct2/scenario/Scenario.h"
|
||||||
|
|
Loading…
Add table
Reference in a new issue