|
|
@ -52,6 +52,7 @@ static bool IsRoad(TileIndex tile)
|
|
|
|
// Checks if a tile 'a' is between the tiles 'b' and 'c'
|
|
|
|
// Checks if a tile 'a' is between the tiles 'b' and 'c'
|
|
|
|
#define TILES_BETWEEN(a, b, c) (TileX(a) >= TileX(b) && TileX(a) <= TileX(c) && TileY(a) >= TileY(b) && TileY(a) <= TileY(c))
|
|
|
|
#define TILES_BETWEEN(a, b, c) (TileX(a) >= TileX(b) && TileX(a) <= TileX(c) && TileY(a) >= TileY(b) && TileY(a) <= TileY(c))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check if the current tile is in our end-area
|
|
|
|
// Check if the current tile is in our end-area
|
|
|
|
static int32 AyStar_AiPathFinder_EndNodeCheck(AyStar *aystar, OpenListNode *current)
|
|
|
|
static int32 AyStar_AiPathFinder_EndNodeCheck(AyStar *aystar, OpenListNode *current)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -66,6 +67,7 @@ static int32 AyStar_AiPathFinder_EndNodeCheck(AyStar *aystar, OpenListNode *curr
|
|
|
|
return AYSTAR_DONE;
|
|
|
|
return AYSTAR_DONE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Calculates the hash
|
|
|
|
// Calculates the hash
|
|
|
|
// Currently it is a 10 bit hash, so the hash array has a max depth of 6 bits (so 64)
|
|
|
|
// Currently it is a 10 bit hash, so the hash array has a max depth of 6 bits (so 64)
|
|
|
|
static uint AiPathFinder_Hash(uint key1, uint key2)
|
|
|
|
static uint AiPathFinder_Hash(uint key1, uint key2)
|
|
|
@ -73,6 +75,7 @@ static uint AiPathFinder_Hash(uint key1, uint key2)
|
|
|
|
return (TileX(key1) & 0x1F) + ((TileY(key1) & 0x1F) << 5);
|
|
|
|
return (TileX(key1) & 0x1F) + ((TileY(key1) & 0x1F) << 5);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Clear the memory of all the things
|
|
|
|
// Clear the memory of all the things
|
|
|
|
static void AyStar_AiPathFinder_Free(AyStar *aystar)
|
|
|
|
static void AyStar_AiPathFinder_Free(AyStar *aystar)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -80,11 +83,13 @@ static void AyStar_AiPathFinder_Free(AyStar *aystar)
|
|
|
|
free(aystar);
|
|
|
|
free(aystar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static int32 AyStar_AiPathFinder_CalculateG(AyStar *aystar, AyStarNode *current, OpenListNode *parent);
|
|
|
|
static int32 AyStar_AiPathFinder_CalculateG(AyStar *aystar, AyStarNode *current, OpenListNode *parent);
|
|
|
|
static int32 AyStar_AiPathFinder_CalculateH(AyStar *aystar, AyStarNode *current, OpenListNode *parent);
|
|
|
|
static int32 AyStar_AiPathFinder_CalculateH(AyStar *aystar, AyStarNode *current, OpenListNode *parent);
|
|
|
|
static void AyStar_AiPathFinder_FoundEndNode(AyStar *aystar, OpenListNode *current);
|
|
|
|
static void AyStar_AiPathFinder_FoundEndNode(AyStar *aystar, OpenListNode *current);
|
|
|
|
static void AyStar_AiPathFinder_GetNeighbours(AyStar *aystar, OpenListNode *current);
|
|
|
|
static void AyStar_AiPathFinder_GetNeighbours(AyStar *aystar, OpenListNode *current);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// This creates the AiPathFinder
|
|
|
|
// This creates the AiPathFinder
|
|
|
|
AyStar *new_AyStar_AiPathFinder(int max_tiles_around, Ai_PathFinderInfo *PathFinderInfo)
|
|
|
|
AyStar *new_AyStar_AiPathFinder(int max_tiles_around, Ai_PathFinderInfo *PathFinderInfo)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -129,6 +134,7 @@ AyStar *new_AyStar_AiPathFinder(int max_tiles_around, Ai_PathFinderInfo *PathFin
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// To reuse AyStar we sometimes have to clean all the memory
|
|
|
|
// To reuse AyStar we sometimes have to clean all the memory
|
|
|
|
void clean_AyStar_AiPathFinder(AyStar *aystar, Ai_PathFinderInfo *PathFinderInfo)
|
|
|
|
void clean_AyStar_AiPathFinder(AyStar *aystar, Ai_PathFinderInfo *PathFinderInfo)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -158,6 +164,7 @@ void clean_AyStar_AiPathFinder(AyStar *aystar, Ai_PathFinderInfo *PathFinderInfo
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// The h-value, simple calculation
|
|
|
|
// The h-value, simple calculation
|
|
|
|
static int32 AyStar_AiPathFinder_CalculateH(AyStar *aystar, AyStarNode *current, OpenListNode *parent)
|
|
|
|
static int32 AyStar_AiPathFinder_CalculateH(AyStar *aystar, AyStarNode *current, OpenListNode *parent)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -177,6 +184,7 @@ static int32 AyStar_AiPathFinder_CalculateH(AyStar *aystar, AyStarNode *current,
|
|
|
|
return r * AI_PATHFINDER_H_MULTIPLER;
|
|
|
|
return r * AI_PATHFINDER_H_MULTIPLER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// We found the end.. let's get the route back and put it in an array
|
|
|
|
// We found the end.. let's get the route back and put it in an array
|
|
|
|
static void AyStar_AiPathFinder_FoundEndNode(AyStar *aystar, OpenListNode *current)
|
|
|
|
static void AyStar_AiPathFinder_FoundEndNode(AyStar *aystar, OpenListNode *current)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -199,6 +207,7 @@ static void AyStar_AiPathFinder_FoundEndNode(AyStar *aystar, OpenListNode *curre
|
|
|
|
DEBUG(ai, 1)("[Ai-PathFinding] Found route of %d nodes long in %d nodes of searching", i, Hash_Size(&aystar->ClosedListHash));
|
|
|
|
DEBUG(ai, 1)("[Ai-PathFinding] Found route of %d nodes long in %d nodes of searching", i, Hash_Size(&aystar->ClosedListHash));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// What tiles are around us.
|
|
|
|
// What tiles are around us.
|
|
|
|
static void AyStar_AiPathFinder_GetNeighbours(AyStar *aystar, OpenListNode *current)
|
|
|
|
static void AyStar_AiPathFinder_GetNeighbours(AyStar *aystar, OpenListNode *current)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -321,7 +330,6 @@ static void AyStar_AiPathFinder_GetNeighbours(AyStar *aystar, OpenListNode *curr
|
|
|
|
if (ti.tileh != 0 ||
|
|
|
|
if (ti.tileh != 0 ||
|
|
|
|
(PathFinderInfo->rail_or_road && IsTileType(tile + TileOffsByDir(dir), MP_STREET)) ||
|
|
|
|
(PathFinderInfo->rail_or_road && IsTileType(tile + TileOffsByDir(dir), MP_STREET)) ||
|
|
|
|
(!PathFinderInfo->rail_or_road && IsTileType(tile + TileOffsByDir(dir), MP_RAILWAY))) {
|
|
|
|
(!PathFinderInfo->rail_or_road && IsTileType(tile + TileOffsByDir(dir), MP_RAILWAY))) {
|
|
|
|
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
for (;;) {
|
|
|
|
new_tile += TileOffsByDir(dir);
|
|
|
|
new_tile += TileOffsByDir(dir);
|
|
|
|
|
|
|
|
|
|
|
@ -362,6 +370,7 @@ static void AyStar_AiPathFinder_GetNeighbours(AyStar *aystar, OpenListNode *curr
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern uint GetRailFoundation(uint tileh, uint bits);
|
|
|
|
extern uint GetRailFoundation(uint tileh, uint bits);
|
|
|
|
extern uint GetRoadFoundation(uint tileh, uint bits);
|
|
|
|
extern uint GetRoadFoundation(uint tileh, uint bits);
|
|
|
|
extern uint GetBridgeFoundation(uint tileh, byte direction);
|
|
|
|
extern uint GetBridgeFoundation(uint tileh, byte direction);
|
|
|
@ -383,9 +392,10 @@ static int32 AyStar_AiPathFinder_CalculateG(AyStar *aystar, AyStarNode *current,
|
|
|
|
// Check if we hit the end-tile
|
|
|
|
// Check if we hit the end-tile
|
|
|
|
if (TILES_BETWEEN(current->tile, PathFinderInfo->end_tile_tl, PathFinderInfo->end_tile_br)) {
|
|
|
|
if (TILES_BETWEEN(current->tile, PathFinderInfo->end_tile_tl, PathFinderInfo->end_tile_br)) {
|
|
|
|
// We are at the end-tile, check if we had a direction or something...
|
|
|
|
// We are at the end-tile, check if we had a direction or something...
|
|
|
|
if (PathFinderInfo->end_direction != AI_PATHFINDER_NO_DIRECTION && AiNew_GetDirection(current->tile, parent->path.node.tile) != PathFinderInfo->end_direction)
|
|
|
|
if (PathFinderInfo->end_direction != AI_PATHFINDER_NO_DIRECTION && AiNew_GetDirection(current->tile, parent->path.node.tile) != PathFinderInfo->end_direction) {
|
|
|
|
// We are not pointing the right way, invalid tile
|
|
|
|
// We are not pointing the right way, invalid tile
|
|
|
|
return AYSTAR_INVALID_NODE;
|
|
|
|
return AYSTAR_INVALID_NODE;
|
|
|
|
|
|
|
|
}
|
|
|
|
// If it was valid, drop out.. we don't build on the endtile
|
|
|
|
// If it was valid, drop out.. we don't build on the endtile
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -453,10 +463,8 @@ static int32 AyStar_AiPathFinder_CalculateG(AyStar *aystar, AyStarNode *current,
|
|
|
|
if (GetBridgeFoundation(ti.tileh, (current->user_data[0] >> 8) & 1) < 15)
|
|
|
|
if (GetBridgeFoundation(ti.tileh, (current->user_data[0] >> 8) & 1) < 15)
|
|
|
|
res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
|
|
|
|
res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (parent_ti.tileh == 0)
|
|
|
|
if (parent_ti.tileh == 0) res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
|
|
|
|
res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
|
|
|
|
if (ti.tileh == 0) res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
|
|
|
|
if (ti.tileh == 0)
|
|
|
|
|
|
|
|
res += AI_PATHFINDER_BRIDGE_GOES_UP_PENALTY;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// To prevent the AI from taking the fastest way in tiles, but not the fastest way
|
|
|
|
// To prevent the AI from taking the fastest way in tiles, but not the fastest way
|
|
|
|