def compatible_with_mission( self, unit_type: AircraftType, airfield: ControlPoint ) -> bool: if unit_type not in aircraft_for_task(FlightType.TRANSPORT): return False if not self.transfer.origin.can_operate(unit_type): return False if not self.next_stop.can_operate(unit_type): return False # Cargo planes have no maximum range. if not unit_type.dcs_unit_type.helicopter: return True # A helicopter that is transport capable and able to operate at both bases. Need # to check that no leg of the journey exceeds the maximum range. This doesn't # account for any routing around threats that might take place, but it's close # enough. home = airfield.position pickup = self.transfer.position.position drop_off = self.transfer.position.position if meters(home.distance_to_point(pickup)) > self.HELO_MAX_RANGE: return False if meters(pickup.distance_to_point(drop_off)) > self.HELO_MAX_RANGE: return False if meters(drop_off.distance_to_point(home)) > self.HELO_MAX_RANGE: return False return True
def find_aircraft_for_task( self, flight: ProposedFlight, task: FlightType ) -> Optional[Tuple[ControlPoint, Squadron]]: types = aircraft_for_task(task) airfields_in_range = self.closest_airfields.operational_airfields_within( flight.max_distance ) for airfield in airfields_in_range: if not airfield.is_friendly(self.is_player): continue inventory = self.global_inventory.for_control_point(airfield) for aircraft in types: if not airfield.can_operate(aircraft): continue if inventory.available(aircraft) < flight.num_aircraft: continue # Valid location with enough aircraft available. Find a squadron to fit # the role. squadrons = self.air_wing.auto_assignable_for_task_with_type( aircraft, task ) for squadron in squadrons: if squadron.can_provide_pilots(flight.num_aircraft): inventory.remove_aircraft(aircraft, flight.num_aircraft) return airfield, squadron return None
def _affordable_aircraft_for_task( self, task: FlightType, airbase: ControlPoint, number: int, max_price: float, ) -> Optional[AircraftType]: best_choice: Optional[AircraftType] = None for unit in aircraft_for_task(task): if unit not in self.faction.aircrafts: continue if unit.price * number > max_price: continue if not airbase.can_operate(unit): continue for squadron in self.air_wing.squadrons_for(unit): if task in squadron.auto_assignable_mission_types: break else: continue # Affordable, compatible, and we have a squadron capable of the task. To # keep some variety, skip with a 50/50 chance. Might be a good idea to have # the chance to skip based on the price compared to the rest of the choices. best_choice = unit if random.choice([True, False]): break return best_choice
def update_items(self, mission_type: FlightType, aircraft_types): current_aircraft = self.currentData() self.clear() for aircraft in aircraft_types: if aircraft in aircraft_for_task(mission_type): self.addItem(f"{aircraft}", userData=aircraft) current_aircraft_index = self.findData(current_aircraft) if current_aircraft_index != -1: self.setCurrentIndex(current_aircraft_index) if self.count() == 0: self.addItem("No capable aircraft available", userData=None)
def find_aircraft_for_flight( self, flight: ProposedFlight ) -> Optional[Tuple[ControlPoint, Type[FlyingType]]]: """Finds aircraft suitable for the given mission. Searches for aircraft capable of performing the given mission within the maximum allowed range. If insufficient aircraft are available for the mission, None is returned. Airfields are searched ordered nearest to farthest from the target and searched twice. The first search looks for aircraft which prefer the mission type, and the second search looks for any aircraft which are capable of the mission type. For example, an F-14 from a nearby carrier will be preferred for the CAP of an airfield that has only F-16s, but if the carrier has only F/A-18s the F-16s will be used for CAP instead. Note that aircraft *will* be removed from the global inventory on success. This is to ensure that the same aircraft are not matched twice on subsequent calls. If the found aircraft are not used, the caller is responsible for returning them to the inventory. """ return self.find_aircraft_of_type(flight, aircraft_for_task(flight.task))
def affordable_aircraft_for(self, request: AircraftProcurementRequest, airbase: ControlPoint, budget: float) -> Optional[Type[FlyingType]]: return self._affordable_aircraft_of_types( aircraft_for_task(request.task_capability), airbase, request.number, budget)