Format with updated black

This commit is contained in:
Raffson 2024-10-12 17:20:44 +02:00
parent 11a9d67b91
commit 5fdf38c663
No known key found for this signature in database
GPG Key ID: B0402B2C9B764D99
58 changed files with 164 additions and 187 deletions

View File

@ -1,4 +1,5 @@
"""Objective adjacency lists.""" """Objective adjacency lists."""
from __future__ import annotations from __future__ import annotations
from typing import Dict, Iterator, List, Optional, TYPE_CHECKING from typing import Dict, Iterator, List, Optional, TYPE_CHECKING

View File

@ -201,9 +201,11 @@ class Builder(IBuilder[AirliftFlightPlan, AirliftLayout]):
return_ascent = self._create_ascent_or_descent( return_ascent = self._create_ascent_or_descent(
builder, builder,
cargo.next_stop.position (
if cargo.next_stop != self.flight.arrival cargo.next_stop.position
else cargo.origin.position, if cargo.next_stop != self.flight.arrival
else cargo.origin.position
),
self.flight.arrival.position, self.flight.arrival.position,
altitude, altitude,
altitude_is_agl, altitude_is_agl,
@ -211,9 +213,11 @@ class Builder(IBuilder[AirliftFlightPlan, AirliftLayout]):
return_descent = self._create_ascent_or_descent( return_descent = self._create_ascent_or_descent(
builder, builder,
self.flight.arrival.position, self.flight.arrival.position,
cargo.next_stop.position (
if cargo.next_stop != self.flight.arrival cargo.next_stop.position
else cargo.origin.position, if cargo.next_stop != self.flight.arrival
else cargo.origin.position
),
altitude, altitude,
altitude_is_agl, altitude_is_agl,
) )

View File

@ -5,6 +5,7 @@ MissionPlanner. Those only plan basic information like the objective, aircraft
type, and the size of the flight. The FlightPlanBuilder is responsible for type, and the size of the flight. The FlightPlanBuilder is responsible for
generating the waypoints for the mission. generating the waypoints for the mission.
""" """
from __future__ import annotations from __future__ import annotations
import math import math

View File

@ -33,8 +33,7 @@ class FormationLayout(LoiterLayout, ABC):
class FormationFlightPlan(LoiterFlightPlan, ABC): class FormationFlightPlan(LoiterFlightPlan, ABC):
@property @property
@abstractmethod @abstractmethod
def package_speed_waypoints(self) -> set[FlightWaypoint]: def package_speed_waypoints(self) -> set[FlightWaypoint]: ...
...
@property @property
def combat_speed_waypoints(self) -> set[FlightWaypoint]: def combat_speed_waypoints(self) -> set[FlightWaypoint]:
@ -77,13 +76,11 @@ class FormationFlightPlan(LoiterFlightPlan, ABC):
@property @property
@abstractmethod @abstractmethod
def join_time(self) -> datetime: def join_time(self) -> datetime: ...
...
@property @property
@abstractmethod @abstractmethod
def split_time(self) -> datetime: def split_time(self) -> datetime: ...
...
def tot_for_waypoint(self, waypoint: FlightWaypoint) -> datetime | None: def tot_for_waypoint(self, waypoint: FlightWaypoint) -> datetime | None:
if waypoint == self.layout.join: if waypoint == self.layout.join:

View File

@ -60,8 +60,7 @@ class IBuilder(ABC, Generic[FlightPlanT, LayoutT]):
return self.flight.departure.theater return self.flight.departure.theater
@abstractmethod @abstractmethod
def build(self, dump_debug_info: bool = False) -> FlightPlanT: def build(self, dump_debug_info: bool = False) -> FlightPlanT: ...
...
@property @property
def package(self) -> Package: def package(self) -> Package:

View File

@ -26,8 +26,7 @@ class LoiterFlightPlan(StandardFlightPlan[Any], ABC):
@property @property
@abstractmethod @abstractmethod
def push_time(self) -> datetime: def push_time(self) -> datetime: ...
...
def depart_time_for_waypoint(self, waypoint: FlightWaypoint) -> datetime | None: def depart_time_for_waypoint(self, waypoint: FlightWaypoint) -> datetime | None:
if waypoint == self.layout.hold: if waypoint == self.layout.hold:

View File

@ -14,5 +14,4 @@ class UiZone:
class UiZoneDisplay(abc.ABC): class UiZoneDisplay(abc.ABC):
@abc.abstractmethod @abc.abstractmethod
def ui_zone(self) -> UiZone: def ui_zone(self) -> UiZone: ...
...

View File

@ -273,9 +273,11 @@ class WaypointBuilder:
return FlightWaypoint( return FlightWaypoint(
"INGRESS", "INGRESS",
ingress_type, ingress_type,
objective.position.point_from_heading(heading, nautical_miles(5).meters) (
if self.is_helo objective.position.point_from_heading(heading, nautical_miles(5).meters)
else position, if self.is_helo
else position
),
alt, alt,
alt_type, alt_type,
description=f"INGRESS on {objective.name}", description=f"INGRESS on {objective.name}",
@ -328,9 +330,11 @@ class WaypointBuilder:
return FlightWaypoint( return FlightWaypoint(
target.name, target.name,
FlightWaypointType.TARGET_POINT, FlightWaypointType.TARGET_POINT,
target.target.ground_object.position (
if isinstance(target.target, TheaterGroup) target.target.ground_object.position
else target.target.position, if isinstance(target.target, TheaterGroup)
else target.target.position
),
meters(0), meters(0),
"RADIO", "RADIO",
description=description, description=description,
@ -432,9 +436,11 @@ class WaypointBuilder:
"CAS", "CAS",
FlightWaypointType.CAS, FlightWaypointType.CAS,
position, position,
feet(self.flight.coalition.game.settings.heli_combat_alt_agl) (
if self.is_helo feet(self.flight.coalition.game.settings.heli_combat_alt_agl)
else max(meters(1000), altitude), if self.is_helo
else max(meters(1000), altitude)
),
"RADIO", "RADIO",
description="Provide CAS", description="Provide CAS",
pretty_name="CAS", pretty_name="CAS",

View File

@ -60,14 +60,12 @@ class FlightState(ABC):
@property @property
@abstractmethod @abstractmethod
def cancelable(self) -> bool: def cancelable(self) -> bool: ...
...
@abstractmethod @abstractmethod
def on_game_tick( def on_game_tick(
self, events: GameUpdateEvents, time: datetime, duration: timedelta self, events: GameUpdateEvents, time: datetime, duration: timedelta
) -> None: ) -> None: ...
...
@property @property
def in_flight(self) -> bool: def in_flight(self) -> bool:
@ -98,17 +96,14 @@ class FlightState(ABC):
@property @property
@abstractmethod @abstractmethod
def is_waiting_for_start(self) -> bool: def is_waiting_for_start(self) -> bool: ...
...
@abstractmethod @abstractmethod
def estimate_position(self) -> Point: def estimate_position(self) -> Point: ...
...
@property @property
@abstractmethod @abstractmethod
def spawn_type(self) -> StartType: def spawn_type(self) -> StartType: ...
...
def a2a_commit_region(self) -> Optional[ThreatPoly]: def a2a_commit_region(self) -> Optional[ThreatPoly]:
return None return None

View File

@ -57,16 +57,13 @@ class InFlight(FlightState, ABC):
) )
@abstractmethod @abstractmethod
def estimate_position(self) -> Point: def estimate_position(self) -> Point: ...
...
@abstractmethod @abstractmethod
def estimate_altitude(self) -> tuple[Distance, str]: def estimate_altitude(self) -> tuple[Distance, str]: ...
...
@abstractmethod @abstractmethod
def estimate_speed(self) -> Speed: def estimate_speed(self) -> Speed: ...
...
def estimate_fuel_at_current_waypoint(self) -> float: def estimate_fuel_at_current_waypoint(self) -> float:
initial_fuel = super().estimate_fuel() initial_fuel = super().estimate_fuel()

View File

@ -9,36 +9,28 @@ if TYPE_CHECKING:
class IFlightRoster(ABC): class IFlightRoster(ABC):
@abstractmethod @abstractmethod
def iter_pilots(self) -> Iterator[Pilot | None]: def iter_pilots(self) -> Iterator[Pilot | None]: ...
...
@abstractmethod @abstractmethod
def pilot_at(self, idx: int) -> Pilot | None: def pilot_at(self, idx: int) -> Pilot | None: ...
...
@property @property
@abstractmethod @abstractmethod
def squadron(self) -> Squadron: def squadron(self) -> Squadron: ...
...
@property @property
@abstractmethod @abstractmethod
def max_size(self) -> int: def max_size(self) -> int: ...
...
@property @property
@abstractmethod @abstractmethod
def player_count(self) -> int: def player_count(self) -> int: ...
...
@abstractmethod @abstractmethod
def resize(self, new_size: int) -> None: def resize(self, new_size: int) -> None: ...
...
@abstractmethod @abstractmethod
def set_pilot(self, index: int, pilot: Optional[Pilot]) -> None: def set_pilot(self, index: int, pilot: Optional[Pilot]) -> None: ...
...
@abstractmethod @abstractmethod
def clear(self) -> None: def clear(self) -> None: ...
...

View File

@ -166,9 +166,11 @@ class Loadout:
# last - the first element in the tuple will be tried first, then the second, # last - the first element in the tuple will be tried first, then the second,
# etc. # etc.
loadout_names = { loadout_names = {
t: [f"Liberation {t.value}", f"Retribution {t.value}"] t: (
if prefer_liberation_payloads() [f"Liberation {t.value}", f"Retribution {t.value}"]
else [f"Retribution {t.value}", f"Liberation {t.value}"] if prefer_liberation_payloads()
else [f"Retribution {t.value}", f"Liberation {t.value}"]
)
for t in FlightType for t in FlightType
} }
legacy_names = { legacy_names = {

View File

@ -1,4 +1,5 @@
"""Support for working with DCS group callsigns.""" """Support for working with DCS group callsigns."""
import logging import logging
import re import re
from typing import Any from typing import Any

View File

@ -21,8 +21,7 @@ class FrontLineStanceTask(TheaterCommanderTask, ABC):
@property @property
@abstractmethod @abstractmethod
def stance(self) -> CombatStance: def stance(self) -> CombatStance: ...
...
@staticmethod @staticmethod
def management_allowed(state: TheaterState) -> bool: def management_allowed(state: TheaterState) -> bool:
@ -49,8 +48,7 @@ class FrontLineStanceTask(TheaterCommanderTask, ABC):
@property @property
@abstractmethod @abstractmethod
def have_sufficient_front_line_advantage(self) -> bool: def have_sufficient_front_line_advantage(self) -> bool: ...
...
@property @property
def ground_force_balance(self) -> float: def ground_force_balance(self) -> float:

View File

@ -57,8 +57,7 @@ class PackagePlanningTask(TheaterCommanderTask, Generic[MissionTargetT]):
coalition.ato.add_package(self.package) coalition.ato.add_package(self.package)
@abstractmethod @abstractmethod
def propose_flights(self) -> None: def propose_flights(self) -> None: ...
...
def propose_flight( def propose_flight(
self, self,
@ -122,9 +121,9 @@ class PackagePlanningTask(TheaterCommanderTask, Generic[MissionTargetT]):
target_ranges: list[ target_ranges: list[
tuple[Union[IadsGroundObject, NavalGroundObject], Distance] tuple[Union[IadsGroundObject, NavalGroundObject], Distance]
] = [] ] = []
all_iads: Iterator[ all_iads: Iterator[Union[IadsGroundObject, NavalGroundObject]] = (
Union[IadsGroundObject, NavalGroundObject] itertools.chain(state.enemy_air_defenses, state.enemy_ships)
] = itertools.chain(state.enemy_air_defenses, state.enemy_ships) )
for target in all_iads: for target in all_iads:
distance = meters(target.distance_to(self.target)) distance = meters(target.distance_to(self.target))
if range_type is RangeType.Detection: if range_type is RangeType.Detection:
@ -158,9 +157,7 @@ class PackagePlanningTask(TheaterCommanderTask, Generic[MissionTargetT]):
return ( return (
1.0 1.0
if target.task in [GroupTask.LORAD, GroupTask.MERAD] if target.task in [GroupTask.LORAD, GroupTask.MERAD]
else 0.5 else 0.5 if target.task == GroupTask.AAA else 0.9
if target.task == GroupTask.AAA
else 0.9
) )
def iter_detecting_iads( def iter_detecting_iads(

View File

@ -12,5 +12,4 @@ if TYPE_CHECKING:
class TheaterCommanderTask(PrimitiveTask[TheaterState]): class TheaterCommanderTask(PrimitiveTask[TheaterState]):
@abstractmethod @abstractmethod
def execute(self, coalition: Coalition) -> None: def execute(self, coalition: Coalition) -> None: ...
...

View File

@ -52,6 +52,7 @@ even though it is a primitive task used by many other tasks.
https://en.wikipedia.org/wiki/Hierarchical_task_network https://en.wikipedia.org/wiki/Hierarchical_task_network
""" """
from __future__ import annotations from __future__ import annotations
from datetime import datetime from datetime import datetime

View File

@ -203,7 +203,7 @@ class TheaterState(WorldState["TheaterState"]):
threat_zones=game.threat_zone_for(not player), threat_zones=game.threat_zone_for(not player),
vulnerable_control_points=vulnerable_control_points, vulnerable_control_points=vulnerable_control_points,
control_point_priority_queue=ordered_capturable_points, control_point_priority_queue=ordered_capturable_points,
priority_cp=ordered_capturable_points[0] priority_cp=(
if ordered_capturable_points ordered_capturable_points[0] if ordered_capturable_points else None
else None, ),
) )

View File

@ -60,9 +60,9 @@ class GroundUnitType(UnitType[Type[VehicleType]]):
reversed_heading: bool = False reversed_heading: bool = False
_by_name: ClassVar[dict[str, GroundUnitType]] = {} _by_name: ClassVar[dict[str, GroundUnitType]] = {}
_by_unit_type: ClassVar[ _by_unit_type: ClassVar[dict[type[VehicleType], list[GroundUnitType]]] = (
dict[type[VehicleType], list[GroundUnitType]] defaultdict(list)
] = defaultdict(list) )
def __setstate__(self, state: dict[str, Any]) -> None: def __setstate__(self, state: dict[str, Any]) -> None:
# Save compat: the `name` field has been renamed `variant_id`. # Save compat: the `name` field has been renamed `variant_id`.

View File

@ -17,12 +17,10 @@ class LaserCodeConfig(ABC):
) )
@abstractmethod @abstractmethod
def iter_prop_ids(self) -> Iterator[str]: def iter_prop_ids(self) -> Iterator[str]: ...
...
@abstractmethod @abstractmethod
def property_dict_for_code(self, code: int) -> dict[str, int]: def property_dict_for_code(self, code: int) -> dict[str, int]: ...
...
class SinglePropertyLaserCodeConfig(LaserCodeConfig): class SinglePropertyLaserCodeConfig(LaserCodeConfig):

View File

@ -28,14 +28,12 @@ def point_at_heading(p: Point, heading: Heading, distance: Distance) -> Point:
class Prerequisite(ABC): class Prerequisite(ABC):
@abstractmethod @abstractmethod
def is_satisfied(self) -> bool: def is_satisfied(self) -> bool: ...
...
@abstractmethod @abstractmethod
def describe_debug_info( def describe_debug_info(
self, to_geojson: Callable[[BaseGeometry], dict[str, Any]] self, to_geojson: Callable[[BaseGeometry], dict[str, Any]]
) -> dict[str, Any]: ) -> dict[str, Any]: ...
...
class DistancePrerequisite(Prerequisite): class DistancePrerequisite(Prerequisite):

View File

@ -11,8 +11,7 @@ WorldStateT = TypeVar("WorldStateT", bound="WorldState[Any]")
class WorldState(ABC, Generic[WorldStateT]): class WorldState(ABC, Generic[WorldStateT]):
@abstractmethod @abstractmethod
def clone(self) -> WorldStateT: def clone(self) -> WorldStateT: ...
...
class Task(Generic[WorldStateT]): class Task(Generic[WorldStateT]):
@ -24,18 +23,17 @@ Method = Sequence[Task[WorldStateT]]
class PrimitiveTask(Task[WorldStateT], Generic[WorldStateT], ABC): class PrimitiveTask(Task[WorldStateT], Generic[WorldStateT], ABC):
@abstractmethod @abstractmethod
def preconditions_met(self, state: WorldStateT) -> bool: def preconditions_met(self, state: WorldStateT) -> bool: ...
...
@abstractmethod @abstractmethod
def apply_effects(self, state: WorldStateT) -> None: def apply_effects(self, state: WorldStateT) -> None: ...
...
class CompoundTask(Task[WorldStateT], Generic[WorldStateT], ABC): class CompoundTask(Task[WorldStateT], Generic[WorldStateT], ABC):
@abstractmethod @abstractmethod
def each_valid_method(self, state: WorldStateT) -> Iterator[Method[WorldStateT]]: def each_valid_method(
... self, state: WorldStateT
) -> Iterator[Method[WorldStateT]]: ...
PrimitiveTaskT = TypeVar("PrimitiveTaskT", bound=PrimitiveTask[Any]) PrimitiveTaskT = TypeVar("PrimitiveTaskT", bound=PrimitiveTask[Any])

View File

@ -10,9 +10,11 @@ class Information:
def __str__(self) -> str: def __str__(self) -> str:
return "[{}][{}] {} {}".format( return "[{}][{}] {} {}".format(
self.timestamp.strftime("%Y-%m-%d %H:%M:%S") (
if self.timestamp is not None self.timestamp.strftime("%Y-%m-%d %H:%M:%S")
else "", if self.timestamp is not None
else ""
),
self.turn, self.turn,
self.title, self.title,
self.text, self.text,

View File

@ -9,9 +9,7 @@ if TYPE_CHECKING:
class ILaserCodeRegistry(ABC): class ILaserCodeRegistry(ABC):
@abstractmethod @abstractmethod
def alloc_laser_code(self) -> LaserCode: def alloc_laser_code(self) -> LaserCode: ...
...
@abstractmethod @abstractmethod
def release_code(self, code: LaserCode) -> None: def release_code(self, code: LaserCode) -> None: ...
...

View File

@ -1,4 +1,5 @@
"""Logging APIs.""" """Logging APIs."""
import logging import logging
import logging.config import logging.config
import os import os

View File

@ -1,6 +1,7 @@
""" """
Briefing generation logic Briefing generation logic
""" """
from __future__ import annotations from __future__ import annotations
import os import os

View File

@ -22,6 +22,7 @@ https://forums.eagle.ru/showthread.php?t=206360 claims that kneeboard pages can
only be added per airframe, so PvP missions where each side have the same only be added per airframe, so PvP missions where each side have the same
aircraft will be able to see the enemy's kneeboard for the same airframe. aircraft will be able to see the enemy's kneeboard for the same airframe.
""" """
import datetime import datetime
import math import math
import textwrap import textwrap

View File

@ -5,6 +5,7 @@ groups, statics, missile sites, and AA sites for the mission. Each of these
objectives is defined in the Theater by a TheaterGroundObject. These classes objectives is defined in the Theater by a TheaterGroundObject. These classes
create the pydcs groups and statics for those areas and add them to the mission. create the pydcs groups and statics for those areas and add them to the mission.
""" """
from __future__ import annotations from __future__ import annotations
import logging import logging
@ -1362,9 +1363,9 @@ class TgoGenerator:
self.ground_spawns_large: dict[ self.ground_spawns_large: dict[
ControlPoint, list[Tuple[StaticGroup, Point]] ControlPoint, list[Tuple[StaticGroup, Point]]
] = defaultdict(list) ] = defaultdict(list)
self.ground_spawns: dict[ self.ground_spawns: dict[ControlPoint, list[Tuple[StaticGroup, Point]]] = (
ControlPoint, list[Tuple[StaticGroup, Point]] defaultdict(list)
] = defaultdict(list) )
self.mission_data = mission_data self.mission_data = mission_data
def generate(self) -> None: def generate(self) -> None:
@ -1383,9 +1384,9 @@ class TgoGenerator:
self.m, cp, self.game, self.radio_registry, self.tacan_registry self.m, cp, self.game, self.radio_registry, self.tacan_registry
) )
ground_spawn_roadbase_gen.generate() ground_spawn_roadbase_gen.generate()
self.ground_spawns_roadbase[ self.ground_spawns_roadbase[cp] = (
cp ground_spawn_roadbase_gen.ground_spawns_roadbase
] = ground_spawn_roadbase_gen.ground_spawns_roadbase )
random.shuffle(self.ground_spawns_roadbase[cp]) random.shuffle(self.ground_spawns_roadbase[cp])
# Generate Large Ground Spawn slots # Generate Large Ground Spawn slots

View File

@ -5,6 +5,7 @@ groups, statics, missile sites, and AA sites for the mission. Each of these
objectives is defined in the Theater by a TheaterGroundObject. These classes objectives is defined in the Theater by a TheaterGroundObject. These classes
create the pydcs groups and statics for those areas and add them to the mission. create the pydcs groups and statics for those areas and add them to the mission.
""" """
from __future__ import annotations from __future__ import annotations
import random import random
@ -819,9 +820,9 @@ class PretenseTgoGenerator(TgoGenerator):
self.ground_spawns_roadbase: dict[ self.ground_spawns_roadbase: dict[
ControlPoint, list[Tuple[StaticGroup, Point]] ControlPoint, list[Tuple[StaticGroup, Point]]
] = defaultdict(list) ] = defaultdict(list)
self.ground_spawns: dict[ self.ground_spawns: dict[ControlPoint, list[Tuple[StaticGroup, Point]]] = (
ControlPoint, list[Tuple[StaticGroup, Point]] defaultdict(list)
] = defaultdict(list) )
self.mission_data = mission_data self.mission_data = mission_data
def generate(self) -> None: def generate(self) -> None:
@ -848,9 +849,9 @@ class PretenseTgoGenerator(TgoGenerator):
self.m, cp, self.game, self.radio_registry, self.tacan_registry self.m, cp, self.game, self.radio_registry, self.tacan_registry
) )
ground_spawn_roadbase_gen.generate() ground_spawn_roadbase_gen.generate()
self.ground_spawns_roadbase[ self.ground_spawns_roadbase[cp] = (
cp ground_spawn_roadbase_gen.ground_spawns_roadbase
] = ground_spawn_roadbase_gen.ground_spawns_roadbase )
random.shuffle(self.ground_spawns_roadbase[cp]) random.shuffle(self.ground_spawns_roadbase[cp])
# Generate STOL pads # Generate STOL pads

View File

@ -48,12 +48,10 @@ class PurchaseAdapter(Generic[ItemType]):
return self.pending_delivery_quantity(item) < 0 return self.pending_delivery_quantity(item) < 0
@abstractmethod @abstractmethod
def current_quantity_of(self, item: ItemType) -> int: def current_quantity_of(self, item: ItemType) -> int: ...
...
@abstractmethod @abstractmethod
def pending_delivery_quantity(self, item: ItemType) -> int: def pending_delivery_quantity(self, item: ItemType) -> int: ...
...
def expected_quantity_next_turn(self, item: ItemType) -> int: def expected_quantity_next_turn(self, item: ItemType) -> int:
return self.current_quantity_of(item) + self.pending_delivery_quantity(item) return self.current_quantity_of(item) + self.pending_delivery_quantity(item)
@ -65,36 +63,28 @@ class PurchaseAdapter(Generic[ItemType]):
return self.can_sell(item) or self.has_pending_orders(item) return self.can_sell(item) or self.has_pending_orders(item)
@abstractmethod @abstractmethod
def can_sell(self, item: ItemType) -> bool: def can_sell(self, item: ItemType) -> bool: ...
...
@abstractmethod @abstractmethod
def do_purchase(self, item: ItemType) -> None: def do_purchase(self, item: ItemType) -> None: ...
...
@abstractmethod @abstractmethod
def do_cancel_purchase(self, item: ItemType) -> None: def do_cancel_purchase(self, item: ItemType) -> None: ...
...
@abstractmethod @abstractmethod
def do_sale(self, item: ItemType) -> None: def do_sale(self, item: ItemType) -> None: ...
...
@abstractmethod @abstractmethod
def do_cancel_sale(self, item: ItemType) -> None: def do_cancel_sale(self, item: ItemType) -> None: ...
...
@abstractmethod @abstractmethod
def price_of(self, item: ItemType) -> int: def price_of(self, item: ItemType) -> int: ...
...
@abstractmethod @abstractmethod
def name_of(self, item: ItemType, multiline: bool = False) -> str: def name_of(self, item: ItemType, multiline: bool = False) -> str: ...
...
@abstractmethod @abstractmethod
def unit_type_of(self, item: ItemType) -> UnitType[Any]: def unit_type_of(self, item: ItemType) -> UnitType[Any]: ...
...
class AircraftPurchaseAdapter(PurchaseAdapter[Squadron]): class AircraftPurchaseAdapter(PurchaseAdapter[Squadron]):

View File

@ -16,5 +16,4 @@ class CallsignContainer:
@property @property
@abstractmethod @abstractmethod
def available_callsigns(self) -> List[str]: def available_callsigns(self) -> List[str]: ...
...

View File

@ -1,4 +1,5 @@
"""Radio frequency types and allocators.""" """Radio frequency types and allocators."""
from __future__ import annotations from __future__ import annotations
import itertools import itertools

View File

@ -1,4 +1,5 @@
"""TACAN channel handling.""" """TACAN channel handling."""
from __future__ import annotations from __future__ import annotations
import re import re

View File

@ -1,4 +1,5 @@
"""Runway information and selection.""" """Runway information and selection."""
from __future__ import annotations from __future__ import annotations
import logging import logging

View File

@ -1,4 +1,5 @@
"""Tools for aiding in save compat removal after compatibility breaks.""" """Tools for aiding in save compat removal after compatibility breaks."""
from collections.abc import Callable from collections.abc import Callable
from typing import TypeVar from typing import TypeVar

View File

@ -10,6 +10,7 @@ from the output.
https://nso.nato.int/nso/nsdd/main/standards/ap-details/1912/EN https://nso.nato.int/nso/nsdd/main/standards/ap-details/1912/EN
https://www.spatialillusions.com/milsymbol/docs/milsymbol-APP6d.html https://www.spatialillusions.com/milsymbol/docs/milsymbol-APP6d.html
""" """
from __future__ import annotations from __future__ import annotations
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
@ -330,18 +331,15 @@ class SymbolIdentificationCode:
class SidcDescribable(ABC): class SidcDescribable(ABC):
@property @property
@abstractmethod @abstractmethod
def standard_identity(self) -> StandardIdentity: def standard_identity(self) -> StandardIdentity: ...
...
@property @property
@abstractmethod @abstractmethod
def sidc_status(self) -> Status: def sidc_status(self) -> Status: ...
...
@property @property
@abstractmethod @abstractmethod
def symbol_set_and_entity(self) -> tuple[SymbolSet, Entity]: def symbol_set_and_entity(self) -> tuple[SymbolSet, Entity]: ...
...
def sidc(self) -> SymbolIdentificationCode: def sidc(self) -> SymbolIdentificationCode:
symbol_set, entity = self.symbol_set_and_entity symbol_set, entity = self.symbol_set_and_entity

View File

@ -40,20 +40,16 @@ class FrozenCombat(ABC):
events: GameUpdateEvents, events: GameUpdateEvents,
time: datetime, time: datetime,
elapsed_time: timedelta, elapsed_time: timedelta,
) -> None: ) -> None: ...
...
@abstractmethod @abstractmethod
def because(self) -> str: def because(self) -> str: ...
...
@abstractmethod @abstractmethod
def describe(self) -> str: def describe(self) -> str: ...
...
@abstractmethod @abstractmethod
def iter_flights(self) -> Iterator[Flight]: def iter_flights(self) -> Iterator[Flight]: ...
...
def update_flight_states(self) -> None: def update_flight_states(self) -> None:
for flight in self.iter_flights(): for flight in self.iter_flights():

View File

@ -18,8 +18,7 @@ class JoinableCombat(FrozenCombat, ABC):
self.flights = flights self.flights = flights
@abstractmethod @abstractmethod
def joinable_by(self, flight: Flight) -> bool: def joinable_by(self, flight: Flight) -> bool: ...
...
def join(self, flight: Flight) -> None: def join(self, flight: Flight) -> None:
assert isinstance(flight.state, InFlight) assert isinstance(flight.state, InFlight)

View File

@ -343,9 +343,11 @@ class MissionResultsProcessor:
settings = source.coalition.game.settings settings = source.coalition.game.settings
reserves = max( reserves = max(
1, 1,
settings.reserves_procurement_target (
if source.captured settings.reserves_procurement_target
else settings.reserves_procurement_target_red, if source.captured
else settings.reserves_procurement_target_red
),
) )
total_units = source.base.total_armor total_units = source.base.total_armor
reserves_factor = (reserves - 1) / total_units # slight underestimation reserves_factor = (reserves - 1) / total_units # slight underestimation

View File

@ -525,8 +525,7 @@ class ControlPoint(MissionTarget, SidcDescribable, ABC):
@property @property
@abstractmethod @abstractmethod
def heading(self) -> Heading: def heading(self) -> Heading: ...
...
def __str__(self) -> str: def __str__(self) -> str:
return self.name return self.name
@ -690,8 +689,7 @@ class ControlPoint(MissionTarget, SidcDescribable, ABC):
@property @property
@abstractmethod @abstractmethod
def can_deploy_ground_units(self) -> bool: def can_deploy_ground_units(self) -> bool: ...
...
@abstractmethod @abstractmethod
def total_aircraft_parking(self, parking_type: ParkingType) -> int: def total_aircraft_parking(self, parking_type: ParkingType) -> int:
@ -986,8 +984,7 @@ class ControlPoint(MissionTarget, SidcDescribable, ABC):
return None return None
@abstractmethod @abstractmethod
def can_operate(self, aircraft: AircraftType) -> bool: def can_operate(self, aircraft: AircraftType) -> bool: ...
...
def unclaimed_parking(self, parking_type: ParkingType) -> int: def unclaimed_parking(self, parking_type: ParkingType) -> int:
return ( return (
@ -1001,8 +998,7 @@ class ControlPoint(MissionTarget, SidcDescribable, ABC):
theater: ConflictTheater, theater: ConflictTheater,
conditions: Conditions, conditions: Conditions,
dynamic_runways: Dict[str, RunwayData], dynamic_runways: Dict[str, RunwayData],
) -> RunwayData: ) -> RunwayData: ...
...
def stub_runway_data(self) -> RunwayData: def stub_runway_data(self) -> RunwayData:
return RunwayData( return RunwayData(
@ -1019,13 +1015,11 @@ class ControlPoint(MissionTarget, SidcDescribable, ABC):
@property @property
@abstractmethod @abstractmethod
def runway_is_destroyable(self) -> bool: def runway_is_destroyable(self) -> bool: ...
...
@property @property
@abstractmethod @abstractmethod
def runway_status(self) -> RunwayStatus: def runway_status(self) -> RunwayStatus: ...
...
@property @property
def runway_can_be_repaired(self) -> bool: def runway_can_be_repaired(self) -> bool:
@ -1199,13 +1193,11 @@ class ControlPoint(MissionTarget, SidcDescribable, ABC):
@property @property
@abstractmethod @abstractmethod
def category(self) -> str: def category(self) -> str: ...
...
@property @property
@abstractmethod @abstractmethod
def status(self) -> ControlPointStatus: def status(self) -> ControlPointStatus: ...
...
class Airfield(ControlPoint, CTLD): class Airfield(ControlPoint, CTLD):

View File

@ -107,7 +107,7 @@ class FrontLine(MissionTarget):
yield from [ yield from [
FlightType.CAS, FlightType.CAS,
FlightType.AEWC, FlightType.AEWC,
FlightType.REFUELING FlightType.REFUELING,
# TODO: FlightType.TROOP_TRANSPORT # TODO: FlightType.TROOP_TRANSPORT
# TODO: FlightType.EVAC # TODO: FlightType.EVAC
] ]

View File

@ -47,9 +47,9 @@ class TransitConnection(Enum):
class TransitNetwork: class TransitNetwork:
def __init__(self) -> None: def __init__(self) -> None:
self.nodes: Dict[ self.nodes: Dict[ControlPoint, Dict[ControlPoint, TransitConnection]] = (
ControlPoint, Dict[ControlPoint, TransitConnection] defaultdict(dict)
] = defaultdict(dict) )
def has_destinations(self, control_point: ControlPoint) -> bool: def has_destinations(self, control_point: ControlPoint) -> bool:
return bool(self.nodes[control_point]) return bool(self.nodes[control_point])

View File

@ -29,6 +29,7 @@ transports and processing the turn's transit actions.
Routing is handled by TransitNetwork. Routing is handled by TransitNetwork.
""" """
from __future__ import annotations from __future__ import annotations
import logging import logging
@ -499,9 +500,9 @@ TransportType = TypeVar("TransportType", bound=MultiGroupTransport)
class TransportMap(Generic[TransportType]): class TransportMap(Generic[TransportType]):
def __init__(self) -> None: def __init__(self) -> None:
# Dict of origin -> destination -> transport. # Dict of origin -> destination -> transport.
self.transports: dict[ self.transports: dict[ControlPoint, dict[ControlPoint, TransportType]] = (
ControlPoint, dict[ControlPoint, TransportType] defaultdict(dict)
] = defaultdict(dict) )
def create_transport( def create_transport(
self, origin: ControlPoint, destination: ControlPoint self, origin: ControlPoint, destination: ControlPoint

View File

@ -1,4 +1,5 @@
"""Maps generated units back to their Retribution types.""" """Maps generated units back to their Retribution types."""
from __future__ import annotations from __future__ import annotations
import itertools import itertools

View File

@ -101,8 +101,7 @@ class Weather(ABC):
@property @property
@abstractmethod @abstractmethod
def archetype(self) -> WeatherArchetype: def archetype(self) -> WeatherArchetype: ...
...
@property @property
def pressure_adjustment(self) -> float: def pressure_adjustment(self) -> float:

View File

@ -25,8 +25,7 @@ class WeibullWindSpeedParameters:
class WindSpeedGenerator(ABC): class WindSpeedGenerator(ABC):
@abstractmethod @abstractmethod
def random_wind(self) -> WindConditions: def random_wind(self) -> WindConditions: ...
...
@staticmethod @staticmethod
def from_data(data: dict[str, Any]) -> WindSpeedGenerator: def from_data(data: dict[str, Any]) -> WindSpeedGenerator:

View File

@ -1,4 +1,5 @@
"""Application-wide dialog management.""" """Application-wide dialog management."""
from typing import Optional from typing import Optional
from game.ato.flight import Flight from game.ato.flight import Flight

View File

@ -1,4 +1,5 @@
"""Qt data models for game objects.""" """Qt data models for game objects."""
from __future__ import annotations from __future__ import annotations
import datetime import datetime

View File

@ -1,4 +1,5 @@
"""Spin box for selecting the number of aircraft in a flight.""" """Spin box for selecting the number of aircraft in a flight."""
from PySide6.QtWidgets import QSpinBox from PySide6.QtWidgets import QSpinBox

View File

@ -1,4 +1,5 @@
"""A layout containing a widget with an associated label.""" """A layout containing a widget with an associated label."""
from typing import Optional from typing import Optional
from PySide6.QtCore import Qt from PySide6.QtCore import Qt

View File

@ -1,4 +1,5 @@
"""Widgets for displaying air tasking orders.""" """Widgets for displaying air tasking orders."""
import logging import logging
from copy import deepcopy from copy import deepcopy
from typing import Optional from typing import Optional

View File

@ -1,4 +1,5 @@
"""Widgets for displaying client slots.""" """Widgets for displaying client slots."""
from PySide6.QtWidgets import QLabel from PySide6.QtWidgets import QLabel
from qt_ui.models import AtoModel from qt_ui.models import AtoModel

View File

@ -1,4 +1,5 @@
"""Combo box for selecting aircraft types.""" """Combo box for selecting aircraft types."""
from PySide6.QtWidgets import QComboBox from PySide6.QtWidgets import QComboBox
from game.dcs.aircrafttype import AircraftType from game.dcs.aircrafttype import AircraftType

View File

@ -1,4 +1,5 @@
"""Combo box for selecting a departure airfield.""" """Combo box for selecting a departure airfield."""
from typing import Iterable, Optional from typing import Iterable, Optional
from PySide6.QtWidgets import QComboBox from PySide6.QtWidgets import QComboBox

View File

@ -1,4 +1,5 @@
"""Dialog window for editing flights.""" """Dialog window for editing flights."""
from PySide6.QtWidgets import ( from PySide6.QtWidgets import (
QDialog, QDialog,
QVBoxLayout, QVBoxLayout,

View File

@ -1,4 +1,5 @@
"""Dialogs for creating and editing ATO packages.""" """Dialogs for creating and editing ATO packages."""
import logging import logging
from typing import Optional from typing import Optional

View File

@ -1,4 +1,5 @@
"""Combo box for selecting squadrons.""" """Combo box for selecting squadrons."""
from typing import Optional from typing import Optional
from PySide6.QtWidgets import QComboBox from PySide6.QtWidgets import QComboBox

View File

@ -1,2 +1 @@
class MissingPropertyDataError(RuntimeError): class MissingPropertyDataError(RuntimeError): ...
...