mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Move mission type compatibility to the target.
This was also needed in other parts of the UI and is easier to implement in the target class anyway. Note that DEAD is now properly restricted to air defense targets. Also added error boxes to the UI for when planning fails on an invalid target.
This commit is contained in:
parent
f3553ced78
commit
8bd00bf450
@ -20,7 +20,13 @@ from dcs.unit import Unit
|
|||||||
|
|
||||||
from game.data.doctrine import Doctrine
|
from game.data.doctrine import Doctrine
|
||||||
from game.utils import nm_to_meter
|
from game.utils import nm_to_meter
|
||||||
from theater import ControlPoint, FrontLine, MissionTarget, TheaterGroundObject
|
from theater import (
|
||||||
|
ControlPoint,
|
||||||
|
FrontLine,
|
||||||
|
MissionTarget,
|
||||||
|
SamGroundObject,
|
||||||
|
TheaterGroundObject,
|
||||||
|
)
|
||||||
from .closestairfields import ObjectiveDistanceCache
|
from .closestairfields import ObjectiveDistanceCache
|
||||||
from .flight import Flight, FlightType, FlightWaypoint, FlightWaypointType
|
from .flight import Flight, FlightType, FlightWaypoint, FlightWaypointType
|
||||||
from .traveltime import GroundSpeed, TravelTime
|
from .traveltime import GroundSpeed, TravelTime
|
||||||
@ -616,13 +622,7 @@ class FlightPlanBuilder:
|
|||||||
raise RuntimeError("Flight must be a part of the package")
|
raise RuntimeError("Flight must be a part of the package")
|
||||||
if self.package.waypoints is None:
|
if self.package.waypoints is None:
|
||||||
self.regenerate_package_waypoints()
|
self.regenerate_package_waypoints()
|
||||||
|
flight.flight_plan = self.generate_flight_plan(flight, custom_targets)
|
||||||
try:
|
|
||||||
flight_plan = self.generate_flight_plan(flight, custom_targets)
|
|
||||||
except PlanningError:
|
|
||||||
logging.exception(f"Could not create flight plan")
|
|
||||||
return
|
|
||||||
flight.flight_plan = flight_plan
|
|
||||||
|
|
||||||
def generate_flight_plan(
|
def generate_flight_plan(
|
||||||
self, flight: Flight,
|
self, flight: Flight,
|
||||||
@ -872,7 +872,7 @@ class FlightPlanBuilder:
|
|||||||
"""
|
"""
|
||||||
location = self.package.target
|
location = self.package.target
|
||||||
|
|
||||||
if not isinstance(location, TheaterGroundObject):
|
if not isinstance(location, SamGroundObject):
|
||||||
logging.exception(f"Invalid Objective Location for DEAD flight {flight=} at {location=}")
|
logging.exception(f"Invalid Objective Location for DEAD flight {flight=} at {location=}")
|
||||||
raise InvalidObjectiveLocation(flight.flight_type, location)
|
raise InvalidObjectiveLocation(flight.flight_type, location)
|
||||||
|
|
||||||
@ -897,9 +897,6 @@ class FlightPlanBuilder:
|
|||||||
"""
|
"""
|
||||||
location = self.package.target
|
location = self.package.target
|
||||||
|
|
||||||
if not isinstance(location, TheaterGroundObject):
|
|
||||||
raise InvalidObjectiveLocation(flight.flight_type, location)
|
|
||||||
|
|
||||||
# TODO: Unify these.
|
# TODO: Unify these.
|
||||||
# There doesn't seem to be any reason to treat the UI fragged missions
|
# There doesn't seem to be any reason to treat the UI fragged missions
|
||||||
# different from the automatic missions.
|
# different from the automatic missions.
|
||||||
@ -1066,7 +1063,7 @@ class FlightPlanBuilder:
|
|||||||
return builder.land(arrival)
|
return builder.land(arrival)
|
||||||
|
|
||||||
def strike_flightplan(
|
def strike_flightplan(
|
||||||
self, flight: Flight, location: TheaterGroundObject,
|
self, flight: Flight, location: MissionTarget,
|
||||||
targets: Optional[List[StrikeTarget]] = None) -> StrikeFlightPlan:
|
targets: Optional[List[StrikeTarget]] = None) -> StrikeFlightPlan:
|
||||||
assert self.package.waypoints is not None
|
assert self.package.waypoints is not None
|
||||||
builder = WaypointBuilder(self.game.conditions, flight, self.doctrine,
|
builder = WaypointBuilder(self.game.conditions, flight, self.doctrine,
|
||||||
@ -1116,8 +1113,8 @@ class FlightPlanBuilder:
|
|||||||
def _advancing_rendezvous_point(self, attack_transition: Point) -> Point:
|
def _advancing_rendezvous_point(self, attack_transition: Point) -> Point:
|
||||||
"""Creates a rendezvous point that advances toward the target."""
|
"""Creates a rendezvous point that advances toward the target."""
|
||||||
heading = self._heading_to_package_airfield(attack_transition)
|
heading = self._heading_to_package_airfield(attack_transition)
|
||||||
return attack_transition.point_from_heading(heading,
|
return attack_transition.point_from_heading(
|
||||||
-self.doctrine.join_distance)
|
heading, -self.doctrine.join_distance)
|
||||||
|
|
||||||
def _rendezvous_should_retreat(self, attack_transition: Point) -> bool:
|
def _rendezvous_should_retreat(self, attack_transition: Point) -> bool:
|
||||||
transition_target_distance = attack_transition.distance_to_point(
|
transition_target_distance = attack_transition.distance_to_point(
|
||||||
|
|||||||
@ -1,107 +1,16 @@
|
|||||||
"""Combo box for selecting a flight's task type."""
|
"""Combo box for selecting a flight's task type."""
|
||||||
import logging
|
|
||||||
from typing import Iterator
|
|
||||||
|
|
||||||
from PySide2.QtWidgets import QComboBox
|
from PySide2.QtWidgets import QComboBox
|
||||||
|
|
||||||
from gen.flights.flight import FlightType
|
from theater import ConflictTheater, MissionTarget
|
||||||
from theater import (
|
|
||||||
ConflictTheater,
|
|
||||||
ControlPoint,
|
|
||||||
FrontLine,
|
|
||||||
MissionTarget,
|
|
||||||
TheaterGroundObject,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class QFlightTypeComboBox(QComboBox):
|
class QFlightTypeComboBox(QComboBox):
|
||||||
"""Combo box for selecting a flight task type."""
|
"""Combo box for selecting a flight task type."""
|
||||||
|
|
||||||
COMMON_ENEMY_MISSIONS = [
|
|
||||||
FlightType.TARCAP,
|
|
||||||
FlightType.ESCORT,
|
|
||||||
FlightType.SEAD,
|
|
||||||
FlightType.DEAD,
|
|
||||||
FlightType.SWEEP,
|
|
||||||
# TODO: FlightType.ELINT,
|
|
||||||
# TODO: FlightType.EWAR,
|
|
||||||
# TODO: FlightType.RECON,
|
|
||||||
]
|
|
||||||
|
|
||||||
COMMON_FRIENDLY_MISSIONS = [
|
|
||||||
FlightType.BARCAP,
|
|
||||||
]
|
|
||||||
|
|
||||||
FRIENDLY_AIRBASE_MISSIONS = [
|
|
||||||
# TODO: FlightType.INTERCEPTION
|
|
||||||
# TODO: FlightType.LOGISTICS
|
|
||||||
] + COMMON_FRIENDLY_MISSIONS
|
|
||||||
|
|
||||||
FRIENDLY_CARRIER_MISSIONS = [
|
|
||||||
# TODO: FlightType.INTERCEPTION
|
|
||||||
# TODO: Buddy tanking for the A-4?
|
|
||||||
# TODO: Rescue chopper?
|
|
||||||
# TODO: Inter-ship logistics?
|
|
||||||
] + COMMON_FRIENDLY_MISSIONS
|
|
||||||
|
|
||||||
ENEMY_CARRIER_MISSIONS = [
|
|
||||||
FlightType.ESCORT,
|
|
||||||
FlightType.BARCAP,
|
|
||||||
# TODO: FlightType.ANTISHIP
|
|
||||||
]
|
|
||||||
|
|
||||||
ENEMY_AIRBASE_MISSIONS = [
|
|
||||||
# TODO: FlightType.STRIKE
|
|
||||||
] + COMMON_ENEMY_MISSIONS
|
|
||||||
|
|
||||||
FRIENDLY_GROUND_OBJECT_MISSIONS = [
|
|
||||||
# TODO: FlightType.LOGISTICS
|
|
||||||
# TODO: FlightType.TROOP_TRANSPORT
|
|
||||||
] + COMMON_FRIENDLY_MISSIONS
|
|
||||||
|
|
||||||
ENEMY_GROUND_OBJECT_MISSIONS = [
|
|
||||||
FlightType.STRIKE,
|
|
||||||
] + COMMON_ENEMY_MISSIONS
|
|
||||||
|
|
||||||
FRONT_LINE_MISSIONS = [
|
|
||||||
FlightType.CAS,
|
|
||||||
# TODO: FlightType.TROOP_TRANSPORT
|
|
||||||
# TODO: FlightType.EVAC
|
|
||||||
] + COMMON_ENEMY_MISSIONS
|
|
||||||
|
|
||||||
# TODO: Add BAI missions after we have useful BAI targets.
|
|
||||||
|
|
||||||
def __init__(self, theater: ConflictTheater, target: MissionTarget) -> None:
|
def __init__(self, theater: ConflictTheater, target: MissionTarget) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.theater = theater
|
self.theater = theater
|
||||||
self.target = target
|
self.target = target
|
||||||
for mission_type in self.mission_types_for_target():
|
for mission_type in self.target.mission_types(for_player=True):
|
||||||
self.addItem(mission_type.name, userData=mission_type)
|
self.addItem(mission_type.name, userData=mission_type)
|
||||||
|
|
||||||
def mission_types_for_target(self) -> Iterator[FlightType]:
|
|
||||||
if isinstance(self.target, ControlPoint):
|
|
||||||
friendly = self.target.captured
|
|
||||||
fleet = self.target.is_fleet
|
|
||||||
if friendly:
|
|
||||||
if fleet:
|
|
||||||
yield from self.FRIENDLY_CARRIER_MISSIONS
|
|
||||||
else:
|
|
||||||
yield from self.FRIENDLY_AIRBASE_MISSIONS
|
|
||||||
else:
|
|
||||||
if fleet:
|
|
||||||
yield from self.ENEMY_CARRIER_MISSIONS
|
|
||||||
else:
|
|
||||||
yield from self.ENEMY_AIRBASE_MISSIONS
|
|
||||||
elif isinstance(self.target, TheaterGroundObject):
|
|
||||||
# TODO: Filter more based on the category.
|
|
||||||
friendly = self.target.control_point.captured
|
|
||||||
if friendly:
|
|
||||||
yield from self.FRIENDLY_GROUND_OBJECT_MISSIONS
|
|
||||||
else:
|
|
||||||
yield from self.ENEMY_GROUND_OBJECT_MISSIONS
|
|
||||||
elif isinstance(self.target, FrontLine):
|
|
||||||
yield from self.FRONT_LINE_MISSIONS
|
|
||||||
else:
|
|
||||||
logging.error(
|
|
||||||
f"Unhandled target type: {self.target.__class__.__name__}"
|
|
||||||
)
|
|
||||||
|
|||||||
@ -8,6 +8,7 @@ from PySide2.QtWidgets import (
|
|||||||
QDialog,
|
QDialog,
|
||||||
QHBoxLayout,
|
QHBoxLayout,
|
||||||
QLabel,
|
QLabel,
|
||||||
|
QMessageBox,
|
||||||
QPushButton,
|
QPushButton,
|
||||||
QTimeEdit,
|
QTimeEdit,
|
||||||
QVBoxLayout,
|
QVBoxLayout,
|
||||||
@ -16,7 +17,7 @@ from PySide2.QtWidgets import (
|
|||||||
from game.game import Game
|
from game.game import Game
|
||||||
from gen.ato import Package
|
from gen.ato import Package
|
||||||
from gen.flights.flight import Flight
|
from gen.flights.flight import Flight
|
||||||
from gen.flights.flightplan import FlightPlanBuilder
|
from gen.flights.flightplan import FlightPlanBuilder, PlanningError
|
||||||
from gen.flights.traveltime import TotEstimator
|
from gen.flights.traveltime import TotEstimator
|
||||||
from qt_ui.models import AtoModel, GameModel, PackageModel
|
from qt_ui.models import AtoModel, GameModel, PackageModel
|
||||||
from qt_ui.uiconstants import EVENT_ICONS
|
from qt_ui.uiconstants import EVENT_ICONS
|
||||||
@ -167,7 +168,15 @@ class QPackageDialog(QDialog):
|
|||||||
self.package_model.add_flight(flight)
|
self.package_model.add_flight(flight)
|
||||||
planner = FlightPlanBuilder(self.game, self.package_model.package,
|
planner = FlightPlanBuilder(self.game, self.package_model.package,
|
||||||
is_player=True)
|
is_player=True)
|
||||||
planner.populate_flight_plan(flight)
|
try:
|
||||||
|
planner.populate_flight_plan(flight)
|
||||||
|
except PlanningError as ex:
|
||||||
|
self.game.aircraft_inventory.return_from_flight(flight)
|
||||||
|
self.package_model.delete_flight(flight)
|
||||||
|
logging.exception("Could not create flight")
|
||||||
|
QMessageBox.critical(
|
||||||
|
self, "Could not create flight", str(ex), QMessageBox.Ok
|
||||||
|
)
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
self.package_changed.emit()
|
self.package_changed.emit()
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import logging
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
from PySide2.QtCore import Signal
|
from PySide2.QtCore import Signal
|
||||||
@ -13,13 +14,15 @@ from PySide2.QtWidgets import (
|
|||||||
from game import Game
|
from game import Game
|
||||||
from gen.ato import Package
|
from gen.ato import Package
|
||||||
from gen.flights.flight import Flight, FlightType
|
from gen.flights.flight import Flight, FlightType
|
||||||
from gen.flights.flightplan import FlightPlanBuilder
|
from gen.flights.flightplan import (
|
||||||
|
FlightPlanBuilder,
|
||||||
|
PlanningError,
|
||||||
|
)
|
||||||
from qt_ui.windows.mission.flight.waypoints.QFlightWaypointList import \
|
from qt_ui.windows.mission.flight.waypoints.QFlightWaypointList import \
|
||||||
QFlightWaypointList
|
QFlightWaypointList
|
||||||
from qt_ui.windows.mission.flight.waypoints\
|
from qt_ui.windows.mission.flight.waypoints \
|
||||||
.QPredefinedWaypointSelectionWindow import \
|
.QPredefinedWaypointSelectionWindow import \
|
||||||
QPredefinedWaypointSelectionWindow
|
QPredefinedWaypointSelectionWindow
|
||||||
from theater import FrontLine
|
|
||||||
|
|
||||||
|
|
||||||
class QFlightWaypointTab(QFrame):
|
class QFlightWaypointTab(QFrame):
|
||||||
@ -55,17 +58,8 @@ class QFlightWaypointTab(QFrame):
|
|||||||
rlayout.addWidget(QLabel("<strong>Generator :</strong>"))
|
rlayout.addWidget(QLabel("<strong>Generator :</strong>"))
|
||||||
rlayout.addWidget(QLabel("<small>AI compatible</small>"))
|
rlayout.addWidget(QLabel("<small>AI compatible</small>"))
|
||||||
|
|
||||||
# TODO: Filter by objective type.
|
|
||||||
self.recreate_buttons.clear()
|
self.recreate_buttons.clear()
|
||||||
recreate_types = [
|
for task in self.package.target.mission_types(for_player=True):
|
||||||
FlightType.CAS,
|
|
||||||
FlightType.CAP,
|
|
||||||
FlightType.DEAD,
|
|
||||||
FlightType.ESCORT,
|
|
||||||
FlightType.SEAD,
|
|
||||||
FlightType.STRIKE
|
|
||||||
]
|
|
||||||
for task in recreate_types:
|
|
||||||
def make_closure(arg):
|
def make_closure(arg):
|
||||||
def closure():
|
def closure():
|
||||||
return self.confirm_recreate(arg)
|
return self.confirm_recreate(arg)
|
||||||
@ -142,19 +136,17 @@ class QFlightWaypointTab(QFrame):
|
|||||||
QMessageBox.No,
|
QMessageBox.No,
|
||||||
QMessageBox.Yes
|
QMessageBox.Yes
|
||||||
)
|
)
|
||||||
|
original_task = self.flight.flight_type
|
||||||
if result == QMessageBox.Yes:
|
if result == QMessageBox.Yes:
|
||||||
# TODO: Should be buttons for both BARCAP and TARCAP.
|
|
||||||
# BARCAP and TARCAP behave differently. TARCAP arrives a few minutes
|
|
||||||
# ahead of the rest of the package and stays until the package
|
|
||||||
# departs, whereas BARCAP usually isn't part of a strike package and
|
|
||||||
# has a fixed mission time.
|
|
||||||
if task == FlightType.CAP:
|
|
||||||
if self.package.target.is_friendly(to_player=True):
|
|
||||||
task = FlightType.BARCAP
|
|
||||||
else:
|
|
||||||
task = FlightType.TARCAP
|
|
||||||
self.flight.flight_type = task
|
self.flight.flight_type = task
|
||||||
self.planner.populate_flight_plan(self.flight)
|
try:
|
||||||
|
self.planner.populate_flight_plan(self.flight)
|
||||||
|
except PlanningError as ex:
|
||||||
|
self.flight.flight_type = original_task
|
||||||
|
logging.exception("Could not recreate flight")
|
||||||
|
QMessageBox.critical(
|
||||||
|
self, "Could not recreate flight", str(ex), QMessageBox.Ok
|
||||||
|
)
|
||||||
self.flight_waypoint_list.update_list()
|
self.flight_waypoint_list.update_list()
|
||||||
self.on_change()
|
self.on_change()
|
||||||
|
|
||||||
|
|||||||
@ -2,3 +2,4 @@ from .base import *
|
|||||||
from .conflicttheater import *
|
from .conflicttheater import *
|
||||||
from .controlpoint import *
|
from .controlpoint import *
|
||||||
from .missiontarget import MissionTarget
|
from .missiontarget import MissionTarget
|
||||||
|
from .theatergroundobject import SamGroundObject
|
||||||
|
|||||||
@ -18,6 +18,7 @@ from dcs.terrain import (
|
|||||||
)
|
)
|
||||||
from dcs.terrain.terrain import Terrain
|
from dcs.terrain.terrain import Terrain
|
||||||
|
|
||||||
|
from gen.flights.flight import FlightType
|
||||||
from .controlpoint import ControlPoint, MissionTarget
|
from .controlpoint import ControlPoint, MissionTarget
|
||||||
from .landmap import Landmap, load_landmap, poly_contains
|
from .landmap import Landmap, load_landmap, poly_contains
|
||||||
|
|
||||||
@ -354,6 +355,14 @@ class FrontLine(MissionTarget):
|
|||||||
"""Returns True if the objective is in friendly territory."""
|
"""Returns True if the objective is in friendly territory."""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
|
||||||
|
yield from [
|
||||||
|
FlightType.CAS,
|
||||||
|
# TODO: FlightType.TROOP_TRANSPORT
|
||||||
|
# TODO: FlightType.EVAC
|
||||||
|
]
|
||||||
|
yield from super().mission_types(for_player)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def position(self):
|
def position(self):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -2,8 +2,8 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import itertools
|
import itertools
|
||||||
import re
|
import re
|
||||||
from typing import Dict, List, TYPE_CHECKING
|
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
from typing import Dict, Iterator, List, TYPE_CHECKING
|
||||||
|
|
||||||
from dcs.mapping import Point
|
from dcs.mapping import Point
|
||||||
from dcs.ships import (
|
from dcs.ships import (
|
||||||
@ -20,12 +20,12 @@ from .base import Base
|
|||||||
from .missiontarget import MissionTarget
|
from .missiontarget import MissionTarget
|
||||||
from .theatergroundobject import (
|
from .theatergroundobject import (
|
||||||
BaseDefenseGroundObject,
|
BaseDefenseGroundObject,
|
||||||
SamGroundObject,
|
|
||||||
TheaterGroundObject,
|
TheaterGroundObject,
|
||||||
)
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from game import Game
|
from game import Game
|
||||||
|
from gen.flights.flight import FlightType
|
||||||
|
|
||||||
|
|
||||||
class ControlPointType(Enum):
|
class ControlPointType(Enum):
|
||||||
@ -237,3 +237,28 @@ class ControlPoint(MissionTarget):
|
|||||||
from .start_generator import BaseDefenseGenerator
|
from .start_generator import BaseDefenseGenerator
|
||||||
self.base_defenses = []
|
self.base_defenses = []
|
||||||
BaseDefenseGenerator(game, self).generate()
|
BaseDefenseGenerator(game, self).generate()
|
||||||
|
|
||||||
|
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
|
||||||
|
yield from super().mission_types(for_player)
|
||||||
|
if self.is_friendly(for_player):
|
||||||
|
if self.is_fleet:
|
||||||
|
yield from [
|
||||||
|
# TODO: FlightType.INTERCEPTION
|
||||||
|
# TODO: Buddy tanking for the A-4?
|
||||||
|
# TODO: Rescue chopper?
|
||||||
|
# TODO: Inter-ship logistics?
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
yield from [
|
||||||
|
# TODO: FlightType.INTERCEPTION
|
||||||
|
# TODO: FlightType.LOGISTICS
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
if self.is_fleet:
|
||||||
|
yield from [
|
||||||
|
# TODO: FlightType.ANTISHIP
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
yield from [
|
||||||
|
# TODO: FlightType.STRIKE
|
||||||
|
]
|
||||||
|
|||||||
@ -1,7 +1,12 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Iterator, TYPE_CHECKING
|
||||||
|
|
||||||
from dcs.mapping import Point
|
from dcs.mapping import Point
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from gen.flights.flight import FlightType
|
||||||
|
|
||||||
|
|
||||||
class MissionTarget:
|
class MissionTarget:
|
||||||
def __init__(self, name: str, position: Point) -> None:
|
def __init__(self, name: str, position: Point) -> None:
|
||||||
@ -21,3 +26,18 @@ class MissionTarget:
|
|||||||
def is_friendly(self, to_player: bool) -> bool:
|
def is_friendly(self, to_player: bool) -> bool:
|
||||||
"""Returns True if the objective is in friendly territory."""
|
"""Returns True if the objective is in friendly territory."""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
|
||||||
|
from gen.flights.flight import FlightType
|
||||||
|
if self.is_friendly(for_player):
|
||||||
|
yield FlightType.BARCAP
|
||||||
|
else:
|
||||||
|
yield from [
|
||||||
|
FlightType.ESCORT,
|
||||||
|
FlightType.TARCAP,
|
||||||
|
FlightType.SEAD,
|
||||||
|
FlightType.SWEEP,
|
||||||
|
# TODO: FlightType.ELINT,
|
||||||
|
# TODO: FlightType.EWAR,
|
||||||
|
# TODO: FlightType.RECON,
|
||||||
|
]
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import itertools
|
import itertools
|
||||||
from typing import List, TYPE_CHECKING
|
from typing import Iterator, List, TYPE_CHECKING
|
||||||
|
|
||||||
from dcs.mapping import Point
|
from dcs.mapping import Point
|
||||||
from dcs.unit import Unit
|
from dcs.unit import Unit
|
||||||
@ -9,6 +9,8 @@ from dcs.unitgroup import Group
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .controlpoint import ControlPoint
|
from .controlpoint import ControlPoint
|
||||||
|
from gen.flights.flight import FlightType
|
||||||
|
|
||||||
from .missiontarget import MissionTarget
|
from .missiontarget import MissionTarget
|
||||||
|
|
||||||
NAME_BY_CATEGORY = {
|
NAME_BY_CATEGORY = {
|
||||||
@ -114,7 +116,18 @@ class TheaterGroundObject(MissionTarget):
|
|||||||
return "BLUE" if self.control_point.captured else "RED"
|
return "BLUE" if self.control_point.captured else "RED"
|
||||||
|
|
||||||
def is_friendly(self, to_player: bool) -> bool:
|
def is_friendly(self, to_player: bool) -> bool:
|
||||||
return not self.control_point.is_friendly(to_player)
|
return self.control_point.is_friendly(to_player)
|
||||||
|
|
||||||
|
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
|
||||||
|
from gen.flights.flight import FlightType
|
||||||
|
if self.is_friendly(for_player):
|
||||||
|
yield from [
|
||||||
|
# TODO: FlightType.LOGISTICS
|
||||||
|
# TODO: FlightType.TROOP_TRANSPORT
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
yield FlightType.STRIKE
|
||||||
|
yield from super().mission_types(for_player)
|
||||||
|
|
||||||
|
|
||||||
class BuildingGroundObject(TheaterGroundObject):
|
class BuildingGroundObject(TheaterGroundObject):
|
||||||
@ -240,6 +253,12 @@ class SamGroundObject(BaseDefenseGroundObject):
|
|||||||
else:
|
else:
|
||||||
return super().group_name
|
return super().group_name
|
||||||
|
|
||||||
|
def mission_types(self, for_player: bool) -> Iterator[FlightType]:
|
||||||
|
from gen.flights.flight import FlightType
|
||||||
|
if not self.is_friendly(for_player):
|
||||||
|
yield FlightType.DEAD
|
||||||
|
yield from super().mission_types(for_player)
|
||||||
|
|
||||||
|
|
||||||
class EwrGroundObject(BaseDefenseGroundObject):
|
class EwrGroundObject(BaseDefenseGroundObject):
|
||||||
def __init__(self, name: str, group_id: int, position: Point,
|
def __init__(self, name: str, group_id: int, position: Point,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user