Changed garrison terminology to battle position. (#2352)

This commit is contained in:
SnappyComebacks 2022-07-26 22:41:45 -06:00 committed by GitHub
parent 2ecb3506b5
commit 2bd39bd9f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 46 additions and 44 deletions

View File

@ -9,7 +9,7 @@ from game.utils import meters
@dataclass @dataclass
class Garrisons: class BattlePositions:
blocking_capture: list[VehicleGroupGroundObject] blocking_capture: list[VehicleGroupGroundObject]
defending_front_line: list[VehicleGroupGroundObject] defending_front_line: list[VehicleGroupGroundObject]
@ -18,35 +18,35 @@ class Garrisons:
yield from self.blocking_capture yield from self.blocking_capture
yield from self.defending_front_line yield from self.defending_front_line
def eliminate(self, garrison: VehicleGroupGroundObject) -> None: def eliminate(self, battle_position: VehicleGroupGroundObject) -> None:
if garrison in self.blocking_capture: if battle_position in self.blocking_capture:
self.blocking_capture.remove(garrison) self.blocking_capture.remove(battle_position)
if garrison in self.defending_front_line: if battle_position in self.defending_front_line:
self.defending_front_line.remove(garrison) self.defending_front_line.remove(battle_position)
def __contains__(self, item: VehicleGroupGroundObject) -> bool: def __contains__(self, item: VehicleGroupGroundObject) -> bool:
return item in self.in_priority_order return item in self.in_priority_order
@classmethod @classmethod
def for_control_point(cls, control_point: ControlPoint) -> Garrisons: def for_control_point(cls, control_point: ControlPoint) -> BattlePositions:
"""Categorize garrison groups based on target priority. """Categorize battle position groups based on target priority.
Any garrisons blocking base capture are the highest priority. Any battle positions blocking base capture are the highest priority.
""" """
blocking = [] blocking = []
defending = [] defending = []
garrisons = [ battle_positions = [
tgo tgo
for tgo in control_point.ground_objects for tgo in control_point.ground_objects
if isinstance(tgo, VehicleGroupGroundObject) and not tgo.is_dead if isinstance(tgo, VehicleGroupGroundObject) and not tgo.is_dead
] ]
for garrison in garrisons: for battle_position in battle_positions:
if ( if (
meters(garrison.distance_to(control_point)) meters(battle_position.distance_to(control_point))
< ControlPoint.CAPTURE_DISTANCE < ControlPoint.CAPTURE_DISTANCE
): ):
blocking.append(garrison) blocking.append(battle_position)
else: else:
defending.append(garrison) defending.append(battle_position)
return Garrisons(blocking, defending) return BattlePositions(blocking, defending)

View File

@ -105,7 +105,7 @@ class ObjectiveFinder:
# better control over planning profiles and target dependent # better control over planning profiles and target dependent
# loadouts we can clean this up. # loadouts we can clean this up.
if not isinstance(ground_object, BuildingGroundObject): if not isinstance(ground_object, BuildingGroundObject):
# Other group types (like ships, SAMs, garrisons, etc) have better # Other group types (like ships, SAMs, battle positions, etc) have better
# suited mission types like anti-ship, DEAD, and BAI. # suited mission types like anti-ship, DEAD, and BAI.
continue continue

View File

@ -11,5 +11,5 @@ class AttackAirInfrastructure(CompoundTask[TheaterState]):
aircraft_cold_start: bool aircraft_cold_start: bool
def each_valid_method(self, state: TheaterState) -> Iterator[Method[TheaterState]]: def each_valid_method(self, state: TheaterState) -> Iterator[Method[TheaterState]]:
for garrison in state.oca_targets: for battle_position in state.oca_targets:
yield [PlanOcaStrike(garrison, self.aircraft_cold_start)] yield [PlanOcaStrike(battle_position, self.aircraft_cold_start)]

View File

@ -5,8 +5,8 @@ from game.commander.theaterstate import TheaterState
from game.htn import CompoundTask, Method from game.htn import CompoundTask, Method
class AttackGarrisons(CompoundTask[TheaterState]): class AttackBattlePositions(CompoundTask[TheaterState]):
def each_valid_method(self, state: TheaterState) -> Iterator[Method[TheaterState]]: def each_valid_method(self, state: TheaterState) -> Iterator[Method[TheaterState]]:
for garrisons in state.enemy_garrisons.values(): for battle_positions in state.enemy_battle_positions.values():
for garrison in garrisons.in_priority_order: for battle_position in battle_positions.in_priority_order:
yield [PlanBai(garrison)] yield [PlanBai(battle_position)]

View File

@ -5,7 +5,7 @@ from game.commander.tasks.compound.attackairinfrastructure import (
AttackAirInfrastructure, AttackAirInfrastructure,
) )
from game.commander.tasks.compound.attackbuildings import AttackBuildings from game.commander.tasks.compound.attackbuildings import AttackBuildings
from game.commander.tasks.compound.attackgarrisons import AttackGarrisons from game.commander.tasks.compound.attackbattlepositions import AttackBattlePositions
from game.commander.tasks.compound.capturebases import CaptureBases from game.commander.tasks.compound.capturebases import CaptureBases
from game.commander.tasks.compound.defendbases import DefendBases from game.commander.tasks.compound.defendbases import DefendBases
from game.commander.tasks.compound.degradeiads import DegradeIads from game.commander.tasks.compound.degradeiads import DegradeIads
@ -28,7 +28,7 @@ class PlanNextAction(CompoundTask[TheaterState]):
yield [CaptureBases()] yield [CaptureBases()]
yield [DefendBases()] yield [DefendBases()]
yield [InterdictReinforcements()] yield [InterdictReinforcements()]
yield [AttackGarrisons()] yield [AttackBattlePositions()]
yield [AttackAirInfrastructure(self.aircraft_cold_start)] yield [AttackAirInfrastructure(self.aircraft_cold_start)]
yield [AttackBuildings()] yield [AttackBuildings()]
yield [DegradeIads()] yield [DegradeIads()]

