mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Add BAI missions.
BAI is used for attacking ground vehicles as opposed to buildings like strike does, and not air defenses like DEAD does. Unlike strike, BAI is tolerant of moving targets. Fixes https://github.com/Khopa/dcs_liberation/issues/216
This commit is contained in:
parent
8bd00bf450
commit
9fb33526a7
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
# Features/Improvements
|
# Features/Improvements
|
||||||
* **[Flight Planner]** Added fighter sweep missions.
|
* **[Flight Planner]** Added fighter sweep missions.
|
||||||
|
* **[Flight Planner]** Added BAI missions.
|
||||||
* **[Flight Planner]** Differentiated BARCAP and TARCAP. TARCAP is now for hostile areas and will arrive before the package.
|
* **[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
|
* **[Modding]** Possible to setup liveries overrides for factions
|
||||||
|
|
||||||
|
|||||||
@ -1279,6 +1279,7 @@ class PydcsWaypointBuilder:
|
|||||||
package: Package, flight: Flight,
|
package: Package, flight: Flight,
|
||||||
mission: Mission) -> PydcsWaypointBuilder:
|
mission: Mission) -> PydcsWaypointBuilder:
|
||||||
builders = {
|
builders = {
|
||||||
|
FlightWaypointType.INGRESS_BAI: BaiIngressBuilder,
|
||||||
FlightWaypointType.INGRESS_CAS: CasIngressBuilder,
|
FlightWaypointType.INGRESS_CAS: CasIngressBuilder,
|
||||||
FlightWaypointType.INGRESS_DEAD: DeadIngressBuilder,
|
FlightWaypointType.INGRESS_DEAD: DeadIngressBuilder,
|
||||||
FlightWaypointType.INGRESS_SEAD: SeadIngressBuilder,
|
FlightWaypointType.INGRESS_SEAD: SeadIngressBuilder,
|
||||||
@ -1339,6 +1340,32 @@ class HoldPointBuilder(PydcsWaypointBuilder):
|
|||||||
return waypoint
|
return waypoint
|
||||||
|
|
||||||
|
|
||||||
|
class BaiIngressBuilder(PydcsWaypointBuilder):
|
||||||
|
def build(self) -> MovingPoint:
|
||||||
|
waypoint = super().build()
|
||||||
|
|
||||||
|
target_group = self.package.target
|
||||||
|
if isinstance(target_group, TheaterGroundObject):
|
||||||
|
# Match search is used due to TheaterGroundObject.name not matching
|
||||||
|
# the Mission group name because of SkyNet prefixes.
|
||||||
|
tgroup = self.mission.find_group(target_group.group_name,
|
||||||
|
search="match")
|
||||||
|
if tgroup is not None:
|
||||||
|
task = AttackGroup(tgroup.id, weapon_type=WeaponType.Auto)
|
||||||
|
task.params["attackQtyLimit"] = False
|
||||||
|
task.params["directionEnabled"] = False
|
||||||
|
task.params["altitudeEnabled"] = False
|
||||||
|
task.params["groupAttack"] = True
|
||||||
|
waypoint.tasks.append(task)
|
||||||
|
else:
|
||||||
|
logging.error("Could not find group for BAI mission %s",
|
||||||
|
target_group.group_name)
|
||||||
|
else:
|
||||||
|
logging.error("Unexpected target type for BAI mission: %s",
|
||||||
|
target_group.__class__.__name__)
|
||||||
|
return waypoint
|
||||||
|
|
||||||
|
|
||||||
class CasIngressBuilder(PydcsWaypointBuilder):
|
class CasIngressBuilder(PydcsWaypointBuilder):
|
||||||
def build(self) -> MovingPoint:
|
def build(self) -> MovingPoint:
|
||||||
waypoint = super().build()
|
waypoint = super().build()
|
||||||
@ -1372,14 +1399,16 @@ class DeadIngressBuilder(PydcsWaypointBuilder):
|
|||||||
|
|
||||||
target_group = self.package.target
|
target_group = self.package.target
|
||||||
if isinstance(target_group, TheaterGroundObject):
|
if isinstance(target_group, TheaterGroundObject):
|
||||||
tgroup = self.mission.find_group(target_group.group_name, search="match") # Match search is used due to TheaterGroundObject.name not matching
|
# Match search is used due to TheaterGroundObject.name not matching
|
||||||
if tgroup is not None: # the Mission group name because of SkyNet prefixes.
|
# the Mission group name because of SkyNet prefixes.
|
||||||
task = AttackGroup(tgroup.id)
|
tgroup = self.mission.find_group(target_group.group_name,
|
||||||
|
search="match")
|
||||||
|
if tgroup is not None:
|
||||||
|
task = AttackGroup(tgroup.id, weapon_type=WeaponType.Guided)
|
||||||
task.params["expend"] = "All"
|
task.params["expend"] = "All"
|
||||||
task.params["attackQtyLimit"] = False
|
task.params["attackQtyLimit"] = False
|
||||||
task.params["directionEnabled"] = False
|
task.params["directionEnabled"] = False
|
||||||
task.params["altitudeEnabled"] = False
|
task.params["altitudeEnabled"] = False
|
||||||
task.params["weaponType"] = 268402702 # Guided Weapons
|
|
||||||
task.params["groupAttack"] = True
|
task.params["groupAttack"] = True
|
||||||
waypoint.tasks.append(task)
|
waypoint.tasks.append(task)
|
||||||
else:
|
else:
|
||||||
@ -1394,8 +1423,11 @@ class SeadIngressBuilder(PydcsWaypointBuilder):
|
|||||||
|
|
||||||
target_group = self.package.target
|
target_group = self.package.target
|
||||||
if isinstance(target_group, TheaterGroundObject):
|
if isinstance(target_group, TheaterGroundObject):
|
||||||
tgroup = self.mission.find_group(target_group.group_name, search="match") # Match search is used due to TheaterGroundObject.name not matching
|
# Match search is used due to TheaterGroundObject.name not matching
|
||||||
if tgroup is not None: # the Mission group name because of SkyNet prefixes.
|
# the Mission group name because of SkyNet prefixes.
|
||||||
|
tgroup = self.mission.find_group(target_group.group_name,
|
||||||
|
search="match")
|
||||||
|
if tgroup is not None:
|
||||||
waypoint.add_task(EngageTargetsInZone(
|
waypoint.add_task(EngageTargetsInZone(
|
||||||
position=tgroup.position,
|
position=tgroup.position,
|
||||||
radius=nm_to_meter(30),
|
radius=nm_to_meter(30),
|
||||||
|
|||||||
@ -64,6 +64,7 @@ class FlightWaypointType(Enum):
|
|||||||
INGRESS_ESCORT = 19
|
INGRESS_ESCORT = 19
|
||||||
INGRESS_DEAD = 20
|
INGRESS_DEAD = 20
|
||||||
INGRESS_SWEEP = 21
|
INGRESS_SWEEP = 21
|
||||||
|
INGRESS_BAI = 22
|
||||||
|
|
||||||
|
|
||||||
class FlightWaypoint:
|
class FlightWaypoint:
|
||||||
|
|||||||
@ -629,7 +629,9 @@ class FlightPlanBuilder:
|
|||||||
custom_targets: Optional[List[Unit]]) -> FlightPlan:
|
custom_targets: Optional[List[Unit]]) -> FlightPlan:
|
||||||
# TODO: Flesh out mission types.
|
# TODO: Flesh out mission types.
|
||||||
task = flight.flight_type
|
task = flight.flight_type
|
||||||
if task == FlightType.BARCAP:
|
if task == FlightType.BAI:
|
||||||
|
return self.generate_bai(flight)
|
||||||
|
elif task == FlightType.BARCAP:
|
||||||
return self.generate_barcap(flight)
|
return self.generate_barcap(flight)
|
||||||
elif task == FlightType.CAS:
|
elif task == FlightType.CAS:
|
||||||
return self.generate_cas(flight)
|
return self.generate_cas(flight)
|
||||||
@ -702,6 +704,23 @@ class FlightPlanBuilder:
|
|||||||
|
|
||||||
return self.strike_flightplan(flight, location, targets)
|
return self.strike_flightplan(flight, location, targets)
|
||||||
|
|
||||||
|
def generate_bai(self, flight: Flight) -> StrikeFlightPlan:
|
||||||
|
"""Generates a BAI flight plan.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
flight: The flight to generate the flight plan for.
|
||||||
|
"""
|
||||||
|
location = self.package.target
|
||||||
|
|
||||||
|
if not isinstance(location, TheaterGroundObject):
|
||||||
|
raise InvalidObjectiveLocation(flight.flight_type, location)
|
||||||
|
|
||||||
|
targets: List[StrikeTarget] = []
|
||||||
|
for group in location.groups:
|
||||||
|
targets.append(StrikeTarget(f"{group.id}", group))
|
||||||
|
|
||||||
|
return self.strike_flightplan(flight, location, targets)
|
||||||
|
|
||||||
def generate_barcap(self, flight: Flight) -> BarCapFlightPlan:
|
def generate_barcap(self, flight: Flight) -> BarCapFlightPlan:
|
||||||
"""Generate a BARCAP flight at a given location.
|
"""Generate a BARCAP flight at a given location.
|
||||||
|
|
||||||
@ -965,7 +984,9 @@ class FlightPlanBuilder:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def target_waypoint(flight: Flight, builder: WaypointBuilder,
|
def target_waypoint(flight: Flight, builder: WaypointBuilder,
|
||||||
target: StrikeTarget) -> FlightWaypoint:
|
target: StrikeTarget) -> FlightWaypoint:
|
||||||
if flight.flight_type == FlightType.DEAD:
|
if flight.flight_type == FlightType.BAI:
|
||||||
|
return builder.bai_group(target)
|
||||||
|
elif flight.flight_type == FlightType.DEAD:
|
||||||
return builder.dead_point(target)
|
return builder.dead_point(target)
|
||||||
elif flight.flight_type == FlightType.SEAD:
|
elif flight.flight_type == FlightType.SEAD:
|
||||||
return builder.sead_point(target)
|
return builder.sead_point(target)
|
||||||
@ -1068,7 +1089,6 @@ class FlightPlanBuilder:
|
|||||||
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,
|
||||||
targets)
|
targets)
|
||||||
# sead_types = {FlightType.DEAD, FlightType.SEAD}
|
|
||||||
if flight.flight_type is FlightType.SEAD:
|
if flight.flight_type is FlightType.SEAD:
|
||||||
ingress = builder.ingress_sead(self.package.waypoints.ingress,
|
ingress = builder.ingress_sead(self.package.waypoints.ingress,
|
||||||
location)
|
location)
|
||||||
@ -1076,6 +1096,9 @@ class FlightPlanBuilder:
|
|||||||
elif flight.flight_type is FlightType.DEAD:
|
elif flight.flight_type is FlightType.DEAD:
|
||||||
ingress = builder.ingress_dead(self.package.waypoints.ingress,
|
ingress = builder.ingress_dead(self.package.waypoints.ingress,
|
||||||
location)
|
location)
|
||||||
|
elif flight.flight_type is FlightType.BAI:
|
||||||
|
ingress = builder.ingress_bai(self.package.waypoints.ingress,
|
||||||
|
location)
|
||||||
else:
|
else:
|
||||||
ingress = builder.ingress_strike(self.package.waypoints.ingress,
|
ingress = builder.ingress_strike(self.package.waypoints.ingress,
|
||||||
location)
|
location)
|
||||||
|
|||||||
@ -5,6 +5,7 @@ from typing import List, Optional, Tuple, Union
|
|||||||
|
|
||||||
from dcs.mapping import Point
|
from dcs.mapping import Point
|
||||||
from dcs.unit import Unit
|
from dcs.unit import Unit
|
||||||
|
from dcs.unitgroup import VehicleGroup
|
||||||
|
|
||||||
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
|
||||||
@ -17,7 +18,7 @@ from ..runways import RunwayAssigner
|
|||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class StrikeTarget:
|
class StrikeTarget:
|
||||||
name: str
|
name: str
|
||||||
target: Union[TheaterGroundObject, Unit]
|
target: Union[VehicleGroup, TheaterGroundObject, Unit]
|
||||||
|
|
||||||
|
|
||||||
class WaypointBuilder:
|
class WaypointBuilder:
|
||||||
@ -168,6 +169,11 @@ class WaypointBuilder:
|
|||||||
objective: MissionTarget) -> FlightWaypoint:
|
objective: MissionTarget) -> FlightWaypoint:
|
||||||
return self._ingress(FlightWaypointType.INGRESS_ESCORT, position,
|
return self._ingress(FlightWaypointType.INGRESS_ESCORT, position,
|
||||||
objective)
|
objective)
|
||||||
|
|
||||||
|
def ingress_bai(self, position: Point,
|
||||||
|
objective: MissionTarget) -> FlightWaypoint:
|
||||||
|
return self._ingress(FlightWaypointType.INGRESS_BAI, position,
|
||||||
|
objective)
|
||||||
|
|
||||||
def ingress_dead(self, position:Point,
|
def ingress_dead(self, position:Point,
|
||||||
objective: MissionTarget) -> FlightWaypoint:
|
objective: MissionTarget) -> FlightWaypoint:
|
||||||
@ -211,6 +217,9 @@ class WaypointBuilder:
|
|||||||
waypoint.name = "EGRESS"
|
waypoint.name = "EGRESS"
|
||||||
return waypoint
|
return waypoint
|
||||||
|
|
||||||
|
def bai_group(self, target: StrikeTarget) -> FlightWaypoint:
|
||||||
|
return self._target_point(target, f"ATTACK {target.name}")
|
||||||
|
|
||||||
def dead_point(self, target: StrikeTarget) -> FlightWaypoint:
|
def dead_point(self, target: StrikeTarget) -> FlightWaypoint:
|
||||||
return self._target_point(target, f"STRIKE {target.name}")
|
return self._target_point(target, f"STRIKE {target.name}")
|
||||||
|
|
||||||
|
|||||||
@ -126,7 +126,10 @@ class TheaterGroundObject(MissionTarget):
|
|||||||
# TODO: FlightType.TROOP_TRANSPORT
|
# TODO: FlightType.TROOP_TRANSPORT
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
yield FlightType.STRIKE
|
yield from [
|
||||||
|
FlightType.STRIKE,
|
||||||
|
FlightType.BAI,
|
||||||
|
]
|
||||||
yield from super().mission_types(for_player)
|
yield from super().mission_types(for_player)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user