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; }; }