mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Let the TheaterCommander manage front line stance.
This improves the AI behavior by choosing the stances non-randomly: * Breakthrough will be used if the base is expected to be capturable and the coalition outnumbers the enemy by 20%. * Elimination will be used if the coalition has at least as many units as the enemy. * Defensive will be used if the coalition has at least half as many units as the enemy. * Retreat will be used if the coalition is significantly outnumbers. This also exposes the option to the player.
This commit is contained in:
@@ -12,6 +12,8 @@ from gen.flights.flight import FlightType
|
||||
@dataclass
|
||||
class PlanAewc(PackagePlanningTask[MissionTarget]):
|
||||
def preconditions_met(self, state: TheaterState) -> bool:
|
||||
if not super().preconditions_met(state):
|
||||
return False
|
||||
return self.target in state.aewc_targets
|
||||
|
||||
def apply_effects(self, state: TheaterState) -> None:
|
||||
|
||||
@@ -13,6 +13,8 @@ from gen.flights.flight import FlightType
|
||||
@dataclass
|
||||
class PlanAntiShip(PackagePlanningTask[NavalGroundObject]):
|
||||
def preconditions_met(self, state: TheaterState) -> bool:
|
||||
if not super().preconditions_met(state):
|
||||
return False
|
||||
if self.target not in state.threatening_air_defenses:
|
||||
return False
|
||||
return self.target_area_preconditions_met(state, ignore_iads=True)
|
||||
|
||||
@@ -12,6 +12,8 @@ from gen.flights.flight import FlightType
|
||||
@dataclass
|
||||
class PlanAntiShipping(PackagePlanningTask[CargoShip]):
|
||||
def preconditions_met(self, state: TheaterState) -> bool:
|
||||
if not super().preconditions_met(state):
|
||||
return False
|
||||
if self.target not in state.enemy_shipping:
|
||||
return False
|
||||
return self.target_area_preconditions_met(state)
|
||||
|
||||
@@ -12,6 +12,8 @@ from gen.flights.flight import FlightType
|
||||
@dataclass
|
||||
class PlanBai(PackagePlanningTask[VehicleGroupGroundObject]):
|
||||
def preconditions_met(self, state: TheaterState) -> bool:
|
||||
if not super().preconditions_met(state):
|
||||
return False
|
||||
if self.target not in state.enemy_garrisons:
|
||||
return False
|
||||
return self.target_area_preconditions_met(state)
|
||||
|
||||
@@ -19,6 +19,8 @@ class PlanBarcap(TheaterCommanderTask):
|
||||
target: ControlPoint
|
||||
|
||||
def preconditions_met(self, state: TheaterState) -> bool:
|
||||
if state.player and not state.ato_automation_enabled:
|
||||
return False
|
||||
return self.target in state.vulnerable_control_points
|
||||
|
||||
def apply_effects(self, state: TheaterState) -> None:
|
||||
|
||||
37
game/commander/tasks/primitive/breakthroughattack.py
Normal file
37
game/commander/tasks/primitive/breakthroughattack.py
Normal file
@@ -0,0 +1,37 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from game.commander.tasks.frontlinestancetask import FrontLineStanceTask
|
||||
from game.commander.theaterstate import TheaterState
|
||||
from game.theater import ControlPoint
|
||||
from game.theater.theatergroundobject import VehicleGroupGroundObject
|
||||
from game.utils import meters
|
||||
from gen.ground_forces.combat_stance import CombatStance
|
||||
|
||||
|
||||
class BreakthroughAttack(FrontLineStanceTask):
|
||||
@property
|
||||
def stance(self) -> CombatStance:
|
||||
return CombatStance.BREAKTHROUGH
|
||||
|
||||
@property
|
||||
def have_sufficient_front_line_advantage(self) -> bool:
|
||||
return self.ground_force_balance >= 1.2
|
||||
|
||||
@property
|
||||
def opposing_garrisons_eliminated(self) -> bool:
|
||||
# TODO: Should operate on TheaterState to account for BAIs planned this turn.
|
||||
for tgo in self.enemy_cp.ground_objects:
|
||||
if not isinstance(tgo, VehicleGroupGroundObject):
|
||||
continue
|
||||
if meters(tgo.distance_to(self.enemy_cp)) < ControlPoint.CAPTURE_DISTANCE:
|
||||
return False
|
||||
return True
|
||||
|
||||
def preconditions_met(self, state: TheaterState) -> bool:
|
||||
if not super().preconditions_met(state):
|
||||
return False
|
||||
return self.opposing_garrisons_eliminated
|
||||
|
||||
def apply_effects(self, state: TheaterState) -> None:
|
||||
super().apply_effects(state)
|
||||
state.active_front_lines.remove(self.front_line)
|
||||
@@ -12,6 +12,8 @@ from gen.flights.flight import FlightType
|
||||
@dataclass
|
||||
class PlanCas(PackagePlanningTask[FrontLine]):
|
||||
def preconditions_met(self, state: TheaterState) -> bool:
|
||||
if not super().preconditions_met(state):
|
||||
return False
|
||||
return self.target in state.vulnerable_front_lines
|
||||
|
||||
def apply_effects(self, state: TheaterState) -> None:
|
||||
|
||||
@@ -12,6 +12,8 @@ from gen.flights.flight import FlightType
|
||||
@dataclass
|
||||
class PlanConvoyInterdiction(PackagePlanningTask[Convoy]):
|
||||
def preconditions_met(self, state: TheaterState) -> bool:
|
||||
if not super().preconditions_met(state):
|
||||
return False
|
||||
if self.target not in state.enemy_convoys:
|
||||
return False
|
||||
return self.target_area_preconditions_met(state)
|
||||
|
||||
@@ -13,6 +13,8 @@ from gen.flights.flight import FlightType
|
||||
@dataclass
|
||||
class PlanDead(PackagePlanningTask[IadsGroundObject]):
|
||||
def preconditions_met(self, state: TheaterState) -> bool:
|
||||
if not super().preconditions_met(state):
|
||||
return False
|
||||
if (
|
||||
self.target not in state.threatening_air_defenses
|
||||
and self.target not in state.detecting_air_defenses
|
||||
|
||||
14
game/commander/tasks/primitive/defensivestance.py
Normal file
14
game/commander/tasks/primitive/defensivestance.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from game.commander.tasks.frontlinestancetask import FrontLineStanceTask
|
||||
from gen.ground_forces.combat_stance import CombatStance
|
||||
|
||||
|
||||
class DefensiveStance(FrontLineStanceTask):
|
||||
@property
|
||||
def stance(self) -> CombatStance:
|
||||
return CombatStance.DEFENSIVE
|
||||
|
||||
@property
|
||||
def have_sufficient_front_line_advantage(self) -> bool:
|
||||
return self.ground_force_balance >= 0.5
|
||||
14
game/commander/tasks/primitive/eliminationattack.py
Normal file
14
game/commander/tasks/primitive/eliminationattack.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from game.commander.tasks.frontlinestancetask import FrontLineStanceTask
|
||||
from gen.ground_forces.combat_stance import CombatStance
|
||||
|
||||
|
||||
class EliminationAttack(FrontLineStanceTask):
|
||||
@property
|
||||
def stance(self) -> CombatStance:
|
||||
return CombatStance.ELIMINATION
|
||||
|
||||
@property
|
||||
def have_sufficient_front_line_advantage(self) -> bool:
|
||||
return self.ground_force_balance >= 1.0
|
||||
@@ -14,6 +14,8 @@ class PlanOcaStrike(PackagePlanningTask[ControlPoint]):
|
||||
aircraft_cold_start: bool
|
||||
|
||||
def preconditions_met(self, state: TheaterState) -> bool:
|
||||
if not super().preconditions_met(state):
|
||||
return False
|
||||
if self.target not in state.oca_targets:
|
||||
return False
|
||||
return self.target_area_preconditions_met(state)
|
||||
|
||||
@@ -12,6 +12,8 @@ from gen.flights.flight import FlightType
|
||||
@dataclass
|
||||
class PlanRefueling(PackagePlanningTask[MissionTarget]):
|
||||
def preconditions_met(self, state: TheaterState) -> bool:
|
||||
if not super().preconditions_met(state):
|
||||
return False
|
||||
return self.target in state.refueling_targets
|
||||
|
||||
def apply_effects(self, state: TheaterState) -> None:
|
||||
|
||||
14
game/commander/tasks/primitive/retreatstance.py
Normal file
14
game/commander/tasks/primitive/retreatstance.py
Normal file
@@ -0,0 +1,14 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from game.commander.tasks.frontlinestancetask import FrontLineStanceTask
|
||||
from gen.ground_forces.combat_stance import CombatStance
|
||||
|
||||
|
||||
class RetreatStance(FrontLineStanceTask):
|
||||
@property
|
||||
def stance(self) -> CombatStance:
|
||||
return CombatStance.RETREAT
|
||||
|
||||
@property
|
||||
def have_sufficient_front_line_advantage(self) -> bool:
|
||||
return True
|
||||
@@ -13,6 +13,8 @@ from gen.flights.flight import FlightType
|
||||
@dataclass
|
||||
class PlanStrike(PackagePlanningTask[TheaterGroundObject[Any]]):
|
||||
def preconditions_met(self, state: TheaterState) -> bool:
|
||||
if not super().preconditions_met(state):
|
||||
return False
|
||||
if self.target not in state.strike_targets:
|
||||
return False
|
||||
return self.target_area_preconditions_met(state)
|
||||
|
||||
Reference in New Issue
Block a user