/**
* Find a suitable spot for an airport, walking all towns hoping to find one.
* When a town is used, it is marked as such and not re-used.
*/
function WrightAI::FindSuitableAirportSpot(airportTypes, airport1_tile, large_aircraft, small_aircraft, helicopter, triedTowns)
{
local town_list = AITownList();
/* Remove all the towns we already used */
town_list.RemoveList(this.towns_used);
/* Remove towns we have tried recently */
town_list.RemoveList(triedTowns);
if (AIController.GetSetting("cities_only")) {
town_list.Valuate(AITown.IsCity);
town_list.KeepValue(1);
}
town_list.Valuate(AITown.GetLastMonthProduction, this.cargoId);
town_list.KeepAboveValue(LuDiAIAfterFix.cargoClass == AICargo.CC_PASSENGERS ? 70 : 18);
if (AIController.GetSetting("pick_random")) {
town_list.Valuate(AIBase.RandItem);
} else {
town_list.Sort(AIList.SORT_BY_VALUE, false);
}
/* Keep the best 10, if we can't find a station in there, just leave it anyway */
town_list.KeepTop(10);
/* Now find a suitable town */
for (local town = town_list.Begin(); town_list.HasNext(); town = town_list.Next()) {
// /* Don't make this a CPU hog */
// Sleep(1);
local town_tile = AITown.GetLocation(town);
AILog.Info("Checking town " + AITown.GetName(town));
local tileList = AITileList();
for (local i = airportTypes.Begin(); airportTypes.HasNext(); i = airportTypes.Next()) {
local a = airportTypes.GetValue(i);
local airport_x = AIAirport.GetAirportWidth(a);
local airport_y = AIAirport.GetAirportHeight(a);
local airport_rad = AIAirport.GetAirportCoverageRadius(a);
// AILog.Info("Checking airport of type " + a);
if (!AIAirport.IsValidAirportType(a)) continue;
if (large_aircraft && a != AIAirport.AT_INTERCON && a != AIAirport.AT_INTERNATIONAL && a != AIAirport.AT_METROPOLITAN && a != AIAirport.AT_LARGE) {
continue;
}
if (small_aircraft && (a == AIAirport.AT_INTERCON || a == AIAirport.AT_INTERNATIONAL || a == AIAirport.AT_METROPOLITAN || a == AIAirport.AT_LARGE)) {
continue;
}
if (helicopter && a != AIAirport.AT_HELISTATION && a != AIAirport.AT_HELIDEPOT && a != AIAirport.AT_HELIPORT) {
continue;
}
local rectangleCoordinates = this.TownAirportRadRect(a, town);
tileList.AddRectangle(rectangleCoordinates[0], rectangleCoordinates[1]);
tileList.Valuate(AITile.GetClosestTown);
tileList.KeepValue(town);
tileList.Valuate(AITile.IsBuildableRectangle, airport_x, airport_y);
tileList.KeepValue(1)
if (tileList.Count() == 0) continue;
if (airport1_tile != 0) {
/* If we have the tile of the first airport, we don't want the second airport to be as close */
tileList.Valuate(AITile.GetDistanceManhattanToTile, airport1_tile);
tileList.KeepAboveValue(min_air_distance);
if (tileList.Count() == 0) continue;
}
/* Sort on acceptance, remove places that don't have acceptance */
tileList.Valuate(AITile.GetCargoAcceptance, this.cargoId, airport_x, airport_y, airport_rad);
tileList.RemoveBelowValue(10);
if (tileList.Count() == 0) continue;
tileList.Valuate(AITile.GetCargoProduction, this.cargoId, airport_x, airport_y, airport_rad);
tileList.RemoveBelowValue(10);
if (tileList.Count() == 0) continue;
tileList.Sort(AIList.SORT_BY_VALUE, false);
/* Couldn't find a suitable place for this town, skip to the next */
if (tileList.Count() == 0) continue;
/* Walk all the tiles and see if we can build the airport at all */
local test = AITestMode();
local good_tile = 0;
for (local tile = tileList.Begin(); tileList.HasNext(); tile = tileList.Next()) {
local adjacentStationId = checkAdjacentStation(tile, a);
local nearest_town;
if (adjacentStationId == AIStation.STATION_NEW) {
nearest_town = AITile.GetClosestTown(tile);
} else {
nearest_town = AIStation.GetNearestTown(adjacentStationId);
}
local noise = AIAirport.GetNoiseLevelIncrease(tile, a);
local allowed_noise = AITown.GetAllowedNoise(AIAirport.GetNearestTown(tile, a));
if (noise > allowed_noise) continue;
// AISign.BuildSign(tile, ("" + noise + " <= " + allowed_noise + ""));
Sleep(1);
// local test = AITestMode();
if (!AIAirport.BuildAirport(tile, a, AIStation.STATION_NEW)) continue;
good_tile = tile;
// AILog.Info("Found a good spot for an airport near " + AITown.GetName(nearest_town) + " or " + AITown.GetName(aitile) + " at tile " + good_tile);
AILog.Info("Found a good spot for an airport near " + AITown.GetName(nearest_town) + " at tile " + good_tile);
/* Make the town as used, so we don't use it again */
assert(!towns_used.HasItem(nearest_town) && town == nearest_town);
this.towns_used.AddItem(nearest_town, good_tile);
if (a == AIAirport.AT_INTERCON || a == AIAirport.AT_INTERNATIONAL || a == AIAirport.AT_METROPOLITAN || a == AIAirport.AT_LARGE) {
large_aircraft = true;
}
if (a == AIAirport.AT_SMALL || a == AIAirport.AT_COMMUTER) {
small_aircraft = true;
}
if (a == AIAirport.AT_HELISTATION || a == AIAirport.AT_HELIDEPOT || a == AIAirport.AT_HELIPORT) {
helicopter = true;
}
return [good_tile, a, large_aircraft, small_aircraft, helicopter, triedTowns];
}
}
/* All airport types were tried on this town and no suitable location was found */
if (airport1_tile == 0) {
triedTowns.AddItem(town, town_tile);
}
}
/* We haven't found a suitable location for any airport type in any town */
return [-1, AIAirport.AT_INVALID, large_aircraft, small_aircraft, helicopter, triedTowns];
}