Revert "Migrate buildings and TGOs to unit map."

Not registering kills correctly. It was in my limited testing, so need
to dig deeper.

https://github.com/Khopa/dcs_liberation/issues/494

This reverts commit 90697194a1a4ca67b53eb7b4056e4f7f5416ac58.
This commit is contained in:
Dan Albert 2020-12-04 23:57:58 -08:00
parent ccb41829c9
commit 72ac8ca872
9 changed files with 245 additions and 237 deletions

View File

@ -6,22 +6,14 @@ import os
import threading
import time
from collections import defaultdict
from dataclasses import dataclass, field
from typing import (
Any,
Callable,
Dict,
Iterator,
List,
Type,
TYPE_CHECKING,
)
from dataclasses import dataclass
from typing import Any, Callable, Dict, List, Type, TYPE_CHECKING
from dcs.unittype import FlyingType, UnitType
from game import db
from game.theater import Airfield, ControlPoint
from game.unitmap import Building, FrontLineUnit, GroundObjectUnit, UnitMap
from game.theater import Airfield, ControlPoint, TheaterGroundObject
from game.unitmap import UnitMap
from gen.flights.flight import Flight
if TYPE_CHECKING:
@ -30,6 +22,12 @@ if TYPE_CHECKING:
DEBRIEFING_LOG_EXTENSION = "log"
@dataclass(frozen=True)
class DebriefingDeadUnitInfo:
player_unit: bool
type: Type[UnitType]
@dataclass(frozen=True)
class DebriefingDeadAircraftInfo:
#: The Flight that resulted in the generated unit.
@ -40,6 +38,27 @@ class DebriefingDeadAircraftInfo:
return self.flight.departure.captured
@dataclass(frozen=True)
class DebriefingDeadFrontLineUnitInfo:
#: The Flight that resulted in the generated unit.
unit_type: Type[UnitType]
control_point: ControlPoint
@property
def player_unit(self) -> bool:
return self.control_point.captured
@dataclass(frozen=True)
class DebriefingDeadBuildingInfo:
#: The ground object this building was present at.
ground_object: TheaterGroundObject
@property
def player_unit(self) -> bool:
return self.ground_object.control_point.captured
@dataclass(frozen=True)
class AirLosses:
losses: List[DebriefingDeadAircraftInfo]
@ -61,12 +80,18 @@ class AirLosses:
return flight.count - losses
@dataclass
class GroundLosses:
front_line: List[FrontLineUnit] = field(default_factory=list)
ground_objects: List[GroundObjectUnit] = field(default_factory=list)
buildings: List[Building] = field(default_factory=list)
airfields: List[Airfield] = field(default_factory=list)
@dataclass(frozen=True)
class FrontLineLosses:
losses: List[DebriefingDeadFrontLineUnitInfo]
def by_type(self, player: bool) -> Dict[Type[UnitType], int]:
losses_by_type: Dict[Type[UnitType], int] = defaultdict(int)
for loss in self.losses:
if loss.control_point.captured != player:
continue
losses_by_type[loss.unit_type] += 1
return losses_by_type
@dataclass(frozen=True)
@ -106,51 +131,80 @@ class Debriefing:
self.game = game
self.unit_map = unit_map
logging.info("--------------------------------")
logging.info("Starting Debriefing preprocessing")
logging.info("--------------------------------")
logging.info(self.state_data)
logging.info("--------------------------------")
self.player_country_id = db.country_id_from_name(game.player_country)
self.enemy_country_id = db.country_id_from_name(game.enemy_country)
self.air_losses = self.dead_aircraft()
self.ground_losses = self.dead_ground_units()
self.front_line_losses = self.dead_front_line_units()
self.dead_units = []
self.damaged_runways = self.find_damaged_runways()
self.dead_aaa_groups: List[DebriefingDeadUnitInfo] = []
self.dead_buildings: List[DebriefingDeadBuildingInfo] = []
@property
def front_line_losses(self) -> Iterator[FrontLineUnit]:
yield from self.ground_losses.front_line
for unit_name in self.state_data.killed_ground_units:
for cp in game.theater.controlpoints:
if cp.captured:
country = self.player_country_id
else:
country = self.enemy_country_id
player_unit = (country == self.player_country_id)
@property
def ground_object_losses(self) -> Iterator[GroundObjectUnit]:
yield from self.ground_losses.ground_objects
for ground_object in cp.ground_objects:
# TODO: This seems to destroy an arbitrary building?
if ground_object.is_same_group(unit_name):
self.dead_buildings.append(
DebriefingDeadBuildingInfo(ground_object))
elif ground_object.dcs_identifier in ["AA", "CARRIER",
"LHA"]:
for g in ground_object.groups:
for u in g.units:
if u.name != unit_name:
continue
unit_type = db.unit_type_from_name(u.type)
if unit_type is None:
logging.error(
f"Could not determine type of %s",
unit_name)
continue
self.dead_units.append(DebriefingDeadUnitInfo(
player_unit, unit_type))
@property
def building_losses(self) -> Iterator[Building]:
yield from self.ground_losses.buildings
self.player_dead_units = [a for a in self.dead_units if a.player_unit]
self.enemy_dead_units = [a for a in self.dead_units if not a.player_unit]
self.player_dead_buildings = [a for a in self.dead_buildings if a.player_unit]
self.enemy_dead_buildings = [a for a in self.dead_buildings if not a.player_unit]
@property
def damaged_runways(self) -> Iterator[Airfield]:
yield from self.ground_losses.airfields
self.player_dead_units_dict: Dict[Type[UnitType], int] = defaultdict(int)
for a in self.player_dead_units:
self.player_dead_units_dict[a.type] += 1
def casualty_count(self, control_point: ControlPoint) -> int:
return len(
[x for x in self.front_line_losses if x.origin == control_point]
)
self.enemy_dead_units_dict: Dict[Type[UnitType], int] = defaultdict(int)
for a in self.enemy_dead_units:
self.enemy_dead_units_dict[a.type] += 1
def front_line_losses_by_type(
self, player: bool) -> Dict[Type[UnitType], int]:
losses_by_type: Dict[Type[UnitType], int] = defaultdict(int)
for loss in self.ground_losses.front_line:
if loss.origin.captured != player:
continue
self.player_dead_buildings_dict: Dict[str, int] = defaultdict(int)
for b in self.player_dead_buildings:
self.player_dead_buildings_dict[b.ground_object.dcs_identifier] += 1
losses_by_type[loss.unit_type] += 1
return losses_by_type
self.enemy_dead_buildings_dict: Dict[str, int] = defaultdict(int)
for b in self.enemy_dead_buildings:
self.enemy_dead_buildings_dict[b.ground_object.dcs_identifier] += 1
def building_losses_by_type(self, player: bool) -> Dict[str, int]:
losses_by_type: Dict[str, int] = defaultdict(int)
for loss in self.ground_losses.buildings:
if loss.ground_object.control_point.captured != player:
continue
losses_by_type[loss.ground_object.dcs_identifier] += 1
return losses_by_type
logging.info("--------------------------------")
logging.info("Debriefing pre process results :")
logging.info("--------------------------------")
logging.info(self.air_losses)
logging.info(self.front_line_losses)
logging.info(self.player_dead_units_dict)
logging.info(self.enemy_dead_units_dict)
logging.info(self.player_dead_buildings_dict)
logging.info(self.enemy_dead_buildings_dict)
def dead_aircraft(self) -> AirLosses:
losses = []
@ -162,38 +216,30 @@ class Debriefing:
losses.append(DebriefingDeadAircraftInfo(flight))
return AirLosses(losses)
def dead_ground_units(self) -> GroundLosses:
losses = GroundLosses()
def dead_front_line_units(self) -> FrontLineLosses:
losses = []
for unit_name in self.state_data.killed_ground_units:
front_line_unit = self.unit_map.front_line_unit(unit_name)
if front_line_unit is not None:
losses.front_line.append(front_line_unit)
unit = self.unit_map.front_line_unit(unit_name)
if unit is None:
# Killed "ground units" might also be runways or TGO units, so
# no need to log an error.
continue
losses.append(
DebriefingDeadFrontLineUnitInfo(unit.unit_type, unit.origin))
return FrontLineLosses(losses)
ground_object_unit = self.unit_map.ground_object_unit(unit_name)
if ground_object_unit is not None:
losses.ground_objects.append(ground_object_unit)
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
building = self.unit_map.building(unit_name)
if building is not None:
losses.buildings.append(building)
continue
airfield = self.unit_map.airfield(unit_name)
if airfield is not None:
losses.airfields.append(airfield)
continue
# Only logging as debug because we don't currently track infantry
# deaths, so we expect to see quite a few unclaimed dead ground
# units. We should start tracking those and covert this to a
# warning.
logging.debug(f"Death of untracked ground unit {unit_name} will "
"have no effect. This may be normal behavior.")
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."""

View File

@ -2,20 +2,21 @@ from __future__ import annotations
import logging
import math
from typing import Dict, List, TYPE_CHECKING, Type
from collections import defaultdict
from typing import Dict, List, Optional, TYPE_CHECKING, Type
from dcs.mapping import Point
from dcs.task import Task
from dcs.unittype import UnitType
from game import persistency
from game import db, persistency
from game.debriefing import AirLosses, Debriefing
from game.infos.information import Information
from game.operation.operation import Operation
from game.theater import ControlPoint
from gen import AirTaskingOrder
from gen.ground_forces.combat_stance import CombatStance
from ..unitmap import UnitMap
from game.operation.operation import Operation
if TYPE_CHECKING:
from ..game import Game
@ -129,10 +130,12 @@ class Event:
cp.base.aircraft[aircraft] -= 1
@staticmethod
def commit_front_line_losses(debriefing: Debriefing) -> None:
for loss in debriefing.front_line_losses:
def commit_front_line_losses(debriefing: Debriefing) -> Dict[int, int]:
killed_unit_count_by_cp: Dict[int, int] = defaultdict(int)
for loss in debriefing.front_line_losses.losses:
unit_type = loss.unit_type
control_point = loss.origin
control_point = loss.control_point
killed_unit_count_by_cp[control_point.id] += 1
available = control_point.base.total_units_of_type(unit_type)
if available <= 0:
logging.error(
@ -142,41 +145,64 @@ class Event:
logging.info(f"{unit_type} destroyed from {control_point}")
control_point.base.armor[unit_type] -= 1
@staticmethod
def commit_ground_object_losses(debriefing: Debriefing) -> None:
for loss in debriefing.ground_object_losses:
# TODO: This should be stored in the TGO, not in the pydcs Group.
if not hasattr(loss.group, "units_losts"):
loss.group.units_losts = []
loss.group.units.remove(loss.unit)
loss.group.units_losts.append(loss.unit)
if not loss.ground_object.alive_unit_count:
loss.ground_object.is_dead = True
def commit_building_losses(self, debriefing: Debriefing) -> None:
for loss in debriefing.building_losses:
loss.ground_object.is_dead = True
self.game.informations.append(Information(
"Building destroyed",
f"{loss.ground_object.dcs_identifier} has been destroyed at "
f"location {loss.ground_object.obj_name}", self.game.turn
))
@staticmethod
def commit_damaged_runways(debriefing: Debriefing) -> None:
for damaged_runway in debriefing.damaged_runways:
damaged_runway.damage_runway()
return killed_unit_count_by_cp
def commit(self, debriefing: Debriefing):
logging.info("Committing mission results")
for damaged_runway in debriefing.damaged_runways:
damaged_runway.damage_runway()
self.commit_air_losses(debriefing)
self.commit_front_line_losses(debriefing)
self.commit_ground_object_losses(debriefing)
self.commit_building_losses(debriefing)
self.commit_damaged_runways(debriefing)
killed_unit_count_by_cp = self.commit_front_line_losses(debriefing)
# ------------------------------
# Static ground objects
for destroyed_ground_unit_name in debriefing.state_data.killed_ground_units:
for cp in self.game.theater.controlpoints:
if not cp.ground_objects:
continue
# -- Static ground objects
for i, ground_object in enumerate(cp.ground_objects):
if ground_object.is_dead:
continue
if (
(ground_object.group_name == destroyed_ground_unit_name)
or
(ground_object.is_same_group(destroyed_ground_unit_name))
):
logging.info("cp {} killing ground object {}".format(cp, ground_object.group_name))
cp.ground_objects[i].is_dead = True
info = Information("Building destroyed",
ground_object.dcs_identifier + " has been destroyed at location " + ground_object.obj_name,
self.game.turn)
self.game.informations.append(info)
# -- AA Site groups
destroyed_units = 0
info = Information("Units destroyed at " + ground_object.obj_name,
"",
self.game.turn)
for i, ground_object in enumerate(cp.ground_objects):
if ground_object.dcs_identifier in ["AA", "CARRIER", "LHA", "EWR"]:
for g in ground_object.groups:
if not hasattr(g, "units_losts"):
g.units_losts = []
for u in g.units:
if u.name == destroyed_ground_unit_name:
g.units.remove(u)
g.units_losts.append(u)
destroyed_units = destroyed_units + 1
info.text = u.type
ucount = sum([len(g.units) for g in ground_object.groups])
if ucount == 0:
ground_object.is_dead = True
if destroyed_units > 0:
self.game.informations.append(info)
# ------------------------------
# Captured bases
@ -231,8 +257,8 @@ class Event:
delta = 0.0
player_won = True
ally_casualties = debriefing.casualty_count(cp)
enemy_casualties = debriefing.casualty_count(enemy_cp)
ally_casualties = killed_unit_count_by_cp[cp.id]
enemy_casualties = killed_unit_count_by_cp[enemy_cp.id]
ally_units_alive = cp.base.total_armor
enemy_units_alive = enemy_cp.base.total_armor

View File

@ -265,8 +265,7 @@ class Operation:
cls.current_mission,
cls.game,
cls.radio_registry,
cls.tacan_registry,
cls.unit_map
cls.tacan_registry
)
cls.groundobjectgen.generate()

View File

@ -23,7 +23,7 @@ class Base:
def __init__(self):
self.aircraft: Dict[Type[FlyingType], int] = {}
self.armor: Dict[Type[VehicleType], int] = {}
self.armor: Dict[VehicleType, int] = {}
self.aa: Dict[AirDefence, int] = {}
self.commision_points: Dict[Type, float] = {}
self.strength = 1

View File

@ -136,10 +136,6 @@ class TheaterGroundObject(MissionTarget):
]
yield from super().mission_types(for_player)
@property
def alive_unit_count(self) -> int:
return sum(len(g.units) for g in self.groups)
class BuildingGroundObject(TheaterGroundObject):
def __init__(self, name: str, category: str, group_id: int, object_id: int,

View File

@ -2,41 +2,25 @@
from dataclasses import dataclass
from typing import Dict, Optional, Type
from dcs.unit import Unit
from dcs.unitgroup import FlyingGroup, Group, StaticGroup
from dcs.unittype import VehicleType
from dcs.unitgroup import FlyingGroup, Group
from dcs.unittype import UnitType
from game import db
from game.theater import Airfield, ControlPoint, TheaterGroundObject
from game.theater.theatergroundobject import BuildingGroundObject
from game.theater import Airfield, ControlPoint
from gen.flights.flight import Flight
@dataclass(frozen=True)
@dataclass
class FrontLineUnit:
unit_type: Type[VehicleType]
unit_type: Type[UnitType]
origin: ControlPoint
@dataclass(frozen=True)
class GroundObjectUnit:
ground_object: TheaterGroundObject
group: Group
unit: Unit
@dataclass(frozen=True)
class Building:
ground_object: BuildingGroundObject
class UnitMap:
def __init__(self) -> None:
self.aircraft: Dict[str, Flight] = {}
self.airfields: Dict[str, Airfield] = {}
self.front_line_units: Dict[str, FrontLineUnit] = {}
self.ground_object_units: Dict[str, GroundObjectUnit] = {}
self.buildings: Dict[str, Building] = {}
def add_aircraft(self, group: FlyingGroup, flight: Flight) -> None:
for unit in group.units:
@ -68,36 +52,7 @@ class UnitMap:
unit_type = db.unit_type_from_name(unit.type)
if unit_type is None:
raise RuntimeError(f"Unknown unit type: {unit.type}")
if not issubclass(unit_type, VehicleType):
raise RuntimeError(
f"{name} is a {unit_type.__name__}, expected a VehicleType")
self.front_line_units[name] = FrontLineUnit(unit_type, origin)
def front_line_unit(self, name: str) -> Optional[FrontLineUnit]:
return self.front_line_units.get(name, None)
def add_ground_object_units(self, ground_object: TheaterGroundObject,
group: Group) -> None:
for unit in group.units:
# The actual name is a String (the pydcs translatable string), which
# doesn't define __eq__.
name = str(unit.name)
if name in self.ground_object_units:
raise RuntimeError(f"Duplicate TGO unit: {name}")
self.ground_object_units[name] = GroundObjectUnit(ground_object,
group, unit)
def ground_object_unit(self, name: str) -> Optional[GroundObjectUnit]:
return self.ground_object_units.get(name, None)
def add_building(self, ground_object: BuildingGroundObject,
building: StaticGroup) -> None:
# The actual name is a String (the pydcs translatable string), which
# doesn't define __eq__.
name = str(building.name)
if name in self.buildings:
raise RuntimeError(f"Duplicate TGO unit: {name}")
self.buildings[name] = Building(ground_object)
def building(self, name: str) -> Optional[Building]:
return self.buildings.get(name, None)

View File

@ -9,7 +9,7 @@ from __future__ import annotations
import logging
import random
from typing import Dict, Iterator, Optional, TYPE_CHECKING, Type
from typing import Dict, Iterator, Optional, TYPE_CHECKING
from dcs import Mission
from dcs.country import Country
@ -33,7 +33,7 @@ from game.theater.theatergroundobject import (
GenericCarrierGroundObject,
LhaGroundObject, ShipGroundObject,
)
from game.unitmap import UnitMap
from .conflictgen import Conflict
from .radios import RadioFrequency, RadioRegistry
from .runways import RunwayData
from .tacan import TacanBand, TacanChannel, TacanRegistry
@ -52,12 +52,11 @@ class GenericGroundObjectGenerator:
Currently used only for SAM and missile (V1/V2) sites.
"""
def __init__(self, ground_object: TheaterGroundObject, country: Country,
game: Game, mission: Mission, unit_map: UnitMap) -> None:
game: Game, mission: Mission) -> None:
self.ground_object = ground_object
self.country = country
self.game = game
self.m = mission
self.unit_map = unit_map
def generate(self) -> None:
if self.game.position_culled(self.ground_object.position):
@ -90,10 +89,9 @@ class GenericGroundObjectGenerator:
self.enable_eplrs(vg, unit_type)
self.set_alarm_state(vg)
self._register_unit_group(vg)
@staticmethod
def enable_eplrs(group: Group, unit_type: Type[UnitType]) -> None:
def enable_eplrs(group: Group, unit_type: UnitType) -> None:
if hasattr(unit_type, 'eplrs'):
if unit_type.eplrs:
group.points[0].tasks.append(EPLRS(group.id))
@ -104,9 +102,6 @@ class GenericGroundObjectGenerator:
else:
group.points[0].tasks.append(OptAlarmState(1))
def _register_unit_group(self, group: Group) -> None:
self.unit_map.add_ground_object_units(self.ground_object, group)
class BuildingSiteGenerator(GenericGroundObjectGenerator):
"""Generator for building sites.
@ -138,17 +133,16 @@ class BuildingSiteGenerator(GenericGroundObjectGenerator):
def generate_vehicle_group(self, unit_type: UnitType) -> None:
if not self.ground_object.is_dead:
group = self.m.vehicle_group(
self.m.vehicle_group(
country=self.country,
name=self.ground_object.group_name,
_type=unit_type,
position=self.ground_object.position,
heading=self.ground_object.heading,
)
self._register_unit_group(group)
def generate_static(self, static_type: StaticType) -> None:
group = self.m.static_group(
self.m.static_group(
country=self.country,
name=self.ground_object.group_name,
_type=static_type,
@ -156,11 +150,6 @@ class BuildingSiteGenerator(GenericGroundObjectGenerator):
heading=self.ground_object.heading,
dead=self.ground_object.is_dead,
)
self._register_building(group)
def _register_building(self, building: StaticGroup) -> None:
assert isinstance(self.ground_object, BuildingGroundObject)
self.unit_map.add_building(self.ground_object, building)
class GenericCarrierGenerator(GenericGroundObjectGenerator):
@ -172,8 +161,8 @@ class GenericCarrierGenerator(GenericGroundObjectGenerator):
control_point: ControlPoint, country: Country, game: Game,
mission: Mission, radio_registry: RadioRegistry,
tacan_registry: TacanRegistry, icls_alloc: Iterator[int],
runways: Dict[str, RunwayData], unit_map: UnitMap) -> None:
super().__init__(ground_object, country, game, mission, unit_map)
runways: Dict[str, RunwayData]) -> None:
super().__init__(ground_object, country, game, mission)
self.ground_object = ground_object
self.control_point = control_point
self.radio_registry = radio_registry
@ -201,9 +190,8 @@ class GenericCarrierGenerator(GenericGroundObjectGenerator):
brc = self.steam_into_wind(ship_group)
self.activate_beacons(ship_group, tacan, tacan_callsign, icls)
self.add_runway_data(brc or 0, atc, tacan, tacan_callsign, icls)
self._register_unit_group(ship_group)
def get_carrier_type(self, group: Group) -> Type[UnitType]:
def get_carrier_type(self, group: Group) -> UnitType:
unit_type = unit_type_from_name(group.units[0].type)
if unit_type is None:
raise RuntimeError(
@ -340,9 +328,8 @@ class ShipObjectGenerator(GenericGroundObjectGenerator):
self.generate_group(group, unit_type)
def generate_group(self, group_def: Group,
first_unit_type: Type[UnitType]) -> None:
group = self.m.ship_group(self.country, group_def.name, first_unit_type,
def generate_group(self, group_def: Group, unit_type: UnitType):
group = self.m.ship_group(self.country, group_def.name, unit_type,
position=group_def.position,
heading=group_def.units[0].heading)
group.units[0].name = self.m.string(group_def.units[0].name)
@ -356,7 +343,6 @@ class ShipObjectGenerator(GenericGroundObjectGenerator):
ship.heading = unit.heading
group.add_unit(ship)
self.set_alarm_state(group)
self._register_unit_group(group)
class GroundObjectsGenerator:
@ -369,13 +355,11 @@ class GroundObjectsGenerator:
"""
def __init__(self, mission: Mission, game: Game,
radio_registry: RadioRegistry, tacan_registry: TacanRegistry,
unit_map: UnitMap) -> None:
radio_registry: RadioRegistry, tacan_registry: TacanRegistry):
self.m = mission
self.game = game
self.radio_registry = radio_registry
self.tacan_registry = tacan_registry
self.unit_map = unit_map
self.icls_alloc = iter(range(1, 21))
self.runways: Dict[str, RunwayData] = {}
@ -389,26 +373,25 @@ class GroundObjectsGenerator:
for ground_object in cp.ground_objects:
if isinstance(ground_object, BuildingGroundObject):
generator = BuildingSiteGenerator(
ground_object, country, self.game, self.m,
self.unit_map)
generator = BuildingSiteGenerator(ground_object, country,
self.game, self.m)
elif isinstance(ground_object, CarrierGroundObject):
generator = CarrierGenerator(
ground_object, cp, country, self.game, self.m,
self.radio_registry, self.tacan_registry,
self.icls_alloc, self.runways, self.unit_map)
generator = CarrierGenerator(ground_object, cp, country,
self.game, self.m,
self.radio_registry,
self.tacan_registry,
self.icls_alloc, self.runways)
elif isinstance(ground_object, LhaGroundObject):
generator = CarrierGenerator(
ground_object, cp, country, self.game, self.m,
self.radio_registry, self.tacan_registry,
self.icls_alloc, self.runways, self.unit_map)
generator = CarrierGenerator(ground_object, cp, country,
self.game, self.m,
self.radio_registry,
self.tacan_registry,
self.icls_alloc, self.runways)
elif isinstance(ground_object, ShipGroundObject):
generator = ShipObjectGenerator(
ground_object, country, self.game, self.m,
self.unit_map)
generator = ShipObjectGenerator(ground_object, country,
self.game, self.m)
else:
generator = GenericGroundObjectGenerator(
ground_object, country, self.game, self.m,
self.unit_map)
generator = GenericGroundObjectGenerator(ground_object,
country, self.game,
self.m)
generator.generate()

