Fix some typing in preparation for pydcs types.

Not complete, but progress.
This commit is contained in:
Dan Albert 2021-07-08 22:50:55 -07:00
parent fb9a0fe833
commit 53f6a0b32b
30 changed files with 208 additions and 193 deletions

View File

@ -5,14 +5,14 @@ import inspect
import logging import logging
from collections import defaultdict from collections import defaultdict
from dataclasses import dataclass, field from dataclasses import dataclass, field
from typing import Dict, Iterator, Optional, Set, Tuple, Union, cast from typing import Dict, Iterator, Optional, Set, Tuple, Union, cast, Any
from dcs.unitgroup import FlyingGroup from dcs.unitgroup import FlyingGroup
from dcs.weapons_data import Weapons, weapon_ids from dcs.weapons_data import Weapons, weapon_ids
from game.dcs.aircrafttype import AircraftType from game.dcs.aircrafttype import AircraftType
PydcsWeapon = Dict[str, Union[int, str]] PydcsWeapon = Dict[str, Any]
PydcsWeaponAssignment = Tuple[int, PydcsWeapon] PydcsWeaponAssignment = Tuple[int, PydcsWeapon]

View File

@ -106,7 +106,7 @@ class PatrolConfig:
@dataclass(frozen=True) @dataclass(frozen=True)
class AircraftType(UnitType[FlyingType]): class AircraftType(UnitType[Type[FlyingType]]):
carrier_capable: bool carrier_capable: bool
lha_capable: bool lha_capable: bool
always_keeps_gun: bool always_keeps_gun: bool

View File

@ -15,7 +15,7 @@ from game.dcs.unittype import UnitType
@dataclass(frozen=True) @dataclass(frozen=True)
class GroundUnitType(UnitType[VehicleType]): class GroundUnitType(UnitType[Type[VehicleType]]):
unit_class: Optional[GroundUnitClass] unit_class: Optional[GroundUnitClass]
spawn_weight: int spawn_weight: int

View File

@ -4,12 +4,12 @@ from typing import TypeVar, Generic, Type
from dcs.unittype import UnitType as DcsUnitType from dcs.unittype import UnitType as DcsUnitType
DcsUnitTypeT = TypeVar("DcsUnitTypeT", bound=DcsUnitType) DcsUnitTypeT = TypeVar("DcsUnitTypeT", bound=Type[DcsUnitType])
@dataclass(frozen=True) @dataclass(frozen=True)
class UnitType(Generic[DcsUnitTypeT]): class UnitType(Generic[DcsUnitTypeT]):
dcs_unit_type: Type[DcsUnitTypeT] dcs_unit_type: DcsUnitTypeT
name: str name: str
description: str description: str
year_introduced: str year_introduced: str

View File

@ -5,7 +5,6 @@ from typing import List, TYPE_CHECKING, Type
from dcs.mapping import Point from dcs.mapping import Point
from dcs.task import Task from dcs.task import Task
from dcs.unittype import VehicleType
from game import persistency from game import persistency
from game.debriefing import AirLosses, Debriefing from game.debriefing import AirLosses, Debriefing

View File

@ -84,10 +84,10 @@ class Faction:
requirements: Dict[str, str] = field(default_factory=dict) requirements: Dict[str, str] = field(default_factory=dict)
# possible aircraft carrier units # possible aircraft carrier units
aircraft_carrier: List[Type[UnitType]] = field(default_factory=list) aircraft_carrier: List[Type[ShipType]] = field(default_factory=list)
# possible helicopter carrier units # possible helicopter carrier units
helicopter_carrier: List[Type[UnitType]] = field(default_factory=list) helicopter_carrier: List[Type[ShipType]] = field(default_factory=list)
# Possible carrier names # Possible carrier names
carrier_names: List[str] = field(default_factory=list) carrier_names: List[str] = field(default_factory=list)

View File

@ -70,20 +70,6 @@ class Operation:
cls._setup_mission_coalitions() cls._setup_mission_coalitions()
cls.current_mission.options.load_from_dict(options_dict) cls.current_mission.options.load_from_dict(options_dict)
@classmethod
def conflicts(cls) -> Iterable[Conflict]:
assert cls.game
for frontline in cls.game.theater.conflicts():
yield Conflict(
cls.game.theater,
frontline,
cls.game.player_faction.name,
cls.game.enemy_faction.name,
cls.game.player_country,
cls.game.enemy_country,
frontline.position,
)
@classmethod @classmethod
def air_conflict(cls) -> Conflict: def air_conflict(cls) -> Conflict:
assert cls.game assert cls.game
@ -97,8 +83,8 @@ class Operation:
FrontLine(player_cp, enemy_cp), FrontLine(player_cp, enemy_cp),
cls.game.player_faction.name, cls.game.player_faction.name,
cls.game.enemy_faction.name, cls.game.enemy_faction.name,
cls.game.player_country, cls.current_mission.country(cls.game.player_country),
cls.game.enemy_country, cls.current_mission.country(cls.game.enemy_country),
mid_point, mid_point,
) )

View File

