mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Improve prioritization of garrison targeting.
Garrison groups should be preferred with the following priority: 1. Groups blocking base capture 2. Groups at bases connected to an active front line 3. Rear guard units Previously they were being prioritized based on the distance to the closest friendy control point, which is similar to this but an aggressively placed carrier could throw it off.
This commit is contained in:
parent
cd558daf5a
commit
7e4390d743
63
game/commander/garrisons.py
Normal file
63
game/commander/garrisons.py
Normal file
@ -0,0 +1,63 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections import Iterator
|
||||
from dataclasses import dataclass
|
||||
|
||||
from game.theater import ConflictTheater
|
||||
from game.theater.theatergroundobject import VehicleGroupGroundObject
|
||||
from game.utils import meters, nautical_miles
|
||||
|
||||
|
||||
@dataclass
|
||||
class Garrisons:
|
||||
blocking_capture: list[VehicleGroupGroundObject]
|
||||
defending_front_line: list[VehicleGroupGroundObject]
|
||||
reserves: list[VehicleGroupGroundObject]
|
||||
|
||||
@property
|
||||
def in_priority_order(self) -> Iterator[VehicleGroupGroundObject]:
|
||||
yield from self.blocking_capture
|
||||
yield from self.defending_front_line
|
||||
yield from self.reserves
|
||||
|
||||
def eliminate(self, garrison: VehicleGroupGroundObject) -> None:
|
||||
if garrison in self.blocking_capture:
|
||||
self.blocking_capture.remove(garrison)
|
||||
if garrison in self.defending_front_line:
|
||||
self.defending_front_line.remove(garrison)
|
||||
if garrison in self.reserves:
|
||||
self.reserves.remove(garrison)
|
||||
|
||||
def __contains__(self, item: VehicleGroupGroundObject) -> bool:
|
||||
return item in self.in_priority_order
|
||||
|
||||
@classmethod
|
||||
def from_theater(cls, theater: ConflictTheater, player_owned: bool) -> Garrisons:
|
||||
"""Categorize garrison groups based on target priority.
|
||||
|
||||
Any garrisons blocking base capture are the highest priority, followed by other
|
||||
garrisons at front-line bases, and finally any garrisons in reserve at other
|
||||
bases.
|
||||
"""
|
||||
blocking = []
|
||||
defending = []
|
||||
reserves = []
|
||||
for cp in theater.control_points_for(player_owned):
|
||||
garrisons = [
|
||||
tgo
|
||||
for tgo in cp.ground_objects
|
||||
if isinstance(tgo, VehicleGroupGroundObject)
|
||||
]
|
||||
if not cp.has_active_frontline:
|
||||
reserves.extend(garrisons)
|
||||
continue
|
||||
|
||||
for garrison in garrisons:
|
||||
# Not sure what distance DCS uses, but assuming it's about 2NM since
|
||||
# that's roughly the distance of the circle on the map.
|
||||
if meters(garrison.distance_to(cp)) < nautical_miles(2):
|
||||
blocking.append(garrison)
|
||||
else:
|
||||
defending.append(garrison)
|
||||
|
||||
return Garrisons(blocking, defending, reserves)
|
||||
@ -65,14 +65,6 @@ class ObjectiveFinder:
|
||||
|
||||
yield ground_object
|
||||
|
||||
def threatening_vehicle_groups(self) -> Iterator[VehicleGroupGroundObject]:
|
||||
"""Iterates over enemy vehicle groups near friendly control points.
|
||||
|
||||
Groups are sorted by their closest proximity to any friendly control
|
||||
point (airfield or fleet).
|
||||
"""
|
||||
return self._targets_by_range(self.enemy_vehicle_groups())
|
||||
|
||||
def enemy_ships(self) -> Iterator[NavalGroundObject]:
|
||||
for cp in self.enemy_control_points():
|
||||
for ground_object in cp.ground_objects:
|
||||
|
||||
@ -7,5 +7,5 @@ from game.htn import CompoundTask, Method
|
||||
|
||||
class AttackGarrisons(CompoundTask[TheaterState]):
|
||||
def each_valid_method(self, state: TheaterState) -> Iterator[Method[TheaterState]]:
|
||||
for garrison in state.enemy_garrisons:
|
||||
for garrison in state.enemy_garrisons.in_priority_order:
|
||||
yield [PlanBai(garrison)]
|
||||
|
||||
@ -17,7 +17,7 @@ class PlanBai(PackagePlanningTask[VehicleGroupGroundObject]):
|
||||
return self.target_area_preconditions_met(state)
|
||||
|
||||
def apply_effects(self, state: TheaterState) -> None:
|
||||
state.enemy_garrisons.remove(self.target)
|
||||
state.enemy_garrisons.eliminate(self.target)
|
||||
|
||||
def propose_flights(self, doctrine: Doctrine) -> None:
|
||||
self.propose_flight(FlightType.BAI, 2, doctrine.mission_ranges.offensive)
|
||||
|
||||
@ -1,16 +1,17 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import dataclasses
|
||||
import itertools
|
||||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING, Any, Union
|
||||
|
||||
from game.commander.garrisons import Garrisons
|
||||
from game.commander.objectivefinder import ObjectiveFinder
|
||||
from game.data.doctrine import Doctrine
|
||||
from game.htn import WorldState
|
||||
from game.theater import ControlPoint, FrontLine, MissionTarget
|
||||
from game.theater.theatergroundobject import (
|
||||
TheaterGroundObject,
|
||||
VehicleGroupGroundObject,
|
||||
NavalGroundObject,
|
||||
IadsGroundObject,
|
||||
)
|
||||
@ -32,7 +33,7 @@ class TheaterState(WorldState["TheaterState"]):
|
||||
enemy_convoys: list[Convoy]
|
||||
enemy_shipping: list[CargoShip]
|
||||
enemy_ships: list[NavalGroundObject]
|
||||
enemy_garrisons: list[VehicleGroupGroundObject]
|
||||
enemy_garrisons: Garrisons
|
||||
oca_targets: list[ControlPoint]
|
||||
strike_targets: list[TheaterGroundObject[Any]]
|
||||
enemy_barcaps: list[ControlPoint]
|
||||
@ -69,7 +70,7 @@ class TheaterState(WorldState["TheaterState"]):
|
||||
enemy_convoys=list(self.enemy_convoys),
|
||||
enemy_shipping=list(self.enemy_shipping),
|
||||
enemy_ships=list(self.enemy_ships),
|
||||
enemy_garrisons=list(self.enemy_garrisons),
|
||||
enemy_garrisons=dataclasses.replace(self.enemy_garrisons),
|
||||
oca_targets=list(self.oca_targets),
|
||||
strike_targets=list(self.strike_targets),
|
||||
enemy_barcaps=list(self.enemy_barcaps),
|
||||
@ -97,7 +98,7 @@ class TheaterState(WorldState["TheaterState"]):
|
||||
enemy_convoys=list(finder.convoys()),
|
||||
enemy_shipping=list(finder.cargo_ships()),
|
||||
enemy_ships=list(finder.enemy_ships()),
|
||||
enemy_garrisons=list(finder.threatening_vehicle_groups()),
|
||||
enemy_garrisons=Garrisons.from_theater(game.theater, not player),
|
||||
oca_targets=list(finder.oca_targets(min_aircraft=20)),
|
||||
strike_targets=list(finder.strike_targets()),
|
||||
enemy_barcaps=list(game.theater.control_points_for(not player)),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user