View File

@ -41,6 +41,13 @@ class QDebriefingWindow(QDialog):
self.layout.addWidget(header)
self.layout.addStretch()
# Result
#if self.gameEvent.is_successfull(self.debriefing):
# title = QLabel("<b>Operation end !</b>")
# title.setProperty("style", "title-success")
#else:
# title = QLabel("<b>Operation end !</b>")
# title.setProperty("style", "title-danger")
title = QLabel("<b>Casualty report</b>")
self.layout.addWidget(title)
@ -61,7 +68,7 @@ class QDebriefingWindow(QDialog):
logging.exception(
f"Issue adding {unit_type} to debriefing information")
front_line_losses = self.debriefing.front_line_losses_by_type(
front_line_losses = self.debriefing.front_line_losses.by_type(
player=True
)
for unit_type, count in front_line_losses.items():
@ -74,10 +81,9 @@ class QDebriefingWindow(QDialog):
logging.exception(
f"Issue adding {unit_type} to debriefing information")
building_losses = self.debriefing.building_losses_by_type(player=True)
for building, count in building_losses.items():
for building, count in self.debriefing.player_dead_buildings_dict.items():
try:
lostUnitsLayout.addWidget(QLabel(building), row, 0)
lostUnitsLayout.addWidget(QLabel(building, row, 0))
lostUnitsLayout.addWidget(QLabel(str(count)), row, 1)
row += 1
except AttributeError:
@ -91,6 +97,12 @@ class QDebriefingWindow(QDialog):
enemylostUnitsLayout = QGridLayout()
enemylostUnits.setLayout(enemylostUnitsLayout)
#row = 0
#if self.debriefing.destroyed_objects:
# enemylostUnitsLayout.addWidget(QLabel("Ground assets"), row, 0)
# enemylostUnitsLayout.addWidget(QLabel("{}".format(len(self.debriefing.destroyed_objects))), row, 1)
# row += 1
enemy_air_losses = self.debriefing.air_losses.by_type(player=False)
for unit_type, count in enemy_air_losses.items():
try:
@ -102,7 +114,7 @@ class QDebriefingWindow(QDialog):
logging.exception(
f"Issue adding {unit_type} to debriefing information")
front_line_losses = self.debriefing.front_line_losses_by_type(
front_line_losses = self.debriefing.front_line_losses.by_type(
player=False
)
for unit_type, count in front_line_losses.items():
@ -112,8 +124,7 @@ class QDebriefingWindow(QDialog):
enemylostUnitsLayout.addWidget(QLabel("{}".format(count)), row, 1)
row += 1
building_losses = self.debriefing.building_losses_by_type(player=False)
for building, count in building_losses.items():
for building, count in self.debriefing.enemy_dead_buildings_dict.items():
try:
enemylostUnitsLayout.addWidget(QLabel(building), row, 0)
enemylostUnitsLayout.addWidget(QLabel("{}".format(count)), row, 1)
@ -124,8 +135,6 @@ class QDebriefingWindow(QDialog):
self.layout.addWidget(enemylostUnits)
# TODO: Display dead ground object units and runways.
# confirm button
okay = QPushButton("Okay")
okay.clicked.connect(self.close)

View File

@ -138,21 +138,15 @@ class QWaitingForMissionResultWindow(QDialog):
updateLayout.addWidget(
QLabel("<b>Front line units destroyed</b>"), 1, 0)
updateLayout.addWidget(
QLabel(str(len(list(debriefing.front_line_losses)))), 1, 1)
QLabel(str(len(debriefing.front_line_losses.losses))), 1, 1)
updateLayout.addWidget(
QLabel("<b>Other ground units destroyed</b>"), 2, 0)
updateLayout.addWidget(
QLabel(str(len(list(debriefing.ground_object_losses)))), 2, 1)
updateLayout.addWidget(QLabel(str(len(debriefing.dead_units))), 2, 1)
updateLayout.addWidget(QLabel("<b>Base Capture Events</b>"), 3, 0)
updateLayout.addWidget(
QLabel("<b>Buildings destroyed</b>"), 3, 0)
updateLayout.addWidget(
QLabel(str(len(list(debriefing.building_losses)))), 3, 1)
updateLayout.addWidget(QLabel("<b>Base Capture Events</b>"), 4, 0)
updateLayout.addWidget(
QLabel(str(len(debriefing.base_capture_events))), 4, 1)
QLabel(str(len(debriefing.base_capture_events))), 3, 1)
# Clear previous content of the window
for i in reversed(range(self.gridLayout.count())):