* Find the nearest hangar to v * StationID::Invalid() is returned, if the company does not have any suitable * airports (like helipads only) * @param v vehicle looking for a hangar * @return the StationID if one is found, otherwise, StationID::Invalid() */
| 118 | * @return the StationID if one is found, otherwise, StationID::Invalid() |
| 119 | */ |
| 120 | static StationID FindNearestHangar(const Aircraft *v) |
| 121 | { |
| 122 | uint best = 0; |
| 123 | StationID index = StationID::Invalid(); |
| 124 | TileIndex vtile = TileVirtXYClampedToMap(v->x_pos, v->y_pos); |
| 125 | const AircraftVehicleInfo *avi = AircraftVehInfo(v->engine_type); |
| 126 | uint max_range = v->acache.cached_max_range_sqr; |
| 127 | |
| 128 | /* Determine destinations where it's coming from and where it's heading to */ |
| 129 | const Station *last_dest = nullptr; |
| 130 | const Station *next_dest = nullptr; |
| 131 | if (max_range != 0) { |
| 132 | if (v->current_order.IsType(OT_GOTO_STATION) || |
| 133 | (v->current_order.IsType(OT_GOTO_DEPOT) && !v->current_order.GetDepotActionType().Test(OrderDepotActionFlag::NearestDepot))) { |
| 134 | last_dest = Station::GetIfValid(v->last_station_visited); |
| 135 | next_dest = Station::GetIfValid(v->current_order.GetDestination().ToStationID()); |
| 136 | } else { |
| 137 | last_dest = GetTargetAirportIfValid(v); |
| 138 | std::vector<StationID> next_station; |
| 139 | v->GetNextStoppingStation(next_station); |
| 140 | if (!next_station.empty()) next_dest = Station::GetIfValid(next_station.back()); |
| 141 | } |
| 142 | } |
| 143 | |
| 144 | for (const Station *st : Station::Iterate()) { |
| 145 | if (st->owner != v->owner || !st->facilities.Test(StationFacility::Airport) || !st->airport.HasHangar()) continue; |
| 146 | |
| 147 | const AirportFTAClass *afc = st->airport.GetFTA(); |
| 148 | |
| 149 | /* don't crash the plane if we know it can't land at the airport */ |
| 150 | if (afc->flags.Test(AirportFTAClass::Flag::ShortStrip) && (avi->subtype & AIR_FAST) && !_cheats.no_jetcrash.value) continue; |
| 151 | |
| 152 | /* the plane won't land at any helicopter station */ |
| 153 | if (!afc->flags.Test(AirportFTAClass::Flag::Airplanes) && (avi->subtype & AIR_CTOL)) continue; |
| 154 | |
| 155 | /* Check if our last and next destinations can be reached from the depot airport. */ |
| 156 | if (max_range != 0) { |
| 157 | uint last_dist = (last_dest != nullptr && last_dest->airport.tile != INVALID_TILE) ? DistanceSquare(st->airport.tile, last_dest->airport.tile) : 0; |
| 158 | uint next_dist = (next_dest != nullptr && next_dest->airport.tile != INVALID_TILE) ? DistanceSquare(st->airport.tile, next_dest->airport.tile) : 0; |
| 159 | if (last_dist > max_range || next_dist > max_range) continue; |
| 160 | } |
| 161 | |
| 162 | /* v->tile can't be used here, when aircraft is flying v->tile is set to 0 */ |
| 163 | uint distance = DistanceSquare(vtile, st->airport.tile); |
| 164 | if (distance < best || index == StationID::Invalid()) { |
| 165 | best = distance; |
| 166 | index = st->index; |
| 167 | } |
| 168 | } |
| 169 | return index; |
| 170 | } |
| 171 | |
| 172 | void Aircraft::GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const |
| 173 | { |
no test coverage detected