View File

@ -14,7 +14,7 @@ class PlanAirAssault(PackagePlanningTask[ControlPoint]):
if self.target not in state.air_assault_targets: if self.target not in state.air_assault_targets:
return False return False
if self.capture_blocked(state): if self.capture_blocked(state):
# Do not task if there are enemy garrisons blocking the capture # Do not task if there are enemy battle_positions blocking the capture
return False return False
if not self.target_area_preconditions_met(state): if not self.target_area_preconditions_met(state):
# Do not task if air defense is present in the target area # Do not task if air defense is present in the target area
@ -22,8 +22,8 @@ class PlanAirAssault(PackagePlanningTask[ControlPoint]):
return super().preconditions_met(state) return super().preconditions_met(state)
def capture_blocked(self, state: TheaterState) -> bool: def capture_blocked(self, state: TheaterState) -> bool:
garrisons = state.enemy_garrisons[self.target] battle_positions = state.enemy_battle_positions[self.target]
return len(garrisons.blocking_capture) > 0 return len(battle_positions.blocking_capture) > 0
def apply_effects(self, state: TheaterState) -> None: def apply_effects(self, state: TheaterState) -> None:
state.air_assault_targets.remove(self.target) state.air_assault_targets.remove(self.target)

View File

@ -11,14 +11,14 @@ from game.ato.flighttype import FlightType
@dataclass @dataclass
class PlanBai(PackagePlanningTask[VehicleGroupGroundObject]): class PlanBai(PackagePlanningTask[VehicleGroupGroundObject]):
def preconditions_met(self, state: TheaterState) -> bool: def preconditions_met(self, state: TheaterState) -> bool:
if not state.has_garrison(self.target): if not state.has_battle_position(self.target):
return False return False
if not self.target_area_preconditions_met(state): if not self.target_area_preconditions_met(state):
return False return False
return super().preconditions_met(state) return super().preconditions_met(state)
def apply_effects(self, state: TheaterState) -> None: def apply_effects(self, state: TheaterState) -> None:
state.eliminate_garrison(self.target) state.eliminate_battle_position(self.target)
def propose_flights(self) -> None: def propose_flights(self) -> None:
self.propose_flight(FlightType.BAI, 2) self.propose_flight(FlightType.BAI, 2)

View File

@ -14,14 +14,14 @@ class BreakthroughAttack(FrontLineStanceTask):
def have_sufficient_front_line_advantage(self) -> bool: def have_sufficient_front_line_advantage(self) -> bool:
return self.ground_force_balance >= 2.0 return self.ground_force_balance >= 2.0
def opposing_garrisons_eliminated(self, state: TheaterState) -> bool: def opposing_battle_positions_eliminated(self, state: TheaterState) -> bool:
garrisons = state.enemy_garrisons[self.enemy_cp] battle_positions = state.enemy_battle_positions[self.enemy_cp]
return not bool(garrisons.blocking_capture) return not bool(battle_positions.blocking_capture)
def preconditions_met(self, state: TheaterState) -> bool: def preconditions_met(self, state: TheaterState) -> bool:
if not super().preconditions_met(state): if not super().preconditions_met(state):
return False return False
return self.opposing_garrisons_eliminated(state) return self.opposing_battle_positions_eliminated(state)
def apply_effects(self, state: TheaterState) -> None: def apply_effects(self, state: TheaterState) -> None:
super().apply_effects(state) super().apply_effects(state)

