Move Flight and its related components out of gen.

This commit is contained in:
Dan Albert 2021-09-13 23:23:59 -07:00
parent 52b9656a1a
commit be69d17345
87 changed files with 587 additions and 551 deletions

4
game/ato/__init__.py Normal file
View File

@ -0,0 +1,4 @@
from .flight import Flight
from .flighttype import FlightType
from .flightwaypoint import FlightWaypoint
from .package import Package

View File

@ -0,0 +1,24 @@
from dataclasses import dataclass, field
from typing import List
from game.ato.package import Package
@dataclass
class AirTaskingOrder:
"""The entire ATO for one coalition."""
#: The set of all planned packages in the ATO.
packages: List[Package] = field(default_factory=list)
def add_package(self, package: Package) -> None:
"""Adds a package to the ATO."""
self.packages.append(package)
def remove_package(self, package: Package) -> None:
"""Removes a package from the ATO."""
self.packages.remove(package)
def clear(self) -> None:
"""Removes all packages from the ATO."""
self.packages.clear()

107
game/ato/flight.py Normal file
View File

@ -0,0 +1,107 @@
from __future__ import annotations
from typing import Optional, List, TYPE_CHECKING
from gen.flights.loadouts import Loadout
from .flightroster import FlightRoster
if TYPE_CHECKING:
from game.dcs.aircrafttype import AircraftType
from game.squadrons import Squadron, Pilot
from game.theater import ControlPoint, MissionTarget
from game.transfers import TransferOrder
from .flighttype import FlightType
from .flightwaypoint import FlightWaypoint
from .package import Package
class Flight:
def __init__(
self,
package: Package,
country: str,
squadron: Squadron,
count: int,
flight_type: FlightType,
start_type: str,
divert: Optional[ControlPoint],
custom_name: Optional[str] = None,
cargo: Optional[TransferOrder] = None,
roster: Optional[FlightRoster] = None,
) -> None:
self.package = package
self.country = country
self.squadron = squadron
self.squadron.claim_inventory(count)
if roster is None:
self.roster = FlightRoster(self.squadron, initial_size=count)
else:
self.roster = roster
self.departure = self.squadron.location
self.arrival = self.squadron.arrival
self.divert = divert
self.flight_type = flight_type
# TODO: Replace with FlightPlan.
self.targets: List[MissionTarget] = []
self.loadout = Loadout.default_for(self)
self.start_type = start_type
self.use_custom_loadout = False
self.custom_name = custom_name
# Only used by transport missions.
self.cargo = cargo
# Will be replaced with a more appropriate FlightPlan by
# FlightPlanBuilder, but an empty flight plan the flight begins with an
# empty flight plan.
from gen.flights.flightplan import FlightPlan, CustomFlightPlan
self.flight_plan: FlightPlan = CustomFlightPlan(
package=package, flight=self, custom_waypoints=[]
)
@property
def count(self) -> int:
return self.roster.max_size
@property
def client_count(self) -> int:
return self.roster.player_count
@property
def unit_type(self) -> AircraftType:
return self.squadron.aircraft
@property
def from_cp(self) -> ControlPoint:
return self.departure
@property
def points(self) -> List[FlightWaypoint]:
return self.flight_plan.waypoints[1:]
def resize(self, new_size: int) -> None:
self.squadron.claim_inventory(new_size - self.count)
self.roster.resize(new_size)
def set_pilot(self, index: int, pilot: Optional[Pilot]) -> None:
self.roster.set_pilot(index, pilot)
@property
def missing_pilots(self) -> int:
return self.roster.missing_pilots
def return_pilots_and_aircraft(self) -> None:
self.roster.clear()
self.squadron.claim_inventory(-self.count)
def __repr__(self) -> str:
if self.custom_name:
return f"{self.custom_name} {self.count} x {self.unit_type}"
return f"[{self.flight_type}] {self.count} x {self.unit_type}"
def __str__(self) -> str:
if self.custom_name:
return f"{self.custom_name} {self.count} x {self.unit_type}"
return f"[{self.flight_type}] {self.count} x {self.unit_type}"

49
game/ato/flightroster.py Normal file
View File

@ -0,0 +1,49 @@
from __future__ import annotations
from typing import Optional, TYPE_CHECKING
if TYPE_CHECKING:
from game.squadrons import Squadron, Pilot
class FlightRoster:
def __init__(self, squadron: Squadron, initial_size: int = 0) -> None:
self.squadron = squadron
self.pilots: list[Optional[Pilot]] = []
self.resize(initial_size)
@property
def max_size(self) -> int:
return len(self.pilots)
@property
def player_count(self) -> int:
return len([p for p in self.pilots if p is not None and p.player])
@property
def missing_pilots(self) -> int:
return len([p for p in self.pilots if p is None])
def resize(self, new_size: int) -> None:
if self.max_size > new_size:
self.squadron.return_pilots(
[p for p in self.pilots[new_size:] if p is not None]
)
self.pilots = self.pilots[:new_size]
return
self.pilots.extend(
[
self.squadron.claim_available_pilot()
for _ in range(new_size - self.max_size)
]
)
def set_pilot(self, index: int, pilot: Optional[Pilot]) -> None:
if pilot is not None:
self.squadron.claim_pilot(pilot)
if (current_pilot := self.pilots[index]) is not None:
self.squadron.return_pilot(current_pilot)
self.pilots[index] = pilot
def clear(self) -> None:
self.squadron.return_pilots([p for p in self.pilots if p is not None])

90
game/ato/flighttype.py Normal file
View File

@ -0,0 +1,90 @@
from __future__ import annotations
from enum import Enum
class FlightType(Enum):
"""Enumeration of mission types.
The value of each enumeration is the name that will be shown in the UI.
These values are persisted to the save game as well since they are a part of
each flight and thus a part of the ATO, so changing these values will break
save compat.
When adding new mission types to this list, you will also need to update:
* flightplan.py: Add waypoint population in generate_flight_plan. Add a new flight
plan type if necessary, though most are a subclass of StrikeFlightPlan.
* aircraft.py: Add a configuration method and call it in setup_flight_group. This is
responsible for configuring waypoint 0 actions like setting ROE, threat reaction,
and mission abort parameters (winchester, bingo, etc).
* Implementations of MissionTarget.mission_types: A mission type can only be planned
against compatible targets. The mission_types method of each target class defines
which missions may target it.
* ai_flight_planner_db.py: Add the new mission type to aircraft_for_task that
returns the list of compatible aircraft in order of preference.
You may also need to update:
* flightwaypointtype.py: Add a new waypoint type if necessary. Most mission types
will need these, as aircraft.py uses the ingress point type to specialize AI
tasks, and non-strike-like missions will need more specialized control.
* ai_flight_planner.py: Use the new mission type in propose_missions so the AI will
plan the new mission type.
* FlightType.is_air_to_air and FlightType.is_air_to_ground: If the new mission type
fits either of these categories, update those methods accordingly.
"""
TARCAP = "TARCAP"
BARCAP = "BARCAP"
CAS = "CAS"
INTERCEPTION = "Intercept"
STRIKE = "Strike"
ANTISHIP = "Anti-ship"
SEAD = "SEAD"
DEAD = "DEAD"
ESCORT = "Escort"
BAI = "BAI"
SWEEP = "Fighter sweep"
OCA_RUNWAY = "OCA/Runway"
OCA_AIRCRAFT = "OCA/Aircraft"
AEWC = "AEW&C"
TRANSPORT = "Transport"
SEAD_ESCORT = "SEAD Escort"
REFUELING = "Refueling"
FERRY = "Ferry"
def __str__(self) -> str:
return self.value
@classmethod
def from_name(cls, name: str) -> FlightType:
for entry in cls:
if name == entry.value:
return entry
raise KeyError(f"No FlightType with name {name}")
@property
def is_air_to_air(self) -> bool:
return self in {
FlightType.TARCAP,
FlightType.BARCAP,
FlightType.INTERCEPTION,
FlightType.ESCORT,
FlightType.SWEEP,
}
@property
def is_air_to_ground(self) -> bool:
return self in {
FlightType.CAS,
FlightType.STRIKE,
FlightType.ANTISHIP,
FlightType.SEAD,
FlightType.DEAD,
FlightType.BAI,
FlightType.OCA_RUNWAY,
FlightType.OCA_AIRCRAFT,
FlightType.SEAD_ESCORT,
}

