mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Build a proper type for StartType.
This commit is contained in:
parent
be69d17345
commit
b0787d9a3f
@ -1,6 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from typing import Optional, List, TYPE_CHECKING
|
from datetime import datetime, timedelta
|
||||||
|
from typing import Any, Optional, List, TYPE_CHECKING
|
||||||
|
|
||||||
from gen.flights.loadouts import Loadout
|
from gen.flights.loadouts import Loadout
|
||||||
|
|
||||||
@ -14,6 +15,7 @@ if TYPE_CHECKING:
|
|||||||
from .flighttype import FlightType
|
from .flighttype import FlightType
|
||||||
from .flightwaypoint import FlightWaypoint
|
from .flightwaypoint import FlightWaypoint
|
||||||
from .package import Package
|
from .package import Package
|
||||||
|
from .starttype import StartType
|
||||||
|
|
||||||
|
|
||||||
class Flight:
|
class Flight:
|
||||||
@ -24,7 +26,7 @@ class Flight:
|
|||||||
squadron: Squadron,
|
squadron: Squadron,
|
||||||
count: int,
|
count: int,
|
||||||
flight_type: FlightType,
|
flight_type: FlightType,
|
||||||
start_type: str,
|
start_type: StartType,
|
||||||
divert: Optional[ControlPoint],
|
divert: Optional[ControlPoint],
|
||||||
custom_name: Optional[str] = None,
|
custom_name: Optional[str] = None,
|
||||||
cargo: Optional[TransferOrder] = None,
|
cargo: Optional[TransferOrder] = None,
|
||||||
|
|||||||
15
game/ato/starttype.py
Normal file
15
game/ato/starttype.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
from enum import Enum, unique
|
||||||
|
|
||||||
|
|
||||||
|
@unique
|
||||||
|
class StartType(Enum):
|
||||||
|
"""The start type for a Flight.
|
||||||
|
|
||||||
|
This is distinct from dcs.mission.StartType because we need a fourth state:
|
||||||
|
IN_FLIGHT.
|
||||||
|
"""
|
||||||
|
|
||||||
|
IN_FLIGHT = "In Flight"
|
||||||
|
RUNWAY = "Runway"
|
||||||
|
COLD = "Cold"
|
||||||
|
WARM = "Warm"
|
||||||
@ -6,6 +6,7 @@ from game.utils import nautical_miles
|
|||||||
from ..ato.package import Package
|
from ..ato.package import Package
|
||||||
from game.theater import MissionTarget, OffMapSpawn, ControlPoint
|
from game.theater import MissionTarget, OffMapSpawn, ControlPoint
|
||||||
from ..ato.flight import Flight
|
from ..ato.flight import Flight
|
||||||
|
from ..ato.starttype import StartType
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from game.dcs.aircrafttype import AircraftType
|
from game.dcs.aircrafttype import AircraftType
|
||||||
@ -24,7 +25,7 @@ class PackageBuilder:
|
|||||||
air_wing: AirWing,
|
air_wing: AirWing,
|
||||||
is_player: bool,
|
is_player: bool,
|
||||||
package_country: str,
|
package_country: str,
|
||||||
start_type: str,
|
start_type: StartType,
|
||||||
asap: bool,
|
asap: bool,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.closest_airfields = closest_airfields
|
self.closest_airfields = closest_airfields
|
||||||
|
|||||||
@ -13,6 +13,7 @@ from .choicesoption import choices_option
|
|||||||
from .minutesoption import minutes_option
|
from .minutesoption import minutes_option
|
||||||
from .optiondescription import OptionDescription, SETTING_DESCRIPTION_KEY
|
from .optiondescription import OptionDescription, SETTING_DESCRIPTION_KEY
|
||||||
from .skilloption import skill_option
|
from .skilloption import skill_option
|
||||||
|
from ..ato.starttype import StartType
|
||||||
|
|
||||||
|
|
||||||
@unique
|
@unique
|
||||||
@ -323,12 +324,12 @@ class Settings:
|
|||||||
"option only allows the player to wait on the ground.</strong>"
|
"option only allows the player to wait on the ground.</strong>"
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
default_start_type: str = choices_option(
|
default_start_type: StartType = choices_option(
|
||||||
"Default start type for AI aircraft",
|
"Default start type for AI aircraft",
|
||||||
page=MISSION_GENERATOR_PAGE,
|
page=MISSION_GENERATOR_PAGE,
|
||||||
section=GAMEPLAY_SECTION,
|
section=GAMEPLAY_SECTION,
|
||||||
choices=["Cold", "Warm", "Runway", "In Flight"],
|
choices={v.value: v for v in StartType},
|
||||||
default="Cold",
|
default=StartType.COLD,
|
||||||
detail=(
|
detail=(
|
||||||
"Warning: Options other than Cold will significantly reduce the number of "
|
"Warning: Options other than Cold will significantly reduce the number of "
|
||||||
"targets available for OCA/Aircraft missions, and OCA/Aircraft flights "
|
"targets available for OCA/Aircraft missions, and OCA/Aircraft flights "
|
||||||
|
|||||||
@ -49,6 +49,7 @@ from .theatergroundobject import (
|
|||||||
TheaterGroundObject,
|
TheaterGroundObject,
|
||||||
BuildingGroundObject,
|
BuildingGroundObject,
|
||||||
)
|
)
|
||||||
|
from ..ato.starttype import StartType
|
||||||
from ..dcs.aircrafttype import AircraftType
|
from ..dcs.aircrafttype import AircraftType
|
||||||
from ..dcs.groundunittype import GroundUnitType
|
from ..dcs.groundunittype import GroundUnitType
|
||||||
from ..utils import nautical_miles
|
from ..utils import nautical_miles
|
||||||
@ -681,7 +682,7 @@ class ControlPoint(MissionTarget, ABC):
|
|||||||
self.base.set_strength_to_minimum()
|
self.base.set_strength_to_minimum()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def required_aircraft_start_type(self) -> Optional[str]:
|
def required_aircraft_start_type(self) -> Optional[StartType]:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@ -1151,8 +1152,8 @@ class OffMapSpawn(ControlPoint):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def required_aircraft_start_type(self) -> Optional[str]:
|
def required_aircraft_start_type(self) -> Optional[StartType]:
|
||||||
return "In Flight"
|
return StartType.IN_FLIGHT
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def heading(self) -> Heading:
|
def heading(self) -> Heading:
|
||||||
|
|||||||
@ -5,17 +5,16 @@ import logging
|
|||||||
import random
|
import random
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Optional, TYPE_CHECKING, Any
|
from typing import Optional, TYPE_CHECKING
|
||||||
|
|
||||||
from dcs.cloud_presets import Clouds as PydcsClouds
|
from dcs.cloud_presets import Clouds as PydcsClouds
|
||||||
from dcs.weather import CloudPreset, Weather as PydcsWeather, Wind
|
from dcs.weather import CloudPreset, Weather as PydcsWeather, Wind
|
||||||
|
|
||||||
from game.settings import Settings
|
|
||||||
from game.utils import Distance, Heading, meters, interpolate, Pressure, inches_hg
|
from game.utils import Distance, Heading, meters, interpolate, Pressure, inches_hg
|
||||||
|
|
||||||
from game.theater.seasonalconditions import determine_season
|
from game.theater.seasonalconditions import determine_season
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
from game.settings import Settings
|
||||||
from game.theater import ConflictTheater
|
from game.theater import ConflictTheater
|
||||||
from game.theater.seasonalconditions import SeasonalConditions
|
from game.theater.seasonalconditions import SeasonalConditions
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ from dcs.condition import CoalitionHasAirdrome, TimeAfter
|
|||||||
from dcs.country import Country
|
from dcs.country import Country
|
||||||
from dcs.flyingunit import FlyingUnit
|
from dcs.flyingunit import FlyingUnit
|
||||||
from dcs.mapping import Point
|
from dcs.mapping import Point
|
||||||
from dcs.mission import Mission, StartType
|
from dcs.mission import Mission, StartType as DcsStartType
|
||||||
from dcs.planes import (
|
from dcs.planes import (
|
||||||
AJS37,
|
AJS37,
|
||||||
B_17G,
|
B_17G,
|
||||||
@ -67,6 +67,7 @@ from dcs.unitgroup import FlyingGroup, ShipGroup, StaticGroup
|
|||||||
from dcs.unittype import FlyingType
|
from dcs.unittype import FlyingType
|
||||||
|
|
||||||
from game import db
|
from game import db
|
||||||
|
from game.ato.starttype import StartType
|
||||||
from game.data.weapons import Pylon, WeaponType as WeaponTypeEnum
|
from game.data.weapons import Pylon, WeaponType as WeaponTypeEnum
|
||||||
from game.dcs.aircrafttype import AircraftType
|
from game.dcs.aircrafttype import AircraftType
|
||||||
from game.factions.faction import Faction
|
from game.factions.faction import Faction
|
||||||
@ -258,19 +259,19 @@ class AircraftConflictGenerator:
|
|||||||
return total
|
return total
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _start_type(start_type: str) -> StartType:
|
def _start_type(start_type: str) -> DcsStartType:
|
||||||
if start_type == "Runway":
|
if start_type == "Runway":
|
||||||
return StartType.Runway
|
return DcsStartType.Runway
|
||||||
elif start_type == "Cold":
|
elif start_type == "Cold":
|
||||||
return StartType.Cold
|
return DcsStartType.Cold
|
||||||
return StartType.Warm
|
return DcsStartType.Warm
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _start_type_at_group(
|
def _start_type_at_group(
|
||||||
start_type: str,
|
start_type: str,
|
||||||
unit_type: Type[FlyingType],
|
unit_type: Type[FlyingType],
|
||||||
at: Union[ShipGroup, StaticGroup],
|
at: Union[ShipGroup, StaticGroup],
|
||||||
) -> StartType:
|
) -> DcsStartType:
|
||||||
group_units = at.units
|
group_units = at.units
|
||||||
# Setting Su-33s starting from the non-supercarrier Kuznetsov to take off from runway
|
# Setting Su-33s starting from the non-supercarrier Kuznetsov to take off from runway
|
||||||
# to work around a DCS AI issue preventing Su-33s from taking off when set to "Takeoff from ramp" (#1352)
|
# to work around a DCS AI issue preventing Su-33s from taking off when set to "Takeoff from ramp" (#1352)
|
||||||
@ -279,7 +280,7 @@ class AircraftConflictGenerator:
|
|||||||
and group_units[0] is not None
|
and group_units[0] is not None
|
||||||
and group_units[0].type == KUZNECOW.id
|
and group_units[0].type == KUZNECOW.id
|
||||||
):
|
):
|
||||||
return StartType.Runway
|
return DcsStartType.Runway
|
||||||
else:
|
else:
|
||||||
return AircraftConflictGenerator._start_type(start_type)
|
return AircraftConflictGenerator._start_type(start_type)
|
||||||
|
|
||||||
@ -490,7 +491,7 @@ class AircraftConflictGenerator:
|
|||||||
parking_slots=None,
|
parking_slots=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _generate_inflight(
|
def _generate_over_departure(
|
||||||
self, name: str, side: Country, flight: Flight, origin: ControlPoint
|
self, name: str, side: Country, flight: Flight, origin: ControlPoint
|
||||||
) -> FlyingGroup[Any]:
|
) -> FlyingGroup[Any]:
|
||||||
assert flight.count > 0
|
assert flight.count > 0
|
||||||
@ -652,7 +653,7 @@ class AircraftConflictGenerator:
|
|||||||
continue
|
continue
|
||||||
for flight in package.flights:
|
for flight in package.flights:
|
||||||
logging.info(f"Generating flight: {flight.unit_type}")
|
logging.info(f"Generating flight: {flight.unit_type}")
|
||||||
group = self.generate_planned_flight(flight.from_cp, country, flight)
|
group = self.generate_planned_flight(country, flight)
|
||||||
self.unit_map.add_aircraft(group, flight)
|
self.unit_map.add_aircraft(group, flight)
|
||||||
self.setup_flight_group(group, package, flight, dynamic_runways)
|
self.setup_flight_group(group, package, flight, dynamic_runways)
|
||||||
self.create_waypoints(group, package, flight)
|
self.create_waypoints(group, package, flight)
|
||||||
@ -691,7 +692,7 @@ class AircraftConflictGenerator:
|
|||||||
squadron,
|
squadron,
|
||||||
1,
|
1,
|
||||||
FlightType.BARCAP,
|
FlightType.BARCAP,
|
||||||
"Cold",
|
StartType.COLD,
|
||||||
divert=None,
|
divert=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -753,14 +754,14 @@ class AircraftConflictGenerator:
|
|||||||
coalition = self.game.coalition_for(flight.departure.captured).coalition_id
|
coalition = self.game.coalition_for(flight.departure.captured).coalition_id
|
||||||
trigger.add_condition(CoalitionHasAirdrome(coalition, flight.from_cp.id))
|
trigger.add_condition(CoalitionHasAirdrome(coalition, flight.from_cp.id))
|
||||||
|
|
||||||
def generate_planned_flight(
|
def generate_flight_at_departure(
|
||||||
self, cp: ControlPoint, country: Country, flight: Flight
|
self, country: Country, flight: Flight, start_type: StartType
|
||||||
) -> FlyingGroup[Any]:
|
) -> FlyingGroup[Any]:
|
||||||
name = namegen.next_aircraft_name(country, cp.id, flight)
|
name = namegen.next_aircraft_name(country, flight.departure.id, flight)
|
||||||
group: FlyingGroup[Any]
|
cp = flight.departure
|
||||||
try:
|
try:
|
||||||
if flight.start_type == "In Flight":
|
if start_type is StartType.IN_FLIGHT:
|
||||||
group = self._generate_inflight(
|
group = self._generate_over_departure(
|
||||||
name=name, side=country, flight=flight, origin=cp
|
name=name, side=country, flight=flight, origin=cp
|
||||||
)
|
)
|
||||||
return group
|
return group
|
||||||
@ -777,7 +778,7 @@ class AircraftConflictGenerator:
|
|||||||
side=country,
|
side=country,
|
||||||
unit_type=flight.unit_type.dcs_unit_type,
|
unit_type=flight.unit_type.dcs_unit_type,
|
||||||
count=flight.count,
|
count=flight.count,
|
||||||
start_type=flight.start_type,
|
start_type=start_type.value,
|
||||||
at=carrier_group,
|
at=carrier_group,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@ -788,7 +789,7 @@ class AircraftConflictGenerator:
|
|||||||
side=country,
|
side=country,
|
||||||
unit_type=flight.unit_type.dcs_unit_type,
|
unit_type=flight.unit_type.dcs_unit_type,
|
||||||
count=flight.count,
|
count=flight.count,
|
||||||
start_type=flight.start_type,
|
start_type=start_type.value,
|
||||||
cp=cp,
|
cp=cp,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -801,22 +802,26 @@ class AircraftConflictGenerator:
|
|||||||
side=country,
|
side=country,
|
||||||
unit_type=flight.unit_type.dcs_unit_type,
|
unit_type=flight.unit_type.dcs_unit_type,
|
||||||
count=flight.count,
|
count=flight.count,
|
||||||
start_type=flight.start_type,
|
start_type=start_type.value,
|
||||||
airport=cp.airport,
|
airport=cp.airport,
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except NoParkingSlotError:
|
||||||
# Generated when there is no place on Runway or on Parking Slots
|
# Generated when there is no place on Runway or on Parking Slots
|
||||||
logging.error(e)
|
logging.exception(
|
||||||
logging.warning(
|
|
||||||
"No room on runway or parking slots. Starting from the air."
|
"No room on runway or parking slots. Starting from the air."
|
||||||
)
|
)
|
||||||
flight.start_type = "In Flight"
|
flight.start_type = StartType.IN_FLIGHT
|
||||||
group = self._generate_inflight(
|
group = self._generate_over_departure(
|
||||||
name=name, side=country, flight=flight, origin=cp
|
name=name, side=country, flight=flight, origin=cp
|
||||||
)
|
)
|
||||||
group.points[0].alt = 1500
|
group.points[0].alt = 1500
|
||||||
return group
|
return group
|
||||||
|
|
||||||
|
def generate_planned_flight(
|
||||||
|
self, country: Country, flight: Flight
|
||||||
|
) -> FlyingGroup[Any]:
|
||||||
|
return self.generate_flight_at_departure(country, flight, flight.start_type)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def set_reduced_fuel(
|
def set_reduced_fuel(
|
||||||
flight: Flight, group: FlyingGroup[Any], unit_type: Type[FlyingType]
|
flight: Flight, group: FlyingGroup[Any], unit_type: Type[FlyingType]
|
||||||
@ -1360,7 +1365,7 @@ class AircraftConflictGenerator:
|
|||||||
# Late activation causes the aircraft to not be spawned
|
# Late activation causes the aircraft to not be spawned
|
||||||
# until triggered.
|
# until triggered.
|
||||||
self.set_activation_time(flight, group, start_time)
|
self.set_activation_time(flight, group, start_time)
|
||||||
elif flight.start_type == "Cold":
|
elif flight.start_type is StartType.COLD:
|
||||||
# Setting the start time causes the AI to wait until the
|
# Setting the start time causes the AI to wait until the
|
||||||
# specified time to begin their startup sequence.
|
# specified time to begin their startup sequence.
|
||||||
self.set_startup_time(flight, group, start_time)
|
self.set_startup_time(flight, group, start_time)
|
||||||
@ -1374,7 +1379,7 @@ class AircraftConflictGenerator:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def should_activate_late(flight: Flight) -> bool:
|
def should_activate_late(flight: Flight) -> bool:
|
||||||
if flight.start_type != "Cold":
|
if flight.start_type is StartType.COLD:
|
||||||
# Avoid spawning aircraft in the air or on the runway until it's
|
# Avoid spawning aircraft in the air or on the runway until it's
|
||||||
# time for their mission. Also avoid burning through gas spawning
|
# time for their mission. Also avoid burning through gas spawning
|
||||||
# hot aircraft hours before their takeoff time.
|
# hot aircraft hours before their takeoff time.
|
||||||
|
|||||||
@ -19,6 +19,7 @@ from dcs.mapping import Point
|
|||||||
from dcs.unit import Unit
|
from dcs.unit import Unit
|
||||||
from shapely.geometry import Point as ShapelyPoint
|
from shapely.geometry import Point as ShapelyPoint
|
||||||
|
|
||||||
|
from game.ato.starttype import StartType
|
||||||
from game.data.doctrine import Doctrine
|
from game.data.doctrine import Doctrine
|
||||||
from game.dcs.aircrafttype import FuelConsumption
|
from game.dcs.aircrafttype import FuelConsumption
|
||||||
from game.flightplan import IpZoneGeometry, JoinZoneGeometry, HoldZoneGeometry
|
from game.flightplan import IpZoneGeometry, JoinZoneGeometry, HoldZoneGeometry
|
||||||
@ -275,7 +276,7 @@ class FlightPlan:
|
|||||||
return start_time
|
return start_time
|
||||||
|
|
||||||
def estimate_startup(self) -> timedelta:
|
def estimate_startup(self) -> timedelta:
|
||||||
if self.flight.start_type == "Cold":
|
if self.flight.start_type is StartType.COLD:
|
||||||
if self.flight.client_count:
|
if self.flight.client_count:
|
||||||
return timedelta(minutes=10)
|
return timedelta(minutes=10)
|
||||||
else:
|
else:
|
||||||
@ -284,7 +285,7 @@ class FlightPlan:
|
|||||||
return timedelta()
|
return timedelta()
|
||||||
|
|
||||||
def estimate_ground_ops(self) -> timedelta:
|
def estimate_ground_ops(self) -> timedelta:
|
||||||
if self.flight.start_type in ("Runway", "In Flight"):
|
if self.flight.start_type in {StartType.RUNWAY, StartType.IN_FLIGHT}:
|
||||||
return timedelta()
|
return timedelta()
|
||||||
if self.flight.from_cp.is_fleet:
|
if self.flight.from_cp.is_fleet:
|
||||||
return timedelta(minutes=2)
|
return timedelta(minutes=2)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user