mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-15 11:03:00 +01:00
Part of pathfinding rework
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
#include "localisation/Localisation.h"
|
||||
#include "management/NewsItem.h"
|
||||
#include "network/network.h"
|
||||
#include "./peep/GuestPathfinding.h"
|
||||
#include "platform/Platform.h"
|
||||
#include "profiling/Profiling.h"
|
||||
#include "ride/Vehicle.h"
|
||||
@@ -88,6 +89,9 @@ void GameState::InitAll(const TileCoordsXY& mapSize)
|
||||
CheatsReset();
|
||||
ClearRestrictedScenery();
|
||||
|
||||
// TODO: find a better place for this
|
||||
gGuestPathfinder = new OriginalPathfinding();
|
||||
|
||||
#ifdef ENABLE_SCRIPTING
|
||||
auto& scriptEngine = GetContext()->GetScriptEngine();
|
||||
scriptEngine.ClearParkStorage();
|
||||
|
||||
@@ -81,6 +81,7 @@ static void* _crowdSoundChannel = nullptr;
|
||||
static void peep_128_tick_update(Peep* peep, int32_t index);
|
||||
static void peep_release_balloon(Guest* peep, int16_t spawn_height);
|
||||
|
||||
|
||||
static PeepActionSpriteType PeepSpecialSpriteToSpriteTypeMap[] = {
|
||||
PeepActionSpriteType::None,
|
||||
PeepActionSpriteType::HoldMat,
|
||||
@@ -2357,7 +2358,7 @@ void Peep::PerformNextAction(uint8_t& pathing_result, TileElement*& tile_result)
|
||||
|
||||
if (guest != nullptr)
|
||||
{
|
||||
result = guest_path_finding(guest);
|
||||
result = gGuestPathfinder->guest_path_finding(guest);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -399,7 +399,7 @@ public: // Peep
|
||||
bool IsActionInterruptable() const;
|
||||
|
||||
// Reset the peep's stored goal, which means they will forget any stored pathfinding history
|
||||
// on the next peep_pathfind_choose_direction call.
|
||||
// on the next GuestPathfinding::peep_pathfind_choose_direction call.
|
||||
void ResetPathfindGoal();
|
||||
|
||||
void SetDestination(const CoordsXY& coords);
|
||||
|
||||
@@ -66,6 +66,8 @@ colour_t gStaffHandymanColour;
|
||||
colour_t gStaffMechanicColour;
|
||||
colour_t gStaffSecurityColour;
|
||||
|
||||
GuestPathfinding* gGuestPathfinder;
|
||||
|
||||
// Maximum manhattan distance that litter can be for a handyman to seek to it
|
||||
const uint16_t MAX_LITTER_DISTANCE = 3 * COORDS_XY_STEP;
|
||||
|
||||
@@ -181,7 +183,7 @@ bool Staff::CanIgnoreWideFlag(const CoordsXYZ& staffPos, TileElement* path) cons
|
||||
}
|
||||
|
||||
/* test_element is a path */
|
||||
if (!IsValidPathZAndDirection(test_element, adjacPos.z / COORDS_Z_STEP, adjac_dir))
|
||||
if (!GuestPathfinding::IsValidPathZAndDirection(test_element, adjacPos.z / COORDS_Z_STEP, adjac_dir))
|
||||
continue;
|
||||
|
||||
/* test_element is a connected path */
|
||||
@@ -722,7 +724,7 @@ Direction Staff::MechanicDirectionPath(uint8_t validDirections, PathElement* pat
|
||||
PathfindLoggingEnable(this);
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
|
||||
Direction pathfindDirection = peep_pathfind_choose_direction(TileCoordsXYZ{ NextLoc }, this);
|
||||
Direction pathfindDirection = gGuestPathfinder->peep_pathfind_choose_direction(TileCoordsXYZ{ NextLoc }, this);
|
||||
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
PathfindLoggingDisable();
|
||||
@@ -732,7 +734,7 @@ Direction Staff::MechanicDirectionPath(uint8_t validDirections, PathElement* pat
|
||||
{
|
||||
/* 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 GuestPathfinding::peep_pathfind_choose_direction().
|
||||
* 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). */
|
||||
|
||||
@@ -289,7 +289,7 @@ static uint8_t footpath_element_next_in_direction(TileCoordsXYZ loc, PathElement
|
||||
continue;
|
||||
if (nextTileElement->GetType() != TileElementType::Path)
|
||||
continue;
|
||||
if (!IsValidPathZAndDirection(nextTileElement, loc.z, chosenDirection))
|
||||
if (!GuestPathfinding::IsValidPathZAndDirection(nextTileElement, loc.z, chosenDirection))
|
||||
continue;
|
||||
if (nextTileElement->AsPath()->IsWide())
|
||||
return PATH_SEARCH_WIDE;
|
||||
@@ -382,7 +382,7 @@ static uint8_t footpath_element_dest_in_dir(TileCoordsXYZ loc, Direction chosenD
|
||||
break;
|
||||
case TileElementType::Path:
|
||||
{
|
||||
if (!IsValidPathZAndDirection(tileElement, loc.z, chosenDirection))
|
||||
if (!GuestPathfinding::IsValidPathZAndDirection(tileElement, loc.z, chosenDirection))
|
||||
continue;
|
||||
if (tileElement->AsPath()->IsWide())
|
||||
return PATH_SEARCH_WIDE;
|
||||
@@ -824,7 +824,7 @@ static void peep_pathfind_heuristic_search(
|
||||
* queue path.
|
||||
* Otherwise, peeps walk on path tiles to get to the goal. */
|
||||
|
||||
if (!IsValidPathZAndDirection(tileElement, loc.z, test_edge))
|
||||
if (!GuestPathfinding::IsValidPathZAndDirection(tileElement, loc.z, test_edge))
|
||||
continue;
|
||||
|
||||
// Path may be sloped, so set z to path base height.
|
||||
@@ -1261,7 +1261,7 @@ static void peep_pathfind_heuristic_search(
|
||||
*
|
||||
* rct2: 0x0069A5F0
|
||||
*/
|
||||
Direction peep_pathfind_choose_direction(const TileCoordsXYZ& loc, Peep* peep)
|
||||
Direction OriginalPathfinding::peep_pathfind_choose_direction(const TileCoordsXYZ& loc, Peep* peep)
|
||||
{
|
||||
PROFILED_FUNCTION();
|
||||
|
||||
@@ -1661,7 +1661,7 @@ static std::optional<CoordsXYZ> GetNearestParkEntrance(const CoordsXY& loc)
|
||||
*
|
||||
* rct2: 0x006952C0
|
||||
*/
|
||||
static int32_t 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);
|
||||
@@ -1710,7 +1710,7 @@ static uint8_t get_nearest_peep_spawn_index(uint16_t x, uint16_t y)
|
||||
*
|
||||
* rct2: 0x0069536C
|
||||
*/
|
||||
static int32_t 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);
|
||||
@@ -1741,7 +1741,7 @@ static int32_t GuestPathFindPeepSpawn(Peep* peep, uint8_t edges)
|
||||
*
|
||||
* rct2: 0x00695161
|
||||
*/
|
||||
static int32_t 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)
|
||||
@@ -1971,7 +1971,7 @@ static StationIndex guest_pathfinding_select_random_station(
|
||||
*
|
||||
* rct2: 0x00694C35
|
||||
*/
|
||||
int32_t guest_path_finding(Guest* peep)
|
||||
int32_t OriginalPathfinding::guest_path_finding(Guest* peep)
|
||||
{
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
PathfindLoggingEnable(peep);
|
||||
@@ -2266,7 +2266,7 @@ int32_t guest_path_finding(Guest* peep)
|
||||
return peep_move_one_tile(direction, peep);
|
||||
}
|
||||
|
||||
bool IsValidPathZAndDirection(TileElement* tileElement, int32_t currentZ, int32_t currentDirection)
|
||||
bool GuestPathfinding::IsValidPathZAndDirection(TileElement* tileElement, int32_t currentZ, int32_t currentDirection)
|
||||
{
|
||||
if (tileElement->AsPath()->IsSloped())
|
||||
{
|
||||
|
||||
@@ -17,6 +17,8 @@ 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).
|
||||
//
|
||||
@@ -37,19 +39,42 @@ extern RideId gPeepPathFindQueueRideIndex;
|
||||
// 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);
|
||||
class GuestPathfinding
|
||||
{
|
||||
public:
|
||||
// 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.
|
||||
virtual Direction peep_pathfind_choose_direction(const TileCoordsXYZ& loc, Peep* peep) = 0;
|
||||
|
||||
// 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);
|
||||
// Test whether the given tile can be walked onto, if the peep is currently at height currentZ and
|
||||
// moving in direction currentDirection.
|
||||
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.
|
||||
//
|
||||
// Returns 0 if the guest has successfully had a new destination set up, nonzero otherwise.
|
||||
int32_t guest_path_finding(Guest* peep);
|
||||
// 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.
|
||||
virtual int32_t guest_path_finding(Guest* peep) = 0;
|
||||
|
||||
};
|
||||
|
||||
class OriginalPathfinding : public GuestPathfinding
|
||||
{
|
||||
public:
|
||||
Direction peep_pathfind_choose_direction(const TileCoordsXYZ& loc, Peep* peep);
|
||||
|
||||
int32_t guest_path_finding(Guest* peep);
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
//TODO: Implement a better solution than a global variable for the utilized pathfinder
|
||||
extern GuestPathfinding* gGuestPathfinder;
|
||||
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
# define PATHFIND_DEBUG \
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
using namespace OpenRCT2;
|
||||
|
||||
|
||||
static std::ostream& operator<<(std::ostream& os, const TileCoordsXYZ& coords)
|
||||
{
|
||||
return os << "(" << coords.x << ", " << coords.y << ", " << coords.z << ")";
|
||||
@@ -84,7 +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 = peep_pathfind_choose_direction(*pos, peep);
|
||||
const Direction moveDir = gGuestPathfinder->peep_pathfind_choose_direction(*pos, peep);
|
||||
if (moveDir == INVALID_DIRECTION)
|
||||
{
|
||||
// Couldn't determine a direction to move off in
|
||||
|
||||
Reference in New Issue
Block a user