View File

@ -0,0 +1,92 @@
from datetime import timedelta
from typing import Optional, Sequence, Union
from dcs import Point
from dcs.point import MovingPoint, PointAction
from dcs.unit import Unit
from game.theater import ControlPoint, MissionTarget
from game.utils import Distance, meters
from game.ato.flightwaypointtype import FlightWaypointType
class FlightWaypoint:
def __init__(
self,
waypoint_type: FlightWaypointType,
x: float,
y: float,
alt: Distance = meters(0),
control_point: Optional[ControlPoint] = None,
) -> None:
"""Creates a flight waypoint.
Args:
waypoint_type: The waypoint type.
x: X coordinate of the waypoint.
y: Y coordinate of the waypoint.
alt: Altitude of the waypoint. By default this is MSL, but it can be
changed to AGL by setting alt_type to "RADIO"
control_point: The control point to associate with this waypoint. Needed for
landing points.
"""
self.waypoint_type = waypoint_type
self.x = x
self.y = y
self.alt = alt
self.control_point = control_point
self.alt_type = "BARO"
self.name = ""
# TODO: Merge with pretty_name.
# Only used in the waypoint list in the flight edit page. No sense
# having three names. A short and long form is enough.
self.description = ""
self.targets: Sequence[Union[MissionTarget, Unit]] = []
self.obj_name = ""
self.pretty_name = ""
self.only_for_player = False
self.flyover = False
# The minimum amount of fuel remaining at this waypoint in pounds.
self.min_fuel: Optional[float] = None
# These are set very late by the air conflict generator (part of mission
# generation). We do it late so that we don't need to propagate changes
# to waypoint times whenever the player alters the package TOT or the
# flight's offset in the UI.
self.tot: Optional[timedelta] = None
self.departure_time: Optional[timedelta] = None
@property
def position(self) -> Point:
return Point(self.x, self.y)
@classmethod
def from_pydcs(cls, point: MovingPoint, from_cp: ControlPoint) -> "FlightWaypoint":
waypoint = FlightWaypoint(
FlightWaypointType.NAV,
point.position.x,
point.position.y,
meters(point.alt),
)
waypoint.alt_type = point.alt_type
# Other actions exist... but none of them *should* be the first
# waypoint for a flight.
waypoint.waypoint_type = {
PointAction.TurningPoint: FlightWaypointType.NAV,
PointAction.FlyOverPoint: FlightWaypointType.NAV,
PointAction.FromParkingArea: FlightWaypointType.TAKEOFF,
PointAction.FromParkingAreaHot: FlightWaypointType.TAKEOFF,
PointAction.FromRunway: FlightWaypointType.TAKEOFF,
PointAction.FromGroundArea: FlightWaypointType.TAKEOFF,
PointAction.FromGroundAreaHot: FlightWaypointType.TAKEOFF,
}[point.action]
if waypoint.waypoint_type == FlightWaypointType.NAV:
waypoint.name = "NAV"
waypoint.pretty_name = "Nav"
waypoint.description = "Nav"
else:
waypoint.name = "TAKEOFF"
waypoint.pretty_name = "Takeoff"
waypoint.description = "Takeoff"
waypoint.description = f"Takeoff from {from_cp.name}"
return waypoint

View File

@ -0,0 +1,47 @@
from enum import Enum
class FlightWaypointType(Enum):
"""Enumeration of waypoint types.
The value of the enum has no meaning but should remain stable to prevent breaking
save game compatibility.
When adding a new waypoint type, you will also need to update:
* waypointbuilder.py: Add a builder to simplify construction of the new waypoint
type unless the new waypoint type will be a parameter to an existing builder
method (such as how escort ingress waypoints work).
* aircraft.py: Associate AI actions with the new waypoint type by subclassing
PydcsWaypointBuilder and using it in PydcsWaypointBuilder.for_waypoint.
"""
TAKEOFF = 0 # Take off point
ASCEND_POINT = 1 # Ascension point after take off
PATROL = 2 # Patrol point
PATROL_TRACK = 3 # Patrol race track
NAV = 4 # Nav point
INGRESS_STRIKE = 5 # Ingress strike (For generator, means that this should have bombing on next TARGET_POINT points)
INGRESS_SEAD = 6 # Ingress sead (For generator, means that this should attack groups on TARGET_GROUP_LOC points)
INGRESS_CAS = 7 # Ingress cas (should start CAS task)
CAS = 8 # Should do CAS there
EGRESS = 9 # Should stop attack
DESCENT_POINT = 10 # Should start descending to pattern alt
LANDING_POINT = 11 # Should land there
TARGET_POINT = 12 # A target building or static object, position
TARGET_GROUP_LOC = 13 # A target group approximate location
TARGET_SHIP = 14 # Unused.
CUSTOM = 15 # User waypoint (no specific behaviour)
JOIN = 16
SPLIT = 17
LOITER = 18
INGRESS_ESCORT = 19
INGRESS_DEAD = 20
INGRESS_SWEEP = 21
INGRESS_BAI = 22
DIVERT = 23
INGRESS_OCA_RUNWAY = 24
INGRESS_OCA_AIRCRAFT = 25
PICKUP = 26
DROP_OFF = 27
BULLSEYE = 28

View File

@ -1,46 +1,15 @@
"""Air Tasking Orders.
The classes of the Air Tasking Order (ATO) define all of the missions that have
been planned, and which aircraft have been assigned to them. Each planned
mission, or "package" is composed of individual flights. The package may contain
dissimilar aircraft performing different roles, but all for the same goal. For
example, the package to strike an enemy airfield may contain an escort flight,
a SEAD flight, and the strike aircraft themselves. CAP packages may contain only
the single CAP flight.
"""
from __future__ import annotations
import logging
from collections import defaultdict
from dataclasses import dataclass, field
from datetime import timedelta
from typing import Dict, List, Optional
from typing import List, Optional, Dict
from dcs.mapping import Point
from game.theater.missiontarget import MissionTarget
from game.ato import Flight, FlightType
from game.ato.packagewaypoints import PackageWaypoints
from game.theater import MissionTarget
from game.utils import Speed
from .flights.flight import Flight, FlightType
from .flights.flightplan import FormationFlightPlan
from .flights.traveltime import TotEstimator
@dataclass(frozen=True)
class Task:
"""The main task of a flight or package."""
#: The type of task.
task_type: FlightType
#: The location of the objective.
location: str
@dataclass(frozen=True)
class PackageWaypoints:
join: Point
ingress: Point
split: Point
from gen.flights.flightplan import FormationFlightPlan
from gen.flights.traveltime import TotEstimator
@dataclass
@ -212,23 +181,3 @@ class Package:
def __hash__(self) -> int:
# TODO: Far from perfect. Number packages?
return hash(self.target.name)
@dataclass
class AirTaskingOrder:
"""The entire ATO for one coalition."""
#: The set of all planned packages in the ATO.
packages: List[Package] = field(default_factory=list)
def add_package(self, package: Package) -> None:
"""Adds a package to the ATO."""
self.packages.append(package)
def remove_package(self, package: Package) -> None:
"""Removes a package from the ATO."""
self.packages.remove(package)
def clear(self) -> None:
"""Removes all packages from the ATO."""
self.packages.clear()

