mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-10-16 22:01:12 +03:00
* init TODO: Make this part of the surveillance camera system Make this be bearable when unpowered(Probably commented out until we make AI lose vision without power) Remove leftover shit Probably clean up the camera RSI * move to surv cameras, unpowered, remove leftovers * silly * review * review * I can see the light * reverse fixtures * review * dependency query * unused oops
110 lines
4.2 KiB
C#
110 lines
4.2 KiB
C#
using Content.Server.Chat.Systems;
|
|
using Content.Shared.Speech;
|
|
using Content.Shared.Speech.Components;
|
|
using Content.Shared.SurveillanceCamera.Components;
|
|
using Content.Shared.Whitelist;
|
|
using Robust.Shared.Player;
|
|
using static Content.Server.Chat.Systems.ChatSystem;
|
|
|
|
namespace Content.Server.SurveillanceCamera;
|
|
|
|
public sealed class SurveillanceCameraMicrophoneSystem : EntitySystem
|
|
{
|
|
[Dependency] private readonly SharedTransformSystem _xforms = default!;
|
|
[Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
SubscribeLocalEvent<SurveillanceCameraMicrophoneComponent, ComponentInit>(OnInit);
|
|
SubscribeLocalEvent<SurveillanceCameraMicrophoneComponent, ListenEvent>(RelayEntityMessage);
|
|
SubscribeLocalEvent<SurveillanceCameraMicrophoneComponent, ListenAttemptEvent>(CanListen);
|
|
SubscribeLocalEvent<ExpandICChatRecipientsEvent>(OnExpandRecipients);
|
|
}
|
|
|
|
private void OnExpandRecipients(ExpandICChatRecipientsEvent ev)
|
|
{
|
|
var xformQuery = GetEntityQuery<TransformComponent>();
|
|
var sourceXform = Transform(ev.Source);
|
|
var sourcePos = _xforms.GetWorldPosition(sourceXform, xformQuery);
|
|
|
|
// This function ensures that chat popups appear on camera views that have connected microphones.
|
|
foreach (var (_, __, camera, xform) in EntityQuery<SurveillanceCameraMicrophoneComponent, ActiveListenerComponent, SurveillanceCameraComponent, TransformComponent>())
|
|
{
|
|
if (camera.ActivePvsViewers.Count == 0)
|
|
continue;
|
|
|
|
// get range to camera. This way wispers will still appear as obfuscated if they are too far from the camera's microphone
|
|
var range = (xform.MapID != sourceXform.MapID)
|
|
? -1
|
|
: (sourcePos - _xforms.GetWorldPosition(xform, xformQuery)).Length();
|
|
|
|
if (range < 0 || range > ev.VoiceRange)
|
|
continue;
|
|
|
|
foreach (var viewer in camera.ActivePvsViewers)
|
|
{
|
|
// if the player has not already received the chat message, send it to them but don't log it to the chat
|
|
// window. This is simply so that it appears in camera.
|
|
if (TryComp(viewer, out ActorComponent? actor))
|
|
ev.Recipients.TryAdd(actor.PlayerSession, new ICChatRecipientData(range, false, true));
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnInit(EntityUid uid, SurveillanceCameraMicrophoneComponent component, ComponentInit args)
|
|
{
|
|
if (component.Enabled)
|
|
EnsureComp<ActiveListenerComponent>(uid).Range = component.Range;
|
|
else
|
|
RemCompDeferred<ActiveListenerComponent>(uid);
|
|
}
|
|
|
|
public void CanListen(EntityUid uid, SurveillanceCameraMicrophoneComponent microphone, ListenAttemptEvent args)
|
|
{
|
|
// TODO maybe just make this a part of ActiveListenerComponent?
|
|
if (_whitelistSystem.IsWhitelistPass(microphone.Blacklist, args.Source))
|
|
args.Cancel();
|
|
}
|
|
|
|
public void RelayEntityMessage(EntityUid uid, SurveillanceCameraMicrophoneComponent component, ListenEvent args)
|
|
{
|
|
if (!TryComp(uid, out SurveillanceCameraComponent? camera))
|
|
return;
|
|
|
|
var ev = new SurveillanceCameraSpeechSendEvent(args.Source, args.Message);
|
|
|
|
foreach (var monitor in camera.ActiveMonitors)
|
|
{
|
|
RaiseLocalEvent(monitor, ev);
|
|
}
|
|
}
|
|
|
|
public void SetEnabled(EntityUid uid, bool value, SurveillanceCameraMicrophoneComponent? microphone = null)
|
|
{
|
|
if (!Resolve(uid, ref microphone))
|
|
return;
|
|
|
|
if (value == microphone.Enabled)
|
|
return;
|
|
|
|
microphone.Enabled = value;
|
|
|
|
if (value)
|
|
EnsureComp<ActiveListenerComponent>(uid).Range = microphone.Range;
|
|
else
|
|
RemCompDeferred<ActiveListenerComponent>(uid);
|
|
}
|
|
}
|
|
|
|
public sealed class SurveillanceCameraSpeechSendEvent : EntityEventArgs
|
|
{
|
|
public EntityUid Speaker { get; }
|
|
public string Message { get; }
|
|
|
|
public SurveillanceCameraSpeechSendEvent(EntityUid speaker, string message)
|
|
{
|
|
Speaker = speaker;
|
|
Message = message;
|
|
}
|
|
}
|
|
|