Loading

Paste #plclcisfi

  1. /**
  2.  * Find a suitable spot for an airport, walking all towns hoping to find one.
  3.  * When a town is used, it is marked as such and not re-used.
  4.  */
  5. function WrightAI::FindSuitableAirportSpot(airportTypes, airport1_tile, large_aircraft, small_aircraft, helicopter)
  6. {
  7.     local town_list = AITownList();
  8.     /* Remove all the towns we already used */
  9.     town_list.RemoveList(this.towns_used);
  10.    
  11.     /* Remove towns we have tried recently */
  12.     town_list.RemoveList(this.triedTowns);
  13.    
  14.     if (AIController.GetSetting("cities_only")) {
  15.         town_list.Valuate(AITown.IsCity);
  16.         town_list.KeepValue(1);
  17.     }
  18.  
  19.     town_list.Valuate(AITown.GetLastMonthProduction, this.cargoId);
  20.     town_list.KeepAboveValue(LuDiAIAfterFix.cargoClass == AICargo.CC_PASSENGERS ? 70 : 18);
  21.     if (AIController.GetSetting("pick_random")) {
  22.         town_list.Valuate(AIBase.RandItem);
  23.     } else {
  24.         town_list.Sort(AIList.SORT_BY_VALUE, false);
  25.     }
  26.     /* Keep the best 10, if we can't find a station in there, just leave it anyway */
  27.     town_list.KeepTop(10);
  28.    
  29.     if (town_list.Count() <= 1) {
  30.         this.triedTowns.Clear();
  31.     }
  32.  
  33.     /* Now find a suitable town */
  34.     for (local town = town_list.Begin(); town_list.HasNext(); town = town_list.Next()) {
  35.         /* Don't make this a CPU hog */
  36.         AIController.Sleep(1);
  37.         local town_tile = AITown.GetLocation(town);
  38. //      AILog.Info("Checking town " + AITown.GetName(town));
  39.        
  40.         for (local i = airportTypes.Begin(); airportTypes.HasNext(); i = airportTypes.Next()) {
  41.             local a = airportTypes.GetValue(i);
  42.             local airport_x = AIAirport.GetAirportWidth(a);
  43.             local airport_y = AIAirport.GetAirportHeight(a);
  44.             local airport_rad = AIAirport.GetAirportCoverageRadius(a);
  45. //          AILog.Info("Checking airport of type " + a);
  46.             if (!AIAirport.IsValidAirportType(a)) continue;
  47.        
  48.             if (large_aircraft && a != AIAirport.AT_INTERCON && a != AIAirport.AT_INTERNATIONAL && a != AIAirport.AT_METROPOLITAN && a != AIAirport.AT_LARGE) {
  49.                 continue;
  50.             }
  51.             if (small_aircraft && a != AIAirport.AT_INTERCON && a != AIAirport.AT_INTERNATIONAL && a != AIAirport.AT_METROPOLITAN && a != AIAirport.AT_LARGE && a != AIAirport.AT_SMALL && a != AIAirport.AT_COMMUTER) {
  52.                 continue;
  53.             }
  54.             if (helicopter && a != AIAirport.AT_HELISTATION && a != AIAirport.AT_HELIDEPOT && a != AIAirport.AT_HELIPORT) {
  55.                 if (AIAirport.IsValidAirportType(AIAirport.AT_HELISTATION) || AIAirport.IsValidAirportType(AIAirport.AT_HELIDEPOT)) {
  56.                     continue;
  57.                 }
  58.             }
  59.            
  60.             local engine_list = null;
  61.             if (large_aircraft) {
  62.                 engine_list = this.GetBestAirportEngine(AIAirport.AT_LARGE, true);
  63.             } else if (small_aircraft) {
  64.                 engine_list = this.GetBestAirportEngine(AIAirport.AT_SMALL, true);
  65.             } else if (helicopter) {
  66.                 engine_list = this.GetBestAirportEngine(AIAirport.AT_HELIPORT, true);
  67.             } else {
  68.                 engine_list = this.GetBestAirportEngine(a, true);
  69.             }
  70.             if (engine_list == null) continue;
  71.            
  72.             local engine = WrightAI.GetBestEngineIncome(engine_list);
  73.             if (engine[0] == null) continue;
  74.  
  75.             local fakedist = engine[1];
  76.  
  77.             /* Best engine is unprofitable enough */
  78.             if (fakedist == 0) continue;
  79.  
  80.             local rectangleCoordinates = this.TownAirportRadRect(a, town);
  81.             local tileList = AITileList();
  82.             tileList.AddRectangle(rectangleCoordinates[0], rectangleCoordinates[1]);
  83.             tileList.Valuate(AITile.GetClosestTown);
  84.             tileList.KeepValue(town);
  85.             if (tileList.Count() == 0) continue;
  86.  
  87.             if (airport1_tile != 0) {
  88.                 /* If we have the tile of the first airport, we don't want the second airport to be as close or as further */
  89.                 tileList.Valuate(AITile.GetDistanceSquareToTile, airport1_tile);
  90.                 local max_order_dist = WrightAI.GetMaximumOrderDistance(engine[0]);
  91.                 local max_dist = max_order_dist > AIMap.GetMapSize() ? AIMap.GetMapSize() : max_order_dist;
  92.                 local min_order_dist = (fakedist / 2) * (fakedist / 2);
  93.                 local min_dist = min_order_dist > max_dist * 3 / 4 ? max_dist * 3 / 4 > AIMap.GetMapSize() / 8 ? AIMap.GetMapSize() / 8 : max_dist * 3 / 4 : min_order_dist;
  94.                 tileList.KeepBetweenValue(min_dist, max_dist);
  95. //              AILog.Info("KeepBetweenValue " + min_dist + " and " + max_dist);
  96.                 tileList.Valuate(WrightAI.DistanceRealFake, airport1_tile);
  97.                 tileList.KeepBelowValue(fakedist * 11 / 10);
  98.                 if (tileList.Count() == 0) continue;
  99.             }
  100.             tileList.Valuate(AITile.IsBuildableRectangle, airport_x, airport_y);
  101.             tileList.KeepValue(1)
  102.             if (tileList.Count() == 0) continue;
  103.  
  104.             /* Sort on acceptance, remove places that don't have acceptance */
  105.             tileList.Valuate(AITile.GetCargoAcceptance, this.cargoId, airport_x, airport_y, airport_rad);
  106.             tileList.RemoveBelowValue(10);
  107.             if (tileList.Count() == 0) continue;
  108.        
  109.             tileList.Valuate(AITile.GetCargoProduction, this.cargoId, airport_x, airport_y, airport_rad);
  110.             tileList.RemoveBelowValue(LuDiAIAfterFix.cargoClass == AICargo.CC_PASSENGERS ? 70 : 18);
  111.             /* Couldn't find a suitable place for this town, skip to the next */
  112.             if (tileList.Count() == 0) continue;
  113.             tileList.Sort(AIList.SORT_BY_VALUE, false);
  114.        
  115.             /* Walk all the tiles and see if we can build the airport at all */
  116.             local good_tile = 0;
  117.             for (local tile = tileList.Begin(); tileList.HasNext(); tile = tileList.Next()) {
  118.                 local adjacentStationId = checkAdjacentStation(tile, a);
  119.                 local nearest_town;
  120.                 if (adjacentStationId == AIStation.STATION_NEW) {
  121.                     nearest_town = AITile.GetClosestTown(tile);
  122.                 } else {
  123.                     nearest_town = AIStation.GetNearestTown(adjacentStationId);
  124.                     if (nearest_town != town) {
  125.                         adjacentStationId = AIStation.STATION_NEW;
  126.                         nearest_town = AITile.GetClosestTown(tile);
  127.                     }
  128.                 }
  129.                 local noise = AIAirport.GetNoiseLevelIncrease(tile, a);
  130.                 local allowed_noise = AITown.GetAllowedNoise(AIAirport.GetNearestTown(tile, a));
  131.                 if (noise > allowed_noise) continue;
  132.  
  133.                 /* Don't build airport if there is any competitor station in the vicinity, or an airport of mine */
  134.                 local airportcoverage = this.TownAirportRadRect(a, tile, false);
  135.                 local tileList2 = AITileList();
  136.                 tileList2.AddRectangle(airportcoverage[0], airportcoverage[1]);
  137.                 local nearby_station = false;
  138.                 for (local t = tileList2.Begin(); tileList2.HasNext(); t = tileList2.Next()) {
  139.                     if (AITile.IsStationTile(t) && (AIAirport.IsAirportTile(t) || AITile.GetOwner(t) != AICompany.ResolveCompanyID(AICompany.COMPANY_SELF) && AIController.GetSetting("is_friendly"))) {
  140.                         nearby_station = true;
  141.                         break;
  142.                     }
  143.                 }
  144.                 if (nearby_station) continue;
  145.                
  146. //              AISign.BuildSign(tile, ("" + noise + " <= " + allowed_noise + ""));
  147.                 AIController.Sleep(1);
  148.                 if (AITestMode() && !AIAirport.BuildAirport(tile, a, adjacentStationId)) continue;
  149.                 good_tile = tile;
  150.                 AILog.Info("Found a good spot for an airport near " + AITown.GetName(nearest_town) + " at tile " + good_tile);
  151.  
  152.                 /* Mark the town as used, so we don't use it again */
  153.                 assert(!towns_used.HasItem(nearest_town) && !triedTowns.HasItem(nearest_town) && nearest_town == town);
  154.                 this.triedTowns.AddItem(nearest_town, good_tile);
  155.                
  156.                 if (a == AIAirport.AT_INTERCON || a == AIAirport.AT_INTERNATIONAL || a == AIAirport.AT_METROPOLITAN || a == AIAirport.AT_LARGE) {
  157.                     large_aircraft = true;
  158.                 }
  159.                 if (a == AIAirport.AT_SMALL || a == AIAirport.AT_COMMUTER) {
  160.                     small_aircraft = true;
  161.                 }
  162.                 if (a == AIAirport.AT_HELISTATION || a == AIAirport.AT_HELIDEPOT || a == AIAirport.AT_HELIPORT) {
  163.                     helicopter = true;
  164.                 }
  165.                 return [good_tile, a, large_aircraft, small_aircraft, helicopter, adjacentStationId];
  166.             }
  167.         }
  168.        
  169.         /* All airport types were tried on this town and no suitable location was found */
  170.         assert(!triedTowns.HasItem(town));
  171.         this.triedTowns.AddItem(town, town_tile);
  172.     }
  173.    
  174.     /* We haven't found a suitable location for any airport type in any town */
  175.     return [-1, AIAirport.AT_INVALID, large_aircraft, small_aircraft, helicopter, -1];
  176. }

Comments