mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
refactor to enum typing and many other fixes fix tests attempt to fix some typescript more typescript fixes more typescript test fixes revert all API changes update to pydcs mypy fixes Use properties to check if player is blue/red/neutral update requirements.txt black -_- bump pydcs and fix mypy add opponent property bump pydcs
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, Player
|
|
|
|
|
|
@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: Player) -> 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: Player) -> 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
|