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
## Features/Improvements
* **[Mission Generation]** Given a CAS flight was planned, delay ground force attack until first CAS flight is on station
## Fixes
* **[UI]** Removed deprecated options

View File

@ -3,6 +3,7 @@ from __future__ import annotations
import logging
import math
import random
from datetime import timedelta
from typing import List, Optional, TYPE_CHECKING, Tuple
from dcs import Mission
@ -15,7 +16,6 @@ from dcs.task import (
AFAC,
AttackGroup,
ControlledTask,
EPLRS,
FAC,
FireAtPoint,
GoToWaypoint,
@ -47,6 +47,7 @@ from .frontlineconflictdescription import FrontLineConflictDescription
from .groundforcepainter import GroundForcePainter
from .lasercoderegistry import LaserCodeRegistry
from .missiondata import JtacInfo, MissionData
from ..ato import FlightType
if TYPE_CHECKING:
from game import Game
@ -276,8 +277,29 @@ class FlotGenerator:
vehicle = vg.units[0]
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(
self, dcs_group: VehicleGroup, forward_heading: Heading
self,
dcs_group: VehicleGroup,
forward_heading: Heading,
hold_duration: timedelta = timedelta(),
) -> None:
"""Setting a waypoint close to the spawn position allows the group to reform gracefully
rather than spin
@ -285,7 +307,10 @@ class FlotGenerator:
reform_point = dcs_group.position.point_from_heading(
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(
self,
@ -323,7 +348,7 @@ class FlotGenerator:
# Hold position
dcs_group.points[1].tasks.append(Hold())
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.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.
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:
# Attack nearest enemy if any
# 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.
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 [
CombatStance.AGGRESSIVE,
CombatStance.BREAKTHROUGH,
@ -496,8 +527,6 @@ class FlotGenerator:
return
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 self.game.settings.perf_artillery:
@ -519,7 +548,7 @@ class FlotGenerator:
if stance == CombatStance.RETREAT:
# 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 (
from_cp.position.distance_to_point(dcs_group.points[0].position)
<= RETREAT_DISTANCE
@ -537,7 +566,7 @@ class FlotGenerator:
self, dcs_group: VehicleGroup, forward_heading: Heading
) -> 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:
@ -554,7 +583,7 @@ class FlotGenerator:
# We add a new retreat waypoint
dcs_group.add_waypoint(
self.find_retreat_point(
dcs_group, forward_heading, (int)(RETREAT_DISTANCE / 8)
dcs_group, forward_heading, int(RETREAT_DISTANCE / 8)
),
self.wpt_pointaction,
)
@ -684,7 +713,7 @@ class FlotGenerator:
@staticmethod
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
if rg > DISTANCE_FROM_FRONTLINE[CombatGroupRole.ARTILLERY][1]: