mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Make AirAssault auto-plannable
This commit is contained in:
parent
ea74471307
commit
234dc52c7e
@ -17,6 +17,7 @@
|
||||
* **[UI]** Allow changing waypoint names in FlightEdit's waypoints tab
|
||||
* **[Waypoints]** Allow user to add navigation waypoints where possible without degrading to a custom flight-plan
|
||||
* **[Campaign Management]** Improve squadron retreat logic to account for parking-slot sizes
|
||||
* **[Autoplanner]** Support for auto-planning Air Assaults
|
||||
|
||||
## Fixes
|
||||
* **[Mission Generation]** Anti-ship strikes should use "group attack" in their attack-task
|
||||
|
||||
@ -167,6 +167,24 @@ class ObjectiveFinder:
|
||||
yield cp
|
||||
break
|
||||
|
||||
def vulnerable_enemy_control_points(self) -> Iterator[ControlPoint]:
|
||||
"""Iterates over enemy CPs that are vulnerable to Air Assault.
|
||||
Vulnerability is defined as any unit being alive in the CP's "blocking_capture" groups.
|
||||
"""
|
||||
for cp in self.enemy_control_points():
|
||||
include = True
|
||||
for tgo in cp.connected_objectives:
|
||||
if tgo.distance_to(cp) > cp.CAPTURE_DISTANCE.meters:
|
||||
continue
|
||||
for u in tgo.units:
|
||||
if u.is_vehicle and u.alive:
|
||||
include = False
|
||||
break
|
||||
if not include:
|
||||
break
|
||||
if include:
|
||||
yield cp
|
||||
|
||||
def oca_targets(self, min_aircraft: int) -> Iterator[ControlPoint]:
|
||||
parking_type = ParkingType()
|
||||
parking_type.include_rotary_wing = True
|
||||
|
||||
@ -7,6 +7,7 @@ from game.commander.tasks.compound.destroyenemygroundunits import (
|
||||
from game.commander.tasks.compound.reduceenemyfrontlinecapacity import (
|
||||
ReduceEnemyFrontLineCapacity,
|
||||
)
|
||||
from game.commander.tasks.primitive.airassault import PlanAirAssault
|
||||
from game.commander.tasks.primitive.breakthroughattack import BreakthroughAttack
|
||||
from game.commander.theaterstate import TheaterState
|
||||
from game.htn import CompoundTask, Method
|
||||
@ -22,6 +23,7 @@ class CaptureBase(CompoundTask[TheaterState]):
|
||||
yield [DestroyEnemyGroundUnits(self.front_line)]
|
||||
if self.worth_destroying_ammo_depots(state):
|
||||
yield [ReduceEnemyFrontLineCapacity(self.enemy_cp(state))]
|
||||
yield [PlanAirAssault(self.enemy_cp(state))]
|
||||
|
||||
def enemy_cp(self, state: TheaterState) -> ControlPoint:
|
||||
return self.front_line.control_point_hostile_to(state.context.coalition.player)
|
||||
|
||||
26
game/commander/tasks/primitive/airassault.py
Normal file
26
game/commander/tasks/primitive/airassault.py
Normal file
@ -0,0 +1,26 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from game.ato.flighttype import FlightType
|
||||
from game.commander.tasks.packageplanningtask import PackagePlanningTask
|
||||
from game.commander.theaterstate import TheaterState
|
||||
from game.theater import ControlPoint
|
||||
|
||||
|
||||
@dataclass
|
||||
class PlanAirAssault(PackagePlanningTask[ControlPoint]):
|
||||
def preconditions_met(self, state: TheaterState) -> bool:
|
||||
if self.target not in state.vulnerable_control_points:
|
||||
return False
|
||||
if not self.target_area_preconditions_met(state):
|
||||
return False
|
||||
return super().preconditions_met(state)
|
||||
|
||||
def apply_effects(self, state: TheaterState) -> None:
|
||||
state.vulnerable_control_points.remove(self.target)
|
||||
|
||||
def propose_flights(self) -> None:
|
||||
size = self.get_flight_size()
|
||||
self.propose_flight(FlightType.AIR_ASSAULT, size)
|
||||
self.propose_common_escorts()
|
||||
@ -60,6 +60,7 @@ class TheaterState(WorldState["TheaterState"]):
|
||||
strike_targets: list[TheaterGroundObject]
|
||||
enemy_barcaps: list[ControlPoint]
|
||||
threat_zones: ThreatZones
|
||||
vulnerable_control_points: list[ControlPoint]
|
||||
|
||||
def _rebuild_threat_zones(self) -> None:
|
||||
"""Recreates the theater's threat zones based on the current planned state."""
|
||||
@ -133,6 +134,7 @@ class TheaterState(WorldState["TheaterState"]):
|
||||
# IADS threats so that DegradeIads will consider it a threat later.
|
||||
threatening_air_defenses=self.threatening_air_defenses,
|
||||
detecting_air_defenses=self.detecting_air_defenses,
|
||||
vulnerable_control_points=self.vulnerable_control_points,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@ -181,4 +183,5 @@ class TheaterState(WorldState["TheaterState"]):
|
||||
strike_targets=list(finder.strike_targets()),
|
||||
enemy_barcaps=list(game.theater.control_points_for(not player)),
|
||||
threat_zones=game.threat_zone_for(not player),
|
||||
vulnerable_control_points=list(finder.vulnerable_enemy_control_points()),
|
||||
)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user