Initial squadrons implementation.

Doesn't actually do anything yet, but squadrons are created for each
aircraft type and pilots will be created as needed to fill flights.

https://github.com/dcs-liberation/dcs_liberation/issues/276
This commit is contained in:
Dan Albert
2021-05-25 00:12:14 -07:00
parent 6b30f47588
commit 4147d2f684
22 changed files with 728 additions and 41 deletions

View File

@@ -1020,7 +1020,7 @@ class AircraftConflictGenerator:
flight = Flight(
Package(control_point),
faction.country,
aircraft,
self.game.air_wing_for(control_point.captured).squadron_for(aircraft),
1,
FlightType.BARCAP,
"Cold",

View File

@@ -22,8 +22,10 @@ from typing import (
from dcs.unittype import FlyingType
from game.factions.faction import Faction
from game.infos.information import Information
from game.procurement import AircraftProcurementRequest
from game.squadrons import AirWing
from game.theater import (
Airfield,
ControlPoint,
@@ -182,6 +184,7 @@ class PackageBuilder:
location: MissionTarget,
closest_airfields: ClosestAirfields,
global_inventory: GlobalAircraftInventory,
air_wing: AirWing,
is_player: bool,
package_country: str,
start_type: str,
@@ -189,6 +192,7 @@ class PackageBuilder:
) -> None:
self.closest_airfields = closest_airfields
self.is_player = is_player
self.air_wing = air_wing
self.package_country = package_country
self.package = Package(location, auto_asap=asap)
self.allocator = AircraftAllocator(
@@ -217,7 +221,7 @@ class PackageBuilder:
flight = Flight(
self.package,
self.package_country,
aircraft,
self.air_wing.squadron_for(aircraft),
plan.num_aircraft,
plan.task,
start_type,
@@ -850,18 +854,13 @@ class CoalitionMissionPlanner:
def plan_mission(self, mission: ProposedMission, reserves: bool = False) -> None:
"""Allocates aircraft for a proposed mission and adds it to the ATO."""
if self.is_player:
package_country = self.game.player_country
else:
package_country = self.game.enemy_country
builder = PackageBuilder(
mission.location,
self.objective_finder.closest_airfields_to(mission.location),
self.game.aircraft_inventory,
self.game.air_wing_for(self.is_player),
self.is_player,
package_country,
self.game.country_for(self.is_player),
self.game.settings.default_start_type,
mission.asap,
)

View File

@@ -10,6 +10,7 @@ from dcs.unit import Unit
from dcs.unittype import FlyingType
from game import db
from game.squadrons import Pilot, Squadron
from game.theater.controlpoint import ControlPoint, MissionTarget
from game.utils import Distance, meters
from gen.flights.loadouts import Loadout
@@ -71,6 +72,13 @@ class FlightType(Enum):
def __str__(self) -> str:
return self.value
@classmethod
def from_name(cls, name: str) -> FlightType:
for value in cls:
if name == value:
return value
raise KeyError(f"No FlightType with name {name}")
class FlightWaypointType(Enum):
"""Enumeration of waypoint types.
@@ -197,7 +205,7 @@ class Flight:
self,
package: Package,
country: str,
unit_type: Type[FlyingType],
squadron: Squadron,
count: int,
flight_type: FlightType,
start_type: str,
@@ -209,8 +217,8 @@ class Flight:
) -> None:
self.package = package
self.country = country
self.unit_type = unit_type
self.count = count
self.squadron = squadron
self.pilots = [squadron.claim_available_pilot() for _ in range(count)]
self.departure = departure
self.arrival = arrival
self.divert = divert
@@ -235,6 +243,14 @@ class Flight:
package=package, flight=self, custom_waypoints=[]
)
@property
def count(self) -> int:
return len(self.pilots)
@property
def unit_type(self) -> Type[FlyingType]:
return self.squadron.aircraft
@property
def from_cp(self) -> ControlPoint:
return self.departure
@@ -243,6 +259,27 @@ class Flight:
def points(self) -> List[FlightWaypoint]:
return self.flight_plan.waypoints[1:]
def resize(self, new_size: int) -> None:
if self.count > 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.count)
]
)
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 __repr__(self):
name = db.unit_type_name(self.unit_type)
if self.custom_name:

View File

@@ -21,6 +21,7 @@ from dcs.unit import Unit
from shapely.geometry import Point as ShapelyPoint
from game.data.doctrine import Doctrine
from game.squadrons import Pilot
from game.theater import (
Airfield,
ControlPoint,
@@ -857,11 +858,7 @@ class FlightPlanBuilder:
self.game = game
self.package = package
self.is_player = is_player
if is_player:
faction = self.game.player_faction
else:
faction = self.game.enemy_faction
self.doctrine: Doctrine = faction.doctrine
self.doctrine: Doctrine = self.game.faction_for(self.is_player).doctrine
self.threat_zones = self.game.threat_zone_for(not self.is_player)
def populate_flight_plan(