//find road way between fromTile and toTile
function buildRoad(fromTile, toTile) {
//can store road tiles into array
local builtTiles = [];
if (fromTile != toTile) {
//* Print the names of the towns we'll try to connect. */
AILog.Info("Connecting " + AITown.GetName(AITile.GetClosestTown(fromTile)) + " and " + AITown.GetName(AITile.GetClosestTown(toTile)));
// Tell OpenTTD we want to build normal road (no tram tracks). */
AIRoad.SetCurrentRoadType(AIRoad.ROADTYPE_ROAD);
// Create an instance of the pathfinder. */
local pathfinder = RoadPathFinder();
/*defaults*/
/*10000000*/pathfinder.cost.max_cost;
/*100*/ pathfinder.cost.tile;
/*40*/ pathfinder.cost.no_existing_road;
/*100*/ pathfinder.cost.turn;
/*100*/ pathfinder.cost.slope;
/*150*/ pathfinder.cost.bridge_per_tile;
/*120*/ pathfinder.cost.tunnel_per_tile;
/*20*/ pathfinder.cost.coast;
/*10*/ pathfinder.cost.max_bridge_length = AIGameSettings.GetValue("max_bridge_length") + 2;
/*20*/ pathfinder.cost.max_tunnel_length = AIGameSettings.GetValue("max_tunnel_length") + 2;
// Give the source and goal tiles to the pathfinder. */
pathfinder.InitializePath([fromTile], [toTile]);
local path = false;
local counter = 0;
while (path == false && counter < 250) {
++counter;
path = pathfinder.FindPath(100);
AIController.Sleep(1);
}
if (path == false || path == null) {
// No path was found. */
AILog.Error("pathfinder: FindPath return null");
return null;
}
AILog.Info("Path found! Building road...");
// local costs = AIAccounting();
// If a path was found, build a road over it. */
while (path != null) {
local par = path.GetParent();
if (par != null) {
local last_node = path.GetTile();
if (AIMap.DistanceManhattan(path.GetTile(), par.GetTile()) == 1) {
local counter = 0;
do {
// if(!AIRoad.BuildRoad(path.GetTile(), par.GetTile())) {
if(!TestBuildRoad().TryBuild(path.GetTile(), par.GetTile())) {
if(AIError.GetLastErrorString() == "ERR_ALREADY_BUILT") {
AILog.Warning("We found a road already built at tiles " + path.GetTile() + " - " + par.GetTile());
break;
}
else {
++counter;
}
}
else {
AILog.Warning("We built a road at tiles " + path.GetTile() + " - " + par.GetTile());
break;
}
AIController.Sleep(1);
} while(counter < 500);
if(counter == 500) {
AILog.Warning("Couldn't build road! " + AIError.GetLastErrorString());
return null;
}
//add road piece into the road array
builtTiles.append(RoadTile(path.GetTile(), RoadTileTypes.ROAD));
}
else {
// Build a bridge or tunnel. */
if (!AIBridge.IsBridgeTile(path.GetTile()) && !AITunnel.IsTunnelTile(path.GetTile())) {
// If it was a road tile, demolish it first. Do this to work around expended roadbits. */
if (AIRoad.IsRoadTile(path.GetTile())) {
// AITile.DemolishTile(path.GetTile());
TestDemolishTile().TryDemolish(path.GetTile());
AILog.Warning("We demolished a road at tile " + path.GetTile());
}
if (AITunnel.GetOtherTunnelEnd(path.GetTile()) == par.GetTile()) {
local counter = 0;
do {
// if (!AITunnel.BuildTunnel(AIVehicle.VT_ROAD, path.GetTile())) {
if (!TestBuildTunnel().TryBuild(AIVehicle.VT_ROAD, path.GetTile())) {
if(AIError.GetLastErrorString() == "ERR_ALREADY_BUILT") {
AILog.Warning("We found a tunnel already built at tiles " + path.GetTile() + " - " + par.GetTile());
break;
}
else {
++counter;
}
}
else {
AILog.Warning("We built a tunnel at tiles " + path.GetTile() + " - " + par.GetTile());
break;
}
AIController.Sleep(1);
} while(counter < 500);
if(counter == 500) {
AILog.Warning("Couldn't build tunnel! " + AIError.GetLastErrorString());
return null;
}
builtTiles.append(RoadTile(path.GetTile(), RoadTileTypes.TUNNEL));
}
else {
local bridge_list = AIBridgeList_Length(AIMap.DistanceManhattan(path.GetTile(), par.GetTile()) + 1);
bridge_list.Valuate(AIBridge.GetMaxSpeed);
bridge_list.Sort(AIAbstractList.SORT_BY_VALUE, false);
local counter = 0;
do {
// if (!AIBridge.BuildBridge(AIVehicle.VT_ROAD, bridge_list.Begin(), path.GetTile(), par.GetTile())) {
if (!TestBuildBridge().TryBuild(AIVehicle.VT_ROAD, bridge_list.Begin(), path.GetTile(), par.GetTile())) {
if(AIError.GetLastErrorString() == "ERR_ALREADY_BUILT") {
AILog.Warning("We found a bridge already built at tiles " + path.GetTile() + " - " + par.GetTile());
break;
}
else {
++counter;
}
}
else {
AILog.Warning("We built a bridge at tiles " + path.GetTile() + " - " + par.GetTile());
break;
}
AIController.Sleep(1);
} while(counter < 500);
if(counter == 500) {
AILog.Warning("Couldn't build bridge! " + AIError.GetLastErrorString());
return null;
}
builtTiles.append(RoadTile(path.GetTile(), RoadTileTypes.BRIDGE, bridge_list.Begin()));
builtTiles.append(RoadTile(par.GetTile(), RoadTileTypes.ROAD));
}
}
}
}
path = par;
}
// AILog.Info("Cost for the road: " + costs.GetCosts());
}
AILog.Info("Road built!");
return builtTiles;
}