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()
|
void Break()
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if defined(DEBUG)
|
||||||
#if __WINDOWS__
|
#if defined(__WINDOWS__)
|
||||||
if (IsDebuggerPresent())
|
if (IsDebuggerPresent())
|
||||||
{
|
{
|
||||||
DebugBreak();
|
DebugBreak();
|
||||||
|
|
|
@ -62,6 +62,10 @@ enum {
|
||||||
#define DEBUG_LEVEL_3 0
|
#define DEBUG_LEVEL_3 0
|
||||||
#define DEBUG_LEVEL_2 0
|
#define DEBUG_LEVEL_2 0
|
||||||
#endif // DEBUG > 1
|
#endif // DEBUG > 1
|
||||||
|
#else
|
||||||
|
#define DEBUG_LEVEL_1 0
|
||||||
|
#define DEBUG_LEVEL_2 0
|
||||||
|
#define DEBUG_LEVEL_3 0
|
||||||
#endif // DEBUG > 0
|
#endif // DEBUG > 0
|
||||||
#else
|
#else
|
||||||
#define DEBUG_LEVEL_3 0
|
#define DEBUG_LEVEL_3 0
|
||||||
|
|
|
@ -55,7 +55,7 @@ extern "C" {
|
||||||
// This define specifies which version of network stream current build uses.
|
// This define specifies which version of network stream current build uses.
|
||||||
// It is used for making sure only compatible builds get connected, even within
|
// It is used for making sure only compatible builds get connected, even within
|
||||||
// single OpenRCT2 version.
|
// single OpenRCT2 version.
|
||||||
#define NETWORK_STREAM_VERSION "13"
|
#define NETWORK_STREAM_VERSION "14"
|
||||||
#define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION
|
#define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#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 "../common.h"
|
||||||
#include "../world/map.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_MAX_THOUGHTS 5
|
||||||
|
|
||||||
#define PEEP_HUNGER_WARNING_THRESHOLD 25
|
#define PEEP_HUNGER_WARNING_THRESHOLD 25
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "../interface/viewport.h"
|
#include "../interface/viewport.h"
|
||||||
#include "../localisation/date.h"
|
#include "../localisation/date.h"
|
||||||
#include "../localisation/string_ids.h"
|
#include "../localisation/string_ids.h"
|
||||||
|
#include "../localisation/localisation.h"
|
||||||
#include "../management/finance.h"
|
#include "../management/finance.h"
|
||||||
#include "../util/util.h"
|
#include "../util/util.h"
|
||||||
#include "../world/sprite.h"
|
#include "../world/sprite.h"
|
||||||
|
@ -999,9 +1000,12 @@ static uint8 staff_mechanic_direction_path_rand(rct_peep* peep, uint8 pathDirect
|
||||||
* rct2: 0x006C0121
|
* rct2: 0x006C0121
|
||||||
*/
|
*/
|
||||||
static uint8 staff_mechanic_direction_path(rct_peep* peep, uint8 validDirections, rct_map_element* pathElement) {
|
static uint8 staff_mechanic_direction_path(rct_peep* peep, uint8 validDirections, rct_map_element* pathElement) {
|
||||||
|
|
||||||
uint8 direction = 0xFF;
|
uint8 direction = 0xFF;
|
||||||
uint8 pathDirections = pathElement->properties.path.edges & 0xF;
|
uint8 pathDirections = pathElement->properties.path.edges & 0xF;
|
||||||
if (peep->state != PEEP_STATE_ANSWERING && peep->state != PEEP_STATE_HEADING_TO_INSPECTION) {
|
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;
|
pathDirections &= validDirections;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1009,6 +1013,7 @@ static uint8 staff_mechanic_direction_path(rct_peep* peep, uint8 validDirections
|
||||||
return staff_mechanic_direction_surface(peep);
|
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)));
|
pathDirections &= ~(1 << (peep->direction ^ (1 << 1)));
|
||||||
if (pathDirections == 0) {
|
if (pathDirections == 0) {
|
||||||
pathDirections |= (1 << (peep->direction ^ (1 << 1)));
|
pathDirections |= (1 << (peep->direction ^ (1 << 1)));
|
||||||
|
@ -1029,11 +1034,14 @@ static uint8 staff_mechanic_direction_path(rct_peep* peep, uint8 validDirections
|
||||||
|
|
||||||
pathDirections |= (1 << direction);
|
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) {
|
if (peep->state == PEEP_STATE_ANSWERING || peep->state == PEEP_STATE_HEADING_TO_INSPECTION) {
|
||||||
rct_ride* ride = get_ride(peep->current_ride);
|
rct_ride* ride = get_ride(peep->current_ride);
|
||||||
uint8 z = ride->station_heights[peep->current_ride_station];
|
uint8 z = ride->station_heights[peep->current_ride_station];
|
||||||
gPeepPathFindGoalPosition.z = z;
|
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];
|
uint16 location = ride->exits[peep->current_ride_station];
|
||||||
if (location == 0xFFFF) {
|
if (location == 0xFFFF) {
|
||||||
location = ride->entrances[peep->current_ride_station];
|
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.x = chosenTile.x;
|
||||||
gPeepPathFindGoalPosition.y = chosenTile.y;
|
gPeepPathFindGoalPosition.y = chosenTile.y;
|
||||||
|
|
||||||
|
// Find the exit/entrance map_element
|
||||||
bool entranceFound = false;
|
bool entranceFound = false;
|
||||||
rct_map_element* mapElement = map_get_first_element_at(chosenTile.x / 32, chosenTile.y / 32);
|
rct_map_element* mapElement = map_get_first_element_at(chosenTile.x / 32, chosenTile.y / 32);
|
||||||
do {
|
do {
|
||||||
|
@ -1068,12 +1077,15 @@ static uint8 staff_mechanic_direction_path(rct_peep* peep, uint8 validDirections
|
||||||
return staff_mechanic_direction_path_rand(peep, pathDirections);
|
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);
|
uint8 entranceDirection = map_element_get_direction(mapElement);
|
||||||
chosenTile.x -= TileDirectionDelta[entranceDirection].x;
|
chosenTile.x -= TileDirectionDelta[entranceDirection].x;
|
||||||
chosenTile.y -= TileDirectionDelta[entranceDirection].y;
|
chosenTile.y -= TileDirectionDelta[entranceDirection].y;
|
||||||
gPeepPathFindGoalPosition.x = chosenTile.x;
|
gPeepPathFindGoalPosition.x = chosenTile.x;
|
||||||
gPeepPathFindGoalPosition.y = chosenTile.y;
|
gPeepPathFindGoalPosition.y = chosenTile.y;
|
||||||
|
|
||||||
|
// Peep is about to walk into the target exit/entrance.
|
||||||
if (chosenTile.x == peep->next_x &&
|
if (chosenTile.x == peep->next_x &&
|
||||||
chosenTile.y == peep->next_y &&
|
chosenTile.y == peep->next_y &&
|
||||||
z == peep->next_z) {
|
z == peep->next_z) {
|
||||||
|
@ -1083,8 +1095,22 @@ static uint8 staff_mechanic_direction_path(rct_peep* peep, uint8 validDirections
|
||||||
gPeepPathFindIgnoreForeignQueues = false;
|
gPeepPathFindIgnoreForeignQueues = false;
|
||||||
gPeepPathFindQueueRideIndex = 255;
|
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);
|
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) {
|
if (pathfindDirection == -1) {
|
||||||
return staff_mechanic_direction_path_rand(peep, pathDirections);
|
return staff_mechanic_direction_path_rand(peep, pathDirections);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1757,13 +1757,23 @@ void footpath_update_path_wide_flags(int x, int y)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
footpath_clear_wide(x, y);
|
footpath_clear_wide(x, y);
|
||||||
x += 0x20;
|
/* Rather than clearing the wide flag of the following tiles and
|
||||||
footpath_clear_wide(x, y);
|
* checking the state of them later, leave them intact and assume
|
||||||
y += 0x20;
|
* they were cleared. Consequently only the wide flag for this single
|
||||||
footpath_clear_wide(x, y);
|
* tile is modified by this update.
|
||||||
x -= 0x20;
|
* This is important for avoiding glitches in pathfinding that occurs
|
||||||
footpath_clear_wide(x, y);
|
* between between the batches of updates to the path wide flags.
|
||||||
y -= 0x20;
|
* 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);
|
rct_map_element *mapElement = map_get_first_element_at(x / 32, y / 32);
|
||||||
do {
|
do {
|
||||||
|
@ -1825,20 +1835,30 @@ void footpath_update_path_wide_flags(int x, int y)
|
||||||
|
|
||||||
if (mapElement->properties.path.edges & 2) {
|
if (mapElement->properties.path.edges & 2) {
|
||||||
F3EFA5 |= 0x8;
|
F3EFA5 |= 0x8;
|
||||||
if (pathList[3] != NULL) {
|
/* In the following:
|
||||||
if (footpath_element_is_wide(pathList[3])) {
|
* footpath_element_is_wide(pathList[3])
|
||||||
F3EFA5 &= ~0x8;
|
* 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) {
|
if (mapElement->properties.path.edges & 4) {
|
||||||
F3EFA5 |= 0x20;
|
F3EFA5 |= 0x20;
|
||||||
if (pathList[5] != NULL) {
|
/* In the following:
|
||||||
if (footpath_element_is_wide(pathList[5])) {
|
* footpath_element_is_wide(pathList[5])
|
||||||
F3EFA5 &= ~0x20;
|
* 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]))) {
|
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;
|
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) &&
|
if ((F3EFA5 & 0x20) &&
|
||||||
(pathList[6] != NULL) && (!footpath_element_is_wide(pathList[6])) &&
|
(pathList[6] != NULL) && (!footpath_element_is_wide(pathList[6])) &&
|
||||||
((pathList[6]->properties.path.edges & 3) == 3) && // N W
|
((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;
|
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) &&
|
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[2]->properties.path.edges & 0xC) == 0xC) &&
|
||||||
(pathList[1] != NULL) && (!footpath_element_is_wide(pathList[1]))) {
|
(pathList[1] != NULL) && (!footpath_element_is_wide(pathList[1]))) {
|
||||||
F3EFA5 |= 0x4;
|
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) &&
|
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[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;
|
F3EFA5 |= 0x10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue