function findRoadTileDepot(tile) {
if(!AIRoad.IsRoadTile(tile)) {
return null;
}
local depotTile = null;
local adjacentTiles = Utils.getAdjacentTiles(tile);
adjacentTiles.Valuate(AIRoad.IsRoadTile);
adjacentTiles.RemoveValue(1);
local roadTiles = Utils.getAdjacentTiles(tile);
roadTiles.Valuate(AIRoad.IsRoadTile);
roadTiles.KeepValue(1);
local roadTile = null;
for (roadTile = roadTiles.Begin(); roadTiles.HasNext(); roadTile = roatTiles.Next()) {
if (AIRoad.AreRoadTilesConnected(roadTile, tile)) {
break;
}
}
assert(roadTile != null);
for (local adjacentTile = adjacentTiles.Begin(); adjacentTiles.HasNext(); adjacentTile = adjacentTiles.Next()) {
AILog.Info("roadTile = " + roadTile + "; adjacentTile = " + adjacentTile + "; tile = " + tile);
if (AIRoad.AreRoadTilesConnected(tile, adjacentTile) || AITile.IsBuildable(adjacentTile) && (AITile.GetSlope(adjacentTile) == AITile.SLOPE_FLAT || !AITile.IsCoastTile(adjacentTile)) &&
AIRoad.CanBuildConnectedRoadPartsHere(tile, roadTile, adjacentTile)) {
depotTile = adjacentTile;
break;
}
}
return depotTile;
}
function buildDepotOnTile(t) {
local square = AITileList();
local squareSize = 1;
square.AddRectangle(Utils.getValidOffsetTile(t, (-1) * squareSize, (-1) * squareSize),
Utils.getValidOffsetTile(t, squareSize, squareSize));
local depotTile = findRoadTileDepot(t);
local depotFrontTile = t;
if(depotTile != null) {
local counter = 0;
do {
if (!TestBuildRoadDepot().TryBuild(depotTile, depotFrontTile)) {
++counter;
}
else {
break;
}
AIController.Sleep(1);
} while(counter < 1);
if (counter == 1) {
return null;
}
else {
local counter = 0;
do {
if(!TestBuildRoad().TryBuild(depotTile, depotFrontTile) && AIError.GetLastErrorString() != "ERR_ALREADY_BUILT") {
++counter;
}
else {
break;
}
AIController.Sleep(1);
} while(counter < 500);
if (counter == 500) {
local counter = 0;
do {
if (!TestRemoveRoadDepot().TryRemove(depotTile)) {
++counter;
}
else {
break;
}
AIController.Sleep(1);
} while(counter < 500);
if (counter == 500) {
LuDiAIAfterFix().scheduledRemovals.AddItem(depotTile, 0);
return null;
}
else {
return null;
}
}
else {
return depotTile;
}
}
}
}
function buildDepotOnRoad(roadArray) {
if(roadArray == null) {
return null;
}
local depotTile = null;
//first attempt, build next to the road route
local arrayMiddleTile = roadArray[roadArray.len() / 2].m_tile;
local roadTiles = AITileList();
for (local index = 1; index < roadArray.len() - 1; ++index) {
roadTiles.AddItem(roadArray[index].m_tile, AIMap.DistanceManhattan(roadArray[index].m_tile, arrayMiddleTile));
}
roadTiles.Sort(AIList.SORT_BY_VALUE, AIList.SORT_ASCENDING);
for (local tile = roadTiles.Begin(); roadTiles.HasNext(); tile = roadTiles.Next()) {
depotTile = buildDepotOnTile(tile);
AISign.BuildSign(tile, "x");
if (depotTile != null) {
return depotTile;
}
}
local squareSize = AIGameSettings.GetValue("station_spread");
//second attempt, build closer to the destination
local tileList = AITileList();
tileList.AddRectangle(Utils.getValidOffsetTile(m_stationTo, -1 * squareSize, -1 * squareSize),
Utils.getValidOffsetTile(m_stationTo, squareSize, squareSize));
tileList.Valuate(AIRoad.IsRoadTile);
tileList.KeepValue(1);
tileList.Valuate(AIMap.DistanceManhattan, m_stationTo);
tileList.Sort(AIList.SORT_BY_VALUE, AIList.SORT_ASCENDING);
for (local tile = tileList.Begin(); tileList.HasNext(); tile = tileList.Next()) {
depotTile = buildDepotOnTile(tile);
if (depotTile != null) {
return depotTile;
}
}
//third attempt, build closer to the source
tileList.Clear();
tileList.AddRectangle(Utils.getValidOffsetTile(m_stationFrom, -1 * squareSize, -1 * squareSize),
Utils.getValidOffsetTile(m_stationFrom, squareSize, squareSize));
tileList.Valuate(AIRoad.IsRoadTile);
tileList.KeepValue(1);
tileList.Valuate(AIMap.DistanceManhattan, m_stationFrom);
tileList.Sort(AIList.SORT_BY_VALUE, AIList.SORT_ASCENDING);
for (local tile = tileList.Begin(); tileList.HasNext(); tile = tileList.Next()) {
depotTile = buildDepotOnTile(tile);
if (depotTile != null) {
return depotTile;
}
}
AILog.Warning("Couldn't built road depot!");
return depotTile;
}