From c0f80416822f9a30c9466901fafca3e05d26004f Mon Sep 17 00:00:00 2001 From: T'kael Date: Fri, 21 Jun 2024 20:17:54 -0700 Subject: [PATCH] `Ship targeted` event fixed to resolve an exception when 'Drive' subsystems with unrecognized module definitions are targeted. Resolves #2624 --- ChangeLog.md | 3 ++- DataDefinitions/ModuleDefinitions.cs | 18 +++++++++--------- Events/ShipTargetedEvent.cs | 10 ++++------ JournalMonitor/JournalMonitor.cs | 14 ++++++++++---- Tests/JournalMonitorTests.cs | 7 ++++--- 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index 6100990b67..5d94e989e1 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -4,7 +4,8 @@ Full details of the variables available for each noted event, and VoiceAttack in ## 4.0.4-b3 * Events - * `Destination arrived` event expanded to trigger when arriving at destination settlements / ground sites. (#2623) + * `Destination arrived` expanded to trigger when arriving at destination settlements / ground sites. (#2623) + * `Ship targeted` fixed to resolve an exception when 'Drive' subsystems were targeted. (#2624) * Speech Responder * Scripts * `Blueprint make report` updated to prevent overwriting the `inventory` map used for tracking cargo. (#2622) diff --git a/DataDefinitions/ModuleDefinitions.cs b/DataDefinitions/ModuleDefinitions.cs index b3fc03aa46..60e3269be0 100644 --- a/DataDefinitions/ModuleDefinitions.cs +++ b/DataDefinitions/ModuleDefinitions.cs @@ -1226,15 +1226,15 @@ static Module() // Guardian fighter stuff new Module(899990190, "ext_emitter_guardian", "ShieldGenerator", 1, "I", 0), - new Module(899990101, "gdn_hybrid_fighter_v1_cockpit", "CockpitCanopy", 1, "I", 0), - new Module(899990102, "gdn_hybrid_fighter_v2_cockpit", "CockpitCanopy", 1, "I", 0), - new Module(899990103, "gdn_hybrid_fighter_v3_cockpit", "CockpitCanopy", 1, "I", 0), - new Module(899990060, "gdn_hybrid_fighter_v1_armour_standard", "FighterArmour", 1, "I", 0), - new Module(899990060, "gdn_hybrid_fighter_v2_armour_standard", "FighterArmour", 1, "I", 0), - new Module(899990060, "gdn_hybrid_fighter_v3_armour_standard", "FighterArmour", 1, "I", 0), - new Module(899990050, "hpt_guardiangauss_fixed_gdn_fighter", "GuardianGaussCannon", 1, "I", 0), - new Module(899990050, "hpt_guardianplasma_fixed_gdn_fighter", "GuardianPlasmaCharger", 1, "I", 0), - new Module(899990050, "hpt_guardianshard_fixed_gdn_fighter", "ShardCannon", 1, "I", 0), + new Module(899990191, "gdn_hybrid_fighter_v1_cockpit", "CockpitCanopy", 1, "I", 0), + new Module(899990192, "gdn_hybrid_fighter_v2_cockpit", "CockpitCanopy", 1, "I", 0), + new Module(899990193, "gdn_hybrid_fighter_v3_cockpit", "CockpitCanopy", 1, "I", 0), + new Module(899990194, "gdn_hybrid_fighter_v1_armour_standard", "FighterArmour", 1, "I", 0), + new Module(899990195, "gdn_hybrid_fighter_v2_armour_standard", "FighterArmour", 1, "I", 0), + new Module(899990196, "gdn_hybrid_fighter_v3_armour_standard", "FighterArmour", 1, "I", 0), + new Module(899990197, "hpt_guardiangauss_fixed_gdn_fighter", "GuardianGaussCannon", 1, "I", 0), + new Module(899990198, "hpt_guardianplasma_fixed_gdn_fighter", "GuardianPlasmaCharger", 1, "I", 0), + new Module(899990199, "hpt_guardianshard_fixed_gdn_fighter", "ShardCannon", 1, "I", 0), // Need pricing confirmed }; diff --git a/Events/ShipTargetedEvent.cs b/Events/ShipTargetedEvent.cs index b7bde0c245..6dca7928b7 100644 --- a/Events/ShipTargetedEvent.cs +++ b/Events/ShipTargetedEvent.cs @@ -44,8 +44,8 @@ [ PublicAPI( "the model of the ship" ) ] [PublicAPI("The health of the hull")] public decimal? hullhealth { get; private set; } - [PublicAPI("The subsystem targeted")] - public string subsystem => SubSystem?.localizedName; + [ PublicAPI( "The subsystem targeted" ) ] + public string subsystem { get; private set; } [PublicAPI("The health of the subsystem targeted")] public decimal? subsystemhealth { get; private set; } @@ -58,13 +58,11 @@ [ PublicAPI( "the model of the ship" ) ] public Power Power { get; } - public Module SubSystem { get; } - public Ship ShipDef { get; } public VehicleDefinition FighterDef { get; } - public ShipTargetedEvent(DateTime timestamp, bool targetlocked, Ship shipDef, VehicleDefinition fighterDef, int? scanstage, string name, CombatRating rank, string faction, Power power, LegalStatus legalstatus, int? bounty, decimal? shieldhealth, decimal? hullhealth, Module subsystem, decimal? subsystemhealth) : base(timestamp, NAME) + public ShipTargetedEvent(DateTime timestamp, bool targetlocked, Ship shipDef, VehicleDefinition fighterDef, int? scanstage, string name, CombatRating rank, string faction, Power power, LegalStatus legalstatus, int? bounty, decimal? shieldhealth, decimal? hullhealth, string subsystem, decimal? subsystemhealth) : base(timestamp, NAME) { this.targetlocked = targetlocked; this.ShipDef = shipDef; @@ -78,7 +76,7 @@ public ShipTargetedEvent(DateTime timestamp, bool targetlocked, Ship shipDef, Ve this.bounty = bounty; this.shieldhealth = shieldhealth; this.hullhealth = hullhealth; - this.SubSystem = subsystem; + this.subsystem = subsystem; this.subsystemhealth = subsystemhealth; } } diff --git a/JournalMonitor/JournalMonitor.cs b/JournalMonitor/JournalMonitor.cs index bd4eb642d4..9c81c71368 100644 --- a/JournalMonitor/JournalMonitor.cs +++ b/JournalMonitor/JournalMonitor.cs @@ -2251,16 +2251,22 @@ async void ModuleArrived() var legalStatus = LegalStatus.FromEDName(JsonParsing.getString(data, "LegalStatus")); var power = Power.FromEDName(JsonParsing.getString(data, "Power")); var bounty = JsonParsing.getOptionalInt(data, "Bounty"); - Module subSystem = null; + string subsystemName = null; decimal? subSystemHealth = null; if ( data.ContainsKey( "Subsystem" ) ) { - subSystem = Module.FromEDName( JsonParsing.getString( data, "Subsystem" ) ); - subSystem.fallbackLocalizedName = JsonParsing.getString( data, "Subsystem_Localised" ); + var subsystemEDName = JsonParsing.getString( data, "Subsystem" ); + subsystemName = subsystemEDName.StartsWith( "$ext_drive" ) + ? EddiDataDefinitions.Properties.Modules.Thrusters // The `ShipTargeted` event uses non-standard drive names + : Module.FromEDName( subsystemEDName )?.localizedName; + if ( string.IsNullOrEmpty(subsystemName) ) + { + subsystemName = JsonParsing.getString( data, "Subsystem_Localised" ); + } subSystemHealth = JsonParsing.getOptionalDecimal( data, "SubsystemHealth" ); } - events.Add(new ShipTargetedEvent(timestamp, targetlocked, shipDef, fighterDef, scanstage, name, rank, faction, power, legalStatus, bounty, shieldHealth, hullHealth, subSystem, subSystemHealth) { raw = line, fromLoad = fromLogLoad }); + events.Add(new ShipTargetedEvent(timestamp, targetlocked, shipDef, fighterDef, scanstage, name, rank, faction, power, legalStatus, bounty, shieldHealth, hullHealth, subsystemName, subSystemHealth) { raw = line, fromLoad = fromLogLoad }); } handled = true; break; diff --git a/Tests/JournalMonitorTests.cs b/Tests/JournalMonitorTests.cs index 74063a5905..1e9e2490f0 100644 --- a/Tests/JournalMonitorTests.cs +++ b/Tests/JournalMonitorTests.cs @@ -2467,8 +2467,9 @@ public void TestShipShutdownThargoidTitanPulse () [DataRow( @"{ ""timestamp"":""2022-02-19T02:01:45Z"", ""event"":""ShipTargeted"", ""TargetLocked"":true, ""Ship"":""empire_eagle"", ""Ship_Localised"":""Imperial Eagle"", ""ScanStage"":1, ""PilotName"":""$npc_name_decorate:#name=Syncronax;"", ""PilotName_Localised"":""Syncronax"", ""PilotRank"":""Dangerous"" }", true, 1, "empire_eagle", "Syncronax", "Dangerous", null, null, null, null, null, null, null )] [DataRow( @"{ ""timestamp"":""2022-02-19T02:01:47Z"", ""event"":""ShipTargeted"", ""TargetLocked"":true, ""Ship"":""empire_eagle"", ""Ship_Localised"":""Imperial Eagle"", ""ScanStage"":2, ""PilotName"":""$npc_name_decorate:#name=Syncronax;"", ""PilotName_Localised"":""Syncronax"", ""PilotRank"":""Dangerous"", ""ShieldHealth"":100.000000, ""HullHealth"":100.000000 }", true, 2, "empire_eagle", "Syncronax", "Dangerous", "100", "100", null, null, null, null, null )] [DataRow( @"{ ""timestamp"":""2022-02-19T02:01:49Z"", ""event"":""ShipTargeted"", ""TargetLocked"":true, ""Ship"":""empire_eagle"", ""Ship_Localised"":""Imperial Eagle"", ""ScanStage"":3, ""PilotName"":""$npc_name_decorate:#name=Syncronax;"", ""PilotName_Localised"":""Syncronax"", ""PilotRank"":""Dangerous"", ""ShieldHealth"":100.000000, ""HullHealth"":100.000000, ""Faction"":""Chun Independent Bond"", ""LegalStatus"":""Wanted"", ""Bounty"":79880 }", true, 3, "empire_eagle", "Syncronax", "Dangerous", "100", "100", "Chun Independent Bond", "Wanted", 79880, null, null )] - [DataRow( @"{ ""timestamp"":""2024-03-31T00:54:01Z"", ""event"":""ShipTargeted"", ""TargetLocked"":true, ""Ship"":""anaconda"", ""ScanStage"":3, ""PilotName"":""$Name_AX_Military; Gregory"", ""PilotRank"":""Master"", ""ShieldHealth"":100.000000, ""HullHealth"":100.000000, ""Faction"":""Earls of Barati"", ""LegalStatus"":""Lawless"", ""Subsystem"":""$modularcargobaydoor_name;"", ""Subsystem_Localised"":""Cargo Hatch"", ""SubsystemHealth"":100.000000 }", true, 3, "anaconda", "Gregory", "Master", "100", "100", "Earls of Barati", "Lawless", null, "$modularcargobaydoor_name;", "100" )] - public void TestShipTargeted ( string line, bool targetLocked, int? scanStage, string edModel, string pilotName, string rankEDName, string shieldHealth, string hullHealth, string faction, string legalStatus, int? bounty, string subsystemEDName, string subsystemHealth ) + [DataRow( @"{ ""timestamp"":""2024-03-31T00:54:01Z"", ""event"":""ShipTargeted"", ""TargetLocked"":true, ""Ship"":""anaconda"", ""ScanStage"":3, ""PilotName"":""$Name_AX_Military; Gregory"", ""PilotRank"":""Master"", ""ShieldHealth"":100.000000, ""HullHealth"":100.000000, ""Faction"":""Earls of Barati"", ""LegalStatus"":""Lawless"", ""Subsystem"":""$modularcargobaydoor_name;"", ""Subsystem_Localised"":""Cargo Hatch"", ""SubsystemHealth"":100.000000 }", true, 3, "anaconda", "Gregory", "Master", "100", "100", "Earls of Barati", "Lawless", null, "Cargo Hatch", "100" )] + [DataRow( @"{ ""timestamp"":""2021-03-01T01:16:34Z"", ""event"":""ShipTargeted"", ""TargetLocked"":true, ""Ship"":""anaconda"", ""ScanStage"":3, ""PilotName"":""$npc_name_decorate:#name=Haggis Gregson;"", ""PilotName_Localised"":""Haggis Gregson"", ""PilotRank"":""Elite"", ""ShieldHealth"":94.133560, ""HullHealth"":100.000000, ""Faction"":""Bugaguti People's Co-operative"", ""LegalStatus"":""Wanted"", ""Bounty"":224775, ""Subsystem"":""$ext_drive_class7_a_name;"", ""Subsystem_Localised"":""Drive"", ""SubsystemHealth"":100.000000 }", true, 3, "anaconda", "Haggis Gregson", "Elite", "94.133560", "100", "Bugaguti People's Co-operative", "Wanted", 224775, "Thrusters", "100" )] + public void TestShipTargeted ( string line, bool targetLocked, int? scanStage, string edModel, string pilotName, string rankEDName, string shieldHealth, string hullHealth, string faction, string legalStatus, int? bounty, string subsystemLocalizedName, string subsystemHealth ) { var events = JournalMonitor.ParseJournalEntry(line); Assert.IsTrue( events.Count == 1 ); @@ -2484,7 +2485,7 @@ public void TestShipTargeted ( string line, bool targetLocked, int? scanStage, s Assert.AreEqual( faction, @event.faction ); Assert.AreEqual( legalStatus, @event.LegalStatus?.invariantName ); Assert.AreEqual( bounty, @event.bounty ); - Assert.AreEqual( Module.FromEDName( subsystemEDName ), @event.SubSystem ); + Assert.AreEqual( subsystemLocalizedName, @event.subsystem ); Assert.AreEqual( subsystemHealth is null ? null : (decimal?)Convert.ToDecimal(subsystemHealth), @event.subsystemhealth ); }