Loading

Paste #p1najb3xj

  1. /**
  2.  * Build an airport route. Find 2 cities that are big enough and try to build airport in both cities.
  3.  *  Then we can build an aircraft and make some money.
  4.  */
  5. function WrightAI::BuildAirportRoute()
  6. {
  7.     /* Check if we can build more aircraft. */
  8.     if (GetAircraftCount() >= AIGameSettings.GetValue("max_aircraft")) return 0;
  9.    
  10.     local engine = null;
  11.     local engine_list = AIEngineList(AIVehicle.VT_AIR);
  12.     engine_list.Valuate(AIEngine.CanRefitCargo, this.cargoId);
  13.     engine_list.KeepValue(1);
  14.     /* There are no engines available. Abort construction. */
  15.     if (engine_list.Count() == 0) return 0;
  16.    
  17.     local airportTypes = AIList();
  18.     airportTypes.AddItem(0, AIAirport.AT_INTERCON);      // 7
  19.     airportTypes.AddItem(1, AIAirport.AT_INTERNATIONAL); // 4
  20.     airportTypes.AddItem(2, AIAirport.AT_METROPOLITAN);  // 3
  21.     airportTypes.AddItem(3, AIAirport.AT_LARGE);         // 1
  22.     airportTypes.AddItem(4, AIAirport.AT_COMMUTER);      // 5
  23.     airportTypes.AddItem(5, AIAirport.AT_SMALL);         // 0
  24.     airportTypes.AddItem(6, AIAirport.AT_HELISTATION);   // 8
  25.     airportTypes.AddItem(7, AIAirport.AT_HELIDEPOT);     // 6
  26.     airportTypes.AddItem(8, AIAirport.AT_HELIPORT);      // 2
  27.    
  28.     AILog.Info("Trying to build an airport route");
  29.  
  30.     local small_aircraft = false;
  31. //  local helicopter = false;
  32.    
  33.     local airport1_type;
  34.     local tile_1;
  35.     for (local i = 0; i < airportTypes.Count() ; i++) {
  36.         local a1 = airportTypes.GetValue(i);
  37.         if (AIAirport.IsValidAirportType(a1)) {
  38.             /* When looking for a location for smaller airports, ensure we're not using big planes */
  39.             if (a1 == AIAirport.AT_SMALL || a1 == AIAirport.AT_COMMUTER) {
  40.                 engine_list.Valuate(AIEngine.GetPlaneType);
  41.                 engine_list.RemoveValue(AIAirport.PT_BIG_PLANE);
  42.                 /* When we're left with no engines available, abort construction. */
  43.                 if (engine_list.Count() == 0) {
  44.                     return 0;
  45.                 }
  46.                 small_aircraft = true;
  47.             }
  48.             /* When looking for a location for heliports, ensure there are helicopters */
  49.             if (a1 == AIAirport.AT_HELISTATION || a1 == AIAirport.AT_HELIDEPOT || a1 == AIAirport.AT_HELIPORT) {
  50.                 engine_list.Valuate(AIEngine.GetPlaneType);
  51.                 engine_list.KeepValue(AIAirport.PT_HELICOPTER);
  52.                 /* No helicopters available */
  53.                 if (engine_list.Count() == 0) {
  54.                     return 0;
  55.                 }
  56. //              helicopter = true;
  57.             }
  58.             tile_1 = this.FindSuitableAirportSpot(a1, 0);
  59.             airport1_type = a1;
  60.             if (tile_1 != -1) {
  61.                 break;
  62.             }
  63.         }
  64.     }
  65.     if (tile_1 < 0) {
  66.         AILog.Info("Couldn't find a suitable town to build the first airport in");
  67.         return -1;
  68.     }
  69.     if (airport1_type == AIAirport.AT_HELIPORT) {
  70.         airportTypes.RemoveValue(AIAirport.AT_HELIPORT);
  71.     }
  72.    
  73.     local airport2_type;
  74.     local tile_2;
  75.     for (local i = 0; i < airportTypes.Count() ; i++) {
  76.         local a2 = airportTypes.GetValue(i);
  77.         if (AIAirport.IsValidAirportType(a2) ) {
  78.             if (small_aircraft && (a2 == AIAirport.AT_INTERCON || a2 == AIAirport.AT_INTERNATIONAL || a2 == AIAirport.AT_METROPOLITAN || a2 == AIAirport.AT_LARGE)) {
  79.                 continue;
  80.             }
  81.             tile_2 = this.FindSuitableAirportSpot(a2, tile_1);
  82.             airport2_type = a2;
  83.             if (tile_2 != -1) {
  84.                 break;
  85.             }
  86.         }
  87.     }
  88.     if (tile_2 < 0) {
  89.         AILog.Info("Couldn't find a suitable town to build the second airport in");
  90.         this.towns_used.RemoveValue(tile_1);
  91.         return -2;
  92.     }
  93.  
  94.     local adjacentStationId = checkAdjacentStation(tile_1);
  95.  
  96.     /* Build the airports for real */
  97.     if (!AIAirport.BuildAirport(tile_1, airport1_type, adjacentStationId)) {
  98.         if (!AIAirport.BuildAirport(tile_1, airport1_type, AIStation.STATION_NEW)) {
  99.             AILog.Warning("Although the testing told us we could build 2 airports, it still failed on the first airport at tile " + tile_1 + ".");
  100.             this.towns_used.RemoveValue(tile_1);
  101.             this.towns_used.RemoveValue(tile_2);
  102.             return -3;
  103.         }
  104.     }
  105.  
  106.     adjacentStationId = checkAdjacentStation(tile_2);
  107.  
  108.     if (!AIAirport.BuildAirport(tile_2, airport2_type, adjacentStationId)) {
  109.         if (!AIAirport.BuildAirport(tile_2, airport2_type, AIStation.STATION_NEW)) {
  110.             AILog.Warning("Although the testing told us we could build 2 airports, it still failed on the second airport at tile " + tile_2 + ".");
  111.             AIAirport.RemoveAirport(tile_1);
  112.             this.towns_used.RemoveValue(tile_1);
  113.             this.towns_used.RemoveValue(tile_2);
  114.             return -4;
  115.         }
  116.     }
  117.  
  118.     local ret = this.BuildAircraft(tile_1, tile_2);
  119.     if (ret < 0) {
  120.         AIAirport.RemoveAirport(tile_1);
  121.         AIAirport.RemoveAirport(tile_2);
  122.         this.towns_used.RemoveValue(tile_1);
  123.         this.towns_used.RemoveValue(tile_2);
  124.         return ret;
  125.     }
  126.  
  127.     AILog.Info("Done building a route");
  128.     return ret;
  129. }
  130.  
  131. /**
  132.  * Build an aircraft with orders from tile_1 to tile_2.
  133.  *  The best available aircraft of that time will be bought.
  134.  */
  135. function WrightAI::BuildAircraft(tile_1, tile_2)
  136. {
  137.     /* Check if we can build more aircraft. */
  138.     if (GetAircraftCount() >= AIGameSettings.GetValue("max_aircraft")) return 0;
  139.  
  140.     /* Build an aircraft */
  141.     local hangar = AIAirport.GetAirportType(tile_1) == AIAirport.AT_HELIPORT ? AIAirport.GetHangarOfAirport(tile_2) : AIAirport.GetHangarOfAirport(tile_1);
  142.     local engine = null;
  143.  
  144.     local engine_list = AIEngineList(AIVehicle.VT_AIR);
  145.  
  146. //  /* When bank balance < 300000, buy cheaper planes */
  147. //  local balance = AICompany.GetBankBalance(AICompany.COMPANY_SELF);
  148. //  engine_list.Valuate(AIEngine.GetPrice);
  149. //  engine_list.KeepBelowValue(balance < 300000 ? 50000 : (balance < 1000000 ? 300000 : 1000000));
  150.  
  151.     engine_list.Valuate(AIEngine.CanRefitCargo, this.cargoId);
  152.     engine_list.KeepValue(1);
  153.    
  154.     local small_aircraft = AIAirport.GetAirportType(tile_1) == AIAirport.AT_SMALL || AIAirport.GetAirportType(tile_2) == AIAirport.AT_SMALL ||
  155.                            AIAirport.GetAirportType(tile_1) == AIAirport.AT_COMMUTER ||AIAirport.GetAirportType(tile_2) == AIAirport.AT_COMMUTER;
  156.     if (small_aircraft) {
  157.         engine_list.Valuate(AIEngine.GetPlaneType);
  158.         engine_list.RemoveValue(AIAirport.PT_BIG_PLANE);
  159.     }
  160.    
  161.     local helicopter = AIAirport.GetAirportType(tile_1) == AIAirport.AT_HELIPORT || AIAirport.GetAirportType(tile_2) == AIAirport.AT_HELIPORT ||
  162.                        AIAirport.GetAirportType(tile_1) == AIAirport.AT_HELIDEPOT || AIAirport.GetAirportType(tile_2) == AIAirport.AT_HELIDEPOT ||
  163.                        AIAirport.GetAirportType(tile_1) == AIAirport.AT_HELISTATION || AIAirport.GetAirportType(tile_2) == AIAirport.AT_HELISTATION;
  164.     if (helicopter) {
  165.         engine_list.Valuate(AIEngine.GetPlaneType);
  166.         engine_list.KeepValue(AIAirport.PT_HELICOPTER);
  167.     }
  168.  
  169.     engine_list.Valuate(AIEngine.GetMaxSpeed);
  170.     engine_list.KeepTop(1);
  171.  
  172.     engine = engine_list.Begin();
  173.  
  174.     if (!AIEngine.IsValidEngine(engine)) {
  175.         AILog.Error("Couldn't find a suitable engine");
  176.         return -5;
  177.     }
  178.     local vehicle = AIVehicle.BuildVehicle(hangar, engine);
  179.     if (!AIVehicle.IsValidVehicle(vehicle)) {
  180.         AILog.Error("Couldn't build the aircraft");
  181.         return -6;
  182.     }
  183.     if (!AIVehicle.RefitVehicle(vehicle, this.cargoId)) {
  184.         AILog.Error("Couldn't refit the aircraft");
  185.         AIVehicle.SellVehicle(vehicle);
  186.         return -7;
  187.     }
  188.     /* Send him on his way */
  189.     local order_1 = AIAirport.IsHangarTile(tile_1) ? AIMap.GetTileIndex(AIMap.GetTileX(tile_1), AIMap.GetTileY(tile_1) + 1) : tile_1;
  190.     local order_2 = AIAirport.IsHangarTile(tile_2) ? AIMap.GetTileIndex(AIMap.GetTileX(tile_2), AIMap.GetTileY(tile_2) + 1) : tile_2;
  191.     AIOrder.AppendOrder(vehicle, order_1, AIOrder.AIOF_NONE);
  192.     AIOrder.AppendOrder(vehicle, order_2, AIOrder.AIOF_NONE);
  193.     AIVehicle.StartStopVehicle(vehicle);
  194.     this.distance_of_route.rawset(vehicle, AIMap.DistanceManhattan(tile_1, tile_2));
  195.     local dist = this.distance_of_route.rawget(vehicle);
  196.    
  197.     local route_list = AIVehicleList_Station(AIStation.GetStationID(tile_1));
  198.     route_list.Valuate(AIVehicle.GetVehicleType);
  199.     route_list.KeepValue(AIVehicle.VT_AIR);
  200.     route_list.Valuate(AIVehicle.GetState);
  201.     route_list.RemoveValue(AIVehicle.VS_CRASHED);
  202.     local count = route_list.Count();
  203.     local max_count = (dist / 35) + 1;
  204.  
  205.     AILog.Info("Built " + AIVehicle.GetName(vehicle) + " from " + AIStation.GetName(AIStation.GetStationID(tile_1)) + " to " + AIStation.GetName(AIStation.GetStationID(tile_2)) + " (" + this.distance_of_route.rawget(vehicle) + " tiles apart, " + count + "/" + max_count + " aircraft)");
  206.  
  207.     return 0;
  208. }
  209.  
  210. /**
  211.  * Find a suitable spot for an airport, walking all towns hoping to find one.
  212.  *  When a town is used, it is marked as such and not re-used.
  213.  */
  214. function WrightAI::FindSuitableAirportSpot(airport_type, center_tile)
  215. {
  216.     local airport_x = AIAirport.GetAirportWidth(airport_type);
  217.     local airport_y = AIAirport.GetAirportHeight(airport_type);
  218.    
  219.     local allow_station = airport_x <= AIGameSettings.GetValue("station_spread") && airport_y <= AIGameSettings.GetValue("station_spread");
  220.     if (!allow_station) return -1;
  221.    
  222.     local airport_rad = AIAirport.GetAirportCoverageRadius(airport_type);
  223.  
  224.     local town_list = AITownList();
  225.     /* Remove all the towns we already used */
  226.     town_list.RemoveList(this.towns_used);
  227.  
  228.     town_list.Valuate(AITown.GetLastMonthProduction, this.cargoId);
  229.     town_list.KeepAboveValue(LuDiAIAfterFix.cargoClass == AICargo.CC_PASSENGERS ? 70 : 18);
  230. //  /* Keep the best 10, if we can't find a station in there, just leave it anyway */
  231. //  town_list.KeepTop(10);
  232.     town_list.Sort(AIList.SORT_BY_VALUE, false);
  233.  
  234.     /* Now find a suitable town */
  235.     for (local town = town_list.Begin(); town_list.HasNext(); town = town_list.Next()) {
  236.         /* Don't make this a CPU hog */
  237.         Sleep(1);
  238.         local tile = AITown.GetLocation(town);
  239.        
  240.         local tileList = AITileList();
  241.         local rectangleCoordinates = this.TownAirportRadRect(airport_type, town);
  242.         tileList.AddRectangle(rectangleCoordinates[0], rectangleCoordinates[1]);
  243.         tileList.Valuate(AITile.IsBuildableRectangle, airport_x, airport_y);
  244.         tileList.KeepValue(1)
  245.         if (center_tile != 0) {
  246.             /* If we have a tile defined, we don't want to be within 35 tiles of this tile */
  247.             tileList.Valuate(AITile.GetDistanceManhattanToTile, center_tile);
  248.             tileList.KeepAboveValue(35);
  249.         }
  250.         /* Sort on acceptance, remove places that don't have acceptance */
  251.         tileList.Valuate(AITile.GetCargoAcceptance, this.cargoId, airport_x, airport_y, airport_rad);
  252.         tileList.RemoveBelowValue(10);
  253.        
  254.         tileList.Valuate(AITile.GetCargoProduction, this.cargoId, airport_x, airport_y, airport_rad);
  255.         tileList.RemoveBelowValue(10);
  256.         tileList.Sort(AIList.SORT_BY_VALUE, false);
  257.        
  258.         /* Couldn't find a suitable place for this town, skip to the next */
  259.         if (tileList.Count() == 0) continue;
  260.  
  261.         /* Walk all the tiles and see if we can build the airport at all */
  262.         {
  263.             local test = AITestMode();
  264.             local good_tile = 0;
  265.  
  266.             for (tile = tileList.Begin(); tileList.HasNext(); tile = tileList.Next()) {
  267.                 Sleep(1);              
  268.                 if (!AIAirport.BuildAirport(tile, airport_type, AIStation.STATION_NEW)) continue;
  269.                 good_tile = tile;
  270.                 break;
  271.             }
  272.  
  273.             /* Did we find a place to build the airport on? */
  274.             if (good_tile == 0) continue;
  275.         }      
  276.  
  277.         local adjacentStationId = checkAdjacentStation(tile);
  278.         local nearest_town;
  279.         if (adjacentStationId == AIStation.STATION_NEW) {
  280.             nearest_town = AITile.GetClosestTown(tile);
  281.         }
  282.         else {
  283.             nearest_town = AIStation.GetNearestTown(adjacentStationId);
  284.         }
  285.         AILog.Info("Found a good spot for an airport near " + AITown.GetName(nearest_town) + " at tile " + tile);
  286.  
  287.         /* Make the town as used, so we don't use it again */
  288.         this.towns_used.AddItem(nearest_town, tile);
  289.  
  290.         return tile;
  291.     }
  292.  
  293.     return -1;
  294. }

Comments