View File

@ -7,7 +7,7 @@ from collections.abc import Iterator
from dataclasses import dataclass from dataclasses import dataclass
from typing import Optional, TYPE_CHECKING, Union from typing import Optional, TYPE_CHECKING, Union
from game.commander.garrisons import Garrisons from game.commander.battlepositions import BattlePositions
from game.commander.objectivefinder import ObjectiveFinder from game.commander.objectivefinder import ObjectiveFinder
from game.db import GameDb from game.db import GameDb
from game.ground_forces.combat_stance import CombatStance from game.ground_forces.combat_stance import CombatStance
@ -56,7 +56,7 @@ class TheaterState(WorldState["TheaterState"]):
enemy_convoys: list[Convoy] enemy_convoys: list[Convoy]
enemy_shipping: list[CargoShip] enemy_shipping: list[CargoShip]
enemy_ships: list[NavalGroundObject] enemy_ships: list[NavalGroundObject]
enemy_garrisons: dict[ControlPoint, Garrisons] enemy_battle_positions: dict[ControlPoint, BattlePositions]
oca_targets: list[ControlPoint] oca_targets: list[ControlPoint]
strike_targets: list[TheaterGroundObject] strike_targets: list[TheaterGroundObject]
enemy_barcaps: list[ControlPoint] enemy_barcaps: list[ControlPoint]
@ -87,11 +87,11 @@ class TheaterState(WorldState["TheaterState"]):
self.enemy_ships.remove(target) self.enemy_ships.remove(target)
self._rebuild_threat_zones() self._rebuild_threat_zones()
def has_garrison(self, target: VehicleGroupGroundObject) -> bool: def has_battle_position(self, target: VehicleGroupGroundObject) -> bool:
return target in self.enemy_garrisons[target.control_point] return target in self.enemy_battle_positions[target.control_point]
def eliminate_garrison(self, target: VehicleGroupGroundObject) -> None: def eliminate_battle_position(self, target: VehicleGroupGroundObject) -> None:
self.enemy_garrisons[target.control_point].eliminate(target) self.enemy_battle_positions[target.control_point].eliminate(target)
def ammo_dumps_at( def ammo_dumps_at(
self, control_point: ControlPoint self, control_point: ControlPoint
@ -119,8 +119,9 @@ class TheaterState(WorldState["TheaterState"]):
enemy_convoys=list(self.enemy_convoys), enemy_convoys=list(self.enemy_convoys),
enemy_shipping=list(self.enemy_shipping), enemy_shipping=list(self.enemy_shipping),
enemy_ships=list(self.enemy_ships), enemy_ships=list(self.enemy_ships),
enemy_garrisons={ enemy_battle_positions={
cp: dataclasses.replace(g) for cp, g in self.enemy_garrisons.items() cp: dataclasses.replace(g)
for cp, g in self.enemy_battle_positions.items()
}, },
oca_targets=list(self.oca_targets), oca_targets=list(self.oca_targets),
strike_targets=list(self.strike_targets), strike_targets=list(self.strike_targets),
@ -128,7 +129,7 @@ class TheaterState(WorldState["TheaterState"]):
threat_zones=self.threat_zones, threat_zones=self.threat_zones,
# Persistent properties are not copied. These are a way for failed subtasks # Persistent properties are not copied. These are a way for failed subtasks
# to communicate requirements to other tasks. For example, the task to # to communicate requirements to other tasks. For example, the task to
# attack enemy garrisons might fail because the target area has IADS # attack enemy battle_positions might fail because the target area has IADS
# protection. In that case, the preconditions of PlanBai would fail, but # protection. In that case, the preconditions of PlanBai would fail, but
# would add the IADS that prevented it from being planned to the list of # would add the IADS that prevented it from being planned to the list of
# IADS threats so that DegradeIads will consider it a threat later. # IADS threats so that DegradeIads will consider it a threat later.
@ -171,8 +172,9 @@ class TheaterState(WorldState["TheaterState"]):
enemy_convoys=list(finder.convoys()), enemy_convoys=list(finder.convoys()),
enemy_shipping=list(finder.cargo_ships()), enemy_shipping=list(finder.cargo_ships()),
enemy_ships=list(finder.enemy_ships()), enemy_ships=list(finder.enemy_ships()),
enemy_garrisons={ enemy_battle_positions={
cp: Garrisons.for_control_point(cp) for cp in ordered_capturable_points cp: BattlePositions.for_control_point(cp)
for cp in ordered_capturable_points
}, },
oca_targets=list(finder.oca_targets(min_aircraft=20)), oca_targets=list(finder.oca_targets(min_aircraft=20)),
strike_targets=list(finder.strike_targets()), strike_targets=list(finder.strike_targets()),