View File

@ -0,0 +1,10 @@
from dataclasses import dataclass
from dcs import Point
@dataclass(frozen=True)
class PackageWaypoints:
join: Point
ingress: Point
split: Point

14
game/ato/task.py Normal file
View File

@ -0,0 +1,14 @@
from dataclasses import dataclass
from game.ato import FlightType
@dataclass(frozen=True)
class Task:
"""The main task of a flight or package."""
#: The type of task.
task_type: FlightType
#: The location of the objective.
location: str

View File

@ -5,7 +5,7 @@ from collections import defaultdict
from dataclasses import dataclass
from typing import Any, TYPE_CHECKING, Union
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
from game.theater.controlpoint import ControlPoint
if TYPE_CHECKING:

View File

@ -6,7 +6,7 @@ from typing import Optional, TYPE_CHECKING
from game.squadrons import Squadron
from game.squadrons.squadrondef import SquadronDef
from game.squadrons.squadrondefloader import SquadronDefLoader
from gen.flights.flight import FlightType
from ..ato.flighttype import FlightType
from .campaignairwingconfig import CampaignAirWingConfig, SquadronConfig
from .squadrondefgenerator import SquadronDefGenerator
from ..dcs.aircrafttype import AircraftType

View File

@ -9,7 +9,7 @@ from game.squadrons.operatingbases import OperatingBases
from game.squadrons.squadrondef import SquadronDef
from game.theater import ControlPoint
from gen.flights.ai_flight_planner_db import aircraft_for_task, tasks_for_aircraft
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
if TYPE_CHECKING:
from game.coalition import Coalition

View File

@ -24,7 +24,7 @@ from game.factions.faction import Faction
from game.procurement import AircraftProcurementRequest, ProcurementAi
from game.theater.bullseye import Bullseye
from game.theater.transitnetwork import TransitNetwork, TransitNetworkBuilder
from gen.ato import AirTaskingOrder
from game.ato.airtaaskingorder import AirTaskingOrder
class Coalition:

View File

@ -3,7 +3,7 @@ from enum import Enum, auto
from typing import Optional
from game.theater import MissionTarget
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
class EscortType(Enum):

View File

@ -7,7 +7,7 @@ from datetime import timedelta
from typing import Iterator, Dict, TYPE_CHECKING
from game.theater import MissionTarget
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
from gen.flights.traveltime import TotEstimator
if TYPE_CHECKING:

View File

@ -3,10 +3,9 @@ from __future__ import annotations
from typing import Optional, TYPE_CHECKING
from game.utils import nautical_miles
from gen.ato import Package
from ..ato.package import Package
from game.theater import MissionTarget, OffMapSpawn, ControlPoint
from gen.flights.flight import Flight
from ..ato.flight import Flight
if TYPE_CHECKING:
from game.dcs.aircrafttype import AircraftType

View File

@ -13,9 +13,10 @@ from game.settings import Settings
from game.squadrons import AirWing
from game.theater import ConflictTheater
from game.threatzones import ThreatZones
from gen.ato import AirTaskingOrder, Package
from game.ato.airtaaskingorder import AirTaskingOrder
from game.ato.package import Package
from gen.flights.closestairfields import ObjectiveDistanceCache
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
from gen.flights.flightplan import FlightPlanBuilder
if TYPE_CHECKING:

View File

@ -15,8 +15,8 @@ from game.settings import AutoAtoBehavior
from game.theater import MissionTarget
from game.theater.theatergroundobject import IadsGroundObject, NavalGroundObject
from game.utils import Distance, meters
from gen.ato import Package
from gen.flights.flight import FlightType
from game.ato.package import Package
from game.ato.flighttype import FlightType
if TYPE_CHECKING:
from game.coalition import Coalition

View File

@ -5,7 +5,7 @@ from dataclasses import dataclass
from game.commander.tasks.packageplanningtask import PackagePlanningTask
from game.commander.theaterstate import TheaterState
from game.theater import MissionTarget
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
@dataclass

View File

@ -6,7 +6,7 @@ from game.commander.missionproposals import EscortType
from game.commander.tasks.packageplanningtask import PackagePlanningTask
from game.commander.theaterstate import TheaterState
from game.theater.theatergroundobject import NavalGroundObject
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
@dataclass

View File

@ -5,7 +5,7 @@ from dataclasses import dataclass
from game.commander.tasks.packageplanningtask import PackagePlanningTask
from game.commander.theaterstate import TheaterState
from game.transfers import CargoShip
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
@dataclass

View File

@ -5,7 +5,7 @@ from dataclasses import dataclass
from game.commander.tasks.packageplanningtask import PackagePlanningTask
from game.commander.theaterstate import TheaterState
from game.theater.theatergroundobject import VehicleGroupGroundObject
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
@dataclass

View File

@ -5,7 +5,7 @@ from dataclasses import dataclass
from game.commander.tasks.packageplanningtask import PackagePlanningTask
from game.commander.theaterstate import TheaterState
from game.theater import ControlPoint
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
@dataclass

View File

@ -5,7 +5,7 @@ from dataclasses import dataclass
from game.commander.tasks.packageplanningtask import PackagePlanningTask
from game.commander.theaterstate import TheaterState
from game.theater import FrontLine
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
@dataclass

View File

@ -6,7 +6,7 @@ from game.commander.tasks.packageplanningtask import PackagePlanningTask
from game.commander.theaterstate import TheaterState
from game.data.doctrine import Doctrine
from game.transfers import Convoy
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
@dataclass

View File

@ -6,7 +6,7 @@ from game.commander.missionproposals import EscortType
from game.commander.tasks.packageplanningtask import PackagePlanningTask
from game.commander.theaterstate import TheaterState
from game.theater.theatergroundobject import IadsGroundObject
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
@dataclass

View File

@ -5,7 +5,7 @@ from dataclasses import dataclass
from game.commander.tasks.packageplanningtask import PackagePlanningTask
from game.commander.theaterstate import TheaterState
from game.theater import ControlPoint
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
@dataclass

View File

@ -5,7 +5,7 @@ from dataclasses import dataclass
from game.commander.tasks.packageplanningtask import PackagePlanningTask
from game.commander.theaterstate import TheaterState
from game.theater import MissionTarget
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
@dataclass

View File

@ -6,7 +6,7 @@ from typing import Any
from game.commander.tasks.packageplanningtask import PackagePlanningTask
from game.commander.theaterstate import TheaterState
from game.theater.theatergroundobject import TheaterGroundObject
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
@dataclass

View File

@ -31,7 +31,7 @@ from game.unitmap import (
UnitMap,
FlyingUnit,
)
from gen.flights.flight import Flight
from game.ato.flight import Flight
if TYPE_CHECKING:
from game import Game

View File

@ -10,7 +10,7 @@ from game import persistency
from game.debriefing import Debriefing
from game.operation.operation import Operation
from game.theater import ControlPoint
from gen.ato import AirTaskingOrder
from ..ato.airtaaskingorder import AirTaskingOrder
from gen.ground_forces.combat_stance import CombatStance
from ..unitmap import UnitMap

View File

@ -6,11 +6,11 @@ import shapely.ops
from dcs import Point
from shapely.geometry import Point as ShapelyPoint, Polygon, MultiPolygon
from game.theater import ConflictTheater
from game.utils import nautical_miles
if TYPE_CHECKING:
from game.coalition import Coalition
from game.theater import ConflictTheater
class HoldZoneGeometry:

