Loading

Paste #p13ckykxj

  1. /**
  2.  * Find the nearest hangar to v
  3.  * INVALID_STATION is returned, if the company does not have any suitable
  4.  * airports (like helipads only)
  5.  * @param v vehicle looking for a hangar
  6.  * @return the StationID if one is found, otherwise, INVALID_STATION
  7.  */
  8. static StationID FindNearestHangar(const Aircraft *v)
  9. {
  10.     const Station *st;
  11.     uint best = 0;
  12.     StationID index = INVALID_STATION;
  13.     TileIndex vtile = TileVirtXY(v->x_pos, v->y_pos);
  14.     const AircraftVehicleInfo *avi = AircraftVehInfo(v->engine_type);
  15.  
  16.     FOR_ALL_STATIONS(st) {
  17.         if (st->owner != v->owner || !(st->facilities & FACIL_AIRPORT) || !st->airport.HasHangar()) continue;
  18.  
  19.         const AirportFTAClass *afc = st->airport.GetFTA();
  20.  
  21.         /* don't crash the plane if we know it can't land at the airport */
  22.         if ((afc->flags & AirportFTAClass::SHORT_STRIP) && (avi->subtype & AIR_FAST) &&
  23.                 (!_cheats.no_jetcrash.value || !_settings_game.vehicle.large_plane_on_short_runway)) continue;
  24.  
  25.         /* the plane won't land at any helicopter station */
  26.         if (!(afc->flags & AirportFTAClass::AIRPLANES) && (avi->subtype & AIR_CTOL)) continue;
  27.  
  28.         /* v->tile can't be used here, when aircraft is flying v->tile is set to 0 */
  29.         uint distance = DistanceSquare(vtile, st->airport.tile);
  30.         if (v->acache.cached_max_range_sqr != 0) {
  31.             /* Determine destinations */
  32.             const Station *cur_dest = GetTargetAirportIfValid(v);
  33.             const Station *next_dest;
  34.             if (v->current_order.IsType(OT_GOTO_STATION) ||
  35.                     v->current_order.IsType(OT_GOTO_DEPOT) && v->current_order.GetDepotActionType() != ODATFB_NEAREST_DEPOT) {
  36.                 next_dest = Station::GetIfValid(v->current_order.GetDestination());
  37.                 if (next_dest == cur_dest) next_dest = Station::GetIfValid(v->last_station_visited);
  38.             } else {
  39.                 next_dest = Station::GetIfValid(v->GetNextStoppingStation().value);
  40.             }
  41.  
  42.             /* Check if our current and next (or previous) destinations can be reached from the depot airport. */
  43.             if (next_dest != NULL && next_dest->airport.tile != INVALID_TILE && cur_dest != NULL) {
  44.                 if (DistanceSquare(st->airport.tile, next_dest->airport.tile) > v->acache.cached_max_range_sqr ||
  45.                     DistanceSquare(st->airport.tile, cur_dest->airport.tile) > v->acache.cached_max_range_sqr) continue;
  46.             } else if (next_dest != NULL && next_dest->airport.tile != INVALID_TILE && cur_dest == NULL) {
  47.                 if (DistanceSquare(st->airport.tile, next_dest->airport.tile) > v->acache.cached_max_range_sqr) continue;
  48.             } else if ((next_dest == NULL || next_dest->airport.tile == INVALID_TILE) && cur_dest != NULL) {
  49.                 if (DistanceSquare(st->airport.tile, cur_dest->airport.tile) > v->acache.cached_max_range_sqr) continue;
  50.             }
  51.         }
  52.         if (distance < best || index == INVALID_STATION) {
  53.             best = distance;
  54.             index = st->index;
  55.         }
  56.     }
  57.     return index;
  58. }

Comments