mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #4527 from zaxcav/fixPathfindHistory
Further pathfinding improvements
This commit is contained in:
commit
b29be9bfeb
|
@ -28,8 +28,8 @@ namespace Debug
|
|||
{
|
||||
void Break()
|
||||
{
|
||||
#if DEBUG
|
||||
#if __WINDOWS__
|
||||
#if defined(DEBUG)
|
||||
#if defined(__WINDOWS__)
|
||||
if (IsDebuggerPresent())
|
||||
{
|
||||
DebugBreak();
|
||||
|
|
|
@ -62,6 +62,10 @@ enum {
|
|||
#define DEBUG_LEVEL_3 0
|
||||
#define DEBUG_LEVEL_2 0
|
||||
#endif // DEBUG > 1
|
||||
#else
|
||||
#define DEBUG_LEVEL_1 0
|
||||
#define DEBUG_LEVEL_2 0
|
||||
#define DEBUG_LEVEL_3 0
|
||||
#endif // DEBUG > 0
|
||||
#else
|
||||
#define DEBUG_LEVEL_3 0
|
||||
|
|
|
@ -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 "13"
|
||||
#define NETWORK_STREAM_VERSION "14"
|
||||
#define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
962
src/peep/peep.c
962
src/peep/peep.c
File diff suppressed because it is too large
Load Diff
|
@ -20,6 +20,12 @@
|
|||
#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
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "../interface/viewport.h"
|
||||
#include "../localisation/date.h"
|
||||
#include "../localisation/string_ids.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../management/finance.h"
|
||||
#include "../util/util.h"
|
||||
#include "../world/sprite.h"
|
||||
|
@ -999,9 +1000,12 @@ static uint8 staff_mechanic_direction_path_rand(rct_peep* peep, uint8 pathDirect
|
|||
* rct2: 0x006C0121
|
||||
*/
|
||||
static uint8 staff_mechanic_direction_path(rct_peep* peep, uint8 validDirections, rct_map_element* pathElement) {
|
||||
|
||||
uint8 direction = 0xFF;
|
||||
uint8 pathDirections = pathElement->properties.path.edges & 0xF;
|
||||
if (peep->state != PEEP_STATE_ANSWERING && peep->state != PEEP_STATE_HEADING_TO_INSPECTION) {
|
||||
/* Mechanic is patrolling, so mask with the valid
|
||||
* patrol directions */
|
||||
pathDirections &= validDirections;
|
||||
}
|
||||
|
||||
|
@ -1009,6 +1013,7 @@ static uint8 staff_mechanic_direction_path(rct_peep* peep, uint8 validDirections
|
|||
return staff_mechanic_direction_surface(peep);
|
||||
}
|
||||
|
||||
// Check if this is dead end - i.e. only way out is the reverse direction.
|
||||
pathDirections &= ~(1 << (peep->direction ^ (1 << 1)));
|
||||
if (pathDirections == 0) {
|
||||
pathDirections |= (1 << (peep->direction ^ (1 << 1)));
|
||||
|
@ -1029,11 +1034,14 @@ static uint8 staff_mechanic_direction_path(rct_peep* peep, uint8 validDirections
|
|||
|
||||
pathDirections |= (1 << direction);
|
||||
|
||||
// Mechanic is heading to ride (either broken down or for inspection).
|
||||
if (peep->state == PEEP_STATE_ANSWERING || peep->state == PEEP_STATE_HEADING_TO_INSPECTION) {
|
||||
rct_ride* ride = get_ride(peep->current_ride);
|
||||
uint8 z = ride->station_heights[peep->current_ride_station];
|
||||
gPeepPathFindGoalPosition.z = z;
|
||||
|
||||
/* Find location of the exit for the target ride station
|
||||
* 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];
|
||||
|
@ -1047,6 +1055,7 @@ static uint8 staff_mechanic_direction_path(rct_peep* peep, uint8 validDirections
|
|||
gPeepPathFindGoalPosition.x = chosenTile.x;
|
||||
gPeepPathFindGoalPosition.y = chosenTile.y;
|
||||
|
||||
// Find the exit/entrance map_element
|
||||
bool entranceFound = false;
|
||||
rct_map_element* mapElement = map_get_first_element_at(chosenTile.x / 32, chosenTile.y / 32);
|
||||
do {
|
||||
|
@ -1068,12 +1077,15 @@ static uint8 staff_mechanic_direction_path(rct_peep* peep, uint8 validDirections
|
|||
return staff_mechanic_direction_path_rand(peep, pathDirections);
|
||||
}
|
||||
|
||||
/* Adjust the peep goal according to the direction of the
|
||||
* exit/entrance. */
|
||||
uint8 entranceDirection = map_element_get_direction(mapElement);
|
||||
chosenTile.x -= TileDirectionDelta[entranceDirection].x;
|
||||
chosenTile.y -= TileDirectionDelta[entranceDirection].y;
|
||||
gPeepPathFindGoalPosition.x = chosenTile.x;
|
||||
gPeepPathFindGoalPosition.y = chosenTile.y;
|
||||
|
||||
// Peep is about to walk into the target exit/entrance.
|
||||
if (chosenTile.x == peep->next_x &&
|
||||
chosenTile.y == peep->next_y &&
|
||||
z == peep->next_z) {
|
||||
|
@ -1083,8 +1095,22 @@ static uint8 staff_mechanic_direction_path(rct_peep* peep, uint8 validDirections
|
|||
gPeepPathFindIgnoreForeignQueues = false;
|
||||
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, peep->name_string_idx, &(peep->id));
|
||||
|
||||
gPathFindDebug = strcmp(gPathFindDebugPeepName, "Mechanic Debug") == 0;
|
||||
#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;
|
||||
#endif // defined(DEBUG_LEVEL_1) && DEBUG_LEVEL_1
|
||||
|
||||
if (pathfindDirection == -1) {
|
||||
return staff_mechanic_direction_path_rand(peep, pathDirections);
|
||||
}
|
||||
|
|
|
@ -1757,13 +1757,23 @@ void footpath_update_path_wide_flags(int x, int y)
|
|||
return;
|
||||
|
||||
footpath_clear_wide(x, y);
|
||||
x += 0x20;
|
||||
footpath_clear_wide(x, y);
|
||||
y += 0x20;
|
||||
footpath_clear_wide(x, y);
|
||||
x -= 0x20;
|
||||
footpath_clear_wide(x, y);
|
||||
y -= 0x20;
|
||||
/* Rather than clearing the wide flag of the following tiles and
|
||||
* checking the state of them later, leave them intact and assume
|
||||
* they were cleared. Consequently only the wide flag for this single
|
||||
* tile is modified by this update.
|
||||
* This is important for avoiding glitches in pathfinding that occurs
|
||||
* between between the batches of updates to the path wide flags.
|
||||
* Corresponding pathList[] indexes for the following tiles
|
||||
* are: 2, 3, 4, 5.
|
||||
* Note: indexes 3, 4, 5 are reset in the current call;
|
||||
* index 2 is reset in the previous call. */
|
||||
//x += 0x20;
|
||||
//footpath_clear_wide(x, y);
|
||||
//y += 0x20;
|
||||
//footpath_clear_wide(x, y);
|
||||
//x -= 0x20;
|
||||
//footpath_clear_wide(x, y);
|
||||
//y -= 0x20;
|
||||
|
||||
rct_map_element *mapElement = map_get_first_element_at(x / 32, y / 32);
|
||||
do {
|
||||
|
@ -1825,20 +1835,30 @@ void footpath_update_path_wide_flags(int x, int y)
|
|||
|
||||
if (mapElement->properties.path.edges & 2) {
|
||||
F3EFA5 |= 0x8;
|
||||
if (pathList[3] != NULL) {
|
||||
if (footpath_element_is_wide(pathList[3])) {
|
||||
F3EFA5 &= ~0x8;
|
||||
}
|
||||
}
|
||||
/* In the following:
|
||||
* footpath_element_is_wide(pathList[3])
|
||||
* is always false due to the tile update order
|
||||
* in combination with reset tiles.
|
||||
* Commented out since it will never occur. */
|
||||
//if (pathList[3] != NULL) {
|
||||
// if (footpath_element_is_wide(pathList[3])) {
|
||||
// F3EFA5 &= ~0x8;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
if (mapElement->properties.path.edges & 4) {
|
||||
F3EFA5 |= 0x20;
|
||||
if (pathList[5] != NULL) {
|
||||
if (footpath_element_is_wide(pathList[5])) {
|
||||
F3EFA5 &= ~0x20;
|
||||
}
|
||||
}
|
||||
/* In the following:
|
||||
* footpath_element_is_wide(pathList[5])
|
||||
* is always false due to the tile update order
|
||||
* in combination with reset tiles.
|
||||
* Commented out since it will never occur. */
|
||||
//if (pathList[5] != NULL) {
|
||||
// if (footpath_element_is_wide(pathList[5])) {
|
||||
// F3EFA5 &= ~0x20;
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
if ((F3EFA5 & 0x80) && (pathList[7] != NULL) && !(footpath_element_is_wide(pathList[7]))) {
|
||||
|
@ -1849,27 +1869,44 @@ void footpath_update_path_wide_flags(int x, int y)
|
|||
F3EFA5 |= 0x1;
|
||||
}
|
||||
|
||||
/* In the following:
|
||||
* footpath_element_is_wide(pathList[5])
|
||||
* is always false due to the tile update order
|
||||
* in combination with reset tiles.
|
||||
* Short circuit the logic appropriately. */
|
||||
if ((F3EFA5 & 0x20) &&
|
||||
(pathList[6] != NULL) && (!footpath_element_is_wide(pathList[6])) &&
|
||||
((pathList[6]->properties.path.edges & 3) == 3) && // N W
|
||||
(pathList[5] != NULL) && (!footpath_element_is_wide(pathList[5]))) {
|
||||
(pathList[5] != NULL) && (true || !footpath_element_is_wide(pathList[5]))) {
|
||||
F3EFA5 |= 0x40;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((F3EFA5 & 0x8) && (pathList[3] != NULL) && !(pathList[3]->type & 2)) {
|
||||
/* In the following:
|
||||
* footpath_element_is_wide(pathList[2])
|
||||
* footpath_element_is_wide(pathList[3])
|
||||
* are always false due to the tile update order
|
||||
* in combination with reset tiles.
|
||||
* Short circuit the logic appropriately. */
|
||||
if ((F3EFA5 & 0x8) && (pathList[3] != NULL) && (true || !footpath_element_is_wide(pathList[3]))) {
|
||||
if ((F3EFA5 & 2) &&
|
||||
(pathList[2] != NULL) && (!footpath_element_is_wide(pathList[2])) &&
|
||||
(pathList[2] != NULL) && (true || !footpath_element_is_wide(pathList[2])) &&
|
||||
((pathList[2]->properties.path.edges & 0xC) == 0xC) &&
|
||||
(pathList[1] != NULL) && (!footpath_element_is_wide(pathList[1]))) {
|
||||
F3EFA5 |= 0x4;
|
||||
}
|
||||
|
||||
/* In the following:
|
||||
* footpath_element_is_wide(pathList[4])
|
||||
* footpath_element_is_wide(pathList[5])
|
||||
* are always false due to the tile update order
|
||||
* in combination with reset tiles.
|
||||
* Short circuit the logic appropriately. */
|
||||
if ((F3EFA5 & 0x20) &&
|
||||
(pathList[4] != NULL) && (!footpath_element_is_wide(pathList[4])) &&
|
||||
(pathList[4] != NULL) && (true || !footpath_element_is_wide(pathList[4])) &&
|
||||
((pathList[4]->properties.path.edges & 9) == 9) &&
|
||||
(pathList[5] != NULL) && (!footpath_element_is_wide(pathList[5]))) {
|
||||
(pathList[5] != NULL) && (true || !footpath_element_is_wide(pathList[5]))) {
|
||||
F3EFA5 |= 0x10;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue