mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
EW Script 2.0 - Enable for AI (#491)
* EW Script 2.0 - Enable for AI * Refactor * Remove unnecessary code + refactor * Fix test -_- * Cleanup --------- Co-authored-by: Raffson <Raffson@users.noreply.github.com> Co-authored-by: Starfire13 <72491792+Starfire13@users.noreply.github.com>
This commit is contained in:
parent
c3fea788f3
commit
af4bba7396
@ -173,18 +173,24 @@ class FlightGroupConfigurator:
|
|||||||
self, unit: FlyingUnit, member: FlightMember, laser_codes: list[Optional[int]]
|
self, unit: FlyingUnit, member: FlightMember, laser_codes: list[Optional[int]]
|
||||||
) -> None:
|
) -> None:
|
||||||
self.set_skill(unit, member)
|
self.set_skill(unit, member)
|
||||||
|
|
||||||
if (code := member.tgp_laser_code) is not None:
|
if (code := member.tgp_laser_code) is not None:
|
||||||
laser_codes.append(code.code)
|
laser_codes.append(code.code)
|
||||||
else:
|
else:
|
||||||
laser_codes.append(None)
|
laser_codes.append(None)
|
||||||
settings = self.flight.coalition.game.settings
|
|
||||||
if not member.is_player or not settings.plugins.get("ewrj"):
|
self.handle_ew_jamming(member, unit)
|
||||||
|
|
||||||
|
def handle_ew_jamming(self, member: FlightMember, unit: FlyingUnit) -> None:
|
||||||
|
if not member.is_player:
|
||||||
return
|
return
|
||||||
|
settings = self.flight.coalition.game.settings
|
||||||
|
# Check if ecm_required option is enabled
|
||||||
jammer_required = settings.plugin_option("ewrj.ecm_required")
|
jammer_required = settings.plugin_option("ewrj.ecm_required")
|
||||||
if jammer_required:
|
has_jammer = member.loadout.has_weapon_of_type(WeaponType.JAMMER)
|
||||||
ecm = WeaponType.JAMMER
|
if jammer_required and not has_jammer:
|
||||||
if not member.loadout.has_weapon_of_type(ecm):
|
return
|
||||||
return
|
# Create the original ewrj_menu_trigger for player flight members
|
||||||
ewrj_menu_trigger = TriggerStart(comment=f"EWRJ-{unit.name}")
|
ewrj_menu_trigger = TriggerStart(comment=f"EWRJ-{unit.name}")
|
||||||
ewrj_menu_trigger.add_action(DoScript(String(f'EWJamming("{unit.name}")')))
|
ewrj_menu_trigger.add_action(DoScript(String(f'EWJamming("{unit.name}")')))
|
||||||
self.mission.triggerrules.triggers.append(ewrj_menu_trigger)
|
self.mission.triggerrules.triggers.append(ewrj_menu_trigger)
|
||||||
|
|||||||
@ -9,9 +9,13 @@ from dcs.task import (
|
|||||||
OptFormation,
|
OptFormation,
|
||||||
Targets,
|
Targets,
|
||||||
SetUnlimitedFuelCommand,
|
SetUnlimitedFuelCommand,
|
||||||
|
RunScript,
|
||||||
|
OptReactOnThreat,
|
||||||
)
|
)
|
||||||
|
|
||||||
from game.ato import FlightType
|
from game.ato import FlightType
|
||||||
|
from game.data.doctrine import Doctrine
|
||||||
|
from game.data.weapons import WeaponType
|
||||||
from game.theater import NavalControlPoint
|
from game.theater import NavalControlPoint
|
||||||
from game.utils import nautical_miles, feet
|
from game.utils import nautical_miles, feet
|
||||||
from .pydcswaypointbuilder import PydcsWaypointBuilder
|
from .pydcswaypointbuilder import PydcsWaypointBuilder
|
||||||
@ -54,29 +58,24 @@ class JoinPointBuilder(PydcsWaypointBuilder):
|
|||||||
max_dist=doctrine.escort_engagement_range.nautical_miles,
|
max_dist=doctrine.escort_engagement_range.nautical_miles,
|
||||||
vertical_spacing=doctrine.escort_spacing.feet,
|
vertical_spacing=doctrine.escort_spacing.feet,
|
||||||
)
|
)
|
||||||
elif self.flight.flight_type == FlightType.SEAD_ESCORT:
|
|
||||||
if isinstance(self.flight.package.target, NavalControlPoint):
|
elif self.flight.flight_type in [
|
||||||
self.configure_escort_tasks(
|
FlightType.SEAD_SWEEP,
|
||||||
waypoint,
|
FlightType.SEAD,
|
||||||
[
|
FlightType.SEAD_ESCORT,
|
||||||
Targets.All.Naval.id,
|
]:
|
||||||
Targets.All.GroundUnits.AirDefence.AAA.SAMRelated.id,
|
self.start_defensive_jamming(waypoint)
|
||||||
],
|
if self.flight.flight_type == FlightType.SEAD_ESCORT:
|
||||||
max_dist=doctrine.sead_escort_engagement_range.nautical_miles,
|
self.handle_sead_escort(doctrine, waypoint)
|
||||||
vertical_spacing=doctrine.sead_escort_spacing.feet,
|
# Let the AI use ECM to preemptively defend themselves.
|
||||||
|
ecm_option = OptECMUsing(
|
||||||
|
value=OptECMUsing.Values.UseIfDetectedLockByRadar
|
||||||
)
|
)
|
||||||
|
waypoint.tasks.append(ecm_option)
|
||||||
else:
|
else:
|
||||||
self.configure_escort_tasks(
|
# Let the AI use ECM to defend themselves.
|
||||||
waypoint,
|
ecm_option = OptECMUsing(value=OptECMUsing.Values.UseIfOnlyLockByRadar)
|
||||||
[Targets.All.GroundUnits.AirDefence.AAA.SAMRelated.id],
|
waypoint.tasks.append(ecm_option)
|
||||||
max_dist=doctrine.sead_escort_engagement_range.nautical_miles,
|
|
||||||
vertical_spacing=doctrine.sead_escort_spacing.feet,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Let the AI use ECM to preemptively defend themselves.
|
|
||||||
ecm_option = OptECMUsing(value=OptECMUsing.Values.UseIfDetectedLockByRadar)
|
|
||||||
waypoint.tasks.append(ecm_option)
|
|
||||||
|
|
||||||
elif not self.flight.flight_type.is_air_to_air:
|
elif not self.flight.flight_type.is_air_to_air:
|
||||||
# Capture any non A/A type to avoid issues with SPJs that use the primary radar such as the F/A-18C.
|
# Capture any non A/A type to avoid issues with SPJs that use the primary radar such as the F/A-18C.
|
||||||
# You can bully them with STT to not be able to fire radar guided missiles at you,
|
# You can bully them with STT to not be able to fire radar guided missiles at you,
|
||||||
@ -86,6 +85,47 @@ class JoinPointBuilder(PydcsWaypointBuilder):
|
|||||||
ecm_option = OptECMUsing(value=OptECMUsing.Values.UseIfOnlyLockByRadar)
|
ecm_option = OptECMUsing(value=OptECMUsing.Values.UseIfOnlyLockByRadar)
|
||||||
waypoint.tasks.append(ecm_option)
|
waypoint.tasks.append(ecm_option)
|
||||||
|
|
||||||
|
def handle_sead_escort(self, doctrine: Doctrine, waypoint: MovingPoint) -> None:
|
||||||
|
if isinstance(self.flight.package.target, NavalControlPoint):
|
||||||
|
self.configure_escort_tasks(
|
||||||
|
waypoint,
|
||||||
|
[
|
||||||
|
Targets.All.Naval.id,
|
||||||
|
Targets.All.GroundUnits.AirDefence.AAA.SAMRelated.id,
|
||||||
|
],
|
||||||
|
max_dist=doctrine.sead_escort_engagement_range.nautical_miles,
|
||||||
|
vertical_spacing=doctrine.sead_escort_spacing.feet,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.configure_escort_tasks(
|
||||||
|
waypoint,
|
||||||
|
[Targets.All.GroundUnits.AirDefence.AAA.SAMRelated.id],
|
||||||
|
max_dist=doctrine.sead_escort_engagement_range.nautical_miles,
|
||||||
|
vertical_spacing=doctrine.sead_escort_spacing.feet,
|
||||||
|
)
|
||||||
|
|
||||||
|
def start_defensive_jamming(self, waypoint: MovingPoint) -> None:
|
||||||
|
# Start Defensive Jamming
|
||||||
|
settings = self.flight.coalition.game.settings
|
||||||
|
ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled")
|
||||||
|
if settings.plugins.get("ewrj") and ai_jammer:
|
||||||
|
ecm_required = settings.plugin_option("ewrj.ecm_required")
|
||||||
|
has_jammer = False
|
||||||
|
for unit, member in zip(self.group.units, self.flight.iter_members()):
|
||||||
|
has_jammer = member.loadout.has_weapon_of_type(WeaponType.JAMMER)
|
||||||
|
if ecm_required and not has_jammer:
|
||||||
|
continue
|
||||||
|
if not member.is_player:
|
||||||
|
script_content = f'startDjamming("{unit.name}")'
|
||||||
|
start_jamming_script = RunScript(script_content)
|
||||||
|
waypoint.tasks.append(start_jamming_script)
|
||||||
|
has_jammer = True
|
||||||
|
if has_jammer:
|
||||||
|
passive_defense = OptReactOnThreat(
|
||||||
|
OptReactOnThreat.Values.PassiveDefense
|
||||||
|
)
|
||||||
|
waypoint.tasks.append(passive_defense)
|
||||||
|
|
||||||
def configure_escort_tasks(
|
def configure_escort_tasks(
|
||||||
self,
|
self,
|
||||||
waypoint: MovingPoint,
|
waypoint: MovingPoint,
|
||||||
|
|||||||
@ -9,6 +9,8 @@ from dcs.task import (
|
|||||||
Tanker,
|
Tanker,
|
||||||
Targets,
|
Targets,
|
||||||
SetUnlimitedFuelCommand,
|
SetUnlimitedFuelCommand,
|
||||||
|
RunScript,
|
||||||
|
OptReactOnThreat,
|
||||||
)
|
)
|
||||||
|
|
||||||
from game.ato import FlightType
|
from game.ato import FlightType
|
||||||
@ -38,6 +40,22 @@ class RaceTrackBuilder(PydcsWaypointBuilder):
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if self.flight.flight_type == FlightType.AEWC:
|
||||||
|
# Start Offensive Jamming for all AWACS flights
|
||||||
|
settings = self.flight.coalition.game.settings
|
||||||
|
ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled")
|
||||||
|
if settings.plugins.get("ewrj") and ai_jammer:
|
||||||
|
# all units in group are AWACS, no specific checks needed
|
||||||
|
for unit, member in zip(self.group.units, self.flight.iter_members()):
|
||||||
|
script_content = f'startEWjamm("{unit.name}")'
|
||||||
|
start_jamming_script = RunScript(script_content)
|
||||||
|
waypoint.tasks.append(start_jamming_script)
|
||||||
|
|
||||||
|
passive_defense = OptReactOnThreat(
|
||||||
|
OptReactOnThreat.Values.PassiveDefense
|
||||||
|
)
|
||||||
|
waypoint.tasks.append(passive_defense)
|
||||||
|
|
||||||
# NB: It's important that the engage task comes before the orbit task.
|
# NB: It's important that the engage task comes before the orbit task.
|
||||||
# Though they're on the same waypoint, if the orbit task comes first it
|
# Though they're on the same waypoint, if the orbit task comes first it
|
||||||
# is their first priority and they will not engage any targets because
|
# is their first priority and they will not engage any targets because
|
||||||
|
|||||||
@ -1,8 +1,13 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from dcs.point import MovingPoint
|
from dcs.point import MovingPoint
|
||||||
from dcs.task import SetUnlimitedFuelCommand
|
from dcs.task import (
|
||||||
|
SetUnlimitedFuelCommand,
|
||||||
|
RunScript,
|
||||||
|
OptReactOnThreat,
|
||||||
|
)
|
||||||
|
|
||||||
|
from game.ato import FlightType
|
||||||
from game.ato.flightplans.patrolling import PatrollingFlightPlan
|
from game.ato.flightplans.patrolling import PatrollingFlightPlan
|
||||||
from .pydcswaypointbuilder import PydcsWaypointBuilder
|
from .pydcswaypointbuilder import PydcsWaypointBuilder
|
||||||
|
|
||||||
@ -13,6 +18,21 @@ class RaceTrackEndBuilder(PydcsWaypointBuilder):
|
|||||||
if self.flight.squadron.coalition.game.settings.ai_unlimited_fuel:
|
if self.flight.squadron.coalition.game.settings.ai_unlimited_fuel:
|
||||||
waypoint.tasks.insert(0, SetUnlimitedFuelCommand(True))
|
waypoint.tasks.insert(0, SetUnlimitedFuelCommand(True))
|
||||||
|
|
||||||
|
# Disable Offensive Jamming at Racetrack End
|
||||||
|
if self.flight.flight_type == FlightType.AEWC:
|
||||||
|
# Stop Offensive Jamming for all AWACS flights
|
||||||
|
settings = self.flight.coalition.game.settings
|
||||||
|
ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled")
|
||||||
|
if settings.plugins.get("ewrj") and ai_jammer:
|
||||||
|
# all units in group are AWACS, no specific checks needed
|
||||||
|
for unit, member in zip(self.group.units, self.flight.iter_members()):
|
||||||
|
script_content = f'stopEWjamming("{unit.name}")'
|
||||||
|
stop_jamming_script = RunScript(script_content)
|
||||||
|
waypoint.tasks.append(stop_jamming_script)
|
||||||
|
|
||||||
|
evade_fire = OptReactOnThreat(OptReactOnThreat.Values.EvadeFire)
|
||||||
|
waypoint.tasks.append(evade_fire)
|
||||||
|
|
||||||
def build(self) -> MovingPoint:
|
def build(self) -> MovingPoint:
|
||||||
waypoint = super().build()
|
waypoint = super().build()
|
||||||
|
|
||||||
|
|||||||
@ -2,11 +2,14 @@ from dcs.point import MovingPoint
|
|||||||
from dcs.task import (
|
from dcs.task import (
|
||||||
OptECMUsing,
|
OptECMUsing,
|
||||||
OptFormation,
|
OptFormation,
|
||||||
RunScript,
|
|
||||||
SetUnlimitedFuelCommand,
|
SetUnlimitedFuelCommand,
|
||||||
SwitchWaypoint,
|
SwitchWaypoint,
|
||||||
|
RunScript,
|
||||||
|
OptReactOnThreat,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from game.ato import FlightType
|
||||||
|
from game.data.weapons import WeaponType
|
||||||
from game.utils import knots
|
from game.utils import knots
|
||||||
from .pydcswaypointbuilder import PydcsWaypointBuilder
|
from .pydcswaypointbuilder import PydcsWaypointBuilder
|
||||||
|
|
||||||
@ -41,6 +44,33 @@ class SplitPointBuilder(PydcsWaypointBuilder):
|
|||||||
f'trigger.action.setUserFlag("split-{id(self.package)}", true)'
|
f'trigger.action.setUserFlag("split-{id(self.package)}", true)'
|
||||||
)
|
)
|
||||||
waypoint.tasks.append(script)
|
waypoint.tasks.append(script)
|
||||||
elif self.flight.flight_type.is_escort_type:
|
|
||||||
index = len(self.group.points)
|
elif self.flight.flight_type in [
|
||||||
self.group.add_trigger_action(SwitchWaypoint(None, index))
|
FlightType.SEAD_SWEEP,
|
||||||
|
FlightType.SEAD,
|
||||||
|
FlightType.SEAD_ESCORT,
|
||||||
|
]:
|
||||||
|
if self.flight.flight_type == FlightType.SEAD_ESCORT:
|
||||||
|
# Moved previous escort split tasks
|
||||||
|
if self.flight.flight_type.is_escort_type:
|
||||||
|
index = len(self.group.points)
|
||||||
|
self.group.add_trigger_action(SwitchWaypoint(None, index))
|
||||||
|
self.stop_defensive_jamming(waypoint)
|
||||||
|
|
||||||
|
def stop_defensive_jamming(self, waypoint: MovingPoint) -> None:
|
||||||
|
# Stop Defensive Jamming
|
||||||
|
settings = self.flight.coalition.game.settings
|
||||||
|
ai_jammer = settings.plugin_option("ewrj.ai_jammer_enabled")
|
||||||
|
if settings.plugins.get("ewrj") and ai_jammer:
|
||||||
|
for unit, member in zip(self.group.units, self.flight.iter_members()):
|
||||||
|
if settings.plugin_option("ewrj.ecm_required"):
|
||||||
|
ecm = WeaponType.JAMMER
|
||||||
|
if not member.loadout.has_weapon_of_type(ecm):
|
||||||
|
continue
|
||||||
|
if not member.is_player:
|
||||||
|
script_content = f'stopDjamming("{unit.name}")'
|
||||||
|
stop_jamming_script = RunScript(script_content)
|
||||||
|
waypoint.tasks.append(stop_jamming_script)
|
||||||
|
|
||||||
|
evaide_fire = OptReactOnThreat(OptReactOnThreat.Values.EvadeFire)
|
||||||
|
waypoint.tasks.append(evaide_fire)
|
||||||
|
|||||||
@ -1,11 +1,16 @@
|
|||||||
{
|
{
|
||||||
"nameInUI": "EW Jammer (for player only)",
|
"nameInUI": "EW Jammer Scipt 2.0",
|
||||||
"defaultValue": false,
|
"defaultValue": false,
|
||||||
"specificOptions": [
|
"specificOptions": [
|
||||||
{
|
{
|
||||||
"nameInUI": "Require ECM pod",
|
"nameInUI": "Require ECM pod",
|
||||||
"mnemonic": "ecm_required",
|
"mnemonic": "ecm_required",
|
||||||
"defaultValue": true
|
"defaultValue": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"nameInUI": "Enable AI Jammers",
|
||||||
|
"mnemonic": "ai_jammer_enabled",
|
||||||
|
"defaultValue": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"scriptsWorkOrders": [
|
"scriptsWorkOrders": [
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user