mirror of https://github.com/OpenTTD/OpenTTD
(svn r2892) Fix indentation
parent
a38d2f15b7
commit
8b85cf53e5
277
ai_build.c
277
ai_build.c
|
@ -23,6 +23,7 @@ bool AiNew_Build_CompanyHQ(Player *p, TileIndex tile)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Build station
|
// Build station
|
||||||
// Params:
|
// Params:
|
||||||
// type : AI_TRAIN/AI_BUS/AI_TRUCK : indicates the type of station
|
// type : AI_TRAIN/AI_BUS/AI_TRUCK : indicates the type of station
|
||||||
|
@ -42,6 +43,7 @@ int AiNew_Build_Station(Player *p, byte type, TileIndex tile, byte length, byte
|
||||||
return DoCommandByTile(tile, direction, RS_TRUCK, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD_STOP);
|
return DoCommandByTile(tile, direction, RS_TRUCK, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD_STOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Builds a brdige. The second best out of the ones available for this player
|
// Builds a brdige. The second best out of the ones available for this player
|
||||||
// Params:
|
// Params:
|
||||||
// tile_a : starting point
|
// tile_a : starting point
|
||||||
|
@ -59,8 +61,7 @@ int AiNew_Build_Bridge(Player *p, TileIndex tile_a, TileIndex tile_b, byte flag)
|
||||||
type2 = type;
|
type2 = type;
|
||||||
type = bridge_type;
|
type = bridge_type;
|
||||||
// We found two bridges, exit
|
// We found two bridges, exit
|
||||||
if (type2 != 0)
|
if (type2 != 0) break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// There is only one bridge that can be build..
|
// There is only one bridge that can be build..
|
||||||
|
@ -84,8 +85,9 @@ int AiNew_Build_Bridge(Player *p, TileIndex tile_a, TileIndex tile_b, byte flag)
|
||||||
// part : Which part we need to build
|
// part : Which part we need to build
|
||||||
//
|
//
|
||||||
// TODO: skip already builded road-pieces (e.g.: cityroad)
|
// TODO: skip already builded road-pieces (e.g.: cityroad)
|
||||||
int AiNew_Build_RoutePart(Player *p, Ai_PathFinderInfo *PathFinderInfo, byte flag) {
|
int AiNew_Build_RoutePart(Player *p, Ai_PathFinderInfo *PathFinderInfo, byte flag)
|
||||||
int part = PathFinderInfo->position;
|
{
|
||||||
|
int part = PathFinderInfo->position;
|
||||||
byte *route_extra = PathFinderInfo->route_extra;
|
byte *route_extra = PathFinderInfo->route_extra;
|
||||||
TileIndex *route = PathFinderInfo->route;
|
TileIndex *route = PathFinderInfo->route;
|
||||||
int dir;
|
int dir;
|
||||||
|
@ -101,144 +103,147 @@ int AiNew_Build_RoutePart(Player *p, Ai_PathFinderInfo *PathFinderInfo, byte fla
|
||||||
|
|
||||||
if (PathFinderInfo->rail_or_road) {
|
if (PathFinderInfo->rail_or_road) {
|
||||||
// Tunnel code
|
// Tunnel code
|
||||||
if ((AI_PATHFINDER_FLAG_TUNNEL & route_extra[part]) != 0) {
|
if ((AI_PATHFINDER_FLAG_TUNNEL & route_extra[part]) != 0) {
|
||||||
cost += DoCommandByTile(route[part], 0, 0, flag, CMD_BUILD_TUNNEL);
|
cost += DoCommandByTile(route[part], 0, 0, flag, CMD_BUILD_TUNNEL);
|
||||||
PathFinderInfo->position++;
|
PathFinderInfo->position++;
|
||||||
// TODO: problems!
|
// TODO: problems!
|
||||||
if (CmdFailed(cost)) {
|
if (CmdFailed(cost)) {
|
||||||
DEBUG(ai,0)("[AiNew - BuildPath] We have a serious problem: tunnel could not be build!");
|
DEBUG(ai,0)("[AiNew - BuildPath] We have a serious problem: tunnel could not be build!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
// Bridge code
|
// Bridge code
|
||||||
if ((AI_PATHFINDER_FLAG_BRIDGE & route_extra[part]) != 0) {
|
if ((AI_PATHFINDER_FLAG_BRIDGE & route_extra[part]) != 0) {
|
||||||
cost += AiNew_Build_Bridge(p, route[part], route[part-1], flag);
|
cost += AiNew_Build_Bridge(p, route[part], route[part-1], flag);
|
||||||
PathFinderInfo->position++;
|
PathFinderInfo->position++;
|
||||||
// TODO: problems!
|
// TODO: problems!
|
||||||
if (CmdFailed(cost)) {
|
if (CmdFailed(cost)) {
|
||||||
DEBUG(ai,0)("[AiNew - BuildPath] We have a serious problem: bridge could not be build!");
|
DEBUG(ai,0)("[AiNew - BuildPath] We have a serious problem: bridge could not be build!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build normal rail
|
// Build normal rail
|
||||||
// Keep it doing till we go an other way
|
// Keep it doing till we go an other way
|
||||||
if (route_extra[part-1] == 0 && route_extra[part] == 0) {
|
if (route_extra[part-1] == 0 && route_extra[part] == 0) {
|
||||||
while (route_extra[part] == 0) {
|
while (route_extra[part] == 0) {
|
||||||
// Get the current direction
|
// Get the current direction
|
||||||
dir = AiNew_GetRailDirection(route[part-1], route[part], route[part+1]);
|
dir = AiNew_GetRailDirection(route[part-1], route[part], route[part+1]);
|
||||||
// Is it the same as the last one?
|
// Is it the same as the last one?
|
||||||
if (old_dir != -1 && old_dir != dir) break;
|
if (old_dir != -1 && old_dir != dir) break;
|
||||||
old_dir = dir;
|
old_dir = dir;
|
||||||
// Build the tile
|
// Build the tile
|
||||||
res = DoCommandByTile(route[part], 0, dir, flag, CMD_BUILD_SINGLE_RAIL);
|
res = DoCommandByTile(route[part], 0, dir, flag, CMD_BUILD_SINGLE_RAIL);
|
||||||
if (CmdFailed(res)) {
|
if (CmdFailed(res)) {
|
||||||
// Problem.. let's just abort it all!
|
// Problem.. let's just abort it all!
|
||||||
p->ainew.state = AI_STATE_NOTHING;
|
p->ainew.state = AI_STATE_NOTHING;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
cost += res;
|
cost += res;
|
||||||
// Go to the next tile
|
// Go to the next tile
|
||||||
part++;
|
part++;
|
||||||
// Check if it is still in range..
|
// Check if it is still in range..
|
||||||
if (part >= PathFinderInfo->route_length - 1) break;
|
if (part >= PathFinderInfo->route_length - 1) break;
|
||||||
}
|
}
|
||||||
part--;
|
part--;
|
||||||
}
|
}
|
||||||
// We want to return the last position, so we go back one
|
// We want to return the last position, so we go back one
|
||||||
PathFinderInfo->position = part;
|
PathFinderInfo->position = part;
|
||||||
} else {
|
} else {
|
||||||
// Tunnel code
|
// Tunnel code
|
||||||
if ((AI_PATHFINDER_FLAG_TUNNEL & route_extra[part]) != 0) {
|
if ((AI_PATHFINDER_FLAG_TUNNEL & route_extra[part]) != 0) {
|
||||||
cost += DoCommandByTile(route[part], 0x200, 0, flag, CMD_BUILD_TUNNEL);
|
cost += DoCommandByTile(route[part], 0x200, 0, flag, CMD_BUILD_TUNNEL);
|
||||||
PathFinderInfo->position++;
|
PathFinderInfo->position++;
|
||||||
// TODO: problems!
|
// TODO: problems!
|
||||||
if (CmdFailed(cost)) {
|
if (CmdFailed(cost)) {
|
||||||
DEBUG(ai,0)("[AiNew - BuildPath] We have a serious problem: tunnel could not be build!");
|
DEBUG(ai,0)("[AiNew - BuildPath] We have a serious problem: tunnel could not be build!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
// Bridge code
|
// Bridge code
|
||||||
if ((AI_PATHFINDER_FLAG_BRIDGE & route_extra[part]) != 0) {
|
if ((AI_PATHFINDER_FLAG_BRIDGE & route_extra[part]) != 0) {
|
||||||
cost += AiNew_Build_Bridge(p, route[part], route[part+1], flag);
|
cost += AiNew_Build_Bridge(p, route[part], route[part+1], flag);
|
||||||
PathFinderInfo->position++;
|
PathFinderInfo->position++;
|
||||||
// TODO: problems!
|
// TODO: problems!
|
||||||
if (CmdFailed(cost)) {
|
if (CmdFailed(cost)) {
|
||||||
DEBUG(ai,0)("[AiNew - BuildPath] We have a serious problem: bridge could not be build!");
|
DEBUG(ai,0)("[AiNew - BuildPath] We have a serious problem: bridge could not be build!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build normal road
|
// Build normal road
|
||||||
// Keep it doing till we go an other way
|
// Keep it doing till we go an other way
|
||||||
// EnsureNoVehicle makes sure we don't build on a tile where a vehicle is. This way
|
// EnsureNoVehicle makes sure we don't build on a tile where a vehicle is. This way
|
||||||
// it will wait till the vehicle is gone..
|
// it will wait till the vehicle is gone..
|
||||||
if (route_extra[part-1] == 0 && route_extra[part] == 0 && (flag != DC_EXEC || EnsureNoVehicle(route[part]))) {
|
if (route_extra[part-1] == 0 && route_extra[part] == 0 && (flag != DC_EXEC || EnsureNoVehicle(route[part]))) {
|
||||||
while (route_extra[part] == 0 && (flag != DC_EXEC || EnsureNoVehicle(route[part]))) {
|
while (route_extra[part] == 0 && (flag != DC_EXEC || EnsureNoVehicle(route[part]))) {
|
||||||
// Get the current direction
|
// Get the current direction
|
||||||
dir = AiNew_GetRoadDirection(route[part-1], route[part], route[part+1]);
|
dir = AiNew_GetRoadDirection(route[part-1], route[part], route[part+1]);
|
||||||
// Is it the same as the last one?
|
// Is it the same as the last one?
|
||||||
if (old_dir != -1 && old_dir != dir) break;
|
if (old_dir != -1 && old_dir != dir) break;
|
||||||
old_dir = dir;
|
old_dir = dir;
|
||||||
// There is already some road, and it is a bridge.. don't build!!!
|
// There is already some road, and it is a bridge.. don't build!!!
|
||||||
if (!IsTileType(route[part], MP_TUNNELBRIDGE)) {
|
if (!IsTileType(route[part], MP_TUNNELBRIDGE)) {
|
||||||
// Build the tile
|
// Build the tile
|
||||||
res = DoCommandByTile(route[part], dir, 0, flag | DC_NO_WATER, CMD_BUILD_ROAD);
|
res = DoCommandByTile(route[part], dir, 0, flag | DC_NO_WATER, CMD_BUILD_ROAD);
|
||||||
// Currently, we ignore CMD_ERRORs!
|
// Currently, we ignore CMD_ERRORs!
|
||||||
if (CmdFailed(res) && flag == DC_EXEC && !IsTileType(route[part], MP_STREET) && !EnsureNoVehicle(route[part])) {
|
if (CmdFailed(res) && flag == DC_EXEC && !IsTileType(route[part], MP_STREET) && !EnsureNoVehicle(route[part])) {
|
||||||
// Problem.. let's just abort it all!
|
// Problem.. let's just abort it all!
|
||||||
DEBUG(ai,0)("Darn, the route could not be builded.. aborting!");
|
DEBUG(ai,0)("Darn, the route could not be builded.. aborting!");
|
||||||
p->ainew.state = AI_STATE_NOTHING;
|
p->ainew.state = AI_STATE_NOTHING;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CmdFailed(res)) cost += res;
|
if (!CmdFailed(res)) cost += res;
|
||||||
}
|
}
|
||||||
// Go to the next tile
|
// Go to the next tile
|
||||||
part++;
|
part++;
|
||||||
// Check if it is still in range..
|
// Check if it is still in range..
|
||||||
if (part >= PathFinderInfo->route_length - 1) break;
|
if (part >= PathFinderInfo->route_length - 1) break;
|
||||||
}
|
}
|
||||||
part--;
|
part--;
|
||||||
// We want to return the last position, so we go back one
|
// We want to return the last position, so we go back one
|
||||||
}
|
}
|
||||||
if (!EnsureNoVehicle(route[part]) && flag == DC_EXEC) part--;
|
if (!EnsureNoVehicle(route[part]) && flag == DC_EXEC) part--;
|
||||||
PathFinderInfo->position = part;
|
PathFinderInfo->position = part;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cost;
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// This functions tries to find the best vehicle for this type of cargo
|
// This functions tries to find the best vehicle for this type of cargo
|
||||||
// It returns vehicle_id or -1 if not found
|
// It returns vehicle_id or -1 if not found
|
||||||
int AiNew_PickVehicle(Player *p) {
|
int AiNew_PickVehicle(Player *p)
|
||||||
if (p->ainew.tbt == AI_TRAIN) {
|
{
|
||||||
// Not supported yet
|
if (p->ainew.tbt == AI_TRAIN) {
|
||||||
return -1;
|
// Not supported yet
|
||||||
} else {
|
return -1;
|
||||||
int start, count, i, ret = CMD_ERROR;
|
} else {
|
||||||
start = _cargoc.ai_roadveh_start[p->ainew.cargo];
|
int start, count, i, ret = CMD_ERROR;
|
||||||
count = _cargoc.ai_roadveh_count[p->ainew.cargo];
|
start = _cargoc.ai_roadveh_start[p->ainew.cargo];
|
||||||
|
count = _cargoc.ai_roadveh_count[p->ainew.cargo];
|
||||||
|
|
||||||
// Let's check it backwards.. we simply want to best engine available..
|
// Let's check it backwards.. we simply want to best engine available..
|
||||||
for (i=start+count-1;i>=start;i--) {
|
for (i=start+count-1;i>=start;i--) {
|
||||||
// Is it availiable?
|
// Is it availiable?
|
||||||
// Also, check if the reliability of the vehicle is above the AI_VEHICLE_MIN_RELIABILTY
|
// Also, check if the reliability of the vehicle is above the AI_VEHICLE_MIN_RELIABILTY
|
||||||
if (!HASBIT(GetEngine(i)->player_avail, _current_player) || GetEngine(i)->reliability * 100 < AI_VEHICLE_MIN_RELIABILTY << 16) continue;
|
if (!HASBIT(GetEngine(i)->player_avail, _current_player) || GetEngine(i)->reliability * 100 < AI_VEHICLE_MIN_RELIABILTY << 16) continue;
|
||||||
// Can we build it?
|
// Can we build it?
|
||||||
ret = DoCommandByTile(0, i, 0, DC_QUERY_COST, CMD_BUILD_ROAD_VEH);
|
ret = DoCommandByTile(0, i, 0, DC_QUERY_COST, CMD_BUILD_ROAD_VEH);
|
||||||
if (!CmdFailed(ret)) break;
|
if (!CmdFailed(ret)) break;
|
||||||
}
|
}
|
||||||
// We did not find a vehicle :(
|
// We did not find a vehicle :(
|
||||||
if (CmdFailed(ret)) { return -1; }
|
if (CmdFailed(ret)) { return -1; }
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Builds the best vehicle possible
|
// Builds the best vehicle possible
|
||||||
int AiNew_Build_Vehicle(Player *p, TileIndex tile, byte flag)
|
int AiNew_Build_Vehicle(Player *p, TileIndex tile, byte flag)
|
||||||
{
|
{
|
||||||
|
@ -246,7 +251,7 @@ int AiNew_Build_Vehicle(Player *p, TileIndex tile, byte flag)
|
||||||
if (i == -1) return CMD_ERROR;
|
if (i == -1) return CMD_ERROR;
|
||||||
|
|
||||||
if (p->ainew.tbt == AI_TRAIN)
|
if (p->ainew.tbt == AI_TRAIN)
|
||||||
return CMD_ERROR;
|
return CMD_ERROR;
|
||||||
|
|
||||||
return DoCommandByTile(tile, i, 0, flag, CMD_BUILD_ROAD_VEH);
|
return DoCommandByTile(tile, i, 0, flag, CMD_BUILD_ROAD_VEH);
|
||||||
}
|
}
|
||||||
|
@ -255,14 +260,14 @@ int AiNew_Build_Depot(Player *p, TileIndex tile, byte direction, byte flag)
|
||||||
{
|
{
|
||||||
static const byte _roadbits_by_dir[4] = {2,1,8,4};
|
static const byte _roadbits_by_dir[4] = {2,1,8,4};
|
||||||
int ret, ret2;
|
int ret, ret2;
|
||||||
if (p->ainew.tbt == AI_TRAIN)
|
if (p->ainew.tbt == AI_TRAIN)
|
||||||
return DoCommandByTile(tile, 0, direction, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_TRAIN_DEPOT);
|
return DoCommandByTile(tile, 0, direction, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_TRAIN_DEPOT);
|
||||||
|
|
||||||
ret = DoCommandByTile(tile, direction, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD_DEPOT);
|
ret = DoCommandByTile(tile, direction, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD_DEPOT);
|
||||||
if (CmdFailed(ret)) return ret;
|
if (CmdFailed(ret)) return ret;
|
||||||
// Try to build the road from the depot
|
// Try to build the road from the depot
|
||||||
ret2 = DoCommandByTile(tile + TileOffsByDir(direction), _roadbits_by_dir[direction], 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD);
|
ret2 = DoCommandByTile(tile + TileOffsByDir(direction), _roadbits_by_dir[direction], 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD);
|
||||||
// If it fails, ignore it..
|
// If it fails, ignore it..
|
||||||
if (CmdFailed(ret2)) return ret;
|
if (CmdFailed(ret2)) return ret;
|
||||||
return ret + ret2;
|
return ret + ret2;
|
||||||
}
|
}
|
||||||
|
|
48
ai_new.h
48
ai_new.h
|
@ -166,33 +166,33 @@
|
||||||
|
|
||||||
// This stops 90degrees curves
|
// This stops 90degrees curves
|
||||||
static const byte _illegal_curves[6] = {
|
static const byte _illegal_curves[6] = {
|
||||||
255, 255, // Horz and vert, don't have the effect
|
255, 255, // Horz and vert, don't have the effect
|
||||||
5, // upleft and upright are not valid
|
5, // upleft and upright are not valid
|
||||||
4, // downright and downleft are not valid
|
4, // downright and downleft are not valid
|
||||||
2, // downleft and upleft are not valid
|
2, // downleft and upleft are not valid
|
||||||
3, // upright and downright are not valid
|
3, // upright and downright are not valid
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
AI_STATE_STARTUP = 0,
|
AI_STATE_STARTUP = 0,
|
||||||
AI_STATE_FIRST_TIME,
|
AI_STATE_FIRST_TIME,
|
||||||
AI_STATE_NOTHING,
|
AI_STATE_NOTHING,
|
||||||
AI_STATE_WAKE_UP,
|
AI_STATE_WAKE_UP,
|
||||||
AI_STATE_LOCATE_ROUTE,
|
AI_STATE_LOCATE_ROUTE,
|
||||||
AI_STATE_FIND_STATION,
|
AI_STATE_FIND_STATION,
|
||||||
AI_STATE_FIND_PATH,
|
AI_STATE_FIND_PATH,
|
||||||
AI_STATE_FIND_DEPOT,
|
AI_STATE_FIND_DEPOT,
|
||||||
AI_STATE_VERIFY_ROUTE,
|
AI_STATE_VERIFY_ROUTE,
|
||||||
AI_STATE_BUILD_STATION,
|
AI_STATE_BUILD_STATION,
|
||||||
AI_STATE_BUILD_PATH,
|
AI_STATE_BUILD_PATH,
|
||||||
AI_STATE_BUILD_DEPOT,
|
AI_STATE_BUILD_DEPOT,
|
||||||
AI_STATE_BUILD_VEHICLE,
|
AI_STATE_BUILD_VEHICLE,
|
||||||
AI_STATE_GIVE_ORDERS,
|
AI_STATE_GIVE_ORDERS,
|
||||||
AI_STATE_START_VEHICLE,
|
AI_STATE_START_VEHICLE,
|
||||||
AI_STATE_REPAY_MONEY,
|
AI_STATE_REPAY_MONEY,
|
||||||
AI_STATE_CHECK_ALL_VEHICLES,
|
AI_STATE_CHECK_ALL_VEHICLES,
|
||||||
AI_STATE_ACTION_DONE,
|
AI_STATE_ACTION_DONE,
|
||||||
AI_STATE_STOP, // Temporary function to stop the AI
|
AI_STATE_STOP, // Temporary function to stop the AI
|
||||||
};
|
};
|
||||||
|
|
||||||
// Used for tbt (train/bus/truck)
|
// Used for tbt (train/bus/truck)
|
||||||
|
@ -212,7 +212,7 @@ enum {
|
||||||
|
|
||||||
// Used for from_type/to_type
|
// Used for from_type/to_type
|
||||||
enum {
|
enum {
|
||||||
AI_NO_TYPE = 0,
|
AI_NO_TYPE = 0,
|
||||||
AI_CITY,
|
AI_CITY,
|
||||||
AI_INDUSTRY,
|
AI_INDUSTRY,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
@ -464,7 +472,7 @@ static int32 AyStar_AiPathFinder_CalculateG(AyStar *aystar, AyStarNode *current,
|
||||||
// This way, we get almost the fastest way in tiles, and a very good speed on the track
|
// This way, we get almost the fastest way in tiles, and a very good speed on the track
|
||||||
if (!PathFinderInfo->rail_or_road) {
|
if (!PathFinderInfo->rail_or_road) {
|
||||||
if (parent->path.parent != NULL &&
|
if (parent->path.parent != NULL &&
|
||||||
AiNew_GetDirection(current->tile, parent->path.node.tile) != AiNew_GetDirection(parent->path.node.tile, parent->path.parent->node.tile)) {
|
AiNew_GetDirection(current->tile, parent->path.node.tile) != AiNew_GetDirection(parent->path.node.tile, parent->path.parent->node.tile)) {
|
||||||
// When road exists, we don't like turning, but its free, so don't be to piggy about it
|
// When road exists, we don't like turning, but its free, so don't be to piggy about it
|
||||||
if (IsRoad(parent->path.node.tile))
|
if (IsRoad(parent->path.node.tile))
|
||||||
res += AI_PATHFINDER_DIRECTION_CHANGE_ON_EXISTING_ROAD_PENALTY;
|
res += AI_PATHFINDER_DIRECTION_CHANGE_ON_EXISTING_ROAD_PENALTY;
|
||||||
|
|
Loading…
Reference in New Issue