/** * 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]; }