mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Fix mypy regressions.
Mostly in the plugin system, which needed a handful of asserts that shouldn't be necessary, but fixing them requires a refactor.
This commit is contained in:
parent
e9bfd58ee1
commit
c06a855113
@ -14,7 +14,7 @@ from dcs.translation import String
|
|||||||
from dcs.triggers import TriggerStart
|
from dcs.triggers import TriggerStart
|
||||||
from dcs.unittype import UnitType
|
from dcs.unittype import UnitType
|
||||||
|
|
||||||
from gen import Conflict, VisualGenerator, FlightType
|
from gen import Conflict, FlightType, VisualGenerator
|
||||||
from gen.aircraft import AIRCRAFT_DATA, AircraftConflictGenerator, FlightData
|
from gen.aircraft import AIRCRAFT_DATA, AircraftConflictGenerator, FlightData
|
||||||
from gen.airfields import AIRFIELD_DATA
|
from gen.airfields import AIRFIELD_DATA
|
||||||
from gen.airsupportgen import AirSupport, AirSupportConflictGenerator
|
from gen.airsupportgen import AirSupport, AirSupportConflictGenerator
|
||||||
@ -28,10 +28,11 @@ from gen.kneeboard import KneeboardGenerator
|
|||||||
from gen.radios import RadioFrequency, RadioRegistry
|
from gen.radios import RadioFrequency, RadioRegistry
|
||||||
from gen.tacan import TacanRegistry
|
from gen.tacan import TacanRegistry
|
||||||
from gen.triggergen import TRIGGER_RADIUS_MEDIUM, TriggersGenerator
|
from gen.triggergen import TRIGGER_RADIUS_MEDIUM, TriggersGenerator
|
||||||
|
from plugin import LuaPluginManager
|
||||||
from theater import ControlPoint
|
from theater import ControlPoint
|
||||||
from .. import db
|
from .. import db
|
||||||
from ..debriefing import Debriefing
|
from ..debriefing import Debriefing
|
||||||
from plugin import LuaPluginManager
|
|
||||||
|
|
||||||
class Operation:
|
class Operation:
|
||||||
attackers_starting_position = None # type: db.StartingPosition
|
attackers_starting_position = None # type: db.StartingPosition
|
||||||
@ -74,7 +75,7 @@ class Operation:
|
|||||||
self.departure_cp = departure_cp
|
self.departure_cp = departure_cp
|
||||||
self.to_cp = to_cp
|
self.to_cp = to_cp
|
||||||
self.is_quick = False
|
self.is_quick = False
|
||||||
self.listOfPluginsScripts = []
|
self.plugin_scripts: List[str] = []
|
||||||
|
|
||||||
def units_of(self, country_name: str) -> List[UnitType]:
|
def units_of(self, country_name: str) -> List[UnitType]:
|
||||||
return []
|
return []
|
||||||
@ -133,33 +134,37 @@ class Operation:
|
|||||||
else:
|
else:
|
||||||
self.defenders_starting_position = None
|
self.defenders_starting_position = None
|
||||||
|
|
||||||
def injectLuaTrigger(self, luascript, comment = "LUA script"):
|
def inject_lua_trigger(self, contents: str, comment: str) -> None:
|
||||||
trigger = TriggerStart(comment=comment)
|
trigger = TriggerStart(comment=comment)
|
||||||
trigger.add_action(DoScript(String(luascript)))
|
trigger.add_action(DoScript(String(contents)))
|
||||||
self.current_mission.triggerrules.triggers.append(trigger)
|
self.current_mission.triggerrules.triggers.append(trigger)
|
||||||
|
|
||||||
def bypassPluginScript(self, pluginName, scriptFileMnemonic):
|
def bypass_plugin_script(self, mnemonic: str) -> None:
|
||||||
self.listOfPluginsScripts.append(scriptFileMnemonic)
|
self.plugin_scripts.append(mnemonic)
|
||||||
|
|
||||||
def injectPluginScript(self, pluginName, scriptFile, scriptFileMnemonic):
|
def inject_plugin_script(self, plugin_mnemonic: str, script: str,
|
||||||
if not scriptFileMnemonic in self.listOfPluginsScripts:
|
script_mnemonic: str) -> None:
|
||||||
self.listOfPluginsScripts.append(scriptFileMnemonic)
|
if script_mnemonic in self.plugin_scripts:
|
||||||
|
logging.debug(
|
||||||
|
f"Skipping already loaded {script} for {plugin_mnemonic}"
|
||||||
|
)
|
||||||
|
|
||||||
plugin_path = Path("./resources/plugins",pluginName)
|
self.plugin_scripts.append(script_mnemonic)
|
||||||
|
|
||||||
if scriptFile != None:
|
plugin_path = Path("./resources/plugins", plugin_mnemonic)
|
||||||
scriptFile_path = Path(plugin_path, scriptFile)
|
|
||||||
if scriptFile_path.exists():
|
|
||||||
trigger = TriggerStart(comment="Load " + scriptFileMnemonic)
|
|
||||||
filename = scriptFile_path.resolve()
|
|
||||||
fileref = self.current_mission.map_resource.add_resource_file(filename)
|
|
||||||
trigger.add_action(DoScriptFile(fileref))
|
|
||||||
self.current_mission.triggerrules.triggers.append(trigger)
|
|
||||||
else:
|
|
||||||
logging.error(f"Cannot find script file {scriptFile} for plugin {pluginName}")
|
|
||||||
|
|
||||||
else:
|
script_path = Path(plugin_path, script)
|
||||||
logging.debug(f"Skipping script file {scriptFile} for plugin {pluginName}")
|
if not script_path.exists():
|
||||||
|
logging.error(
|
||||||
|
f"Cannot find {script_path} for plugin {plugin_mnemonic}"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
trigger = TriggerStart(comment=f"Load {script_mnemonic}")
|
||||||
|
filename = script_path.resolve()
|
||||||
|
fileref = self.current_mission.map_resource.add_resource_file(filename)
|
||||||
|
trigger.add_action(DoScriptFile(fileref))
|
||||||
|
self.current_mission.triggerrules.triggers.append(trigger)
|
||||||
|
|
||||||
def generate(self):
|
def generate(self):
|
||||||
radio_registry = RadioRegistry()
|
radio_registry = RadioRegistry()
|
||||||
@ -334,7 +339,7 @@ class Operation:
|
|||||||
kneeboard_generator.add_flight(flight)
|
kneeboard_generator.add_flight(flight)
|
||||||
if flight.friendly and flight.flight_type in [FlightType.ANTISHIP, FlightType.DEAD, FlightType.SEAD, FlightType.STRIKE]:
|
if flight.friendly and flight.flight_type in [FlightType.ANTISHIP, FlightType.DEAD, FlightType.SEAD, FlightType.STRIKE]:
|
||||||
flightType = flight.flight_type.name
|
flightType = flight.flight_type.name
|
||||||
flightTarget = flight.targetPoint
|
flightTarget = flight.package.target
|
||||||
if flightTarget:
|
if flightTarget:
|
||||||
flightTargetName = None
|
flightTargetName = None
|
||||||
flightTargetType = None
|
flightTargetType = None
|
||||||
@ -453,8 +458,6 @@ dcsLiberation.TargetPoints = {
|
|||||||
self.current_mission.triggerrules.triggers.append(trigger)
|
self.current_mission.triggerrules.triggers.append(trigger)
|
||||||
|
|
||||||
# Inject Plugins Lua Scripts and data
|
# Inject Plugins Lua Scripts and data
|
||||||
self.listOfPluginsScripts = []
|
|
||||||
|
|
||||||
for plugin in LuaPluginManager().getPlugins():
|
for plugin in LuaPluginManager().getPlugins():
|
||||||
plugin.injectScripts(self)
|
plugin.injectScripts(self)
|
||||||
plugin.injectConfiguration(self)
|
plugin.injectConfiguration(self)
|
||||||
|
|||||||
@ -205,6 +205,9 @@ class ChannelAssignment:
|
|||||||
class FlightData:
|
class FlightData:
|
||||||
"""Details of a planned flight."""
|
"""Details of a planned flight."""
|
||||||
|
|
||||||
|
#: The package that the flight belongs to.
|
||||||
|
package: Package
|
||||||
|
|
||||||
flight_type: FlightType
|
flight_type: FlightType
|
||||||
|
|
||||||
#: All units in the flight.
|
#: All units in the flight.
|
||||||
@ -237,14 +240,13 @@ class FlightData:
|
|||||||
#: Map of radio frequencies to their assigned radio and channel, if any.
|
#: Map of radio frequencies to their assigned radio and channel, if any.
|
||||||
frequency_to_channel_map: Dict[RadioFrequency, ChannelAssignment]
|
frequency_to_channel_map: Dict[RadioFrequency, ChannelAssignment]
|
||||||
|
|
||||||
#: Data concerning the target of a CAS/Strike/SEAD flight, or None else
|
def __init__(self, package: Package, flight_type: FlightType,
|
||||||
targetPoint = None
|
units: List[FlyingUnit], size: int, friendly: bool,
|
||||||
|
departure_delay: int, departure: RunwayData,
|
||||||
def __init__(self, flight_type: FlightType, units: List[FlyingUnit],
|
arrival: RunwayData, divert: Optional[RunwayData],
|
||||||
size: int, friendly: bool, departure_delay: int,
|
waypoints: List[FlightWaypoint],
|
||||||
departure: RunwayData, arrival: RunwayData,
|
intra_flight_channel: RadioFrequency) -> None:
|
||||||
divert: Optional[RunwayData], waypoints: List[FlightWaypoint],
|
self.package = package
|
||||||
intra_flight_channel: RadioFrequency, targetPoint: Optional) -> None:
|
|
||||||
self.flight_type = flight_type
|
self.flight_type = flight_type
|
||||||
self.units = units
|
self.units = units
|
||||||
self.size = size
|
self.size = size
|
||||||
@ -257,7 +259,6 @@ class FlightData:
|
|||||||
self.intra_flight_channel = intra_flight_channel
|
self.intra_flight_channel = intra_flight_channel
|
||||||
self.frequency_to_channel_map = {}
|
self.frequency_to_channel_map = {}
|
||||||
self.callsign = create_group_callsign_from_unit(self.units[0])
|
self.callsign = create_group_callsign_from_unit(self.units[0])
|
||||||
self.targetPoint = targetPoint
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def client_units(self) -> List[FlyingUnit]:
|
def client_units(self) -> List[FlyingUnit]:
|
||||||
@ -575,7 +576,8 @@ class AircraftConflictGenerator:
|
|||||||
return StartType.Warm
|
return StartType.Warm
|
||||||
|
|
||||||
def _setup_group(self, group: FlyingGroup, for_task: Type[Task],
|
def _setup_group(self, group: FlyingGroup, for_task: Type[Task],
|
||||||
flight: Flight, dynamic_runways: Dict[str, RunwayData]):
|
package: Package, flight: Flight,
|
||||||
|
dynamic_runways: Dict[str, RunwayData]) -> None:
|
||||||
did_load_loadout = False
|
did_load_loadout = False
|
||||||
unit_type = group.units[0].unit_type
|
unit_type = group.units[0].unit_type
|
||||||
|
|
||||||
@ -635,6 +637,7 @@ class AircraftConflictGenerator:
|
|||||||
departure_runway = fallback_runway
|
departure_runway = fallback_runway
|
||||||
|
|
||||||
self.flights.append(FlightData(
|
self.flights.append(FlightData(
|
||||||
|
package=package,
|
||||||
flight_type=flight.flight_type,
|
flight_type=flight.flight_type,
|
||||||
units=group.units,
|
units=group.units,
|
||||||
size=len(group.units),
|
size=len(group.units),
|
||||||
@ -646,8 +649,7 @@ class AircraftConflictGenerator:
|
|||||||
divert=None,
|
divert=None,
|
||||||
# Waypoints are added later, after they've had their TOTs set.
|
# Waypoints are added later, after they've had their TOTs set.
|
||||||
waypoints=[],
|
waypoints=[],
|
||||||
intra_flight_channel=channel,
|
intra_flight_channel=channel
|
||||||
targetPoint=flight.targetPoint,
|
|
||||||
))
|
))
|
||||||
|
|
||||||
# Special case so Su 33 carrier take off
|
# Special case so Su 33 carrier take off
|
||||||
@ -789,7 +791,7 @@ class AircraftConflictGenerator:
|
|||||||
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,
|
group = self.generate_planned_flight(flight.from_cp, country,
|
||||||
flight)
|
flight)
|
||||||
self.setup_flight_group(group, flight, dynamic_runways)
|
self.setup_flight_group(group, package, flight, dynamic_runways)
|
||||||
self.create_waypoints(group, package, flight, timing)
|
self.create_waypoints(group, package, flight, timing)
|
||||||
|
|
||||||
def set_activation_time(self, flight: Flight, group: FlyingGroup,
|
def set_activation_time(self, flight: Flight, group: FlyingGroup,
|
||||||
@ -906,10 +908,11 @@ class AircraftConflictGenerator:
|
|||||||
if flight.unit_type.eplrs:
|
if flight.unit_type.eplrs:
|
||||||
group.points[0].tasks.append(EPLRS(group.id))
|
group.points[0].tasks.append(EPLRS(group.id))
|
||||||
|
|
||||||
def configure_cap(self, group: FlyingGroup, flight: Flight,
|
def configure_cap(self, group: FlyingGroup, package: Package,
|
||||||
|
flight: Flight,
|
||||||
dynamic_runways: Dict[str, RunwayData]) -> None:
|
dynamic_runways: Dict[str, RunwayData]) -> None:
|
||||||
group.task = CAP.name
|
group.task = CAP.name
|
||||||
self._setup_group(group, CAP, flight, dynamic_runways)
|
self._setup_group(group, CAP, package, flight, dynamic_runways)
|
||||||
|
|
||||||
if flight.unit_type not in GUNFIGHTERS:
|
if flight.unit_type not in GUNFIGHTERS:
|
||||||
ammo_type = OptRTBOnOutOfAmmo.Values.AAM
|
ammo_type = OptRTBOnOutOfAmmo.Values.AAM
|
||||||
@ -921,10 +924,11 @@ class AircraftConflictGenerator:
|
|||||||
group.points[0].tasks.append(EngageTargets(max_distance=nm_to_meter(50),
|
group.points[0].tasks.append(EngageTargets(max_distance=nm_to_meter(50),
|
||||||
targets=[Targets.All.Air]))
|
targets=[Targets.All.Air]))
|
||||||
|
|
||||||
def configure_cas(self, group: FlyingGroup, flight: Flight,
|
def configure_cas(self, group: FlyingGroup, package: Package,
|
||||||
|
flight: Flight,
|
||||||
dynamic_runways: Dict[str, RunwayData]) -> None:
|
dynamic_runways: Dict[str, RunwayData]) -> None:
|
||||||
group.task = CAS.name
|
group.task = CAS.name
|
||||||
self._setup_group(group, CAS, flight, dynamic_runways)
|
self._setup_group(group, CAS, package, flight, dynamic_runways)
|
||||||
self.configure_behavior(
|
self.configure_behavior(
|
||||||
group,
|
group,
|
||||||
react_on_threat=OptReactOnThreat.Values.EvadeFire,
|
react_on_threat=OptReactOnThreat.Values.EvadeFire,
|
||||||
@ -936,10 +940,11 @@ class AircraftConflictGenerator:
|
|||||||
targets=[Targets.All.GroundUnits.GroundVehicles])
|
targets=[Targets.All.GroundUnits.GroundVehicles])
|
||||||
)
|
)
|
||||||
|
|
||||||
def configure_sead(self, group: FlyingGroup, flight: Flight,
|
def configure_sead(self, group: FlyingGroup, package: Package,
|
||||||
dynamic_runways: Dict[str, RunwayData]) -> None:
|
flight: Flight,
|
||||||
|
dynamic_runways: Dict[str, RunwayData]) -> None:
|
||||||
group.task = SEAD.name
|
group.task = SEAD.name
|
||||||
self._setup_group(group, SEAD, flight, dynamic_runways)
|
self._setup_group(group, SEAD, package, flight, dynamic_runways)
|
||||||
self.configure_behavior(
|
self.configure_behavior(
|
||||||
group,
|
group,
|
||||||
react_on_threat=OptReactOnThreat.Values.EvadeFire,
|
react_on_threat=OptReactOnThreat.Values.EvadeFire,
|
||||||
@ -947,33 +952,37 @@ class AircraftConflictGenerator:
|
|||||||
rtb_winchester=OptRTBOnOutOfAmmo.Values.ASM,
|
rtb_winchester=OptRTBOnOutOfAmmo.Values.ASM,
|
||||||
restrict_jettison=True)
|
restrict_jettison=True)
|
||||||
|
|
||||||
def configure_strike(self, group: FlyingGroup, flight: Flight,
|
def configure_strike(self, group: FlyingGroup, package: Package,
|
||||||
|
flight: Flight,
|
||||||
dynamic_runways: Dict[str, RunwayData]) -> None:
|
dynamic_runways: Dict[str, RunwayData]) -> None:
|
||||||
group.task = PinpointStrike.name
|
group.task = PinpointStrike.name
|
||||||
self._setup_group(group, GroundAttack, flight, dynamic_runways)
|
self._setup_group(group, GroundAttack, package, flight, dynamic_runways)
|
||||||
self.configure_behavior(
|
self.configure_behavior(
|
||||||
group,
|
group,
|
||||||
react_on_threat=OptReactOnThreat.Values.EvadeFire,
|
react_on_threat=OptReactOnThreat.Values.EvadeFire,
|
||||||
roe=OptROE.Values.OpenFire,
|
roe=OptROE.Values.OpenFire,
|
||||||
restrict_jettison=True)
|
restrict_jettison=True)
|
||||||
|
|
||||||
def configure_anti_ship(self, group: FlyingGroup, flight: Flight,
|
def configure_anti_ship(self, group: FlyingGroup, package: Package,
|
||||||
|
flight: Flight,
|
||||||
dynamic_runways: Dict[str, RunwayData]) -> None:
|
dynamic_runways: Dict[str, RunwayData]) -> None:
|
||||||
group.task = AntishipStrike.name
|
group.task = AntishipStrike.name
|
||||||
self._setup_group(group, AntishipStrike, flight, dynamic_runways)
|
self._setup_group(group, AntishipStrike, package, flight,
|
||||||
|
dynamic_runways)
|
||||||
self.configure_behavior(
|
self.configure_behavior(
|
||||||
group,
|
group,
|
||||||
react_on_threat=OptReactOnThreat.Values.EvadeFire,
|
react_on_threat=OptReactOnThreat.Values.EvadeFire,
|
||||||
roe=OptROE.Values.OpenFire,
|
roe=OptROE.Values.OpenFire,
|
||||||
restrict_jettison=True)
|
restrict_jettison=True)
|
||||||
|
|
||||||
def configure_escort(self, group: FlyingGroup, flight: Flight,
|
def configure_escort(self, group: FlyingGroup, package: Package,
|
||||||
|
flight: Flight,
|
||||||
dynamic_runways: Dict[str, RunwayData]) -> None:
|
dynamic_runways: Dict[str, RunwayData]) -> None:
|
||||||
# Escort groups are actually given the CAP task so they can perform the
|
# Escort groups are actually given the CAP task so they can perform the
|
||||||
# Search Then Engage task, which we have to use instead of the Escort
|
# Search Then Engage task, which we have to use instead of the Escort
|
||||||
# task for the reasons explained in JoinPointBuilder.
|
# task for the reasons explained in JoinPointBuilder.
|
||||||
group.task = CAP.name
|
group.task = CAP.name
|
||||||
self._setup_group(group, CAP, flight, dynamic_runways)
|
self._setup_group(group, CAP, package, flight, dynamic_runways)
|
||||||
self.configure_behavior(group, roe=OptROE.Values.OpenFire,
|
self.configure_behavior(group, roe=OptROE.Values.OpenFire,
|
||||||
restrict_jettison=True)
|
restrict_jettison=True)
|
||||||
|
|
||||||
@ -982,22 +991,23 @@ class AircraftConflictGenerator:
|
|||||||
logging.error(f"Unhandled flight type: {flight.flight_type.name}")
|
logging.error(f"Unhandled flight type: {flight.flight_type.name}")
|
||||||
self.configure_behavior(group)
|
self.configure_behavior(group)
|
||||||
|
|
||||||
def setup_flight_group(self, group: FlyingGroup, flight: Flight,
|
def setup_flight_group(self, group: FlyingGroup, package: Package,
|
||||||
|
flight: Flight,
|
||||||
dynamic_runways: Dict[str, RunwayData]) -> None:
|
dynamic_runways: Dict[str, RunwayData]) -> None:
|
||||||
flight_type = flight.flight_type
|
flight_type = flight.flight_type
|
||||||
if flight_type in [FlightType.BARCAP, FlightType.TARCAP,
|
if flight_type in [FlightType.BARCAP, FlightType.TARCAP,
|
||||||
FlightType.INTERCEPTION]:
|
FlightType.INTERCEPTION]:
|
||||||
self.configure_cap(group, flight, dynamic_runways)
|
self.configure_cap(group, package, flight, dynamic_runways)
|
||||||
elif flight_type in [FlightType.CAS, FlightType.BAI]:
|
elif flight_type in [FlightType.CAS, FlightType.BAI]:
|
||||||
self.configure_cas(group, flight, dynamic_runways)
|
self.configure_cas(group, package, flight, dynamic_runways)
|
||||||
elif flight_type in [FlightType.SEAD, FlightType.DEAD]:
|
elif flight_type in [FlightType.SEAD, FlightType.DEAD]:
|
||||||
self.configure_sead(group, flight, dynamic_runways)
|
self.configure_sead(group, package, flight, dynamic_runways)
|
||||||
elif flight_type in [FlightType.STRIKE]:
|
elif flight_type in [FlightType.STRIKE]:
|
||||||
self.configure_strike(group, flight, dynamic_runways)
|
self.configure_strike(group, package, flight, dynamic_runways)
|
||||||
elif flight_type in [FlightType.ANTISHIP]:
|
elif flight_type in [FlightType.ANTISHIP]:
|
||||||
self.configure_anti_ship(group, flight, dynamic_runways)
|
self.configure_anti_ship(group, package, flight, dynamic_runways)
|
||||||
elif flight_type == FlightType.ESCORT:
|
elif flight_type == FlightType.ESCORT:
|
||||||
self.configure_escort(group, flight, dynamic_runways)
|
self.configure_escort(group, package, flight, dynamic_runways)
|
||||||
else:
|
else:
|
||||||
self.configure_unknown_task(group, flight)
|
self.configure_unknown_task(group, flight)
|
||||||
|
|
||||||
|
|||||||
@ -206,10 +206,9 @@ class PackageBuilder:
|
|||||||
if assignment is None:
|
if assignment is None:
|
||||||
return False
|
return False
|
||||||
airfield, aircraft = assignment
|
airfield, aircraft = assignment
|
||||||
flight = Flight(aircraft, plan.num_aircraft, airfield, plan.task,
|
flight = Flight(self.package, aircraft, plan.num_aircraft, airfield,
|
||||||
self.start_type)
|
plan.task, self.start_type)
|
||||||
self.package.add_flight(flight)
|
self.package.add_flight(flight)
|
||||||
flight.targetPoint = self.package.target
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def build(self) -> Package:
|
def build(self) -> Package:
|
||||||
@ -222,7 +221,7 @@ class PackageBuilder:
|
|||||||
for flight in flights:
|
for flight in flights:
|
||||||
self.global_inventory.return_from_flight(flight)
|
self.global_inventory.return_from_flight(flight)
|
||||||
self.package.remove_flight(flight)
|
self.package.remove_flight(flight)
|
||||||
flight.targetPoint = None
|
|
||||||
|
|
||||||
class ObjectiveFinder:
|
class ObjectiveFinder:
|
||||||
"""Identifies potential objectives for the mission planner."""
|
"""Identifies potential objectives for the mission planner."""
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Dict, Iterable, List, Optional
|
from typing import Dict, Iterable, List, Optional, TYPE_CHECKING
|
||||||
|
|
||||||
from dcs.mapping import Point
|
from dcs.mapping import Point
|
||||||
from dcs.point import MovingPoint, PointAction
|
from dcs.point import MovingPoint, PointAction
|
||||||
@ -8,6 +10,9 @@ from dcs.unittype import UnitType
|
|||||||
from game import db
|
from game import db
|
||||||
from theater.controlpoint import ControlPoint, MissionTarget
|
from theater.controlpoint import ControlPoint, MissionTarget
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from gen.ato import Package
|
||||||
|
|
||||||
|
|
||||||
class FlightType(Enum):
|
class FlightType(Enum):
|
||||||
CAP = 0 # Do not use. Use BARCAP or TARCAP.
|
CAP = 0 # Do not use. Use BARCAP or TARCAP.
|
||||||
@ -138,10 +143,11 @@ class Flight:
|
|||||||
use_custom_loadout = False
|
use_custom_loadout = False
|
||||||
preset_loadout_name = ""
|
preset_loadout_name = ""
|
||||||
group = False # Contains DCS Mission group data after mission has been generated
|
group = False # Contains DCS Mission group data after mission has been generated
|
||||||
targetPoint = None # Contains either None or a Strike/SEAD target point location
|
|
||||||
|
|
||||||
def __init__(self, unit_type: UnitType, count: int, from_cp: ControlPoint,
|
def __init__(self, package: Package, unit_type: UnitType, count: int,
|
||||||
flight_type: FlightType, start_type: str) -> None:
|
from_cp: ControlPoint, flight_type: FlightType,
|
||||||
|
start_type: str) -> None:
|
||||||
|
self.package = package
|
||||||
self.unit_type = unit_type
|
self.unit_type = unit_type
|
||||||
self.count = count
|
self.count = count
|
||||||
self.from_cp = from_cp
|
self.from_cp = from_cp
|
||||||
|
|||||||
@ -186,6 +186,12 @@ class TotEstimator:
|
|||||||
time_to_target = self.estimate_waypoints_to_target(flight, {
|
time_to_target = self.estimate_waypoints_to_target(flight, {
|
||||||
FlightWaypointType.PATROL_TRACK
|
FlightWaypointType.PATROL_TRACK
|
||||||
})
|
})
|
||||||
|
if time_to_target is None:
|
||||||
|
logging.warning(
|
||||||
|
f"Found no race track. Cannot estimate TOT for {flight}")
|
||||||
|
# Return 0 so this flight's travel time does not affect the rest
|
||||||
|
# of the package.
|
||||||
|
return 0
|
||||||
else:
|
else:
|
||||||
time_to_ingress = self.estimate_waypoints_to_target(
|
time_to_ingress = self.estimate_waypoints_to_target(
|
||||||
flight, INGRESS_TYPES
|
flight, INGRESS_TYPES
|
||||||
|
|||||||
@ -1,44 +1,48 @@
|
|||||||
from typing import List
|
|
||||||
from pathlib import Path
|
|
||||||
from PySide2.QtCore import QSize, Qt, QItemSelectionModel, QPoint
|
|
||||||
from PySide2.QtWidgets import QLabel, QDialog, QGridLayout, QListView, QStackedLayout, QComboBox, QWidget, \
|
|
||||||
QAbstractItemView, QPushButton, QGroupBox, QCheckBox, QVBoxLayout, QSpinBox
|
|
||||||
import json
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import List, Optional
|
||||||
|
|
||||||
class LuaPluginWorkOrder():
|
from PySide2.QtCore import Qt
|
||||||
|
from PySide2.QtWidgets import QCheckBox, QGridLayout, QGroupBox, QLabel
|
||||||
def __init__(self, parent, filename:str, mnemonic:str, disable:bool):
|
|
||||||
|
|
||||||
|
class LuaPluginWorkOrder:
|
||||||
|
|
||||||
|
def __init__(self, parent, filename: str, mnemonic: str,
|
||||||
|
disable: bool) -> None:
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.mnemonic = mnemonic
|
self.mnemonic = mnemonic
|
||||||
self.disable = disable
|
self.disable = disable
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
|
|
||||||
def work(self, mnemonic:str, operation):
|
def work(self, operation):
|
||||||
if self.disable:
|
if self.disable:
|
||||||
operation.bypassPluginScript(self.parent.mnemonic, self.mnemonic)
|
operation.bypass_plugin_script(self.mnemonic)
|
||||||
else:
|
else:
|
||||||
operation.injectPluginScript(self.parent.mnemonic, self.filename, self.mnemonic)
|
operation.inject_plugin_script(self.parent.mnemonic, self.filename,
|
||||||
|
self.mnemonic)
|
||||||
|
|
||||||
class LuaPluginSpecificOption():
|
class LuaPluginSpecificOption:
|
||||||
|
|
||||||
def __init__(self, parent, mnemonic:str, nameInUI:str, defaultValue:bool):
|
def __init__(self, parent, mnemonic: str, nameInUI: str,
|
||||||
|
defaultValue: bool) -> None:
|
||||||
self.mnemonic = mnemonic
|
self.mnemonic = mnemonic
|
||||||
self.nameInUI = nameInUI
|
self.nameInUI = nameInUI
|
||||||
self.defaultValue = defaultValue
|
self.defaultValue = defaultValue
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
|
|
||||||
class LuaPlugin():
|
class LuaPlugin:
|
||||||
NAME_IN_SETTINGS_BASE:str = "plugins."
|
NAME_IN_SETTINGS_BASE:str = "plugins."
|
||||||
|
|
||||||
def __init__(self, jsonFilename:str):
|
def __init__(self, jsonFilename: str) -> None:
|
||||||
self.mnemonic:str = None
|
self.mnemonic: Optional[str] = None
|
||||||
self.skipUI:bool = False
|
self.skipUI: bool = False
|
||||||
self.nameInUI:str = None
|
self.nameInUI: Optional[str] = None
|
||||||
self.nameInSettings:str = None
|
self.nameInSettings: Optional[str] = None
|
||||||
self.defaultValue:bool = False
|
self.defaultValue: bool = False
|
||||||
self.specificOptions = []
|
self.specificOptions: List[LuaPluginSpecificOption] = []
|
||||||
self.scriptsWorkOrders: List[LuaPluginWorkOrder] = None
|
self.scriptsWorkOrders: List[LuaPluginWorkOrder] = []
|
||||||
self.configurationWorkOrders: List[LuaPluginWorkOrder] = None
|
self.configurationWorkOrders: List[LuaPluginWorkOrder] = []
|
||||||
self.initFromJson(jsonFilename)
|
self.initFromJson(jsonFilename)
|
||||||
self.enabled = self.defaultValue
|
self.enabled = self.defaultValue
|
||||||
self.settings = None
|
self.settings = None
|
||||||
@ -50,6 +54,7 @@ class LuaPlugin():
|
|||||||
self.mnemonic = jsonData.get("mnemonic")
|
self.mnemonic = jsonData.get("mnemonic")
|
||||||
self.skipUI = jsonData.get("skipUI", False)
|
self.skipUI = jsonData.get("skipUI", False)
|
||||||
self.nameInUI = jsonData.get("nameInUI")
|
self.nameInUI = jsonData.get("nameInUI")
|
||||||
|
assert self.mnemonic is not None
|
||||||
self.nameInSettings = LuaPlugin.NAME_IN_SETTINGS_BASE + self.mnemonic
|
self.nameInSettings = LuaPlugin.NAME_IN_SETTINGS_BASE + self.mnemonic
|
||||||
self.defaultValue = jsonData.get("defaultValue", False)
|
self.defaultValue = jsonData.get("defaultValue", False)
|
||||||
self.specificOptions = []
|
self.specificOptions = []
|
||||||
@ -76,6 +81,9 @@ class LuaPlugin():
|
|||||||
self.setSettings(settingsWindow.game.settings)
|
self.setSettings(settingsWindow.game.settings)
|
||||||
|
|
||||||
if not self.skipUI:
|
if not self.skipUI:
|
||||||
|
assert self.nameInSettings is not None
|
||||||
|
assert self.settings is not None
|
||||||
|
|
||||||
# create the plugin choice checkbox interface
|
# create the plugin choice checkbox interface
|
||||||
self.uiWidget: QCheckBox = QCheckBox()
|
self.uiWidget: QCheckBox = QCheckBox()
|
||||||
self.uiWidget.setChecked(self.isEnabled())
|
self.uiWidget.setChecked(self.isEnabled())
|
||||||
@ -95,6 +103,7 @@ class LuaPlugin():
|
|||||||
# browse each option in the specific options list
|
# browse each option in the specific options list
|
||||||
row = 0
|
row = 0
|
||||||
for specificOption in self.specificOptions:
|
for specificOption in self.specificOptions:
|
||||||
|
assert specificOption.mnemonic is not None
|
||||||
nameInSettings = self.nameInSettings + "." + specificOption.mnemonic
|
nameInSettings = self.nameInSettings + "." + specificOption.mnemonic
|
||||||
if not nameInSettings in self.settings.plugins:
|
if not nameInSettings in self.settings.plugins:
|
||||||
self.settings.plugins[nameInSettings] = specificOption.defaultValue
|
self.settings.plugins[nameInSettings] = specificOption.defaultValue
|
||||||
@ -149,7 +158,7 @@ class LuaPlugin():
|
|||||||
# execute the work order
|
# execute the work order
|
||||||
if self.scriptsWorkOrders != None:
|
if self.scriptsWorkOrders != None:
|
||||||
for workOrder in self.scriptsWorkOrders:
|
for workOrder in self.scriptsWorkOrders:
|
||||||
workOrder.work(self.mnemonic, operation)
|
workOrder.work(operation)
|
||||||
|
|
||||||
# serves for subclasses
|
# serves for subclasses
|
||||||
return self.isEnabled()
|
return self.isEnabled()
|
||||||
@ -177,12 +186,12 @@ class LuaPlugin():
|
|||||||
lua += defineAllOptions
|
lua += defineAllOptions
|
||||||
lua += "end"
|
lua += "end"
|
||||||
|
|
||||||
operation.injectLuaTrigger(lua, f"{self.mnemonic} plugin configuration")
|
operation.inject_lua_trigger(lua, f"{self.mnemonic} plugin configuration")
|
||||||
|
|
||||||
# execute the work order
|
# execute the work order
|
||||||
if self.configurationWorkOrders != None:
|
if self.configurationWorkOrders != None:
|
||||||
for workOrder in self.configurationWorkOrders:
|
for workOrder in self.configurationWorkOrders:
|
||||||
workOrder.work(self.mnemonic, operation)
|
workOrder.work(operation)
|
||||||
|
|
||||||
# serves for subclasses
|
# serves for subclasses
|
||||||
return self.isEnabled()
|
return self.isEnabled()
|
||||||
|
|||||||
@ -107,7 +107,7 @@ class QFlightCreator(QDialog):
|
|||||||
start_type = "Cold"
|
start_type = "Cold"
|
||||||
else:
|
else:
|
||||||
start_type = "Warm"
|
start_type = "Warm"
|
||||||
flight = Flight(aircraft, size, origin, task, start_type)
|
flight = Flight(self.package, aircraft, size, origin, task, start_type)
|
||||||
flight.scheduled_in = self.package.delay
|
flight.scheduled_in = self.package.delay
|
||||||
flight.client_count = self.client_slots_spinner.value()
|
flight.client_count = self.client_slots_spinner.value()
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import pickle
|
|||||||
from typing import Collection, Optional, Tuple
|
from typing import Collection, Optional, Tuple
|
||||||
|
|
||||||
Zone = Collection[Tuple[float, float]]
|
Zone = Collection[Tuple[float, float]]
|
||||||
Landmap = Tuple[Collection[Zone], Collection[Zone]]
|
Landmap = Tuple[Collection[Zone], Collection[Zone], Collection[Zone]]
|
||||||
|
|
||||||
|
|
||||||
def load_landmap(filename: str) -> Optional[Landmap]:
|
def load_landmap(filename: str) -> Optional[Landmap]:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user