mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
52 lines
2.2 KiB
Python
52 lines
2.2 KiB
Python
from collections.abc import Iterator
|
|
from dataclasses import dataclass
|
|
|
|
from game.commander.tasks.compound.destroyenemygroundunits import (
|
|
DestroyEnemyGroundUnits,
|
|
)
|
|
from game.commander.tasks.compound.reduceenemyfrontlinecapacity import (
|
|
ReduceEnemyFrontLineCapacity,
|
|
)
|
|
from game.commander.tasks.primitive.breakthroughattack import BreakthroughAttack
|
|
from game.commander.theaterstate import TheaterState
|
|
from game.htn import CompoundTask, Method
|
|
from game.theater import ControlPoint, FrontLine
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class CaptureBase(CompoundTask[TheaterState]):
|
|
front_line: FrontLine
|
|
|
|
def each_valid_method(self, state: TheaterState) -> Iterator[Method[TheaterState]]:
|
|
yield [BreakthroughAttack(self.front_line, state.context.coalition.player)]
|
|
yield [DestroyEnemyGroundUnits(self.front_line)]
|
|
if self.worth_destroying_ammo_depots(state):
|
|
yield [ReduceEnemyFrontLineCapacity(self.enemy_cp(state))]
|
|
|
|
def enemy_cp(self, state: TheaterState) -> ControlPoint:
|
|
return self.front_line.control_point_hostile_to(state.context.coalition.player)
|
|
|
|
def units_deployable(self, state: TheaterState, player: bool) -> int:
|
|
cp = self.front_line.control_point_friendly_to(player)
|
|
ammo_depots = list(state.ammo_dumps_at(cp))
|
|
return cp.deployable_front_line_units_with(len(ammo_depots))
|
|
|
|
def unit_cap(self, state: TheaterState, player: bool) -> int:
|
|
cp = self.front_line.control_point_friendly_to(player)
|
|
ammo_depots = list(state.ammo_dumps_at(cp))
|
|
return cp.front_line_capacity_with(len(ammo_depots))
|
|
|
|
def enemy_has_ammo_dumps(self, state: TheaterState) -> bool:
|
|
return bool(state.ammo_dumps_at(self.enemy_cp(state)))
|
|
|
|
def worth_destroying_ammo_depots(self, state: TheaterState) -> bool:
|
|
if not self.enemy_has_ammo_dumps(state):
|
|
return False
|
|
|
|
friendly_cap = self.unit_cap(state, state.context.coalition.player)
|
|
enemy_deployable = self.units_deployable(state, state.context.coalition.player)
|
|
|
|
# If the enemy can currently deploy 50% more units than we possibly could, it's
|
|
# worth killing an ammo depot.
|
|
return enemy_deployable / friendly_cap > 1.5
|