From 082e8c062c42b2be73d129f3f805217e9d42203e Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Mon, 16 Nov 2020 23:29:19 -0800 Subject: [PATCH] Add anti-ship missions. The only practical difference between this and BAI is that the target is floating, so this mostly shares its implementation with BAI. Fixes https://github.com/Khopa/dcs_liberation/issues/350 --- changelog.md | 1 + gen/flights/flightplan.py | 33 ++++++++++++++++++++++++++++++--- theater/controlpoint.py | 4 +--- theater/theatergroundobject.py | 12 ++++++++++-- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/changelog.md b/changelog.md index 8c55e2c0..8b9c30a9 100644 --- a/changelog.md +++ b/changelog.md @@ -3,6 +3,7 @@ # Features/Improvements * **[Flight Planner]** Added fighter sweep missions. * **[Flight Planner]** Added BAI missions. +* **[Flight Planner]** Added anti-ship missions. * **[Flight Planner]** Differentiated BARCAP and TARCAP. TARCAP is now for hostile areas and will arrive before the package. * **[Modding]** Possible to setup liveries overrides for factions diff --git a/gen/flights/flightplan.py b/gen/flights/flightplan.py index 433554c4..be09f3ba 100644 --- a/gen/flights/flightplan.py +++ b/gen/flights/flightplan.py @@ -629,7 +629,9 @@ class FlightPlanBuilder: custom_targets: Optional[List[Unit]]) -> FlightPlan: # TODO: Flesh out mission types. task = flight.flight_type - if task == FlightType.BAI: + if task == FlightType.ANTISHIP: + return self.generate_anti_ship(flight) + elif task == FlightType.BAI: return self.generate_bai(flight) elif task == FlightType.BARCAP: return self.generate_barcap(flight) @@ -722,6 +724,31 @@ class FlightPlanBuilder: return self.strike_flightplan(flight, location, targets) + def generate_anti_ship(self, flight: Flight) -> StrikeFlightPlan: + """Generates an anti-ship flight plan. + + Args: + flight: The flight to generate the flight plan for. + """ + location = self.package.target + + if isinstance(location, ControlPoint): + if location.is_fleet: + # The first group generated will be the carrier group itself. + location = location.ground_objects[0] + else: + raise InvalidObjectiveLocation(flight.flight_type, location) + + if not isinstance(location, TheaterGroundObject): + raise InvalidObjectiveLocation(flight.flight_type, location) + + targets: List[StrikeTarget] = [] + for group in location.groups: + targets.append( + StrikeTarget(f"{group.name} at {location.name}", group)) + + return self.strike_flightplan(flight, location, targets) + def generate_barcap(self, flight: Flight) -> BarCapFlightPlan: """Generate a BARCAP flight at a given location. @@ -985,7 +1012,7 @@ class FlightPlanBuilder: @staticmethod def target_waypoint(flight: Flight, builder: WaypointBuilder, target: StrikeTarget) -> FlightWaypoint: - if flight.flight_type == FlightType.BAI: + if flight.flight_type in {FlightType.ANTISHIP, FlightType.BAI}: return builder.bai_group(target) elif flight.flight_type == FlightType.DEAD: return builder.dead_point(target) @@ -1097,7 +1124,7 @@ class FlightPlanBuilder: elif flight.flight_type is FlightType.DEAD: ingress = builder.ingress_dead(self.package.waypoints.ingress, location) - elif flight.flight_type is FlightType.BAI: + elif flight.flight_type in {FlightType.ANTISHIP, FlightType.BAI}: ingress = builder.ingress_bai(self.package.waypoints.ingress, location) else: diff --git a/theater/controlpoint.py b/theater/controlpoint.py index 4dba0bd7..b4025663 100644 --- a/theater/controlpoint.py +++ b/theater/controlpoint.py @@ -255,9 +255,7 @@ class ControlPoint(MissionTarget): ] else: if self.is_fleet: - yield from [ - # TODO: FlightType.ANTISHIP - ] + yield FlightType.ANTISHIP else: yield from [ # TODO: FlightType.STRIKE diff --git a/theater/theatergroundobject.py b/theater/theatergroundobject.py index 5d44d198..d13b400c 100644 --- a/theater/theatergroundobject.py +++ b/theater/theatergroundobject.py @@ -156,7 +156,15 @@ class BuildingGroundObject(TheaterGroundObject): return f"{self.category}|{self.group_id}|{self.object_id}" -class GenericCarrierGroundObject(TheaterGroundObject): +class NavalGroundObject(TheaterGroundObject): + def mission_types(self, for_player: bool) -> Iterator[FlightType]: + from gen.flights.flight import FlightType + if not self.is_friendly(for_player): + yield FlightType.ANTISHIP + yield from super().mission_types(for_player) + + +class GenericCarrierGroundObject(NavalGroundObject): pass @@ -284,7 +292,7 @@ class EwrGroundObject(BaseDefenseGroundObject): return f"{self.faction_color}|{super().group_name}" -class ShipGroundObject(TheaterGroundObject): +class ShipGroundObject(NavalGroundObject): def __init__(self, name: str, group_id: int, position: Point, control_point: ControlPoint) -> None: super().__init__(