View File

@ -18,10 +18,8 @@ from faker import Faker
from game.models.game_stats import GameStats
from game.plugins import LuaPluginManager
from gen import naming
from gen.ato import AirTaskingOrder
from gen.conflictgen import Conflict
from gen.flights.closestairfields import ObjectiveDistanceCache
from gen.flights.flight import FlightType
from .ato.flighttype import FlightType
from gen.ground_forces.ai_ground_planner import GroundPlanner
from . import persistency
from .campaignloader import CampaignAirWingConfig
@ -31,18 +29,20 @@ from .event.event import Event
from .event.frontlineattack import FrontlineAttackEvent
from .factions.faction import Faction
from .infos.information import Information
from .navmesh import NavMesh
from .profiling import logged_duration
from .settings import Settings
from .theater import ConflictTheater, ControlPoint
from .theater.bullseye import Bullseye
from .theater.transitnetwork import TransitNetwork, TransitNetworkBuilder
from .threatzones import ThreatZones
from .unitmap import UnitMap
from .weather import Conditions, TimeOfDay
if TYPE_CHECKING:
from gen.conflictgen import Conflict
from .ato.airtaaskingorder import AirTaskingOrder
from .navmesh import NavMesh
from .squadrons import AirWing
from .threatzones import ThreatZones
from .unitmap import UnitMap
COMMISION_UNIT_VARIETY = 4
COMMISION_LIMITS_SCALE = 1.5
@ -453,6 +453,8 @@ class Game:
Compute the current conflict center position(s), mainly used for culling calculation
:return: List of points of interests
"""
from gen.conflictgen import Conflict
zones = []
# By default, use the existing frontline conflict position

View File

@ -27,7 +27,7 @@ from gen.cargoshipgen import CargoShipGenerator
from gen.conflictgen import Conflict
from gen.convoygen import ConvoyGenerator
from gen.environmentgen import EnvironmentGenerator
from gen.flights.flight import FlightType
from ..ato.flighttype import FlightType
from gen.forcedoptionsgen import ForcedOptionsGenerator
from gen.groundobjectsgen import GroundObjectsGenerator
from gen.kneeboard import KneeboardGenerator

View File

@ -11,13 +11,10 @@ from game.dcs.groundunittype import GroundUnitType
from game.factions.faction import Faction
from game.squadrons import Squadron
from game.theater import ControlPoint, MissionTarget
from game.utils import meters
from gen.flights.ai_flight_planner_db import aircraft_for_task
from gen.flights.closestairfields import ObjectiveDistanceCache
from gen.flights.flight import FlightType
if TYPE_CHECKING:
from game import Game
from game.ato import FlightType
FRONTLINE_RESERVES_FACTOR = 1.3

View File

@ -7,11 +7,11 @@ from typing import Sequence, Iterator, TYPE_CHECKING, Optional
from game.dcs.aircrafttype import AircraftType
from gen.flights.ai_flight_planner_db import aircraft_for_task
from gen.flights.closestairfields import ObjectiveDistanceCache
from .squadron import Squadron
from ..theater import ControlPoint, MissionTarget
if TYPE_CHECKING:
from gen.flights.flight import FlightType
from ..ato.flighttype import FlightType
from .squadron import Squadron
class AirWing:

View File

@ -12,14 +12,14 @@ from typing import (
from faker import Faker
from game.settings import AutoAtoBehavior, Settings
from gen.ato import Package
from gen.flights.flight import FlightType, Flight
from game.ato import Flight, FlightType
from gen.flights.flightplan import FlightPlanBuilder
from .pilot import Pilot, PilotStatus
from ..utils import meters
if TYPE_CHECKING:
from game import Game
from game.ato import Package
from game.coalition import Coalition
from game.dcs.aircrafttype import AircraftType
from game.theater import ControlPoint, ConflictTheater, MissionTarget

View File

@ -16,7 +16,7 @@ from game.squadrons.operatingbases import OperatingBases
from game.squadrons.pilot import Pilot
if TYPE_CHECKING:
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
from game.theater import ControlPoint
@ -62,7 +62,7 @@ class SquadronDef:
@classmethod
def from_yaml(cls, path: Path) -> SquadronDef:
from gen.flights.ai_flight_planner_db import tasks_for_aircraft
from gen.flights.flight import FlightType
from game.ato import FlightType
with path.open(encoding="utf8") as squadron_file:
data = yaml.safe_load(squadron_file)

View File

@ -56,7 +56,7 @@ from ..weather import Conditions
if TYPE_CHECKING:
from game import Game
from gen.flights.flight import FlightType
from ..ato.flighttype import FlightType
from game.squadrons.squadron import Squadron
from ..coalition import Coalition
from ..transfers import PendingTransfers
@ -892,7 +892,7 @@ class Airfield(ControlPoint):
return self.runway_is_operational()
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
from gen.flights.flight import FlightType
from game.ato import FlightType
if not self.is_friendly(for_player):
yield from [
@ -975,7 +975,7 @@ class NavalControlPoint(ControlPoint, ABC):
return True
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
from gen.flights.flight import FlightType
from game.ato import FlightType
if self.is_friendly(for_player):
yield from [
@ -1063,7 +1063,7 @@ class Carrier(NavalControlPoint):
)
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
from gen.flights.flight import FlightType
from game.ato import FlightType
yield from super().mission_types(for_player)
if self.is_friendly(for_player):
@ -1212,7 +1212,7 @@ class Fob(ControlPoint):
return RunwayStatus()
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
from gen.flights.flight import FlightType
from game.ato import FlightType
if not self.is_friendly(for_player):
yield FlightType.STRIKE

View File

@ -2,17 +2,16 @@ from __future__ import annotations
import logging
from dataclasses import dataclass
from typing import Iterator, List, Tuple, Any
from typing import Iterator, List, Tuple, Any, TYPE_CHECKING
from dcs.mapping import Point
from gen.flights.flight import FlightType
from .controlpoint import (
ControlPoint,
MissionTarget,
)
from .controlpoint import ControlPoint, MissionTarget
from ..utils import Heading, pairwise
if TYPE_CHECKING:
from game.ato import FlightType
FRONTLINE_MIN_CP_DISTANCE = 5000
@ -97,6 +96,8 @@ class FrontLine(MissionTarget):
return False
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
from game.ato import FlightType
yield from [
FlightType.CAS,
FlightType.AEWC,

View File

@ -7,7 +7,7 @@ from dcs.mapping import Point
from dcs.unit import Unit
if TYPE_CHECKING:
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
class MissionTarget:
@ -30,7 +30,7 @@ class MissionTarget:
raise NotImplementedError
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
from gen.flights.flight import FlightType
from game.ato import FlightType
if self.is_friendly(for_player):
yield FlightType.BARCAP

View File

@ -21,7 +21,7 @@ from ..utils import Distance, Heading, meters
if TYPE_CHECKING:
from .controlpoint import ControlPoint
from gen.flights.flight import FlightType
from ..ato.flighttype import FlightType
from .missiontarget import MissionTarget
@ -121,7 +121,7 @@ class TheaterGroundObject(MissionTarget, Generic[GroupT]):
return self.control_point.is_friendly(to_player)
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
from gen.flights.flight import FlightType
from game.ato import FlightType
if self.is_friendly(for_player):
yield from [
@ -352,7 +352,7 @@ class FactoryGroundObject(BuildingGroundObject):
class NavalGroundObject(TheaterGroundObject[ShipGroup]):
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
from gen.flights.flight import FlightType
from game.ato import FlightType
if not self.is_friendly(for_player):
yield FlightType.ANTISHIP
@ -474,7 +474,7 @@ class CoastalSiteGroundObject(TheaterGroundObject[VehicleGroup]):
class IadsGroundObject(TheaterGroundObject[VehicleGroup], ABC):
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
from gen.flights.flight import FlightType
from game.ato import FlightType
if not self.is_friendly(for_player):
yield FlightType.DEAD
@ -504,7 +504,7 @@ class SamGroundObject(IadsGroundObject):
)
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
from gen.flights.flight import FlightType
from game.ato import FlightType
if not self.is_friendly(for_player):
yield FlightType.DEAD

View File

@ -17,7 +17,7 @@ from game.data.doctrine import Doctrine
from game.theater import ControlPoint, MissionTarget, TheaterGroundObject
from game.utils import Distance, meters, nautical_miles
from gen.flights.closestairfields import ObjectiveDistanceCache
from gen.flights.flight import Flight, FlightWaypoint
from game.ato import Flight, FlightWaypoint
if TYPE_CHECKING:
from game import Game

View File

@ -57,10 +57,11 @@ from game.theater.transitnetwork import (
TransitNetwork,
)
from game.utils import meters, nautical_miles
from gen.ato import Package
from game.ato.package import Package
from gen.flights.ai_flight_planner_db import aircraft_for_task
from gen.flights.closestairfields import ObjectiveDistanceCache
from gen.flights.flight import Flight, FlightType
from game.ato.flighttype import FlightType
from game.ato.flight import Flight
from gen.flights.flightplan import FlightPlanBuilder
from gen.naming import namegen

View File

@ -12,7 +12,7 @@ from game.squadrons import Pilot
from game.theater import Airfield, ControlPoint, TheaterGroundObject
from game.theater.theatergroundobject import BuildingGroundObject, SceneryGroundObject
from game.transfers import CargoShip, Convoy, TransferOrder
from gen.flights.flight import Flight
from game.ato.flight import Flight
@dataclass(frozen=True)

View File

@ -83,14 +83,13 @@ from game.theater.theatergroundobject import TheaterGroundObject
from game.transfers import MultiGroupTransport
from game.unitmap import UnitMap
from game.utils import Distance, meters, nautical_miles, pairwise
from gen.ato import AirTaskingOrder, Package
from game.ato.airtaaskingorder import AirTaskingOrder
from game.ato.package import Package
from gen.callsigns import create_group_callsign_from_unit
from gen.flights.flight import (
Flight,
FlightType,
FlightWaypoint,
FlightWaypointType,
)
from game.ato.flighttype import FlightType
from game.ato.flightwaypointtype import FlightWaypointType
from game.ato.flightwaypoint import FlightWaypoint
from game.ato.flight import Flight
from gen.lasercoderegistry import LaserCodeRegistry
from gen.radios import RadioFrequency, RadioRegistry
from gen.runways import RunwayData

View File

@ -15,7 +15,7 @@ from game.theater import ControlPoint, FrontLine
from .aircraft import FlightData
from .airsupportgen import AwacsInfo, TankerInfo
from .armor import JtacInfo
from .flights.flight import FlightWaypoint
from game.ato.flightwaypoint import FlightWaypoint
from .ground_forces.combat_stance import CombatStance
from .radios import RadioFrequency
from .runways import RunwayData

View File

@ -108,7 +108,7 @@ from dcs.planes import (
from dcs.unittype import FlyingType
from game.dcs.aircrafttype import AircraftType
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
from pydcs_extensions.a4ec.a4ec import A_4E_C
from pydcs_extensions.f22a.f22a import F_22A
from pydcs_extensions.hercules.hercules import Hercules

View File

@ -1,369 +0,0 @@
from __future__ import annotations
from datetime import timedelta
from enum import Enum
from typing import List, Optional, TYPE_CHECKING, Union, Sequence
from dcs.mapping import Point
from dcs.point import MovingPoint, PointAction
from dcs.unit import Unit
from game.dcs.aircrafttype import AircraftType
from game.theater.controlpoint import ControlPoint, MissionTarget
from game.utils import Distance, meters
from gen.flights.loadouts import Loadout
if TYPE_CHECKING:
from game.squadrons import Pilot, Squadron
from game.transfers import TransferOrder
from gen.ato import Package
from gen.flights.flightplan import FlightPlan
class FlightType(Enum):
"""Enumeration of mission types.
The value of each enumeration is the name that will be shown in the UI.
These values are persisted to the save game as well since they are a part of
each flight and thus a part of the ATO, so changing these values will break
save compat.
When adding new mission types to this list, you will also need to update:
* flightplan.py: Add waypoint population in generate_flight_plan. Add a new flight
plan type if necessary, though most are a subclass of StrikeFlightPlan.
* aircraft.py: Add a configuration method and call it in setup_flight_group. This is
responsible for configuring waypoint 0 actions like setting ROE, threat reaction,
and mission abort parameters (winchester, bingo, etc).
* Implementations of MissionTarget.mission_types: A mission type can only be planned
against compatible targets. The mission_types method of each target class defines
which missions may target it.
* ai_flight_planner_db.py: Add the new mission type to aircraft_for_task that
returns the list of compatible aircraft in order of preference.
You may also need to update:
* flight.py: Add a new waypoint type if necessary. Most mission types will need
these, as aircraft.py uses the ingress point type to specialize AI tasks, and non-
strike-like missions will need more specialized control.
* ai_flight_planner.py: Use the new mission type in propose_missions so the AI will
plan the new mission type.
* FlightType.is_air_to_air and FlightType.is_air_to_ground: If the new mission type
fits either of these categories, update those methods accordingly.
"""
TARCAP = "TARCAP"
BARCAP = "BARCAP"
CAS = "CAS"
INTERCEPTION = "Intercept"
STRIKE = "Strike"
ANTISHIP = "Anti-ship"
SEAD = "SEAD"
DEAD = "DEAD"
ESCORT = "Escort"
BAI = "BAI"
SWEEP = "Fighter sweep"
OCA_RUNWAY = "OCA/Runway"
OCA_AIRCRAFT = "OCA/Aircraft"
AEWC = "AEW&C"
TRANSPORT = "Transport"
SEAD_ESCORT = "SEAD Escort"
REFUELING = "Refueling"
FERRY = "Ferry"
def __str__(self) -> str:
return self.value
@classmethod
def from_name(cls, name: str) -> FlightType:
for entry in cls:
if name == entry.value:
return entry
raise KeyError(f"No FlightType with name {name}")
@property
def is_air_to_air(self) -> bool:
return self in {
FlightType.TARCAP,
FlightType.BARCAP,
FlightType.INTERCEPTION,
FlightType.ESCORT,
FlightType.SWEEP,
}
@property
def is_air_to_ground(self) -> bool:
return self in {
FlightType.CAS,
FlightType.STRIKE,
FlightType.ANTISHIP,
FlightType.SEAD,
FlightType.DEAD,
FlightType.BAI,
FlightType.OCA_RUNWAY,
FlightType.OCA_AIRCRAFT,
FlightType.SEAD_ESCORT,
}
class FlightWaypointType(Enum):
"""Enumeration of waypoint types.
The value of the enum has no meaning but should remain stable to prevent breaking
save game compatibility.
When adding a new waypoint type, you will also need to update:
* waypointbuilder.py: Add a builder to simplify construction of the new waypoint
type unless the new waypoint type will be a parameter to an existing builder
method (such as how escort ingress waypoints work).
* aircraft.py: Associate AI actions with the new waypoint type by subclassing
PydcsWaypointBuilder and using it in PydcsWaypointBuilder.for_waypoint.
"""
TAKEOFF = 0 # Take off point
ASCEND_POINT = 1 # Ascension point after take off
PATROL = 2 # Patrol point
PATROL_TRACK = 3 # Patrol race track
NAV = 4 # Nav point
INGRESS_STRIKE = 5 # Ingress strike (For generator, means that this should have bombing on next TARGET_POINT points)
INGRESS_SEAD = 6 # Ingress sead (For generator, means that this should attack groups on TARGET_GROUP_LOC points)
INGRESS_CAS = 7 # Ingress cas (should start CAS task)
CAS = 8 # Should do CAS there
EGRESS = 9 # Should stop attack
DESCENT_POINT = 10 # Should start descending to pattern alt
LANDING_POINT = 11 # Should land there
TARGET_POINT = 12 # A target building or static object, position
TARGET_GROUP_LOC = 13 # A target group approximate location
TARGET_SHIP = 14 # Unused.
CUSTOM = 15 # User waypoint (no specific behaviour)
JOIN = 16
SPLIT = 17
LOITER = 18
INGRESS_ESCORT = 19
INGRESS_DEAD = 20
INGRESS_SWEEP = 21
INGRESS_BAI = 22
DIVERT = 23
INGRESS_OCA_RUNWAY = 24
INGRESS_OCA_AIRCRAFT = 25
PICKUP = 26
DROP_OFF = 27
BULLSEYE = 28
class FlightWaypoint:
def __init__(
self,
waypoint_type: FlightWaypointType,
x: float,
y: float,
alt: Distance = meters(0),
control_point: Optional[ControlPoint] = None,
) -> None:
"""Creates a flight waypoint.
Args:
waypoint_type: The waypoint type.
x: X coordinate of the waypoint.
y: Y coordinate of the waypoint.
alt: Altitude of the waypoint. By default this is MSL, but it can be
changed to AGL by setting alt_type to "RADIO"
control_point: The control point to associate with this waypoint. Needed for
landing points.
"""
self.waypoint_type = waypoint_type
self.x = x
self.y = y
self.alt = alt
self.control_point = control_point
self.alt_type = "BARO"
self.name = ""
# TODO: Merge with pretty_name.
# Only used in the waypoint list in the flight edit page. No sense
# having three names. A short and long form is enough.
self.description = ""
self.targets: Sequence[Union[MissionTarget, Unit]] = []
self.obj_name = ""
self.pretty_name = ""
self.only_for_player = False
self.flyover = False
# The minimum amount of fuel remaining at this waypoint in pounds.
self.min_fuel: Optional[float] = None
# These are set very late by the air conflict generator (part of mission
# generation). We do it late so that we don't need to propagate changes
# to waypoint times whenever the player alters the package TOT or the
# flight's offset in the UI.
self.tot: Optional[timedelta] = None
self.departure_time: Optional[timedelta] = None
@property
def position(self) -> Point:
return Point(self.x, self.y)
@classmethod
def from_pydcs(cls, point: MovingPoint, from_cp: ControlPoint) -> "FlightWaypoint":
waypoint = FlightWaypoint(
FlightWaypointType.NAV,
point.position.x,
point.position.y,
meters(point.alt),
)
waypoint.alt_type = point.alt_type
# Other actions exist... but none of them *should* be the first
# waypoint for a flight.
waypoint.waypoint_type = {
PointAction.TurningPoint: FlightWaypointType.NAV,
PointAction.FlyOverPoint: FlightWaypointType.NAV,
PointAction.FromParkingArea: FlightWaypointType.TAKEOFF,
PointAction.FromParkingAreaHot: FlightWaypointType.TAKEOFF,
PointAction.FromRunway: FlightWaypointType.TAKEOFF,
PointAction.FromGroundArea: FlightWaypointType.TAKEOFF,
PointAction.FromGroundAreaHot: FlightWaypointType.TAKEOFF,
}[point.action]
if waypoint.waypoint_type == FlightWaypointType.NAV:
waypoint.name = "NAV"
waypoint.pretty_name = "Nav"
waypoint.description = "Nav"
else:
waypoint.name = "TAKEOFF"
waypoint.pretty_name = "Takeoff"
waypoint.description = "Takeoff"
waypoint.description = f"Takeoff from {from_cp.name}"
return waypoint
class FlightRoster:
def __init__(self, squadron: Squadron, initial_size: int = 0) -> None:
self.squadron = squadron
self.pilots: list[Optional[Pilot]] = []
self.resize(initial_size)
@property
def max_size(self) -> int:
return len(self.pilots)
@property
def player_count(self) -> int:
return len([p for p in self.pilots if p is not None and p.player])
@property
def missing_pilots(self) -> int:
return len([p for p in self.pilots if p is None])
def resize(self, new_size: int) -> None:
if self.max_size > new_size:
self.squadron.return_pilots(
[p for p in self.pilots[new_size:] if p is not None]
)
self.pilots = self.pilots[:new_size]
return
self.pilots.extend(
[
self.squadron.claim_available_pilot()
for _ in range(new_size - self.max_size)
]
)
def set_pilot(self, index: int, pilot: Optional[Pilot]) -> None:
if pilot is not None:
self.squadron.claim_pilot(pilot)
if (current_pilot := self.pilots[index]) is not None:
self.squadron.return_pilot(current_pilot)
self.pilots[index] = pilot
def clear(self) -> None:
self.squadron.return_pilots([p for p in self.pilots if p is not None])
class Flight:
def __init__(
self,
package: Package,
country: str,
squadron: Squadron,
count: int,
flight_type: FlightType,
start_type: str,
divert: Optional[ControlPoint],
custom_name: Optional[str] = None,
cargo: Optional[TransferOrder] = None,
roster: Optional[FlightRoster] = None,
) -> None:
self.package = package
self.country = country
self.squadron = squadron
self.squadron.claim_inventory(count)
if roster is None:
self.roster = FlightRoster(self.squadron, initial_size=count)
else:
self.roster = roster
self.departure = self.squadron.location
self.arrival = self.squadron.arrival
self.divert = divert
self.flight_type = flight_type
# TODO: Replace with FlightPlan.
self.targets: List[MissionTarget] = []
self.loadout = Loadout.default_for(self)
self.start_type = start_type
self.use_custom_loadout = False
self.custom_name = custom_name
# Only used by transport missions.
self.cargo = cargo
# Will be replaced with a more appropriate FlightPlan by
# FlightPlanBuilder, but an empty flight plan the flight begins with an
# empty flight plan.
from gen.flights.flightplan import CustomFlightPlan
self.flight_plan: FlightPlan = CustomFlightPlan(
package=package, flight=self, custom_waypoints=[]
)
@property
def count(self) -> int:
return self.roster.max_size
@property
def client_count(self) -> int:
return self.roster.player_count
@property
def unit_type(self) -> AircraftType:
return self.squadron.aircraft
@property
def from_cp(self) -> ControlPoint:
return self.departure
@property
def points(self) -> List[FlightWaypoint]:
return self.flight_plan.waypoints[1:]
def resize(self, new_size: int) -> None:
self.squadron.claim_inventory(new_size - self.count)
self.roster.resize(new_size)
def set_pilot(self, index: int, pilot: Optional[Pilot]) -> None:
self.roster.set_pilot(index, pilot)
@property
def missing_pilots(self) -> int:
return self.roster.missing_pilots
def return_pilots_and_aircraft(self) -> None:
self.roster.clear()
self.squadron.claim_inventory(-self.count)
def __repr__(self) -> str:
if self.custom_name:
return f"{self.custom_name} {self.count} x {self.unit_type}"
return f"[{self.flight_type}] {self.count} x {self.unit_type}"
def __str__(self) -> str:
if self.custom_name:
return f"{self.custom_name} {self.count} x {self.unit_type}"
return f"[{self.flight_type}] {self.count} x {self.unit_type}"

View File

@ -37,19 +37,23 @@ from game.theater.theatergroundobject import (
NavalGroundObject,
BuildingGroundObject,
)
from game.threatzones import ThreatZones
from game.utils import Distance, Heading, Speed, feet, meters, nautical_miles, knots
from .closestairfields import ObjectiveDistanceCache
from .flight import Flight, FlightType, FlightWaypoint, FlightWaypointType
from game.ato.flighttype import FlightType
from game.ato.flightwaypointtype import FlightWaypointType
from game.ato.flightwaypoint import FlightWaypoint
from game.ato.flight import Flight
from .traveltime import GroundSpeed, TravelTime
from .waypointbuilder import StrikeTarget, WaypointBuilder
from ..conflictgen import Conflict, FRONTLINE_LENGTH
if TYPE_CHECKING:
from gen.ato import Package
from game.ato.package import Package
from game.coalition import Coalition
from game.threatzones import ThreatZones
from game.transfers import Convoy
INGRESS_TYPES = {
FlightWaypointType.INGRESS_CAS,
FlightWaypointType.INGRESS_ESCORT,
@ -1005,7 +1009,7 @@ class FlightPlanBuilder:
raise PlanningError(f"{task} flight plan generation not implemented")
def regenerate_package_waypoints(self) -> None:
from gen.ato import PackageWaypoints
from game.ato.packagewaypoints import PackageWaypoints
package_airfield = self.package_airfield()

View File

@ -8,7 +8,7 @@ from game.data.weapons import Weapon, Pylon, WeaponType
from game.dcs.aircrafttype import AircraftType
if TYPE_CHECKING:
from gen.flights.flight import Flight
from game.ato.flight import Flight
class Loadout:
@ -123,7 +123,7 @@ class Loadout:
@classmethod
def default_loadout_names_for(cls, flight: Flight) -> Iterator[str]:
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
# This is a list of mappings from the FlightType of a Flight to the type of
# payload defined in the resources/payloads/UNIT_TYPE.lua file. A Flight has no

View File

@ -16,10 +16,10 @@ from game.utils import (
mach,
meters,
)
from gen.flights.flight import Flight
from game.ato.flight import Flight
if TYPE_CHECKING:
from gen.ato import Package
from game.ato.package import Package
class GroundSpeed:

View File

@ -29,7 +29,9 @@ from game.theater import (
TheaterGroundObject,
)
from game.utils import Distance, meters, nautical_miles
from .flight import Flight, FlightWaypoint, FlightWaypointType
from game.ato.flightwaypointtype import FlightWaypointType
from game.ato.flightwaypoint import FlightWaypoint
from game.ato.flight import Flight
@dataclass(frozen=True)

View File

@ -45,7 +45,9 @@ from game.weather import Weather
from .aircraft import FlightData
from .airsupportgen import AwacsInfo, TankerInfo
from .briefinggen import CommInfo, JtacInfo, MissionInfoGenerator
from .flights.flight import FlightWaypoint, FlightWaypointType, FlightType
from game.ato.flighttype import FlightType
from game.ato.flightwaypointtype import FlightWaypointType
from game.ato.flightwaypoint import FlightWaypoint
from .radios import RadioFrequency
from .runways import RunwayData

View File

@ -10,7 +10,7 @@ from game.dcs.aircrafttype import AircraftType
from game.dcs.unittype import UnitType
if TYPE_CHECKING:
from gen.flights.flight import Flight
from game.ato.flight import Flight
ALPHA_MILITARY = [
"Alpha",

View File

@ -1,7 +1,7 @@
"""Application-wide dialog management."""
from typing import Optional
from gen.flights.flight import Flight
from game.ato.flight import Flight
from game.theater.missiontarget import MissionTarget
from .models import GameModel, PackageModel
from .windows.mission.QEditFlightDialog import QEditFlightDialog

View File

@ -16,8 +16,10 @@ from game.game import Game
from game.squadrons.squadron import Pilot, Squadron
from game.theater.missiontarget import MissionTarget
from game.transfers import TransferOrder, PendingTransfers
from gen.ato import AirTaskingOrder, Package
from gen.flights.flight import Flight, FlightType
from game.ato.airtaaskingorder import AirTaskingOrder
from game.ato.package import Package
from game.ato.flighttype import FlightType
from game.ato.flight import Flight
from gen.flights.traveltime import TotEstimator
from qt_ui.uiconstants import AIRCRAFT_ICONS

View File

@ -14,7 +14,7 @@ from game import Game
from game.event.airwar import AirWarEvent
from game.profiling import logged_duration
from game.utils import meters
from gen.ato import Package
from game.ato.package import Package
from gen.flights.traveltime import TotEstimator
from qt_ui.models import GameModel
from qt_ui.widgets.QBudgetBox import QBudgetBox

View File

@ -24,8 +24,8 @@ from PySide2.QtWidgets import (
QVBoxLayout,
)
from gen.ato import Package
from gen.flights.flight import Flight
from game.ato.package import Package
from game.ato.flight import Flight
from gen.flights.traveltime import TotEstimator
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal
from ..delegates import TwoColumnRowDelegate

View File

@ -5,7 +5,7 @@ from PySide2.QtWidgets import QComboBox
from dcs.unittype import FlyingType
from gen.flights.ai_flight_planner_db import aircraft_for_task
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
class QAircraftTypeSelector(QComboBox):

View File

@ -4,7 +4,8 @@ from game import Game
from game.theater import ControlPointType, BuildingGroundObject
from game.utils import Distance
from gen.conflictgen import Conflict
from gen.flights.flight import FlightWaypoint, FlightWaypointType
from game.ato.flightwaypointtype import FlightWaypointType
from game.ato.flightwaypoint import FlightWaypoint
from qt_ui.widgets.combos.QFilteredComboBox import QFilteredComboBox

View File

@ -32,8 +32,10 @@ from game.theater import (
from game.threatzones import ThreatZones
from game.transfers import MultiGroupTransport, TransportMap
from game.utils import meters, nautical_miles
from gen.ato import AirTaskingOrder
from gen.flights.flight import Flight, FlightWaypoint, FlightWaypointType
from game.ato.airtaaskingorder import AirTaskingOrder
from game.ato.flightwaypointtype import FlightWaypointType
from game.ato.flightwaypoint import FlightWaypoint
from game.ato.flight import Flight
from gen.flights.flightplan import (
FlightPlan,
PatrollingFlightPlan,

View File

@ -30,7 +30,7 @@ from game import Game
from game.dcs.aircrafttype import AircraftType
from game.squadrons import AirWing, Pilot, Squadron
from game.theater import ControlPoint, ConflictTheater
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
from qt_ui.uiconstants import AIRCRAFT_ICONS

View File

@ -19,7 +19,7 @@ from PySide2.QtWidgets import (
from game.squadrons import Squadron
from game.theater import ConflictTheater
from gen.flights.flight import Flight
from game.ato.flight import Flight
from qt_ui.delegates import TwoColumnRowDelegate
from qt_ui.models import GameModel, AirWingModel, SquadronModel, AtoModel
from qt_ui.windows.SquadronDialog import SquadronDialog

View File

@ -15,7 +15,7 @@ from game.dcs.aircrafttype import AircraftType
from game.dcs.groundunittype import GroundUnitType
from game.dcs.unittype import UnitType
from game.game import Game
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
from qt_ui.uiconstants import AIRCRAFT_BANNERS, VEHICLE_BANNERS

View File

@ -21,7 +21,7 @@ from PySide2.QtWidgets import (
from game.squadrons import Pilot, Squadron
from game.theater import ControlPoint, ConflictTheater
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
from qt_ui.delegates import TwoColumnRowDelegate
from qt_ui.errorreporter import report_errors
from qt_ui.models import SquadronModel, AtoModel

View File

@ -17,7 +17,7 @@ from game.theater import (
FREE_FRONTLINE_UNIT_SUPPLY,
AMMO_DEPOT_FRONTLINE_UNIT_CONTRIBUTION,
)
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
from qt_ui.dialogs import Dialog
from qt_ui.models import GameModel
from qt_ui.uiconstants import EVENT_ICONS

View File

@ -4,7 +4,7 @@ from PySide2.QtWidgets import (
QVBoxLayout,
)
from gen.flights.flight import Flight
from game.ato.flight import Flight
from qt_ui.models import GameModel, PackageModel
from qt_ui.uiconstants import EVENT_ICONS
from qt_ui.windows.GameUpdateSignal import GameUpdateSignal

View File

@ -1,7 +1,7 @@
from PySide2.QtGui import QStandardItem, QIcon
from gen.ato import Package
from gen.flights.flight import Flight
from game.ato.package import Package
from game.ato.flight import Flight
from gen.flights.traveltime import TotEstimator
from qt_ui.uiconstants import AIRCRAFT_ICONS

View File

@ -17,8 +17,8 @@ from PySide2.QtWidgets import (
from game.game import Game
from game.theater.missiontarget import MissionTarget
from gen.ato import Package
from gen.flights.flight import Flight
from game.ato.package import Package
from game.ato.flight import Flight
from gen.flights.flightplan import FlightPlanBuilder, PlanningError
from qt_ui.models import AtoModel, GameModel, PackageModel
from qt_ui.uiconstants import EVENT_ICONS

View File

@ -16,8 +16,9 @@ from dcs.unittype import FlyingType
from game import Game
from game.squadrons.squadron import Squadron
from game.theater import ControlPoint, OffMapSpawn
from gen.ato import Package
from gen.flights.flight import Flight, FlightRoster
from game.ato.package import Package
from game.ato.flightroster import FlightRoster
from game.ato.flight import Flight
from qt_ui.uiconstants import EVENT_ICONS
from qt_ui.widgets.QFlightSizeSpinner import QFlightSizeSpinner
from qt_ui.widgets.QLabeledWidget import QLabeledWidget

View File

@ -1,7 +1,7 @@
from PySide2.QtWidgets import QTabWidget
from game import Game
from gen.flights.flight import Flight
from game.ato.flight import Flight
from qt_ui.models import PackageModel
from qt_ui.windows.mission.flight.payload.QFlightPayloadTab import QFlightPayloadTab
from qt_ui.windows.mission.flight.settings.QGeneralFlightSettingsTab import (

View File

@ -5,7 +5,7 @@ from PySide2.QtWidgets import QComboBox
from game.dcs.aircrafttype import AircraftType
from game.squadrons.airwing import AirWing
from gen.flights.flight import FlightType
from game.ato.flighttype import FlightType
class SquadronSelector(QComboBox):

View File

@ -2,7 +2,7 @@ from PySide2.QtCore import Qt
from PySide2.QtWidgets import QFrame, QLabel, QComboBox, QVBoxLayout
from game import Game
from gen.flights.flight import Flight
from game.ato.flight import Flight
from gen.flights.loadouts import Loadout
from qt_ui.windows.mission.flight.payload.QLoadoutEditor import QLoadoutEditor

View File

@ -8,7 +8,7 @@ from PySide2.QtWidgets import (
from game import Game
from game.data.weapons import Pylon
from gen.flights.flight import Flight
from game.ato.flight import Flight
from qt_ui.windows.mission.flight.payload.QPylonEditor import QPylonEditor

View File

@ -6,7 +6,7 @@ from PySide2.QtWidgets import QComboBox
from game import Game
from game.data.weapons import Pylon, Weapon
from gen.flights.flight import Flight
from game.ato.flight import Flight
from gen.flights.loadouts import Loadout

View File

@ -3,7 +3,7 @@ import logging
from PySide2.QtWidgets import QGroupBox, QLabel, QMessageBox, QVBoxLayout
from game import Game
from gen.flights.flight import Flight
from game.ato.flight import Flight
from gen.flights.flightplan import FlightPlanBuilder, PlanningError
from gen.flights.traveltime import TotEstimator
from qt_ui.models import PackageModel

View File

@ -1,6 +1,6 @@
from PySide2.QtWidgets import QGroupBox, QHBoxLayout, QLabel
from gen.flights.flight import Flight
from game.ato.flight import Flight
class QFlightCustomName(QGroupBox):

View File

@ -15,7 +15,8 @@ from PySide2.QtWidgets import (
from game import Game
from game.squadrons.pilot import Pilot
from gen.flights.flight import Flight, FlightRoster
from game.ato.flightroster import FlightRoster
from game.ato.flight import Flight
from qt_ui.models import PackageModel

View File

@ -6,7 +6,7 @@ from PySide2.QtWidgets import (
QVBoxLayout,
)
from gen.flights.flight import Flight
from game.ato.flight import Flight
from qt_ui.models import PackageModel

View File

@ -2,7 +2,7 @@ from PySide2.QtCore import Signal
from PySide2.QtWidgets import QFrame, QGridLayout, QVBoxLayout
from game import Game
from gen.flights.flight import Flight
from game.ato.flight import Flight
from qt_ui.models import PackageModel
from qt_ui.windows.mission.flight.settings.FlightAirfieldDisplay import (
FlightAirfieldDisplay,

View File

@ -1,6 +1,6 @@
from PySide2.QtWidgets import QGroupBox, QHBoxLayout, QLabel, QVBoxLayout
from gen.flights.flight import FlightWaypoint
from game.ato.flightwaypoint import FlightWaypoint
class QFlightWaypointInfoBox(QGroupBox):

View File

@ -2,7 +2,7 @@ from typing import List
from PySide2.QtGui import QStandardItem
from gen.flights.flight import FlightWaypoint
from game.ato.flightwaypoint import FlightWaypoint
class QWaypointItem(QStandardItem):

View File

@ -4,8 +4,10 @@ from PySide2.QtCore import QItemSelectionModel, QPoint
from PySide2.QtGui import QStandardItem, QStandardItemModel
from PySide2.QtWidgets import QHeaderView, QTableView
from gen.ato import Package
from gen.flights.flight import Flight, FlightWaypoint, FlightWaypointType
from game.ato.package import Package
from game.ato.flightwaypointtype import FlightWaypointType
from game.ato.flightwaypoint import FlightWaypoint
from game.ato.flight import Flight
from qt_ui.windows.mission.flight.waypoints.QFlightWaypointItem import QWaypointItem

View File

@ -12,8 +12,10 @@ from PySide2.QtWidgets import (
)
from game import Game
from gen.ato import Package
from gen.flights.flight import Flight, FlightType, FlightWaypoint
from game.ato.package import Package
from game.ato.flighttype import FlightType
from game.ato.flightwaypoint import FlightWaypoint
from game.ato.flight import Flight
from gen.flights.flightplan import (
CustomFlightPlan,
FlightPlanBuilder,

View File

@ -9,7 +9,7 @@ from PySide2.QtWidgets import (
)
from game import Game
from gen.flights.flight import Flight
from game.ato.flight import Flight
from qt_ui.uiconstants import EVENT_ICONS
from qt_ui.widgets.combos.QPredefinedWaypointSelectionComboBox import (
QPredefinedWaypointSelectionComboBox,