@ -2,8 +2,6 @@ import itertools
import logging import logging
from typing import Any from typing import Any
from dcs.unit import UnitType as DcsUnitType
from game.dcs.aircrafttype import AircraftType from game.dcs.aircrafttype import AircraftType
from game.dcs.groundunittype import GroundUnitType from game.dcs.groundunittype import GroundUnitType
from game.dcs.unittype import UnitType from game.dcs.unittype import UnitType
@ -33,7 +31,7 @@ class Base:
total += unit_type.price * count total += unit_type.price * count
return total return total
def total_units_of_type(self, unit_type: UnitType[DcsUnitType]) -> int: def total_units_of_type(self, unit_type: UnitType[Any]) -> int:
return sum( return sum(
[ [
c c

View File

@ -545,7 +545,7 @@ class ConflictTheater:
def find_ground_objects_by_obj_name( def find_ground_objects_by_obj_name(
self, obj_name: str self, obj_name: str
) -> list[TheaterGroundObject]: ) -> list[TheaterGroundObject[Any]]:
found = [] found = []
for cp in self.controlpoints: for cp in self.controlpoints:
for g in cp.ground_objects: for g in cp.ground_objects:

View File

@ -43,6 +43,7 @@ from .missiontarget import MissionTarget
from .theatergroundobject import ( from .theatergroundobject import (
GenericCarrierGroundObject, GenericCarrierGroundObject,
TheaterGroundObject, TheaterGroundObject,
NavalGroundObject,
) )
from ..dcs.aircrafttype import AircraftType from ..dcs.aircrafttype import AircraftType
from ..dcs.groundunittype import GroundUnitType from ..dcs.groundunittype import GroundUnitType
@ -298,7 +299,7 @@ class ControlPoint(MissionTarget, ABC):
self.id = cp_id self.id = cp_id
self.full_name = name self.full_name = name
self.at = at self.at = at
self.connected_objectives: List[TheaterGroundObject] = [] self.connected_objectives: List[TheaterGroundObject[Any]] = []
self.preset_locations = PresetLocations() self.preset_locations = PresetLocations()
self.helipads: List[PointWithHeading] = [] self.helipads: List[PointWithHeading] = []
@ -326,7 +327,7 @@ class ControlPoint(MissionTarget, ABC):
return f"<{self.__class__}: {self.name}>" return f"<{self.__class__}: {self.name}>"
@property @property
def ground_objects(self) -> List[TheaterGroundObject]: def ground_objects(self) -> List[TheaterGroundObject[Any]]:
return list(self.connected_objectives) return list(self.connected_objectives)
@property @property
@ -502,7 +503,7 @@ class ControlPoint(MissionTarget, ABC):
def find_ground_objects_by_obj_name( def find_ground_objects_by_obj_name(
self, obj_name: str self, obj_name: str
) -> list[TheaterGroundObject]: ) -> list[TheaterGroundObject[Any]]:
found = [] found = []
for g in self.ground_objects: for g in self.ground_objects:
if g.obj_name == obj_name: if g.obj_name == obj_name:
@ -881,9 +882,12 @@ class NavalControlPoint(ControlPoint, ABC):
def heading(self) -> int: def heading(self) -> int:
return 0 # TODO compute heading return 0 # TODO compute heading
def find_main_tgo(self) -> TheaterGroundObject: def find_main_tgo(self) -> GenericCarrierGroundObject:
for g in self.ground_objects: for g in self.ground_objects:
if g.dcs_identifier in ["CARRIER", "LHA"]: if isinstance(g, GenericCarrierGroundObject) and g.dcs_identifier in [
"CARRIER",
"LHA",
]:
return g return g
raise RuntimeError(f"Found no carrier/LHA group for {self.name}") raise RuntimeError(f"Found no carrier/LHA group for {self.name}")

View File

@ -2,12 +2,12 @@ from __future__ import annotations
import itertools import itertools
import logging import logging
from typing import Iterator, List, TYPE_CHECKING, Union from typing import Iterator, List, TYPE_CHECKING, Union, Generic, TypeVar, Any
from dcs.mapping import Point from dcs.mapping import Point
from dcs.triggers import TriggerZone from dcs.triggers import TriggerZone
from dcs.unit import Unit from dcs.unit import Unit
from dcs.unitgroup import Group from dcs.unitgroup import Group, ShipGroup, VehicleGroup
from dcs.unittype import VehicleType from dcs.unittype import VehicleType
from .. import db from .. import db
@ -47,7 +47,10 @@ NAME_BY_CATEGORY = {
} }
class TheaterGroundObject(MissionTarget): GroupT = TypeVar("GroupT", bound=Group)
class TheaterGroundObject(MissionTarget, Generic[GroupT]):
def __init__( def __init__(
self, self,
name: str, name: str,
@ -66,7 +69,7 @@ class TheaterGroundObject(MissionTarget):
self.control_point = control_point self.control_point = control_point
self.dcs_identifier = dcs_identifier self.dcs_identifier = dcs_identifier
self.sea_object = sea_object self.sea_object = sea_object
self.groups: List[Group] = [] self.groups: List[GroupT] = []
@property @property
def is_dead(self) -> bool: def is_dead(self) -> bool:
@ -206,7 +209,7 @@ class TheaterGroundObject(MissionTarget):
raise NotImplementedError raise NotImplementedError
class BuildingGroundObject(TheaterGroundObject): class BuildingGroundObject(TheaterGroundObject[VehicleGroup]):
def __init__( def __init__(
self, self,
name: str, name: str,
@ -253,7 +256,7 @@ class BuildingGroundObject(TheaterGroundObject):
def kill(self) -> None: def kill(self) -> None:
self._dead = True self._dead = True
def iter_building_group(self) -> Iterator[TheaterGroundObject]: def iter_building_group(self) -> Iterator[TheaterGroundObject[Any]]:
for tgo in self.control_point.ground_objects: for tgo in self.control_point.ground_objects:
if tgo.obj_name == self.obj_name and not tgo.is_dead: if tgo.obj_name == self.obj_name and not tgo.is_dead:
yield tgo yield tgo
@ -338,7 +341,7 @@ class FactoryGroundObject(BuildingGroundObject):
) )
class NavalGroundObject(TheaterGroundObject): class NavalGroundObject(TheaterGroundObject[ShipGroup]):
def mission_types(self, for_player: bool) -> Iterator[FlightType]: def mission_types(self, for_player: bool) -> Iterator[FlightType]:
from gen.flights.flight import FlightType from gen.flights.flight import FlightType
@ -407,7 +410,7 @@ class LhaGroundObject(GenericCarrierGroundObject):
return f"{self.faction_color}|EWR|{super().group_name}" return f"{self.faction_color}|EWR|{super().group_name}"
class MissileSiteGroundObject(TheaterGroundObject): class MissileSiteGroundObject(TheaterGroundObject[VehicleGroup]):
def __init__( def __init__(
self, name: str, group_id: int, position: Point, control_point: ControlPoint self, name: str, group_id: int, position: Point, control_point: ControlPoint
) -> None: ) -> None:
@ -431,7 +434,7 @@ class MissileSiteGroundObject(TheaterGroundObject):
return False return False
class CoastalSiteGroundObject(TheaterGroundObject): class CoastalSiteGroundObject(TheaterGroundObject[VehicleGroup]):
def __init__( def __init__(
self, self,
name: str, name: str,
@ -463,7 +466,7 @@ class CoastalSiteGroundObject(TheaterGroundObject):
# The SamGroundObject represents all type of AA # The SamGroundObject represents all type of AA
# The TGO can have multiple types of units (AAA,SAM,Support...) # The TGO can have multiple types of units (AAA,SAM,Support...)
# Differentiation can be made during generation with the airdefensegroupgenerator # Differentiation can be made during generation with the airdefensegroupgenerator
class SamGroundObject(TheaterGroundObject): class SamGroundObject(TheaterGroundObject[VehicleGroup]):
def __init__( def __init__(
self, self,
name: str, name: str,
@ -535,7 +538,7 @@ class SamGroundObject(TheaterGroundObject):
return True return True
class VehicleGroupGroundObject(TheaterGroundObject): class VehicleGroupGroundObject(TheaterGroundObject[VehicleGroup]):
def __init__( def __init__(
self, self,
name: str, name: str,
@ -563,7 +566,7 @@ class VehicleGroupGroundObject(TheaterGroundObject):
return True return True
class EwrGroundObject(TheaterGroundObject): class EwrGroundObject(TheaterGroundObject[VehicleGroup]):
def __init__( def __init__(
self, self,
name: str, name: str,

View File

@ -30,16 +30,16 @@ class PendingUnitDeliveries:
self.destination = destination self.destination = destination
# Maps unit type to order quantity. # Maps unit type to order quantity.
self.units: dict[UnitType[DcsUnitType], int] = defaultdict(int) self.units: dict[UnitType[Any], int] = defaultdict(int)
def __str__(self) -> str: def __str__(self) -> str:
return f"Pending delivery to {self.destination}" return f"Pending delivery to {self.destination}"
def order(self, units: dict[UnitType[DcsUnitType], int]) -> None: def order(self, units: dict[UnitType[Any], int]) -> None:
for k, v in units.items(): for k, v in units.items():
self.units[k] += v self.units[k] += v
def sell(self, units: dict[UnitType[DcsUnitType], int]) -> None: def sell(self, units: dict[UnitType[Any], int]) -> None:
for k, v in units.items(): for k, v in units.items():
self.units[k] -= v self.units[k] -= v

View File

@ -2,7 +2,7 @@
import itertools import itertools
import math import math
from dataclasses import dataclass from dataclasses import dataclass
from typing import Dict, Optional from typing import Dict, Optional, Any
from dcs.unit import Unit from dcs.unit import Unit
from dcs.unitgroup import FlyingGroup, Group, VehicleGroup from dcs.unitgroup import FlyingGroup, Group, VehicleGroup
@ -29,7 +29,7 @@ class FrontLineUnit:
@dataclass(frozen=True) @dataclass(frozen=True)
class GroundObjectUnit: class GroundObjectUnit:
ground_object: TheaterGroundObject ground_object: TheaterGroundObject[Any]
group: Group group: Group
unit: Unit unit: Unit
@ -100,7 +100,7 @@ class UnitMap:
def add_ground_object_units( def add_ground_object_units(
self, self,
ground_object: TheaterGroundObject, ground_object: TheaterGroundObject[Any],
persistence_group: Group, persistence_group: Group,
miz_group: Group, miz_group: Group,
) -> None: ) -> None:

View File

@ -5,7 +5,7 @@ import random
from dataclasses import dataclass from dataclasses import dataclass
from datetime import timedelta from datetime import timedelta
from functools import cached_property from functools import cached_property
from typing import Dict, List, Optional, TYPE_CHECKING, Type, Union, Iterable from typing import Dict, List, Optional, TYPE_CHECKING, Type, Union, Iterable, Any
from dcs import helicopters from dcs import helicopters
from dcs.action import AITaskPush, ActivateGroup from dcs.action import AITaskPush, ActivateGroup
@ -351,7 +351,7 @@ class AircraftConflictGenerator:
def _setup_group( def _setup_group(
self, self,
group: FlyingGroup, group: FlyingGroup[Any],
package: Package, package: Package,
flight: Flight, flight: Flight,
dynamic_runways: Dict[str, RunwayData], dynamic_runways: Dict[str, RunwayData],
@ -537,7 +537,7 @@ class AircraftConflictGenerator:
def _add_radio_waypoint( def _add_radio_waypoint(
self, self,
group: FlyingGroup, group: FlyingGroup[Any],
position: Point, position: Point,
altitude: Distance, altitude: Distance,
airspeed: int = 600, airspeed: int = 600,
@ -548,7 +548,7 @@ class AircraftConflictGenerator:
def _rtb_for( def _rtb_for(
self, self,
group: FlyingGroup, group: FlyingGroup[Any],
cp: ControlPoint, cp: ControlPoint,
at: Optional[db.StartingPosition] = None, at: Optional[db.StartingPosition] = None,
) -> MovingPoint: ) -> MovingPoint:
@ -680,7 +680,7 @@ class AircraftConflictGenerator:
self.unit_map.add_aircraft(group, flight) self.unit_map.add_aircraft(group, flight)
def set_activation_time( def set_activation_time(
self, flight: Flight, group: FlyingGroup, delay: timedelta self, flight: Flight, group: FlyingGroup[Any], delay: timedelta
) -> None: ) -> None:
# Note: Late activation causes the waypoint TOTs to look *weird* in the # Note: Late activation causes the waypoint TOTs to look *weird* in the
# mission editor. Waypoint times will be relative to the group # mission editor. Waypoint times will be relative to the group
@ -699,7 +699,7 @@ class AircraftConflictGenerator:
self.m.triggerrules.triggers.append(activation_trigger) self.m.triggerrules.triggers.append(activation_trigger)
def set_startup_time( def set_startup_time(
self, flight: Flight, group: FlyingGroup, delay: timedelta self, flight: Flight, group: FlyingGroup[Any], delay: timedelta
) -> None: ) -> None:
# Uncontrolled causes the AI unit to spawn, but not begin startup. # Uncontrolled causes the AI unit to spawn, but not begin startup.
group.uncontrolled = True group.uncontrolled = True
@ -775,7 +775,7 @@ class AircraftConflictGenerator:
@staticmethod @staticmethod
def set_reduced_fuel( def set_reduced_fuel(
flight: Flight, group: FlyingGroup, unit_type: Type[PlaneType] flight: Flight, group: FlyingGroup[Any], unit_type: Type[PlaneType]
) -> None: ) -> None:
if unit_type is Su_33: if unit_type is Su_33:
for unit in group.units: for unit in group.units:
@ -801,7 +801,7 @@ class AircraftConflictGenerator:
def configure_behavior( def configure_behavior(
self, self,
flight: Flight, flight: Flight,
group: FlyingGroup, group: FlyingGroup[Any],
react_on_threat: Optional[OptReactOnThreat.Values] = None, react_on_threat: Optional[OptReactOnThreat.Values] = None,
roe: Optional[OptROE.Values] = None, roe: Optional[OptROE.Values] = None,
rtb_winchester: Optional[OptRTBOnOutOfAmmo.Values] = None, rtb_winchester: Optional[OptRTBOnOutOfAmmo.Values] = None,
@ -834,13 +834,13 @@ class AircraftConflictGenerator:
# https://forums.eagle.ru/forum/english/digital-combat-simulator/dcs-world-2-5/bugs-and-problems-ai/ai-ad/7121294-ai-stuck-at-high-aoa-after-making-sharp-turn-if-afterburner-is-restricted # https://forums.eagle.ru/forum/english/digital-combat-simulator/dcs-world-2-5/bugs-and-problems-ai/ai-ad/7121294-ai-stuck-at-high-aoa-after-making-sharp-turn-if-afterburner-is-restricted
@staticmethod @staticmethod
def configure_eplrs(group: FlyingGroup, flight: Flight) -> None: def configure_eplrs(group: FlyingGroup[Any], flight: Flight) -> None:
if flight.unit_type.eplrs_capable: if flight.unit_type.eplrs_capable:
group.points[0].tasks.append(EPLRS(group.id)) group.points[0].tasks.append(EPLRS(group.id))
def configure_cap( def configure_cap(
self, self,
group: FlyingGroup, group: FlyingGroup[Any],
package: Package, package: Package,
flight: Flight, flight: Flight,
dynamic_runways: Dict[str, RunwayData], dynamic_runways: Dict[str, RunwayData],
@ -857,7 +857,7 @@ class AircraftConflictGenerator:
def configure_sweep( def configure_sweep(
self, self,
group: FlyingGroup, group: FlyingGroup[Any],
package: Package, package: Package,
flight: Flight, flight: Flight,
dynamic_runways: Dict[str, RunwayData], dynamic_runways: Dict[str, RunwayData],
@ -874,7 +874,7 @@ class AircraftConflictGenerator:
def configure_cas( def configure_cas(
self, self,
group: FlyingGroup, group: FlyingGroup[Any],
package: Package, package: Package,
flight: Flight, flight: Flight,
dynamic_runways: Dict[str, RunwayData], dynamic_runways: Dict[str, RunwayData],
@ -892,7 +892,7 @@ class AircraftConflictGenerator:
def configure_dead( def configure_dead(
self, self,
group: FlyingGroup, group: FlyingGroup[Any],
package: Package, package: Package,
flight: Flight, flight: Flight,
dynamic_runways: Dict[str, RunwayData], dynamic_runways: Dict[str, RunwayData],
@ -917,7 +917,7 @@ class AircraftConflictGenerator:
def configure_sead( def configure_sead(
self, self,
group: FlyingGroup, group: FlyingGroup[Any],
package: Package, package: Package,
flight: Flight, flight: Flight,
dynamic_runways: Dict[str, RunwayData], dynamic_runways: Dict[str, RunwayData],
@ -941,7 +941,7 @@ class AircraftConflictGenerator:
def configure_strike( def configure_strike(
self, self,
group: FlyingGroup, group: FlyingGroup[Any],
package: Package, package: Package,
flight: Flight, flight: Flight,
dynamic_runways: Dict[str, RunwayData], dynamic_runways: Dict[str, RunwayData],
@ -959,7 +959,7 @@ class AircraftConflictGenerator:
def configure_anti_ship( def configure_anti_ship(
self, self,
group: FlyingGroup, group: FlyingGroup[Any],
package: Package, package: Package,
flight: Flight, flight: Flight,
dynamic_runways: Dict[str, RunwayData], dynamic_runways: Dict[str, RunwayData],
@ -977,7 +977,7 @@ class AircraftConflictGenerator:
def configure_runway_attack( def configure_runway_attack(
self, self,
group: FlyingGroup, group: FlyingGroup[Any],
package: Package, package: Package,
flight: Flight, flight: Flight,
dynamic_runways: Dict[str, RunwayData], dynamic_runways: Dict[str, RunwayData],
@ -995,7 +995,7 @@ class AircraftConflictGenerator:
def configure_oca_strike( def configure_oca_strike(
self, self,
group: FlyingGroup, group: FlyingGroup[Any],
package: Package, package: Package,
flight: Flight, flight: Flight,
dynamic_runways: Dict[str, RunwayData], dynamic_runways: Dict[str, RunwayData],
@ -1012,7 +1012,7 @@ class AircraftConflictGenerator:
def configure_awacs( def configure_awacs(
self, self,
group: FlyingGroup, group: FlyingGroup[Any],
package: Package, package: Package,
flight: Flight, flight: Flight,
dynamic_runways: Dict[str, RunwayData], dynamic_runways: Dict[str, RunwayData],
@ -1040,7 +1040,7 @@ class AircraftConflictGenerator:
def configure_refueling( def configure_refueling(
self, self,
group: FlyingGroup, group: FlyingGroup[Any],
package: Package, package: Package,
flight: Flight, flight: Flight,
dynamic_runways: Dict[str, RunwayData], dynamic_runways: Dict[str, RunwayData],
@ -1066,7 +1066,7 @@ class AircraftConflictGenerator:
def configure_escort( def configure_escort(
self, self,
group: FlyingGroup, group: FlyingGroup[Any],
package: Package, package: Package,
flight: Flight, flight: Flight,
dynamic_runways: Dict[str, RunwayData], dynamic_runways: Dict[str, RunwayData],
@ -1082,7 +1082,7 @@ class AircraftConflictGenerator:
def configure_sead_escort( def configure_sead_escort(
self, self,
group: FlyingGroup, group: FlyingGroup[Any],
package: Package, package: Package,
flight: Flight, flight: Flight,
dynamic_runways: Dict[str, RunwayData], dynamic_runways: Dict[str, RunwayData],
@ -1105,7 +1105,7 @@ class AircraftConflictGenerator:
def configure_transport( def configure_transport(
self, self,
group: FlyingGroup, group: FlyingGroup[Any],
package: Package, package: Package,
flight: Flight, flight: Flight,
dynamic_runways: Dict[str, RunwayData], dynamic_runways: Dict[str, RunwayData],
@ -1120,13 +1120,13 @@ class AircraftConflictGenerator:
restrict_jettison=True, restrict_jettison=True,
) )
def configure_unknown_task(self, group: FlyingGroup, flight: Flight) -> None: def configure_unknown_task(self, group: FlyingGroup[Any], flight: Flight) -> None:
logging.error(f"Unhandled flight type: {flight.flight_type}") logging.error(f"Unhandled flight type: {flight.flight_type}")
self.configure_behavior(flight, group) self.configure_behavior(flight, group)
def setup_flight_group( def setup_flight_group(
self, self,
group: FlyingGroup, group: FlyingGroup[Any],
package: Package, package: Package,
flight: Flight, flight: Flight,
dynamic_runways: Dict[str, RunwayData], dynamic_runways: Dict[str, RunwayData],
@ -1170,7 +1170,7 @@ class AircraftConflictGenerator:
self.configure_eplrs(group, flight) self.configure_eplrs(group, flight)
def create_waypoints( def create_waypoints(
self, group: FlyingGroup, package: Package, flight: Flight self, group: FlyingGroup[Any], package: Package, flight: Flight
) -> None: ) -> None:
for waypoint in flight.points: for waypoint in flight.points:
@ -1238,7 +1238,7 @@ class AircraftConflictGenerator:
waypoint: FlightWaypoint, waypoint: FlightWaypoint,
package: Package, package: Package,
flight: Flight, flight: Flight,
group: FlyingGroup, group: FlyingGroup[Any],
) -> None: ) -> None:
estimator = TotEstimator(package) estimator = TotEstimator(package)
start_time = estimator.mission_start_time(flight) start_time = estimator.mission_start_time(flight)
@ -1281,7 +1281,7 @@ class PydcsWaypointBuilder:
def __init__( def __init__(
self, self,
waypoint: FlightWaypoint, waypoint: FlightWaypoint,
group: FlyingGroup, group: FlyingGroup[Any],
package: Package, package: Package,
flight: Flight, flight: Flight,
mission: Mission, mission: Mission,
@ -1324,7 +1324,7 @@ class PydcsWaypointBuilder:
def for_waypoint( def for_waypoint(
cls, cls,
waypoint: FlightWaypoint, waypoint: FlightWaypoint,
group: FlyingGroup, group: FlyingGroup[Any],
package: Package, package: Package,
flight: Flight, flight: Flight,
mission: Mission, mission: Mission,

View File

@ -1,13 +1,12 @@
from dcs.unitgroup import VehicleGroup
from dcs.vehicles import MissilesSS, Unarmed, AirDefence from dcs.vehicles import MissilesSS, Unarmed, AirDefence
from game import Game from game import Game
from game.factions.faction import Faction from game.factions.faction import Faction
from game.theater.theatergroundobject import CoastalSiteGroundObject from game.theater.theatergroundobject import CoastalSiteGroundObject
from gen.sam.group_generator import GroupGenerator from gen.sam.group_generator import VehicleGroupGenerator
class SilkwormGenerator(GroupGenerator[VehicleGroup]): class SilkwormGenerator(VehicleGroupGenerator[CoastalSiteGroundObject]):
def __init__( def __init__(
self, game: Game, ground_object: CoastalSiteGroundObject, faction: Faction self, game: Game, ground_object: CoastalSiteGroundObject, faction: Faction
) -> None: ) -> None:

View File

@ -1,14 +1,12 @@
import random import random
from dcs.unitgroup import VehicleGroup
from game import Game from game import Game
from game.dcs.groundunittype import GroundUnitType from game.dcs.groundunittype import GroundUnitType
from game.theater.theatergroundobject import VehicleGroupGroundObject from game.theater.theatergroundobject import VehicleGroupGroundObject
from gen.sam.group_generator import GroupGenerator from gen.sam.group_generator import VehicleGroupGenerator
class ArmoredGroupGenerator(GroupGenerator[VehicleGroup]): class ArmoredGroupGenerator(VehicleGroupGenerator[VehicleGroupGroundObject]):
def __init__( def __init__(
self, self,
game: Game, game: Game,
@ -37,7 +35,7 @@ class ArmoredGroupGenerator(GroupGenerator[VehicleGroup]):
) )
class FixedSizeArmorGroupGenerator(GroupGenerator[VehicleGroup]): class FixedSizeArmorGroupGenerator(VehicleGroupGenerator[VehicleGroupGroundObject]):
def __init__( def __init__(
self, self,
game: Game, game: Game,

View File

@ -3,7 +3,6 @@ from __future__ import annotations
import random import random
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from dcs.ships import ( from dcs.ships import (
Type_052C, Type_052C,
Type_052B, Type_052B,
@ -11,9 +10,9 @@ from dcs.ships import (
) )
from game.factions.faction import Faction from game.factions.faction import Faction
from game.theater.theatergroundobject import ShipGroundObject
from gen.fleet.dd_group import DDGroupGenerator from gen.fleet.dd_group import DDGroupGenerator
from gen.sam.group_generator import ShipGroupGenerator from gen.sam.group_generator import ShipGroupGenerator
from game.theater.theatergroundobject import TheaterGroundObject
if TYPE_CHECKING: if TYPE_CHECKING:
from game.game import Game from game.game import Game
@ -65,9 +64,7 @@ class ChineseNavyGroupGenerator(ShipGroupGenerator):
class Type54GroupGenerator(DDGroupGenerator): class Type54GroupGenerator(DDGroupGenerator):
def __init__( def __init__(self, game: Game, ground_object: ShipGroundObject, faction: Faction):
self, game: Game, ground_object: TheaterGroundObject, faction: Faction
):
super(Type54GroupGenerator, self).__init__( super(Type54GroupGenerator, self).__init__(
game, ground_object, faction, Type_054A game, ground_object, faction, Type_054A
) )

View File

@ -1,12 +1,13 @@
from __future__ import annotations from __future__ import annotations
from typing import TYPE_CHECKING, Type from typing import TYPE_CHECKING, Type
from game.factions.faction import Faction
from game.theater.theatergroundobject import TheaterGroundObject
from gen.sam.group_generator import ShipGroupGenerator
from dcs.unittype import ShipType
from dcs.ships import PERRY, USS_Arleigh_Burke_IIa from dcs.ships import PERRY, USS_Arleigh_Burke_IIa
from dcs.unittype import ShipType
from game.factions.faction import Faction
from game.theater.theatergroundobject import ShipGroundObject
from gen.sam.group_generator import ShipGroupGenerator
if TYPE_CHECKING: if TYPE_CHECKING:
from game.game import Game from game.game import Game
@ -16,7 +17,7 @@ class DDGroupGenerator(ShipGroupGenerator):
def __init__( def __init__(
self, self,
game: Game, game: Game,
ground_object: TheaterGroundObject, ground_object: ShipGroundObject,
faction: Faction, faction: Faction,
ddtype: Type[ShipType], ddtype: Type[ShipType],
): ):
@ -42,18 +43,14 @@ class DDGroupGenerator(ShipGroupGenerator):
class OliverHazardPerryGroupGenerator(DDGroupGenerator): class OliverHazardPerryGroupGenerator(DDGroupGenerator):
def __init__( def __init__(self, game: Game, ground_object: ShipGroundObject, faction: Faction):
self, game: Game, ground_object: TheaterGroundObject, faction: Faction
):
super(OliverHazardPerryGroupGenerator, self).__init__( super(OliverHazardPerryGroupGenerator, self).__init__(
game, ground_object, faction, PERRY game, ground_object, faction, PERRY
) )
class ArleighBurkeGroupGenerator(DDGroupGenerator): class ArleighBurkeGroupGenerator(DDGroupGenerator):
def __init__( def __init__(self, game: Game, ground_object: ShipGroundObject, faction: Faction):
self, game: Game, ground_object: TheaterGroundObject, faction: Faction
):
super(ArleighBurkeGroupGenerator, self).__init__( super(ArleighBurkeGroupGenerator, self).__init__(
game, ground_object, faction, USS_Arleigh_Burke_IIa game, ground_object, faction, USS_Arleigh_Burke_IIa
) )

View File

@ -2,14 +2,12 @@ from dcs.ships import La_Combattante_II
from game import Game from game import Game
from game.factions.faction import Faction from game.factions.faction import Faction
from game.theater import TheaterGroundObject from game.theater.theatergroundobject import ShipGroundObject
from gen.fleet.dd_group import DDGroupGenerator from gen.fleet.dd_group import DDGroupGenerator
class LaCombattanteIIGroupGenerator(DDGroupGenerator): class LaCombattanteIIGroupGenerator(DDGroupGenerator):
def __init__( def __init__(self, game: Game, ground_object: ShipGroundObject, faction: Faction):
self, game: Game, ground_object: TheaterGroundObject, faction: Faction
):
super(LaCombattanteIIGroupGenerator, self).__init__( super(LaCombattanteIIGroupGenerator, self).__init__(
game, ground_object, faction, La_Combattante_II game, ground_object, faction, La_Combattante_II
) )

View File

@ -1,4 +1,5 @@
from __future__ import annotations from __future__ import annotations
import random import random
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
@ -12,11 +13,10 @@ from dcs.ships import (
SOM, SOM,
) )
from game.factions.faction import Faction
from game.theater.theatergroundobject import ShipGroundObject
from gen.fleet.dd_group import DDGroupGenerator from gen.fleet.dd_group import DDGroupGenerator
from gen.sam.group_generator import ShipGroupGenerator from gen.sam.group_generator import ShipGroupGenerator
from game.factions.faction import Faction
from game.theater.theatergroundobject import TheaterGroundObject
if TYPE_CHECKING: if TYPE_CHECKING:
from game.game import Game from game.game import Game
@ -85,32 +85,24 @@ class RussianNavyGroupGenerator(ShipGroupGenerator):
class GrishaGroupGenerator(DDGroupGenerator): class GrishaGroupGenerator(DDGroupGenerator):
def __init__( def __init__(self, game: Game, ground_object: ShipGroundObject, faction: Faction):
self, game: Game, ground_object: TheaterGroundObject, faction: Faction
):
super(GrishaGroupGenerator, self).__init__( super(GrishaGroupGenerator, self).__init__(
game, ground_object, faction, ALBATROS game, ground_object, faction, ALBATROS
) )
class MolniyaGroupGenerator(DDGroupGenerator): class MolniyaGroupGenerator(DDGroupGenerator):
def __init__( def __init__(self, game: Game, ground_object: ShipGroundObject, faction: Faction):
self, game: Game, ground_object: TheaterGroundObject, faction: Faction
):
super(MolniyaGroupGenerator, self).__init__( super(MolniyaGroupGenerator, self).__init__(
game, ground_object, faction, MOLNIYA game, ground_object, faction, MOLNIYA
) )
class KiloSubGroupGenerator(DDGroupGenerator): class KiloSubGroupGenerator(DDGroupGenerator):
def __init__( def __init__(self, game: Game, ground_object: ShipGroundObject, faction: Faction):
self, game: Game, ground_object: TheaterGroundObject, faction: Faction
):
super(KiloSubGroupGenerator, self).__init__(game, ground_object, faction, KILO) super(KiloSubGroupGenerator, self).__init__(game, ground_object, faction, KILO)
class TangoSubGroupGenerator(DDGroupGenerator): class TangoSubGroupGenerator(DDGroupGenerator):
def __init__( def __init__(self, game: Game, ground_object: ShipGroundObject, faction: Faction):
self, game: Game, ground_object: TheaterGroundObject, faction: Faction
):
super(TangoSubGroupGenerator, self).__init__(game, ground_object, faction, SOM) super(TangoSubGroupGenerator, self).__init__(game, ground_object, faction, SOM)

View File

@ -18,6 +18,7 @@ from typing import (
TYPE_CHECKING, TYPE_CHECKING,
Tuple, Tuple,
TypeVar, TypeVar,
Any,
) )
from game.dcs.aircrafttype import AircraftType from game.dcs.aircrafttype import AircraftType
@ -284,7 +285,7 @@ class ObjectiveFinder:
self.game = game self.game = game
self.is_player = is_player self.is_player = is_player
def enemy_air_defenses(self) -> Iterator[tuple[TheaterGroundObject, Distance]]: def enemy_air_defenses(self) -> Iterator[tuple[TheaterGroundObject[Any], Distance]]:
"""Iterates over all enemy SAM sites.""" """Iterates over all enemy SAM sites."""
doctrine = self.game.faction_for(self.is_player).doctrine doctrine = self.game.faction_for(self.is_player).doctrine
threat_zones = self.game.threat_zone_for(not self.is_player) threat_zones = self.game.threat_zone_for(not self.is_player)
@ -314,14 +315,14 @@ class ObjectiveFinder:
yield ground_object, target_range yield ground_object, target_range
def threatening_air_defenses(self) -> Iterator[TheaterGroundObject]: def threatening_air_defenses(self) -> Iterator[TheaterGroundObject[Any]]:
"""Iterates over enemy SAMs in threat range of friendly control points. """Iterates over enemy SAMs in threat range of friendly control points.
SAM sites are sorted by their closest proximity to any friendly control SAM sites are sorted by their closest proximity to any friendly control
point (airfield or fleet). point (airfield or fleet).
""" """
target_ranges: list[tuple[TheaterGroundObject, Distance]] = [] target_ranges: list[tuple[TheaterGroundObject[Any], Distance]] = []
for target, threat_range in self.enemy_air_defenses(): for target, threat_range in self.enemy_air_defenses():
ranges: list[Distance] = [] ranges: list[Distance] = []
for cp in self.friendly_control_points(): for cp in self.friendly_control_points():
@ -385,13 +386,13 @@ class ObjectiveFinder:
for target, _range in target_ranges: for target, _range in target_ranges:
yield target yield target
def strike_targets(self) -> Iterator[TheaterGroundObject]: def strike_targets(self) -> Iterator[TheaterGroundObject[Any]]:
"""Iterates over enemy strike targets. """Iterates over enemy strike targets.
Targets are sorted by their closest proximity to any friendly control Targets are sorted by their closest proximity to any friendly control
point (airfield or fleet). point (airfield or fleet).
""" """
targets: List[Tuple[TheaterGroundObject, int]] = [] targets: List[Tuple[TheaterGroundObject[Any], int]] = []
# Building objectives are made of several individual TGOs (one per # Building objectives are made of several individual TGOs (one per
# building). # building).
found_targets: Set[str] = set() found_targets: Set[str] = set()

View File

@ -1130,7 +1130,7 @@ class FlightPlanBuilder:
) )
@staticmethod @staticmethod
def anti_ship_targets_for_tgo(tgo: TheaterGroundObject) -> List[StrikeTarget]: def anti_ship_targets_for_tgo(tgo: NavalGroundObject) -> List[StrikeTarget]:
return [StrikeTarget(f"{g.name} at {tgo.name}", g) for g in tgo.groups] return [StrikeTarget(f"{g.name} at {tgo.name}", g) for g in tgo.groups]
def generate_anti_ship(self, flight: Flight) -> StrikeFlightPlan: def generate_anti_ship(self, flight: Flight) -> StrikeFlightPlan:

View File

@ -10,6 +10,7 @@ from typing import (
TYPE_CHECKING, TYPE_CHECKING,
Tuple, Tuple,
Union, Union,
Any,
) )
from dcs.mapping import Point from dcs.mapping import Point
@ -33,7 +34,9 @@ from .flight import Flight, FlightWaypoint, FlightWaypointType
@dataclass(frozen=True) @dataclass(frozen=True)
class StrikeTarget: class StrikeTarget:
name: str name: str
target: Union[VehicleGroup, TheaterGroundObject, Unit, Group, MultiGroupTransport] target: Union[
VehicleGroup, TheaterGroundObject[Any], Unit, Group, MultiGroupTransport
]
class WaypointBuilder: class WaypointBuilder:

View File

@ -9,7 +9,17 @@ from __future__ import annotations
import logging import logging
import random import random
from typing import Dict, Iterator, Optional, TYPE_CHECKING, Type, List from typing import (
Dict,
Iterator,
Optional,
TYPE_CHECKING,
Type,
List,
TypeVar,
Any,
Generic,
)
from dcs import Mission, Point, unitgroup from dcs import Mission, Point, unitgroup
from dcs.action import SceneryDestructionZone from dcs.action import SceneryDestructionZone
@ -56,7 +66,10 @@ FARP_FRONTLINE_DISTANCE = 10000
AA_CP_MIN_DISTANCE = 40000 AA_CP_MIN_DISTANCE = 40000
class GenericGroundObjectGenerator: TgoT = TypeVar("TgoT", bound=TheaterGroundObject[Any])
class GenericGroundObjectGenerator(Generic[TgoT]):
"""An unspecialized ground object generator. """An unspecialized ground object generator.
Currently used only for SAM Currently used only for SAM
@ -64,7 +77,7 @@ class GenericGroundObjectGenerator:
def __init__( def __init__(
self, self,
ground_object: TheaterGroundObject, ground_object: TgoT,
country: Country, country: Country,
game: Game, game: Game,
mission: Mission, mission: Mission,
@ -133,7 +146,7 @@ class GenericGroundObjectGenerator:
) )
class MissileSiteGenerator(GenericGroundObjectGenerator): class MissileSiteGenerator(GenericGroundObjectGenerator[MissileSiteGroundObject]):
@property @property
def culled(self) -> bool: def culled(self) -> bool:
# Don't cull missile sites - their range is long enough to make them easily # Don't cull missile sites - their range is long enough to make them easily
@ -196,7 +209,7 @@ class MissileSiteGenerator(GenericGroundObjectGenerator):
return site_range return site_range
class BuildingSiteGenerator(GenericGroundObjectGenerator): class BuildingSiteGenerator(GenericGroundObjectGenerator[BuildingGroundObject]):
"""Generator for building sites. """Generator for building sites.
Building sites are the primary type of non-airbase objective locations that Building sites are the primary type of non-airbase objective locations that
@ -324,7 +337,7 @@ class SceneryGenerator(BuildingSiteGenerator):
self.unit_map.add_scenery(scenery) self.unit_map.add_scenery(scenery)
class GenericCarrierGenerator(GenericGroundObjectGenerator): class GenericCarrierGenerator(GenericGroundObjectGenerator[GenericCarrierGroundObject]):
"""Base type for carrier group generation. """Base type for carrier group generation.
Used by both CV(N) groups and LHA groups. Used by both CV(N) groups and LHA groups.
@ -518,7 +531,7 @@ class LhaGenerator(GenericCarrierGenerator):
) )
class ShipObjectGenerator(GenericGroundObjectGenerator): class ShipObjectGenerator(GenericGroundObjectGenerator[ShipGroundObject]):
"""Generator for non-carrier naval groups.""" """Generator for non-carrier naval groups."""
def generate(self) -> None: def generate(self) -> None:
@ -637,7 +650,7 @@ class GroundObjectsGenerator:
).generate() ).generate()
for ground_object in cp.ground_objects: for ground_object in cp.ground_objects:
generator: GenericGroundObjectGenerator generator: GenericGroundObjectGenerator[Any]
if isinstance(ground_object, FactoryGroundObject): if isinstance(ground_object, FactoryGroundObject):
generator = FactoryGenerator( generator = FactoryGenerator(
ground_object, country, self.game, self.m, self.unit_map ground_object, country, self.game, self.m, self.unit_map

View File

@ -1,15 +1,14 @@
import random import random
from dcs.unitgroup import VehicleGroup
from dcs.vehicles import Unarmed, MissilesSS, AirDefence from dcs.vehicles import Unarmed, MissilesSS, AirDefence
from game import Game from game import Game
from game.factions.faction import Faction from game.factions.faction import Faction
from game.theater.theatergroundobject import MissileSiteGroundObject from game.theater.theatergroundobject import MissileSiteGroundObject
from gen.sam.group_generator import GroupGenerator from gen.sam.group_generator import VehicleGroupGenerator
class ScudGenerator(GroupGenerator[VehicleGroup]): class ScudGenerator(VehicleGroupGenerator[MissileSiteGroundObject]):
def __init__( def __init__(
self, game: Game, ground_object: MissileSiteGroundObject, faction: Faction self, game: Game, ground_object: MissileSiteGroundObject, faction: Faction
) -> None: ) -> None:

View File

@ -1,15 +1,14 @@
import random import random
from dcs.unitgroup import VehicleGroup
from dcs.vehicles import Unarmed, MissilesSS, AirDefence from dcs.vehicles import Unarmed, MissilesSS, AirDefence
from game import Game from game import Game
from game.factions.faction import Faction from game.factions.faction import Faction
from game.theater.theatergroundobject import MissileSiteGroundObject from game.theater.theatergroundobject import MissileSiteGroundObject
from gen.sam.group_generator import GroupGenerator from gen.sam.group_generator import VehicleGroupGenerator
class V1GroupGenerator(GroupGenerator[VehicleGroup]): class V1GroupGenerator(VehicleGroupGenerator[MissileSiteGroundObject]):
def __init__( def __init__(
self, game: Game, ground_object: MissileSiteGroundObject, faction: Faction self, game: Game, ground_object: MissileSiteGroundObject, faction: Faction
) -> None: ) -> None:

View File

@ -8,7 +8,7 @@ from dcs.unitgroup import VehicleGroup
from game import Game from game import Game
from game.theater.theatergroundobject import SamGroundObject from game.theater.theatergroundobject import SamGroundObject
from gen.sam.group_generator import GroupGenerator from gen.sam.group_generator import VehicleGroupGenerator
class SkynetRole(Enum): class SkynetRole(Enum):
@ -38,7 +38,7 @@ class AirDefenseRange(Enum):
self.default_role = default_role self.default_role = default_role
class AirDefenseGroupGenerator(GroupGenerator[VehicleGroup], ABC): class AirDefenseGroupGenerator(VehicleGroupGenerator[SamGroundObject], ABC):
""" """
This is the base for all SAM group generators This is the base for all SAM group generators
""" """

View File

@ -1,13 +1,13 @@
from typing import Type from typing import Type
from dcs.unitgroup import VehicleGroup
from dcs.vehicles import AirDefence
from dcs.unittype import VehicleType from dcs.unittype import VehicleType
from dcs.vehicles import AirDefence
from gen.sam.group_generator import GroupGenerator from game.theater.theatergroundobject import EwrGroundObject
from gen.sam.group_generator import VehicleGroupGenerator
class EwrGenerator(GroupGenerator[VehicleGroup]): class EwrGenerator(VehicleGroupGenerator[EwrGroundObject]):
unit_type: Type[VehicleType] unit_type: Type[VehicleType]
@classmethod @classmethod

View File

@ -4,24 +4,27 @@ import logging
import math import math
import random import random
from collections import Iterable from collections import Iterable
from typing import TYPE_CHECKING, Type, TypeVar, Generic from typing import TYPE_CHECKING, Type, TypeVar, Generic, Any
from dcs import unitgroup from dcs import unitgroup
from dcs.mapping import Point from dcs.mapping import Point
from dcs.point import PointAction from dcs.point import PointAction
from dcs.unit import Ship, Vehicle from dcs.unit import Ship, Vehicle, Unit
from dcs.unitgroup import MovingGroup, ShipGroup from dcs.unitgroup import ShipGroup, VehicleGroup
from dcs.unittype import VehicleType, UnitType from dcs.unittype import VehicleType, UnitType, ShipType
from game.dcs.groundunittype import GroundUnitType from game.dcs.groundunittype import GroundUnitType
from game.factions.faction import Faction from game.factions.faction import Faction
from game.theater.theatergroundobject import TheaterGroundObject from game.theater.theatergroundobject import TheaterGroundObject, NavalGroundObject
if TYPE_CHECKING: if TYPE_CHECKING:
from game.game import Game from game.game import Game
GroupType = TypeVar("GroupType", bound=MovingGroup) GroupT = TypeVar("GroupT", VehicleGroup, ShipGroup)
UnitT = TypeVar("UnitT", bound=Unit)
UnitTypeT = TypeVar("UnitTypeT", bound=Type[UnitType])
TgoT = TypeVar("TgoT", bound=TheaterGroundObject[Any])
# TODO: Generate a group description rather than a pydcs group. # TODO: Generate a group description rather than a pydcs group.
@ -29,41 +32,62 @@ GroupType = TypeVar("GroupType", bound=MovingGroup)
# groundobjectsgen for an example). We can do less work and include the data we # groundobjectsgen for an example). We can do less work and include the data we
# care about in the format we want if we just generate our own group description # care about in the format we want if we just generate our own group description
# types rather than pydcs groups. # types rather than pydcs groups.
class GroupGenerator(Generic[GroupType]): class GroupGenerator(Generic[GroupT, UnitT, UnitTypeT, TgoT]):
def __init__(self, game: Game, ground_object: TgoT, group: GroupT) -> None:
price: int
def __init__(self, game: Game, ground_object: TheaterGroundObject) -> None:
self.game = game self.game = game
self.go = ground_object self.go = ground_object
self.position = ground_object.position self.position = ground_object.position
self.heading = random.randint(0, 359) self.heading = random.randint(0, 359)
self.price = 0 self.price = 0
self.vg = unitgroup.VehicleGroup(self.game.next_group_id(), self.go.group_name) self.vg: GroupT = group
wp = self.vg.add_waypoint(self.position, PointAction.OffRoad, 0)
wp.ETA_locked = True
def generate(self) -> None: def generate(self) -> None:
raise NotImplementedError raise NotImplementedError
def get_generated_group(self) -> GroupType: def get_generated_group(self) -> GroupT:
return self.vg return self.vg
def add_unit( def add_unit(
self, self,
unit_type: Type[VehicleType], unit_type: UnitTypeT,
name: str, name: str,
pos_x: float, pos_x: float,
pos_y: float, pos_y: float,
heading: int, heading: int,
) -> Vehicle: ) -> UnitT:
return self.add_unit_to_group( return self.add_unit_to_group(
self.vg, unit_type, name, Point(pos_x, pos_y), heading self.vg, unit_type, name, Point(pos_x, pos_y), heading
) )
def add_unit_to_group( def add_unit_to_group(
self, self,
group: GroupType, group: GroupT,
unit_type: UnitTypeT,
name: str,
position: Point,
heading: int,
) -> UnitT:
raise NotImplementedError
class VehicleGroupGenerator(
Generic[TgoT], GroupGenerator[VehicleGroup, Vehicle, Type[VehicleType], TgoT]
):
def __init__(self, game: Game, ground_object: TgoT) -> None:
super().__init__(
game,
ground_object,
unitgroup.VehicleGroup(self.game.next_group_id(), self.go.group_name),
)
wp = self.vg.add_waypoint(self.position, PointAction.OffRoad, 0)
wp.ETA_locked = True
def generate(self) -> None:
raise NotImplementedError
def add_unit_to_group(
self,
group: VehicleGroup,
unit_type: Type[VehicleType], unit_type: Type[VehicleType],
name: str, name: str,
position: Point, position: Point,
@ -124,32 +148,34 @@ class GroupGenerator(Generic[GroupType]):
return positions return positions
class ShipGroupGenerator(GroupGenerator[ShipGroup]): class ShipGroupGenerator(
GroupGenerator[ShipGroup, Ship, Type[ShipType], NavalGroundObject]
):
"""Abstract class for other ship generator classes""" """Abstract class for other ship generator classes"""
def __init__( def __init__(self, game: Game, ground_object: NavalGroundObject, faction: Faction):
self, game: Game, ground_object: TheaterGroundObject, faction: Faction super().__init__(
): game,
self.game = game ground_object,
self.go = ground_object unitgroup.ShipGroup(self.game.next_group_id(), self.go.group_name),
self.position = ground_object.position )
self.heading = random.randint(0, 359)
self.faction = faction self.faction = faction
self.vg = unitgroup.ShipGroup(self.game.next_group_id(), self.go.group_name)
wp = self.vg.add_waypoint(self.position, 0) wp = self.vg.add_waypoint(self.position, 0)
wp.ETA_locked = True wp.ETA_locked = True
def add_unit( def generate(self) -> None:
raise NotImplementedError
def add_unit_to_group(
self, self,
unit_type: Type[UnitType], group: ShipGroup,
unit_type: Type[ShipType],
name: str, name: str,
pos_x: float, position: Point,
pos_y: float,
heading: int, heading: int,
) -> Ship: ) -> Ship:
unit = Ship(self.game.next_unit_id(), f"{self.go.group_name}|{name}", unit_type) unit = Ship(self.game.next_unit_id(), f"{self.go.group_name}|{name}", unit_type)
unit.position.x = pos_x unit.position = position
unit.position.y = pos_y
unit.heading = heading unit.heading = heading
self.vg.add_unit(unit) group.add_unit(unit)
return unit return unit

View File

@ -1,4 +1,7 @@
from typing import Type
from dcs.mapping import Point from dcs.mapping import Point
from dcs.unittype import VehicleType
from dcs.vehicles import AirDefence from dcs.vehicles import AirDefence
from game import Game from game import Game
@ -20,13 +23,13 @@ class SA10Generator(AirDefenseGroupGenerator):
def __init__(self, game: Game, ground_object: SamGroundObject): def __init__(self, game: Game, ground_object: SamGroundObject):
super().__init__(game, ground_object) super().__init__(game, ground_object)
self.sr1 = AirDefence.S_300PS_40B6MD_sr self.sr1: Type[VehicleType] = AirDefence.S_300PS_40B6MD_sr
self.sr2 = AirDefence.S_300PS_64H6E_sr self.sr2: Type[VehicleType] = AirDefence.S_300PS_64H6E_sr
self.cp = AirDefence.S_300PS_54K6_cp self.cp: Type[VehicleType] = AirDefence.S_300PS_54K6_cp
self.tr1 = AirDefence.S_300PS_40B6M_tr self.tr1: Type[VehicleType] = AirDefence.S_300PS_40B6M_tr
self.tr2 = AirDefence.S_300PS_40B6M_tr self.tr2: Type[VehicleType] = AirDefence.S_300PS_40B6M_tr
self.ln1 = AirDefence.S_300PS_5P85C_ln self.ln1: Type[VehicleType] = AirDefence.S_300PS_5P85C_ln
self.ln2 = AirDefence.S_300PS_5P85D_ln self.ln2: Type[VehicleType] = AirDefence.S_300PS_5P85D_ln
def generate(self) -> None: def generate(self) -> None:
# Search Radar # Search Radar