Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make crew monitors beep when someone dies / crits #2930

Merged
merged 11 commits into from
Feb 11, 2025
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using Content.Shared.Medical.SuitSensor;
using Robust.Shared.Audio; // DeltaV
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; // DeltaV

namespace Content.Server.Medical.CrewMonitoring;

[RegisterComponent]
[RegisterComponent, AutoGenerateComponentPause] // DeltaV - add AutoGenerateComponentPause
[Access(typeof(CrewMonitoringConsoleSystem))]
public sealed partial class CrewMonitoringConsoleComponent : Component
{
Expand All @@ -16,4 +18,35 @@ public sealed partial class CrewMonitoringConsoleComponent : Component
/// </summary>
[DataField("sensorTimeout"), ViewVariables(VVAccess.ReadWrite)]
public float SensorTimeout = 10f;

// DeltaV - start of alert system code
/// <summary>
/// Should the component beep if someone goes critical or dies
/// </summary>
[DataField]
public bool AlertsEnabled = true;

/// <summary>
/// Track sensors that have triggered the crew member critical alert.
/// </summary>
public HashSet<string> AlertedSensors = [];

/// <summary>
/// Accumulated time for tracking alert cooldown
/// </summary>
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoPausedField]
public TimeSpan NextAlert;

/// <summary>
/// Time between alerts
/// </summary>
[DataField]
public TimeSpan AlertCooldown = TimeSpan.FromSeconds(15);

/// <summary>
/// Alert sound that is played when a crew member goes into critical / dies.
/// </summary>
[DataField]
public SoundSpecifier AlertSound = new SoundPathSpecifier("/Audio/_DV/Medical/CrewMonitoring/crew_alert.ogg");
// DeltaV - end of alert system code
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
using System.Linq;
using Content.Server.DeviceNetwork;
using Content.Server.DeviceNetwork.Systems;
using Content.Server.Power.EntitySystems; // DeltaV
using Content.Server.PowerCell;
using Content.Shared.Medical.CrewMonitoring;
using Content.Shared.Medical.SuitSensor;
using Content.Shared.Pinpointer;
using Robust.Server.GameObjects;
using Robust.Shared.Audio; // DeltaV
using Robust.Shared.Audio.Systems; // DeltaV
using Robust.Shared.Timing; // DeltaV

namespace Content.Server.Medical.CrewMonitoring;

public sealed class CrewMonitoringConsoleSystem : EntitySystem
{
[Dependency] private readonly PowerCellSystem _cell = default!;
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!; // DeltaV
[Dependency] private readonly IGameTiming _timing = default!; // DeltaV

public override void Initialize()
{
Expand Down Expand Up @@ -43,6 +49,48 @@ private void OnPacketReceived(EntityUid uid, CrewMonitoringConsoleComponent comp

component.ConnectedSensors = sensorStatus;
UpdateUserInterface(uid, component);

// DeltaV - start of alert system code
if (!component.AlertsEnabled)
return;

// station power (for the machine version)
if (!this.IsPowered(uid, EntityManager))
return;

// cell power (for the handheld)
if (!_cell.HasActivatableCharge(uid))
return;

foreach (var (sensorId, status) in sensorStatus)
{
// DamagePercentage above 1f is considered critical. It is null when sensor vitals are off.
var isCritical = status.DamagePercentage is >= 1f;

// Skip crew members that we have already alerted about
if (component.AlertedSensors.Contains(sensorId))
{
if (status.IsAlive && !isCritical)
component.AlertedSensors.Remove(sensorId);
continue;
}

if (!status.IsAlive || isCritical)
{
if (_timing.CurTime >= component.NextAlert)
{
var audioParams = AudioParams.Default.WithVolume(-2f).WithMaxDistance(4f);
_audio.PlayPvs(component.AlertSound, uid, audioParams);
component.NextAlert = _timing.CurTime + component.AlertCooldown;
}

// We are doing this outside the cooldown check to avoid "alert queues"
// If two people die at the same time and remain dead for longer, we want to alert once for both people
// instead of alerting once for the first one, waiting the cooldown, and then alerting again for the second one.
component.AlertedSensors.Add(sensorId);
}
}
// DeltaV - end of alert system code
}

private void OnUIOpened(EntityUid uid, CrewMonitoringConsoleComponent component, BoundUIOpenedEvent args)
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@
price: 750
- type: Tag # DeltaV - Let it be put in storage implants by removing HighRiskItem
tags: []
- type: CrewMonitoringConsole # DeltaV - disable crew crit / dead beeping alerts
alertsEnabled: false

- type: entity
id: SpyCrewMonitorEmpty
Expand All @@ -85,6 +87,8 @@
sprite: Objects/Specific/Medical/syndihandheldcrewmonitor.rsi
- type: PowerCellDraw
useRate: 0 # DeltaV - Changed to zero with the removal of the microreactor in observations kit
- type: CrewMonitoringConsole # DeltaV - disable crew crit / dead beeping alerts
alertsEnabled: false

- type: entity
id: SyndiCrewMonitorEmpty
Expand Down
Loading