using System.Collections.Generic; using System.Threading.Tasks; using Content.Server.Tools.Components; using Content.Shared.Interaction; using Content.Shared.Notification; using Content.Shared.Notification.Managers; using Content.Shared.Tool; using Robust.Shared.GameObjects; using Robust.Shared.Localization; using Robust.Shared.Serialization; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; namespace Content.Server.MachineLinking.Components { [RegisterComponent] public class SignalTransmitterComponent : Component, IInteractUsing, ISerializationHooks { public override string Name => "SignalTransmitter"; private List? _unresolvedReceivers = new(); private List _receivers = new(); /// /// 0 is unlimited range /// [ViewVariables] [DataField("range")] public float Range { get; private set; } = 10; [DataField("signalReceivers")] private List _receiverIds = new(); void ISerializationHooks.BeforeSerialization() { var entityList = new List(); foreach (var receiver in _receivers) { if (receiver.Deleted) { continue; } entityList.Add(receiver.Owner.Uid); } _receiverIds = entityList; } void ISerializationHooks.AfterDeserialization() { _unresolvedReceivers = new List(); foreach (var id in _receiverIds) { if (!Owner.EntityManager.TryGetEntity(id, out var entity) || !entity.TryGetComponent(out var receiver)) { continue; } _unresolvedReceivers.Add(receiver); } } public override void Initialize() { base.Initialize(); _receivers = new List(); if (_unresolvedReceivers != null) { foreach (var receiver in _unresolvedReceivers) { receiver.Subscribe(this); } _unresolvedReceivers = null; } } public bool TransmitSignal(T signal) { if (_receivers.Count == 0) { return false; } foreach (var receiver in _receivers) { if (Range > 0 && !Owner.Transform.Coordinates.InRange(Owner.EntityManager, receiver.Owner.Transform.Coordinates, Range)) { continue; } receiver.DistributeSignal(signal); } return true; } public void Subscribe(SignalReceiverComponent receiver) { if (_receivers.Contains(receiver)) { return; } _receivers.Add(receiver); } public void Unsubscribe(SignalReceiverComponent receiver) { _receivers.Remove(receiver); } public SignalTransmitterComponent GetSignal(IEntity? user) { if (user != null) { Owner.PopupMessage(user, Loc.GetString("Signal fetched.")); } return this; } async Task IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs) { if (!eventArgs.Using.TryGetComponent(out var tool)) return false; if (tool.HasQuality(ToolQuality.Multitool) && eventArgs.Using.TryGetComponent(out var linker)) { linker.Link = GetSignal(eventArgs.User); } return false; } protected override void Shutdown() { base.Shutdown(); for (var i = _receivers.Count-1; i >= 0; i++) { var receiver = _receivers[i]; if (receiver.Deleted) { continue; } receiver.Unsubscribe(this); } _receivers.Clear(); } } }