Delay ground force attack until first friendly CAS TOT

If no friendly CAS flight was planned, no delay is planned...
This commit is contained in:
Raffson 2022-12-25 16:29:09 +01:00
parent c5a7fbd15a
commit b0a0050725
No known key found for this signature in database
GPG Key ID: B0402B2C9B764D99
2 changed files with 42 additions and 12 deletions

View File

@ -1,6 +1,7 @@
# Retribution 1.1.0 # Retribution 1.1.0
## Features/Improvements ## Features/Improvements
* **[Mission Generation]** Given a CAS flight was planned, delay ground force attack until first CAS flight is on station
## Fixes ## Fixes
* **[UI]** Removed deprecated options * **[UI]** Removed deprecated options

View File

@ -3,6 +3,7 @@ from __future__ import annotations
import logging import logging
import math import math
import random import random
from datetime import timedelta
from typing import List, Optional, TYPE_CHECKING, Tuple from typing import List, Optional, TYPE_CHECKING, Tuple
from dcs import Mission from dcs import Mission
@ -15,7 +16,6 @@ from dcs.task import (
AFAC, AFAC,
AttackGroup, AttackGroup,
ControlledTask, ControlledTask,
EPLRS,
FAC, FAC,
FireAtPoint, FireAtPoint,
GoToWaypoint, GoToWaypoint,
@ -47,6 +47,7 @@ from .frontlineconflictdescription import FrontLineConflictDescription
from .groundforcepainter import GroundForcePainter from .groundforcepainter import GroundForcePainter
from .lasercoderegistry import LaserCodeRegistry from .lasercoderegistry import LaserCodeRegistry
from .missiondata import JtacInfo, MissionData from .missiondata import JtacInfo, MissionData
from ..ato import FlightType
if TYPE_CHECKING: if TYPE_CHECKING:
from game import Game from game import Game
@ -276,8 +277,29 @@ class FlotGenerator:
vehicle = vg.units[0] vehicle = vg.units[0]
GroundForcePainter(faction, vehicle).apply_livery() GroundForcePainter(faction, vehicle).apply_livery()
def _earliest_tot_on_flot(self, player: bool) -> timedelta:
tots = [
x.time_over_target
for x in self.game.ato_for(player).packages
if x.primary_task == FlightType.CAS
]
return (
timedelta()
if len(tots) == 0
else min(
[
x.time_over_target
for x in self.game.ato_for(player).packages
if x.primary_task == FlightType.CAS
]
)
)
def _set_reform_waypoint( def _set_reform_waypoint(
self, dcs_group: VehicleGroup, forward_heading: Heading self,
dcs_group: VehicleGroup,
forward_heading: Heading,
hold_duration: timedelta = timedelta(),
) -> None: ) -> None:
"""Setting a waypoint close to the spawn position allows the group to reform gracefully """Setting a waypoint close to the spawn position allows the group to reform gracefully
rather than spin rather than spin
@ -285,7 +307,10 @@ class FlotGenerator:
reform_point = dcs_group.position.point_from_heading( reform_point = dcs_group.position.point_from_heading(
forward_heading.degrees, 50 forward_heading.degrees, 50
) )
dcs_group.add_waypoint(reform_point) rp = dcs_group.add_waypoint(reform_point)
hold = ControlledTask(Hold())
hold.stop_after_duration(hold_duration.seconds)
rp.add_task(hold)
def _plan_artillery_action( def _plan_artillery_action(
self, self,
@ -323,7 +348,7 @@ class FlotGenerator:
# Hold position # Hold position
dcs_group.points[1].tasks.append(Hold()) dcs_group.points[1].tasks.append(Hold())
retreat = self.find_retreat_point( retreat = self.find_retreat_point(
dcs_group, forward_heading, (int)(RETREAT_DISTANCE / 3) dcs_group, forward_heading, int(RETREAT_DISTANCE / 3)
) )
dcs_group.add_waypoint( dcs_group.add_waypoint(
dcs_group.position.point_from_heading(forward_heading.degrees, 1), dcs_group.position.point_from_heading(forward_heading.degrees, 1),
@ -370,7 +395,10 @@ class FlotGenerator:
Handles adding the DCS tasks for tank and IFV groups for all combat stances. Handles adding the DCS tasks for tank and IFV groups for all combat stances.
Returns True if tasking was added, returns False if the stance was not a combat stance. Returns True if tasking was added, returns False if the stance was not a combat stance.
""" """
self._set_reform_waypoint(dcs_group, forward_heading) duration = timedelta()
if stance != CombatStance.RETREAT:
duration = self._earliest_tot_on_flot(not to_cp.coalition.player)
self._set_reform_waypoint(dcs_group, forward_heading, duration)
if stance == CombatStance.AGGRESSIVE: if stance == CombatStance.AGGRESSIVE:
# Attack nearest enemy if any # Attack nearest enemy if any
# Then move forward OR Attack enemy base if it is not too far away # Then move forward OR Attack enemy base if it is not too far away
@ -457,7 +485,10 @@ class FlotGenerator:
Handles adding the DCS tasks for APC and ATGM groups for all combat stances. Handles adding the DCS tasks for APC and ATGM groups for all combat stances.
Returns True if tasking was added, returns False if the stance was not a combat stance. Returns True if tasking was added, returns False if the stance was not a combat stance.
""" """
self._set_reform_waypoint(dcs_group, forward_heading) duration = timedelta()
if stance != CombatStance.RETREAT:
duration = self._earliest_tot_on_flot(not to_cp.coalition.player)
self._set_reform_waypoint(dcs_group, forward_heading, duration)
if stance in [ if stance in [
CombatStance.AGGRESSIVE, CombatStance.AGGRESSIVE,
CombatStance.BREAKTHROUGH, CombatStance.BREAKTHROUGH,
@ -496,8 +527,6 @@ class FlotGenerator:
return return
for dcs_group, group in ally_groups: for dcs_group, group in ally_groups:
if group.unit_type.eplrs_capable:
dcs_group.points[0].tasks.append(EPLRS(dcs_group.id))
if group.role == CombatGroupRole.ARTILLERY: if group.role == CombatGroupRole.ARTILLERY:
if self.game.settings.perf_artillery: if self.game.settings.perf_artillery:
@ -519,7 +548,7 @@ class FlotGenerator:
if stance == CombatStance.RETREAT: if stance == CombatStance.RETREAT:
# In retreat mode, the units will fall back # In retreat mode, the units will fall back
# If the ally base is close enough, the units will even regroup there # If the allied base is close enough, the units will even regroup there
if ( if (
from_cp.position.distance_to_point(dcs_group.points[0].position) from_cp.position.distance_to_point(dcs_group.points[0].position)
<= RETREAT_DISTANCE <= RETREAT_DISTANCE
@ -537,7 +566,7 @@ class FlotGenerator:
self, dcs_group: VehicleGroup, forward_heading: Heading self, dcs_group: VehicleGroup, forward_heading: Heading
) -> None: ) -> None:
""" """
This add a trigger to manage units fleeing whenever their group is hit hard, or being engaged by CAS This adds a trigger to manage units fleeing whenever their group is hit hard, or being engaged by CAS
""" """
if len(dcs_group.units) == 1: if len(dcs_group.units) == 1:
@ -554,7 +583,7 @@ class FlotGenerator:
# We add a new retreat waypoint # We add a new retreat waypoint
dcs_group.add_waypoint( dcs_group.add_waypoint(
self.find_retreat_point( self.find_retreat_point(
dcs_group, forward_heading, (int)(RETREAT_DISTANCE / 8) dcs_group, forward_heading, int(RETREAT_DISTANCE / 8)
), ),
self.wpt_pointaction, self.wpt_pointaction,
) )
@ -684,7 +713,7 @@ class FlotGenerator:
@staticmethod @staticmethod
def get_artilery_group_distance_from_frontline(group: CombatGroup) -> int: def get_artilery_group_distance_from_frontline(group: CombatGroup) -> int:
""" """
For artilery group, decide the distance from frontline with the range of the unit For artillery group, decide the distance from frontline with the range of the unit
""" """
rg = group.unit_type.dcs_unit_type.threat_range - 7500 rg = group.unit_type.dcs_unit_type.threat_range - 7500
if rg > DISTANCE_FROM_FRONTLINE[CombatGroupRole.ARTILLERY][1]: if rg > DISTANCE_FROM_FRONTLINE[CombatGroupRole.ARTILLERY][1]: