mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #4847 from zaxcav/pathfind_history_fixes
Further pathfinding fixes
This commit is contained in:
commit
1083ccebd0
|
@ -55,7 +55,7 @@ extern "C" {
|
|||
// This define specifies which version of network stream current build uses.
|
||||
// It is used for making sure only compatible builds get connected, even within
|
||||
// single OpenRCT2 version.
|
||||
#define NETWORK_STREAM_VERSION "21"
|
||||
#define NETWORK_STREAM_VERSION "22"
|
||||
#define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
271
src/peep/peep.c
271
src/peep/peep.c
|
@ -145,7 +145,7 @@ static void peep_ride_is_too_intense(rct_peep *peep, int rideIndex, bool peepAtR
|
|||
static void peep_chose_not_to_go_on_ride(rct_peep *peep, int rideIndex, bool peepAtRide, bool updateLastRide);
|
||||
static void peep_tried_to_enter_full_queue(rct_peep *peep, int rideIndex);
|
||||
static bool peep_should_go_to_shop(rct_peep *peep, int rideIndex, bool peepAtShop);
|
||||
static void peep_reset_pathfind_goal(rct_peep *peep);
|
||||
void peep_reset_pathfind_goal(rct_peep *peep);
|
||||
static bool peep_find_ride_to_look_at(rct_peep *peep, uint8 edge, uint8 *rideToView, uint8 *rideSeatToView);
|
||||
static void peep_easter_egg_peep_interactions(rct_peep *peep);
|
||||
static int peep_get_height_on_slope(rct_peep *peep, int x, int y);
|
||||
|
@ -9320,7 +9320,17 @@ static void peep_pathfind_heuristic_search(sint16 x, sint16 y, uint8 z, rct_peep
|
|||
if (peep->pathfind_history[i].x == x >> 5 &&
|
||||
peep->pathfind_history[i].y == y >> 5 &&
|
||||
peep->pathfind_history[i].z == z) {
|
||||
pathLoop = true;
|
||||
if (peep->pathfind_history[i].direction == 0) {
|
||||
/* If all directions have already been tried while
|
||||
* heading to this goal, this is a loop. */
|
||||
pathLoop = true;
|
||||
}
|
||||
else {
|
||||
/* The peep remembers walking through this junction
|
||||
* before, but has not yet tried all directions.
|
||||
* Limit the edges to search to those not yet tried. */
|
||||
edges &= peep->pathfind_history[i].direction;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -9485,21 +9495,50 @@ int peep_pathfind_choose_direction(sint16 x, sint16 y, uint8 z, rct_peep *peep)
|
|||
|
||||
// Get the path element at this location
|
||||
rct_map_element *dest_map_element = map_get_first_element_at(x / 32, y / 32);
|
||||
/* Where there are multiple matching map elements placed with zero
|
||||
* clearance, save the first one for later use to determine the path
|
||||
* slope - this maintains the original behaviour (which only processes
|
||||
* the first matching map element found) and is consistent with peep
|
||||
* placement (i.e. height) on such paths with differing slopes.
|
||||
*
|
||||
* I cannot see a legitimate reason for building overlaid paths with
|
||||
* differing slopes and do not recall ever seeing this in practise.
|
||||
* Normal cases I have seen in practise are overlaid paths with the
|
||||
* same slope (flat) in order to place scenery (e.g. benches) in the
|
||||
* middle of a wide path that can still be walked through.
|
||||
* Anyone attempting to overlay paths with different slopes should
|
||||
* EXPECT to experience path finding irregularities due to those paths!
|
||||
* In particular common edges at different heights will not work
|
||||
* in a useful way. Simply do not do it! :-) */
|
||||
rct_map_element *first_map_element = NULL;
|
||||
|
||||
bool found = false;
|
||||
uint8 permitted_edges = 0;
|
||||
bool isThin = false;
|
||||
do {
|
||||
if (dest_map_element->base_height != z) continue;
|
||||
if (map_element_get_type(dest_map_element) != MAP_ELEMENT_TYPE_PATH) continue;
|
||||
found = true;
|
||||
break;
|
||||
if (first_map_element == NULL) {
|
||||
first_map_element = dest_map_element;
|
||||
}
|
||||
|
||||
/* Check if this path element is a thin junction.
|
||||
* Only 'thin' junctions are remembered in peep->pathfind_history.
|
||||
* 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
|
||||
* overlaid path elements there is a 'thin junction'. */
|
||||
isThin = isThin || path_is_thin_junction(dest_map_element, x, y, z);
|
||||
|
||||
// Collect the permitted edges of ALL matching path elements at this location.
|
||||
permitted_edges |= path_get_permitted_edges(dest_map_element);
|
||||
} while (!map_element_is_last_for_tile(dest_map_element++));
|
||||
// Peep is not on a path.
|
||||
if (!found) return -1;
|
||||
|
||||
/* Determine if the path is a thin junction.
|
||||
* Only 'thin' junctions are remembered in peep->pathfind_history. */
|
||||
bool isThin = path_is_thin_junction(dest_map_element, x, y, z);
|
||||
|
||||
uint8 edges = 0xF;
|
||||
permitted_edges &= 0xF;
|
||||
uint8 edges = permitted_edges;
|
||||
if (isThin && peep->pathfind_goal.x == goal.x &&
|
||||
peep->pathfind_goal.y == goal.y &&
|
||||
peep->pathfind_goal.z == goal.z
|
||||
|
@ -9523,19 +9562,66 @@ int peep_pathfind_choose_direction(sint16 x, sint16 y, uint8 z, rct_peep *peep)
|
|||
if (peep->pathfind_history[i].x == x / 32 &&
|
||||
peep->pathfind_history[i].y == y / 32 &&
|
||||
peep->pathfind_history[i].z == z) {
|
||||
edges = peep->pathfind_history[i].direction & 0xF;
|
||||
|
||||
/* Fix broken pathfind_history[i].direction
|
||||
* which have untried directions that are not
|
||||
* currently possible - could be due to pathing
|
||||
* changes or in earlier code .directions was
|
||||
* initialised to 0xF rather than the permitted
|
||||
* edges. */
|
||||
peep->pathfind_history[i].direction &= permitted_edges;
|
||||
|
||||
edges = peep->pathfind_history[i].direction;
|
||||
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (gPathFindDebug) {
|
||||
log_verbose("Getting untried edges from pf_history for %d,%d,%d: %s,%s,%s,%s", x >> 5, y >> 5, z, (edges & 1) ? "0" : "-", (edges & 2) ? "1" : "-", (edges & 4) ? "2" : "-", (edges & 8) ? "3" : "-");
|
||||
}
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
|
||||
if (edges == 0) {
|
||||
/* If peep has tried all edges, reset to
|
||||
* all edges are untried.
|
||||
* This permits the pathfinding to try
|
||||
* again, which is good for getting
|
||||
* unstuck when the player has edited
|
||||
* the paths or the pathfinding itself
|
||||
* has changed (been fixed) since
|
||||
* the game was saved. */
|
||||
peep->pathfind_history[i].direction = permitted_edges;
|
||||
edges = peep->pathfind_history[i].direction;
|
||||
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (gPathFindDebug) {
|
||||
log_verbose("All edges tried for %d,%d,%d - resetting to all untried", x >> 5, y >> 5, z);
|
||||
}
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove any edges that are not permitted
|
||||
edges &= path_get_permitted_edges(dest_map_element);
|
||||
/* If this is a new goal for the peep. Store it and reset the peep's
|
||||
* pathfind_history. */
|
||||
if (peep->pathfind_goal.direction > 3 ||
|
||||
peep->pathfind_goal.x != goal.x ||
|
||||
peep->pathfind_goal.y != goal.y ||
|
||||
peep->pathfind_goal.z != goal.z
|
||||
) {
|
||||
peep->pathfind_goal.x = goal.x;
|
||||
peep->pathfind_goal.y = goal.y;
|
||||
peep->pathfind_goal.z = goal.z;
|
||||
peep->pathfind_goal.direction = 0;
|
||||
|
||||
// Clear pathfinding history
|
||||
memset(peep->pathfind_history, 0xFF, sizeof(peep->pathfind_history));
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (gPathFindDebug) {
|
||||
log_verbose("New goal; clearing pf_history.");
|
||||
}
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
}
|
||||
|
||||
// Peep has tried all edges.
|
||||
if (edges == 0) return -1;
|
||||
|
@ -9567,8 +9653,8 @@ int peep_pathfind_choose_direction(sint16 x, sint16 y, uint8 z, rct_peep *peep)
|
|||
edges &= ~(1 << test_edge);
|
||||
uint8 height = z;
|
||||
|
||||
if (footpath_element_is_sloped(dest_map_element) &&
|
||||
footpath_element_get_slope_direction(dest_map_element) == test_edge
|
||||
if (footpath_element_is_sloped(first_map_element) &&
|
||||
footpath_element_get_slope_direction(first_map_element) == test_edge
|
||||
) {
|
||||
height += 0x2;
|
||||
}
|
||||
|
@ -9612,7 +9698,13 @@ int peep_pathfind_choose_direction(sint16 x, sint16 y, uint8 z, rct_peep *peep)
|
|||
rct_xyz8 endJunctionList[16] = { 0 };
|
||||
uint8 endDirectionList[16] = { 0 };
|
||||
|
||||
peep_pathfind_heuristic_search(x, y, height, peep, dest_map_element, 0, &score, test_edge, &endJunctions, endJunctionList, endDirectionList, &endXYZ, &endSteps);
|
||||
#if defined(DEBUG_LEVEL_2) && DEBUG_LEVEL_2
|
||||
if (gPathFindDebug) {
|
||||
log_verbose("Pathfind searching in direction: %d from %d,%d,%d", test_edge, x >> 5, y >> 5, z);
|
||||
}
|
||||
#endif // defined(DEBUG_LEVEL_2) && DEBUG_LEVEL_2
|
||||
|
||||
peep_pathfind_heuristic_search(x, y, height, peep, first_map_element, 0, &score, test_edge, &endJunctions, endJunctionList, endDirectionList, &endXYZ, &endSteps);
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (gPathFindDebug) {
|
||||
log_verbose("Pathfind test edge: %d score: %d steps: %d end: %d,%d,%d junctions: %d", test_edge, score, endSteps, endXYZ.x, endXYZ.y, endXYZ.z, endJunctions);
|
||||
|
@ -9663,27 +9755,6 @@ int peep_pathfind_choose_direction(sint16 x, sint16 y, uint8 z, rct_peep *peep)
|
|||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
}
|
||||
|
||||
/* If this is a new goal for the peep. Store it and reset the peep's
|
||||
* pathfind_history. */
|
||||
if (peep->pathfind_goal.direction > 3 ||
|
||||
peep->pathfind_goal.x != goal.x ||
|
||||
peep->pathfind_goal.y != goal.y ||
|
||||
peep->pathfind_goal.z != goal.z
|
||||
) {
|
||||
peep->pathfind_goal.x = goal.x;
|
||||
peep->pathfind_goal.y = goal.y;
|
||||
peep->pathfind_goal.z = goal.z;
|
||||
peep->pathfind_goal.direction = 0;
|
||||
|
||||
// Clear pathfinding history
|
||||
memset(peep->pathfind_history, 0xFF, sizeof(peep->pathfind_history));
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (gPathFindDebug) {
|
||||
log_verbose("New goal; clearing pf_history.");
|
||||
}
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
}
|
||||
|
||||
if (isThin) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (peep->pathfind_history[i].x == x >> 5 &&
|
||||
|
@ -9709,11 +9780,11 @@ int peep_pathfind_choose_direction(sint16 x, sint16 y, uint8 z, rct_peep *peep)
|
|||
peep->pathfind_history[i].x = x >> 5;
|
||||
peep->pathfind_history[i].y = y >> 5;
|
||||
peep->pathfind_history[i].z = z;
|
||||
peep->pathfind_history[i].direction = 0xF;
|
||||
peep->pathfind_history[i].direction = permitted_edges;
|
||||
peep->pathfind_history[i].direction &= ~(1 << chosen_edge);
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (gPathFindDebug) {
|
||||
log_verbose("Storing new pf_history for %d,%d,%d without edge %d.", x >> 5, y >> 5, z, chosen_edge);
|
||||
log_verbose("Storing new pf_history (in index: %d) for %d,%d,%d without edge %d.", i, x >> 5, y >> 5, z, chosen_edge);
|
||||
}
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
}
|
||||
|
@ -9840,18 +9911,13 @@ static int guest_path_find_park_entrance(rct_peep* peep, rct_map_element *map_el
|
|||
gPeepPathFindQueueRideIndex = 255;
|
||||
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
/* Determine if the pathfinding debugging is wanted for this peep. */
|
||||
/* For guests, use the existing PEEP_FLAGS_TRACKING flag to
|
||||
* determine for which guest(s) the pathfinding debugging will
|
||||
* be output for. */
|
||||
format_string(gPathFindDebugPeepName, sizeof(gPathFindDebugPeepName), peep->name_string_idx, &(peep->id));
|
||||
gPathFindDebug = peep->peep_flags & PEEP_FLAGS_TRACKING;
|
||||
pathfind_logging_enable(peep);
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
|
||||
int chosenDirection = peep_pathfind_choose_direction(peep->next_x, peep->next_y, peep->next_z, peep);
|
||||
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
gPathFindDebug = false;
|
||||
pathfind_logging_disable();
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
|
||||
if (chosenDirection == -1)
|
||||
|
@ -9991,6 +10057,13 @@ static int guest_path_finding(rct_peep* peep)
|
|||
{
|
||||
sint16 x, y, z;
|
||||
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
pathfind_logging_enable(peep);
|
||||
if (gPathFindDebug) {
|
||||
log_info("Starting guest_path_finding for %s", gPathFindDebugPeepName);
|
||||
}
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
|
||||
if (peep->next_var_29 & 0x18) {
|
||||
return guest_surface_path_finding(peep);
|
||||
}
|
||||
|
@ -10046,6 +10119,12 @@ static int guest_path_finding(rct_peep* peep)
|
|||
direction = bitscanforward(edges);
|
||||
// IF only one edge to choose from
|
||||
if ((edges & ~(1 << direction)) == 0) {
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (gPathFindDebug) {
|
||||
log_info("Completed guest_path_finding for %s - taking only direction available: %d.", gPathFindDebugPeepName, direction);
|
||||
}
|
||||
pathfind_logging_disable();
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
return peep_move_one_tile(direction, peep);
|
||||
}
|
||||
|
||||
|
@ -10054,6 +10133,12 @@ static int guest_path_finding(rct_peep* peep)
|
|||
// Peep is outside the park.
|
||||
// loc_694F19:
|
||||
if (peep->outside_of_park != 0){
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (gPathFindDebug) {
|
||||
log_info("Completed guest_path_finding for %s - peep is outside the park.", gPathFindDebugPeepName);
|
||||
}
|
||||
pathfind_logging_disable();
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
switch (peep->state) {
|
||||
case PEEP_STATE_ENTERING_PARK:
|
||||
return guest_path_find_entering_park(peep, mapElement, edges);
|
||||
|
@ -10107,18 +10192,39 @@ static int guest_path_finding(rct_peep* peep)
|
|||
}
|
||||
}
|
||||
|
||||
if (peep->peep_flags & PEEP_FLAGS_LEAVING_PARK)
|
||||
if (peep->peep_flags & PEEP_FLAGS_LEAVING_PARK) {
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (gPathFindDebug) {
|
||||
log_info("Completed guest_path_finding for %s - peep is leaving the park.", gPathFindDebugPeepName);
|
||||
}
|
||||
pathfind_logging_disable();
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
return guest_path_find_park_entrance(peep, mapElement, edges);
|
||||
}
|
||||
|
||||
if (peep->guest_heading_to_ride_id == 0xFF)
|
||||
if (peep->guest_heading_to_ride_id == 0xFF) {
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (gPathFindDebug) {
|
||||
log_info("Completed guest_path_finding for %s - peep is aimless.", gPathFindDebugPeepName);
|
||||
}
|
||||
pathfind_logging_disable();
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
return guest_path_find_aimless(peep, edges);
|
||||
}
|
||||
|
||||
// Peep is heading for a ride.
|
||||
uint8 rideIndex = peep->guest_heading_to_ride_id;
|
||||
rct_ride* ride = get_ride(rideIndex);
|
||||
|
||||
if (ride->status != RIDE_STATUS_OPEN)
|
||||
if (ride->status != RIDE_STATUS_OPEN) {
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (gPathFindDebug) {
|
||||
log_info("Completed guest_path_finding for %s - peep is heading to closed ride == aimless.", gPathFindDebugPeepName);
|
||||
}
|
||||
pathfind_logging_disable();
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
return guest_path_find_aimless(peep, edges);
|
||||
}
|
||||
|
||||
// The ride is open.
|
||||
gPeepPathFindQueueRideIndex = rideIndex;
|
||||
|
@ -10190,24 +10296,32 @@ static int guest_path_finding(rct_peep* peep)
|
|||
gPeepPathFindGoalPosition = (rct_xyz16) { x, y, z };
|
||||
gPeepPathFindIgnoreForeignQueues = true;
|
||||
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
/* Determine if the pathfinding debugging is wanted for this peep. */
|
||||
/* For guests, use the existing PEEP_FLAGS_TRACKING flag to
|
||||
* determine for which guest(s) the pathfinding debugging will
|
||||
* be output for. */
|
||||
format_string(gPathFindDebugPeepName, sizeof(gPathFindDebugPeepName), peep->name_string_idx, &(peep->id));
|
||||
gPathFindDebug = peep->peep_flags & PEEP_FLAGS_TRACKING;
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
|
||||
direction = peep_pathfind_choose_direction(peep->next_x, peep->next_y, peep->next_z, peep);
|
||||
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
gPathFindDebug = false;
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
|
||||
if (direction == -1){
|
||||
/* Heuristic search failed for all directions.
|
||||
* Reset the pathfind_goal - this means that the pathfind_history
|
||||
* will be reset in the next call to 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). */
|
||||
peep_reset_pathfind_goal(peep);
|
||||
|
||||
#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();
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
|
||||
return guest_path_find_aimless(peep, edges);
|
||||
}
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (gPathFindDebug) {
|
||||
log_info("Completed guest_path_finding for %s - direction chosen: %d.", gPathFindDebugPeepName, direction);
|
||||
}
|
||||
pathfind_logging_disable();
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
return peep_move_one_tile(direction, peep);
|
||||
}
|
||||
|
||||
|
@ -10963,8 +11077,15 @@ static bool peep_should_use_cash_machine(rct_peep *peep, int rideIndex)
|
|||
*
|
||||
* rct2: 0x0069A98C
|
||||
*/
|
||||
static void peep_reset_pathfind_goal(rct_peep *peep)
|
||||
void peep_reset_pathfind_goal(rct_peep *peep)
|
||||
{
|
||||
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
if (gPathFindDebug) {
|
||||
log_info("Resetting pathfind_goal for %s", gPathFindDebugPeepName);
|
||||
}
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
|
||||
peep->pathfind_goal.x = 0xFF;
|
||||
peep->pathfind_goal.y = 0xFF;
|
||||
peep->pathfind_goal.z = 0xFF;
|
||||
|
@ -12523,3 +12644,31 @@ void game_command_set_guest_name(int *eax, int *ebx, int *ecx, int *edx, int *es
|
|||
(uint8*)edi
|
||||
);
|
||||
}
|
||||
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
void pathfind_logging_enable(rct_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->peep_flags & 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
|
||||
|
|
|
@ -20,12 +20,6 @@
|
|||
#include "../common.h"
|
||||
#include "../world/map.h"
|
||||
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
// Some variables used for the path finding debugging.
|
||||
extern bool gPathFindDebug;
|
||||
extern utf8 gPathFindDebugPeepName[256];
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
|
||||
#define PEEP_MAX_THOUGHTS 5
|
||||
|
||||
#define PEEP_HUNGER_WARNING_THRESHOLD 25
|
||||
|
@ -685,5 +679,19 @@ money32 set_peep_name(int flags, int state, uint16 sprite_index, uint8* text_1,
|
|||
void game_command_set_guest_name(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp);
|
||||
|
||||
int peep_pathfind_choose_direction(sint16 x, sint16 y, uint8 z, rct_peep *peep);
|
||||
void peep_reset_pathfind_goal(rct_peep *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 (non zero)
|
||||
void pathfind_logging_enable(rct_peep* peep);
|
||||
void pathfind_logging_disable();
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1071,7 +1071,7 @@ static uint8 staff_mechanic_direction_path(rct_peep* peep, uint8 validDirections
|
|||
gPeepPathFindGoalPosition.z = z;
|
||||
|
||||
/* Find location of the exit for the target ride station
|
||||
* or if the ride has no exit, the entrance */
|
||||
* or if the ride has no exit, the entrance. */
|
||||
uint16 location = ride->exits[peep->current_ride_station];
|
||||
if (location == 0xFFFF) {
|
||||
location = ride->entrances[peep->current_ride_station];
|
||||
|
@ -1111,22 +1111,23 @@ static uint8 staff_mechanic_direction_path(rct_peep* peep, uint8 validDirections
|
|||
gPeepPathFindQueueRideIndex = 255;
|
||||
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
/* Determine if the pathfinding debugging is wanted for this peep. */
|
||||
/* 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. */
|
||||
format_string(gPathFindDebugPeepName, sizeof(gPathFindDebugPeepName), peep->name_string_idx, &(peep->id));
|
||||
|
||||
gPathFindDebug = strcmp(gPathFindDebugPeepName, "Mechanic Debug") == 0;
|
||||
pathfind_logging_enable(peep);
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
|
||||
int pathfindDirection = peep_pathfind_choose_direction(peep->next_x, peep->next_y, peep->next_z, peep);
|
||||
|
||||
#if defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
gPathFindDebug = false;
|
||||
pathfind_logging_disable();
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
|
||||
if (pathfindDirection == -1) {
|
||||
/* Heuristic search failed for all directions.
|
||||
* Reset the pathfind_goal - this means that the pathfind_history
|
||||
* will be reset in the next call to 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). */
|
||||
peep_reset_pathfind_goal(peep);
|
||||
return staff_mechanic_direction_path_rand(peep, pathDirections);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue