mirror of
https://github.com/dcs-liberation/dcs_liberation.git
synced 2025-11-10 14:22:26 +00:00
Handle runway damage in the debrief.
Apparently we were already getting this info because it's a unit like any other according to the event system, so if runways were actually sufficiently damaged we'd emit a ton of exceptions. This doesn't do anything yet, but tracks the damage state. Will add the ability to repair them next, and then finally make the damage render the runway inoperable.
This commit is contained in:
parent
ef0e565337
commit
0c4e920af3
@ -12,7 +12,7 @@ from typing import Any, Callable, Dict, List, Type, TYPE_CHECKING
|
||||
from dcs.unittype import FlyingType, UnitType
|
||||
|
||||
from game import db
|
||||
from game.theater import TheaterGroundObject
|
||||
from game.theater import Airfield, TheaterGroundObject
|
||||
from game.unitmap import UnitMap
|
||||
from gen.flights.flight import Flight
|
||||
|
||||
@ -91,7 +91,9 @@ class StateData:
|
||||
return cls(
|
||||
mission_ended=data["mission_ended"],
|
||||
killed_aircraft=data["killed_aircrafts"],
|
||||
killed_ground_units=data["killed_ground_units"],
|
||||
# Airfields emit a new "dead" event every time a bomb is dropped on
|
||||
# them when they've already dead. Dedup.
|
||||
killed_ground_units=list(set(data["killed_ground_units"])),
|
||||
destroyed_statics=data["destroyed_objects_positions"],
|
||||
base_capture_events=data["base_capture_events"]
|
||||
)
|
||||
@ -114,28 +116,11 @@ class Debriefing:
|
||||
self.enemy_country_id = db.country_id_from_name(game.enemy_country)
|
||||
|
||||
self.air_losses = self.dead_aircraft()
|
||||
self.dead_units: List[DebriefingDeadUnitInfo] = []
|
||||
self.dead_units = self.dead_ground_units()
|
||||
self.damaged_runways = self.find_damaged_runways()
|
||||
self.dead_aaa_groups: List[DebriefingDeadUnitInfo] = []
|
||||
self.dead_buildings: List[DebriefingDeadBuildingInfo] = []
|
||||
|
||||
for unit_name in self.state_data.killed_ground_units:
|
||||
try:
|
||||
if isinstance(unit_name, int):
|
||||
# For some reason the state file will include many raw
|
||||
# integers in the list of destroyed units. These might be
|
||||
# from the smoke effects?
|
||||
continue
|
||||
country = int(unit_name.split("|")[1])
|
||||
unit_type = db.unit_type_from_name(unit_name.split("|")[4])
|
||||
if unit_type is None:
|
||||
logging.error(f"Could not determine type of {unit_name}")
|
||||
continue
|
||||
player_unit = country == self.player_country_id
|
||||
self.dead_units.append(
|
||||
DebriefingDeadUnitInfo(player_unit, unit_type))
|
||||
except Exception:
|
||||
logging.exception(f"Failed to process dead unit {unit_name}")
|
||||
|
||||
for unit_name in self.state_data.killed_ground_units:
|
||||
for cp in game.theater.controlpoints:
|
||||
if cp.captured:
|
||||
@ -204,6 +189,40 @@ class Debriefing:
|
||||
losses.append(DebriefingDeadAircraftInfo(flight))
|
||||
return AirLosses(losses)
|
||||
|
||||
def dead_ground_units(self) -> List[DebriefingDeadUnitInfo]:
|
||||
losses = []
|
||||
for unit_name in self.state_data.killed_ground_units:
|
||||
try:
|
||||
if isinstance(unit_name, int):
|
||||
# For some reason the state file will include many raw
|
||||
# integers in the list of destroyed units. These might be
|
||||
# from the smoke effects?
|
||||
continue
|
||||
if self._is_airfield(unit_name):
|
||||
continue
|
||||
country = int(unit_name.split("|")[1])
|
||||
unit_type = db.unit_type_from_name(unit_name.split("|")[4])
|
||||
if unit_type is None:
|
||||
logging.error(f"Could not determine type of {unit_name}")
|
||||
continue
|
||||
player_unit = country == self.player_country_id
|
||||
losses.append(DebriefingDeadUnitInfo(player_unit, unit_type))
|
||||
except Exception:
|
||||
logging.exception(f"Failed to process dead unit {unit_name}")
|
||||
return losses
|
||||
|
||||
def find_damaged_runways(self) -> List[Airfield]:
|
||||
losses = []
|
||||
for name in self.state_data.killed_ground_units:
|
||||
airfield = self.unit_map.airfield(name)
|
||||
if airfield is None:
|
||||
continue
|
||||
losses.append(airfield)
|
||||
return losses
|
||||
|
||||
def _is_airfield(self, unit_name: str) -> bool:
|
||||
return self.unit_map.airfield(unit_name) is not None
|
||||
|
||||
@property
|
||||
def base_capture_events(self):
|
||||
"""Keeps only the last instance of a base capture event for each base ID."""
|
||||
|
||||
@ -117,6 +117,9 @@ class Event:
|
||||
|
||||
logging.info("Commiting mission results")
|
||||
|
||||
for damaged_runway in debriefing.damaged_runways:
|
||||
damaged_runway.damaged = True
|
||||
|
||||
# ------------------------------
|
||||
# Destroyed aircrafts
|
||||
for loss in debriefing.air_losses.losses:
|
||||
|
||||
@ -32,6 +32,7 @@ from gen.triggergen import TRIGGER_RADIUS_MEDIUM, TriggersGenerator
|
||||
|
||||
from .. import db
|
||||
from ..debriefing import Debriefing
|
||||
from ..theater import Airfield
|
||||
from ..unitmap import UnitMap
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -173,6 +174,9 @@ class Operation:
|
||||
@classmethod
|
||||
def create_unit_map(cls) -> None:
|
||||
cls.unit_map = UnitMap()
|
||||
for control_point in cls.game.theater.controlpoints:
|
||||
if isinstance(control_point, Airfield):
|
||||
cls.unit_map.add_airfield(control_point)
|
||||
|
||||
@classmethod
|
||||
def create_radio_registries(cls) -> None:
|
||||
|
||||
@ -376,6 +376,7 @@ class Airfield(ControlPoint):
|
||||
size, importance, has_frontline,
|
||||
cptype=ControlPointType.AIRBASE)
|
||||
self.airport = airport
|
||||
self.damaged = False
|
||||
|
||||
def can_land(self, aircraft: FlyingType) -> bool:
|
||||
return True
|
||||
|
||||
@ -3,12 +3,14 @@ from typing import Dict, Optional
|
||||
|
||||
from dcs.unitgroup import FlyingGroup
|
||||
|
||||
from game.theater import Airfield
|
||||
from gen.flights.flight import Flight
|
||||
|
||||
|
||||
class UnitMap:
|
||||
def __init__(self) -> None:
|
||||
self.aircraft: Dict[str, Flight] = {}
|
||||
self.airfields: Dict[str, Airfield] = {}
|
||||
|
||||
def add_aircraft(self, group: FlyingGroup, flight: Flight) -> None:
|
||||
for unit in group.units:
|
||||
@ -21,3 +23,11 @@ class UnitMap:
|
||||
|
||||
def flight(self, unit_name: str) -> Optional[Flight]:
|
||||
return self.aircraft.get(unit_name, None)
|
||||
|
||||
def add_airfield(self, airfield: Airfield) -> None:
|
||||
if airfield.name in self.airfields:
|
||||
raise RuntimeError(f"Duplicate airfield: {airfield.name}")
|
||||
self.airfields[airfield.name] = airfield
|
||||
|
||||
def airfield(self, name: str) -> Optional[Airfield]:
|
||||
return self.airfields.get(name, None)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user