mirror of
https://github.com/dcs-retribution/dcs-retribution.git
synced 2025-11-10 15:41:24 +00:00
Stop counting neutral base captures in status.
These had no effect but were being counted on the waiting for mission results page. Cleaned up the implementation a bunch while I was here. Fixes https://github.com/Khopa/dcs_liberation/issues/1037
This commit is contained in:
parent
e9f25eb562
commit
2b8dfc9dbc
@ -87,6 +87,12 @@ class GroundLosses:
|
|||||||
enemy_airfields: List[Airfield] = field(default_factory=list)
|
enemy_airfields: List[Airfield] = field(default_factory=list)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class BaseCaptureEvent:
|
||||||
|
control_point: ControlPoint
|
||||||
|
captured_by_player: bool
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class StateData:
|
class StateData:
|
||||||
#: True if the mission ended. If False, the mission exited abnormally.
|
#: True if the mission ended. If False, the mission exited abnormally.
|
||||||
@ -122,6 +128,7 @@ class Debriefing:
|
|||||||
self, state_data: Dict[str, Any], game: Game, unit_map: UnitMap
|
self, state_data: Dict[str, Any], game: Game, unit_map: UnitMap
|
||||||
) -> None:
|
) -> None:
|
||||||
self.state_data = StateData.from_json(state_data)
|
self.state_data = StateData.from_json(state_data)
|
||||||
|
self.game = game
|
||||||
self.unit_map = unit_map
|
self.unit_map = unit_map
|
||||||
|
|
||||||
self.player_country = game.player_country
|
self.player_country = game.player_country
|
||||||
@ -131,6 +138,7 @@ class Debriefing:
|
|||||||
|
|
||||||
self.air_losses = self.dead_aircraft()
|
self.air_losses = self.dead_aircraft()
|
||||||
self.ground_losses = self.dead_ground_units()
|
self.ground_losses = self.dead_ground_units()
|
||||||
|
self.base_captures = self.base_capture_events()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def front_line_losses(self) -> Iterator[FrontLineUnit]:
|
def front_line_losses(self) -> Iterator[FrontLineUnit]:
|
||||||
@ -314,15 +322,35 @@ class Debriefing:
|
|||||||
|
|
||||||
return losses
|
return losses
|
||||||
|
|
||||||
@property
|
def base_capture_events(self) -> List[BaseCaptureEvent]:
|
||||||
def base_capture_events(self):
|
|
||||||
"""Keeps only the last instance of a base capture event for each base ID."""
|
"""Keeps only the last instance of a base capture event for each base ID."""
|
||||||
reversed_captures = list(reversed(self.state_data.base_capture_events))
|
blue_coalition_id = 2
|
||||||
last_base_cap_indexes = []
|
seen = set()
|
||||||
for idx, base in enumerate(i.split("||")[0] for i in reversed_captures):
|
captures = []
|
||||||
if base not in [x[1] for x in last_base_cap_indexes]:
|
for capture in reversed(self.state_data.base_capture_events):
|
||||||
last_base_cap_indexes.append((idx, base))
|
cp_id_str, new_owner_id_str, _name = capture.split("||")
|
||||||
return [reversed_captures[idx[0]] for idx in last_base_cap_indexes]
|
cp_id = int(cp_id_str)
|
||||||
|
|
||||||
|
# Only the most recent capture event matters.
|
||||||
|
if cp_id in seen:
|
||||||
|
continue
|
||||||
|
seen.add(cp_id)
|
||||||
|
|
||||||
|
try:
|
||||||
|
control_point = self.game.theater.find_control_point_by_id(cp_id)
|
||||||
|
except KeyError:
|
||||||
|
# Captured base is not a part of the campaign. This happens when neutral
|
||||||
|
# bases are near the conflict. Nothing to do.
|
||||||
|
continue
|
||||||
|
|
||||||
|
captured_by_player = int(new_owner_id_str) == blue_coalition_id
|
||||||
|
if control_point.is_friendly(to_player=captured_by_player):
|
||||||
|
# Base is currently friendly to the new owner. Was captured and
|
||||||
|
# recaptured in the same mission. Nothing to do.
|
||||||
|
continue
|
||||||
|
|
||||||
|
captures.append(BaseCaptureEvent(control_point, captured_by_player))
|
||||||
|
return captures
|
||||||
|
|
||||||
|
|
||||||
class PollDebriefingFileThread(threading.Thread):
|
class PollDebriefingFileThread(threading.Thread):
|
||||||
|
|||||||
@ -222,6 +222,29 @@ class Event:
|
|||||||
for damaged_runway in debriefing.damaged_runways:
|
for damaged_runway in debriefing.damaged_runways:
|
||||||
damaged_runway.damage_runway()
|
damaged_runway.damage_runway()
|
||||||
|
|
||||||
|
def commit_captures(self, debriefing: Debriefing) -> None:
|
||||||
|
for captured in debriefing.base_captures:
|
||||||
|
try:
|
||||||
|
if captured.captured_by_player:
|
||||||
|
info = Information(
|
||||||
|
f"{captured.control_point} captured!",
|
||||||
|
f"We took control of {captured.control_point}.",
|
||||||
|
self.game.turn,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
info = Information(
|
||||||
|
f"{captured.control_point} lost!",
|
||||||
|
f"The enemy took control of {captured.control_point}.",
|
||||||
|
self.game.turn,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.game.informations.append(info)
|
||||||
|
captured.control_point.capture(self.game, captured.captured_by_player)
|
||||||
|
logging.info(f"Will run redeploy for {captured.control_point}")
|
||||||
|
self.redeploy_units(captured.control_point)
|
||||||
|
except Exception:
|
||||||
|
logging.exception(f"Could not process base capture {captured}")
|
||||||
|
|
||||||
def commit(self, debriefing: Debriefing):
|
def commit(self, debriefing: Debriefing):
|
||||||
logging.info("Committing mission results")
|
logging.info("Committing mission results")
|
||||||
|
|
||||||
@ -232,54 +255,7 @@ class Event:
|
|||||||
self.commit_ground_object_losses(debriefing)
|
self.commit_ground_object_losses(debriefing)
|
||||||
self.commit_building_losses(debriefing)
|
self.commit_building_losses(debriefing)
|
||||||
self.commit_damaged_runways(debriefing)
|
self.commit_damaged_runways(debriefing)
|
||||||
|
self.commit_captures(debriefing)
|
||||||
# ------------------------------
|
|
||||||
# Captured bases
|
|
||||||
# if self.game.player_country in db.BLUEFOR_FACTIONS:
|
|
||||||
coalition = 2 # Value in DCS mission event for BLUE
|
|
||||||
# else:
|
|
||||||
# coalition = 1 # Value in DCS mission event for RED
|
|
||||||
|
|
||||||
for captured in debriefing.base_capture_events:
|
|
||||||
try:
|
|
||||||
id = int(captured.split("||")[0])
|
|
||||||
new_owner_coalition = int(captured.split("||")[1])
|
|
||||||
|
|
||||||
captured_cps = []
|
|
||||||
for cp in self.game.theater.controlpoints:
|
|
||||||
if cp.id == id:
|
|
||||||
|
|
||||||
if cp.captured and new_owner_coalition != coalition:
|
|
||||||
for_player = False
|
|
||||||
info = Information(
|
|
||||||
cp.name + " lost !",
|
|
||||||
"The ennemy took control of "
|
|
||||||
+ cp.name
|
|
||||||
+ "\nShame on us !",
|
|
||||||
self.game.turn,
|
|
||||||
)
|
|
||||||
self.game.informations.append(info)
|
|
||||||
captured_cps.append(cp)
|
|
||||||
elif not (cp.captured) and new_owner_coalition == coalition:
|
|
||||||
for_player = True
|
|
||||||
info = Information(
|
|
||||||
cp.name + " captured !",
|
|
||||||
"We took control of " + cp.name + "! Great job !",
|
|
||||||
self.game.turn,
|
|
||||||
)
|
|
||||||
self.game.informations.append(info)
|
|
||||||
captured_cps.append(cp)
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
|
|
||||||
cp.capture(self.game, for_player)
|
|
||||||
|
|
||||||
for cp in captured_cps:
|
|
||||||
logging.info("Will run redeploy for " + cp.name)
|
|
||||||
self.redeploy_units(cp)
|
|
||||||
except Exception:
|
|
||||||
logging.exception(f"Could not process base capture {captured}")
|
|
||||||
|
|
||||||
self.complete_aircraft_transfers(debriefing)
|
self.complete_aircraft_transfers(debriefing)
|
||||||
|
|
||||||
# Destroyed units carcass
|
# Destroyed units carcass
|
||||||
|
|||||||
@ -673,7 +673,7 @@ class ConflictTheater:
|
|||||||
for i in self.controlpoints:
|
for i in self.controlpoints:
|
||||||
if i.id == id:
|
if i.id == id:
|
||||||
return i
|
return i
|
||||||
raise RuntimeError(f"Cannot find ControlPoint with ID {id}")
|
raise KeyError(f"Cannot find ControlPoint with ID {id}")
|
||||||
|
|
||||||
def add_json_cp(self, theater, p: dict) -> ControlPoint:
|
def add_json_cp(self, theater, p: dict) -> ControlPoint:
|
||||||
cp: ControlPoint
|
cp: ControlPoint
|
||||||
|
|||||||
@ -173,7 +173,7 @@ class QWaitingForMissionResultWindow(QDialog):
|
|||||||
"Buildings destroyed", list(debriefing.building_losses), update_layout
|
"Buildings destroyed", list(debriefing.building_losses), update_layout
|
||||||
)
|
)
|
||||||
self.add_update_row(
|
self.add_update_row(
|
||||||
"Base capture events", list(debriefing.base_capture_events), update_layout
|
"Base capture events", debriefing.base_captures, update_layout
|
||||||
)
|
)
|
||||||
|
|
||||||
# Clear previous content of the window
|
# Clear previous content of the window
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user