From a16097fa337dd92775a5f970572cc712b7b67c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ciar=C3=A1n=20Walsh?= Date: Wed, 16 Apr 2025 22:14:05 +0100 Subject: [PATCH] Fix duplicate suit signals (#35918) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Include the suit owner’s UID in suit sensor status updates. * Show a single monitoring entry per crew member * Rewrite sensor collection using a dictionary --- .../CrewMonitoringWindow.xaml.cs | 22 +++++++++++++++++-- .../Medical/SuitSensors/SuitSensorSystem.cs | 6 +++-- .../Medical/SuitSensor/SharedSuitSensor.cs | 5 ++++- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs b/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs index 18c54cd231..b3b3508169 100644 --- a/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs +++ b/Content.Client/Medical/CrewMonitoring/CrewMonitoringWindow.xaml.cs @@ -79,10 +79,28 @@ public sealed partial class CrewMonitoringWindow : FancyWindow NoServerLabel.Visible = false; + // Collect one status per user, using the sensor with the most data available. + Dictionary uniqueSensorsMap = new(); + foreach (var sensor in sensors) + { + if (uniqueSensorsMap.TryGetValue(sensor.OwnerUid, out var existingSensor)) + { + // Skip if we already have a sensor with more data for this mob. + if (existingSensor.Coordinates != null && sensor.Coordinates == null) + continue; + + if (existingSensor.DamagePercentage != null && sensor.DamagePercentage == null) + continue; + } + + uniqueSensorsMap[sensor.OwnerUid] = sensor; + } + var uniqueSensors = uniqueSensorsMap.Values.ToList(); + // Order sensor data - var orderedSensors = sensors.OrderBy(n => n.Name).OrderBy(j => j.Job); + var orderedSensors = uniqueSensors.OrderBy(n => n.Name).OrderBy(j => j.Job); var assignedSensors = new HashSet(); - var departments = sensors.SelectMany(d => d.JobDepartments).Distinct().OrderBy(n => n); + var departments = uniqueSensors.SelectMany(d => d.JobDepartments).Distinct().OrderBy(n => n); // Create department labels and populate lists foreach (var department in departments) diff --git a/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs b/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs index f6e46dd4f8..fa4344cc78 100644 --- a/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs +++ b/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs @@ -406,7 +406,7 @@ public sealed class SuitSensorSystem : EntitySystem totalDamageThreshold = critThreshold.Value.Int(); // finally, form suit sensor status - var status = new SuitSensorStatus(GetNetEntity(uid), userName, userJob, userJobIcon, userJobDepartments); + var status = new SuitSensorStatus(GetNetEntity(sensor.User.Value), GetNetEntity(uid), userName, userJob, userJobIcon, userJobDepartments); switch (sensor.Mode) { case SuitSensorMode.SensorBinary: @@ -461,6 +461,7 @@ public sealed class SuitSensorSystem : EntitySystem [SuitSensorConstants.NET_JOB_DEPARTMENTS] = status.JobDepartments, [SuitSensorConstants.NET_IS_ALIVE] = status.IsAlive, [SuitSensorConstants.NET_SUIT_SENSOR_UID] = status.SuitSensorUid, + [SuitSensorConstants.NET_OWNER_UID] = status.OwnerUid, }; if (status.TotalDamage != null) @@ -491,13 +492,14 @@ public sealed class SuitSensorSystem : EntitySystem if (!payload.TryGetValue(SuitSensorConstants.NET_JOB_DEPARTMENTS, out List? jobDepartments)) return null; if (!payload.TryGetValue(SuitSensorConstants.NET_IS_ALIVE, out bool? isAlive)) return null; if (!payload.TryGetValue(SuitSensorConstants.NET_SUIT_SENSOR_UID, out NetEntity suitSensorUid)) return null; + if (!payload.TryGetValue(SuitSensorConstants.NET_OWNER_UID, out NetEntity ownerUid)) return null; // try get total damage and cords (optionals) payload.TryGetValue(SuitSensorConstants.NET_TOTAL_DAMAGE, out int? totalDamage); payload.TryGetValue(SuitSensorConstants.NET_TOTAL_DAMAGE_THRESHOLD, out int? totalDamageThreshold); payload.TryGetValue(SuitSensorConstants.NET_COORDINATES, out NetCoordinates? coords); - var status = new SuitSensorStatus(suitSensorUid, name, job, jobIcon, jobDepartments) + var status = new SuitSensorStatus(ownerUid, suitSensorUid, name, job, jobIcon, jobDepartments) { IsAlive = isAlive.Value, TotalDamage = totalDamage, diff --git a/Content.Shared/Medical/SuitSensor/SharedSuitSensor.cs b/Content.Shared/Medical/SuitSensor/SharedSuitSensor.cs index f48e31756d..f0a552c7ec 100644 --- a/Content.Shared/Medical/SuitSensor/SharedSuitSensor.cs +++ b/Content.Shared/Medical/SuitSensor/SharedSuitSensor.cs @@ -7,8 +7,9 @@ namespace Content.Shared.Medical.SuitSensor; [Serializable, NetSerializable] public sealed class SuitSensorStatus { - public SuitSensorStatus(NetEntity suitSensorUid, string name, string job, string jobIcon, List jobDepartments) + public SuitSensorStatus(NetEntity ownerUid, NetEntity suitSensorUid, string name, string job, string jobIcon, List jobDepartments) { + OwnerUid = ownerUid; SuitSensorUid = suitSensorUid; Name = name; Job = job; @@ -18,6 +19,7 @@ public sealed class SuitSensorStatus public TimeSpan Timestamp; public NetEntity SuitSensorUid; + public NetEntity OwnerUid; public string Name; public string Job; public string JobIcon; @@ -55,6 +57,7 @@ public enum SuitSensorMode : byte public static class SuitSensorConstants { + public const string NET_OWNER_UID = "ownerUid"; public const string NET_NAME = "name"; public const string NET_JOB = "job"; public const string NET_JOB_ICON = "jobIcon";