function ClosestDepotToRoad(begin)
{
neighbors = AITileList();
neighbors.Add(begin, 0);
costs = {
[begin] = 0
};
cameFrom = {
[begin] = null;
};
function CostFor(current, tile)
{
return GetSlope(tile) != AITile.Slope.SLOPE_FLAT ? 2 : 1;
}
function CostForBridge(tile)
{
return AIBridge.GetMinLength(AIBridge.GetBridgeID(tile))
/ AIBridge.GetMaxSpeed(AIBridge.GetBridgeID(tile));
}
function CostForTunnel(tile)
{
return AITile.GetManhattanDistance(tile, AITunnel.GetOtherTunneEnd(tile))
/ AIEngine.GetMaxSpeed(
AIEngineList(AIVehicle.VehicleType.VT_ROAD)
.Valuate(AIEngine.GetPrice)
.End()
);
}
function CalcCameFrom(tile, current)
{
if ( !cameFrom.HasItem(tile) || neighbors.GetValue(tile) < CostFor(current, tile) )
cameFrom[tile] <- current;
}
function AddNeighbor(tile, current)
{
if ( AIRail.IsRailTile(tile) && AIRail.AreTilesConnected(tile, current) )
{
CalcCameFrom(tile, current);
neighbors.SetValue(tile, CostFor(current, tile));
}
}
function AddBridge(tile)
{
if ( AIBridge.IsBridgeTile(tile) )
{
CalcCameFrom(AIBridge.GetOtherBridgeEnd(tile), tile);
neighbors.SetValue(tile, CostForBridge(tile));
}
else if ( AITunnel.IsTunnelTile(tile) )
{
CalcCameFrom(AITunnel.GetOtherTunneEnd(tile), tile);
neighbors.SetValue(tile, CostForTunnel(tile));
}
}
while ( neighbors.Count() > 0 )
{
t = neighbors.Begin();
neighbors.RemoveTop(1);
// orthogonals
AddNeighbor(tile - AIMap.GetTileIndex(1,0));
AddNeighbor(tile - AIMap.GetTileIndex(0,1));
AddNeighbor(tile - AIMap.GetTileIndex(-1,0));
AddNeighbor(tile - AIMap.GetTileIndex(0,-1));
// diagonals
AddNeighbor(tile - AIMap.GetTileIndex(-1,1));
AddNeighbor(tile - AIMap.GetTileIndex(1,1));
AddNeighbor(tile - AIMap.GetTileIndex(1,-1));
AddNeighbor(tile - AIMap.GetTileIndex(-1,-1));
}
return function(depot)
{
if ( cameFrom.HasItem(depot) )
return costs[depot];
return 0x7FFF;
};
}