From 0d257a2c3b48d46525bfffd9593091a6c427e2ae Mon Sep 17 00:00:00 2001 From: zhexu14 <64713351+zhexu14@users.noreply.github.com> Date: Wed, 19 Apr 2023 16:16:41 +1000 Subject: [PATCH] Track S_EVENT_KILL and S_EVENT_UNIT_LOST as well. Catch a few more death signals. Still not perfect but a bit better. Fixes https://github.com/dcs-liberation/dcs_liberation/issues/2765. --- game/debriefing.py | 43 ++++++++++++++++++----- resources/plugins/base/dcs_liberation.lua | 32 ++++++++++++----- 2 files changed, 57 insertions(+), 18 deletions(-) diff --git a/game/debriefing.py b/game/debriefing.py index fb7b366f..a7ece486 100644 --- a/game/debriefing.py +++ b/game/debriefing.py @@ -109,16 +109,41 @@ class StateData: base_capture_events: List[str] @classmethod - def from_json(cls, data: Dict[str, Any]) -> StateData: + def from_json(cls, data: Dict[str, Any], unit_map: UnitMap) -> StateData: + def clean_unit_list(unit_list: List[Any]) -> List[str]: + # Cleans list of units in state.json by + # - Removing duplicates. Airfields emit a new "dead" event every time a bomb + # is dropped on them when they've already dead. + # - Normalise dead map objects (which are ints) to strings. The unit map + # only stores strings + units = set() + for unit in unit_list: + units.add(str(unit)) + return list(units) + + killed_aircraft = [] + killed_ground_units = [] + + # Process killed units from S_EVENT_UNIT_LOST, S_EVENT_CRASH, S_EVENT_DEAD & S_EVENT_KILL + # Try to process every event that could indicate a unit was killed, even if it is + # inefficient and results in duplication as the logic DCS uses to trigger the various + # event types is not clear and may change over time. + killed_units = clean_unit_list( + data["unit_lost_events"] + + data["kill_events"] + + data["crash_events"] + + data["dead_events"] + ) + for unit in killed_units: # organize killed units into aircraft vs ground + if unit_map.flight(unit) is not None: + killed_aircraft.append(unit) + else: + killed_ground_units.append(unit) + return cls( mission_ended=data["mission_ended"], - killed_aircraft=data["killed_aircrafts"], - # Airfields emit a new "dead" event every time a bomb is dropped on - # them when they've already dead. Dedup. - # - # Also normalize dead map objects (which are ints) to strings. The unit map - # only stores strings. - killed_ground_units=list({str(u) for u in data["killed_ground_units"]}), + killed_aircraft=killed_aircraft, + killed_ground_units=killed_ground_units, destroyed_statics=data["destroyed_objects_positions"], base_capture_events=data["base_capture_events"], ) @@ -128,7 +153,7 @@ class Debriefing: def __init__( self, state_data: Dict[str, Any], game: Game, unit_map: UnitMap ) -> None: - self.state_data = StateData.from_json(state_data) + self.state_data = StateData.from_json(state_data, unit_map) self.game = game self.unit_map = unit_map diff --git a/resources/plugins/base/dcs_liberation.lua b/resources/plugins/base/dcs_liberation.lua index c99903db..086ce500 100644 --- a/resources/plugins/base/dcs_liberation.lua +++ b/resources/plugins/base/dcs_liberation.lua @@ -4,8 +4,10 @@ local WRITESTATE_SCHEDULE_IN_SECONDS = 60 logger = mist.Logger:new("DCSLiberation", "info") logger:info("Check that json.lua is loaded : json = "..tostring(json)) -killed_aircrafts = {} -- killed aircraft will be added via S_EVENT_CRASH event -killed_ground_units = {} -- killed units will be added via S_EVENT_DEAD event +crash_events = {} -- killed aircraft will be added via S_EVENT_CRASH event +dead_events = {} -- killed units will be added via S_EVENT_DEAD event +unit_lost_events = {} -- killed units will be added via S_EVENT_UNIT_LOST +kill_events = {} -- killed units will be added via S_EVENT_KILL base_capture_events = {} destroyed_objects_positions = {} -- will be added via S_EVENT_DEAD event mission_ended = false @@ -30,9 +32,11 @@ function write_state() local fp = io.open(_debriefing_file_location, 'w') local game_state = { - ["killed_aircrafts"] = killed_aircrafts, - ["killed_ground_units"] = killed_ground_units, + ["crash_events"] = crash_events, + ["dead_events"] = dead_events, ["base_capture_events"] = base_capture_events, + ["unit_lost_events"] = unit_lost_events, + ["kill_events"] = kill_events, ["mission_ended"] = mission_ended, ["destroyed_objects_positions"] = destroyed_objects_positions, } @@ -142,13 +146,23 @@ end activeWeapons = {} local function onEvent(event) - if event.id == world.event.S_EVENT_CRASH and event.initiator then - killed_aircrafts[#killed_aircrafts + 1] = event.initiator.getName(event.initiator) - write_state() - end + if event.id == world.event.S_EVENT_CRASH and event.initiator then + crash_events[#crash_events + 1] = event.initiator.getName(event.initiator) + write_state() + end + + if event.id == world.event.S_EVENT_UNIT_LOST and event.initiator then + unit_lost_events[#unit_lost_events + 1] = event.initiator.getName(event.initiator) + write_state() + end + + if event.id == world.event.S_EVENT_KILL and event.target then + kill_events[#kill_events + 1] = event.target.getName(event.target) + write_state() + end if event.id == world.event.S_EVENT_DEAD and event.initiator then - killed_ground_units[#killed_ground_units + 1] = event.initiator.getName(event.initiator) + dead_events[#dead_events + 1] = event.initiator.getName(event.initiator) local position = event.initiator.getPosition(event.initiator) local destruction = {} destruction.x = position.p.x