diff --git a/Content.Server/DeviceNetwork/Systems/DeviceNetworkJammerSystem.cs b/Content.Server/DeviceNetwork/Systems/DeviceNetworkJammerSystem.cs index 1905b752b8..860ff886d4 100644 --- a/Content.Server/DeviceNetwork/Systems/DeviceNetworkJammerSystem.cs +++ b/Content.Server/DeviceNetwork/Systems/DeviceNetworkJammerSystem.cs @@ -30,6 +30,10 @@ public sealed class DeviceNetworkJammerSystem : SharedDeviceNetworkJammerSystem if (!_jammer.GetJammableNetworks((uid, jammerComp)).Contains(ev.NetworkId)) continue; + if (jammerComp.FrequenciesExcluded != null && + jammerComp.FrequenciesExcluded.Contains(ev.Frequency)) + continue; + if (_transform.InRange(jammerXform.Coordinates, ev.SenderTransform.Coordinates, jammerComp.Range) || _transform.InRange(jammerXform.Coordinates, xform.Comp.Coordinates, jammerComp.Range)) { diff --git a/Content.Server/DeviceNetwork/Systems/DeviceNetworkSystem.cs b/Content.Server/DeviceNetwork/Systems/DeviceNetworkSystem.cs index 4b28fd9bf9..b2a648fc63 100644 --- a/Content.Server/DeviceNetwork/Systems/DeviceNetworkSystem.cs +++ b/Content.Server/DeviceNetwork/Systems/DeviceNetworkSystem.cs @@ -349,7 +349,7 @@ namespace Content.Server.DeviceNetwork.Systems if (connection.Owner == packet.Sender) continue; - BeforePacketSentEvent beforeEv = new(packet.Sender, xform, senderPos, connection.NetIdEnum.ToString()); + BeforePacketSentEvent beforeEv = new(packet.Sender, xform, senderPos, connection.NetIdEnum.ToString(), packet.Frequency); RaiseLocalEvent(connection.Owner, beforeEv, false); if (!beforeEv.Cancelled) diff --git a/Content.Server/Radio/EntitySystems/JammerSystem.cs b/Content.Server/Radio/EntitySystems/JammerSystem.cs index 1cea981d3c..02c9c64c6e 100644 --- a/Content.Server/Radio/EntitySystems/JammerSystem.cs +++ b/Content.Server/Radio/EntitySystems/JammerSystem.cs @@ -72,6 +72,15 @@ public sealed class JammerSystem : SharedJammerSystem EnsureComp(ent, out var jammingComp); _jammer.SetRange((ent, jammingComp), GetCurrentRange(ent)); _jammer.AddJammableNetwork((ent, jammingComp), DeviceNetworkComponent.DeviceNetIdDefaults.Wireless.ToString()); + + // Add excluded frequencies using the system method + if (ent.Comp.FrequenciesExcluded != null) + { + foreach (var freq in ent.Comp.FrequenciesExcluded) + { + _jammer.AddExcludedFrequency((ent, jammingComp), (uint)freq); + } + } } else { @@ -96,19 +105,23 @@ public sealed class JammerSystem : SharedJammerSystem private void OnRadioSendAttempt(ref RadioSendAttemptEvent args) { - if (ShouldCancelSend(args.RadioSource)) + if (ShouldCancelSend(args.RadioSource, args.Channel.Frequency)) { args.Cancelled = true; } } - private bool ShouldCancelSend(EntityUid sourceUid) + private bool ShouldCancelSend(EntityUid sourceUid, int frequency) { var source = Transform(sourceUid).Coordinates; var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out _, out var jam, out var transform)) { + // Check if this jammer excludes the frequency + if (jam.FrequenciesExcluded != null && jam.FrequenciesExcluded.Contains(frequency)) + continue; + if (_transform.InRange(source, transform.Coordinates, GetCurrentRange((uid, jam)))) { return true; diff --git a/Content.Shared/DeviceNetwork/Components/DeviceNetworkJammerComponent.cs b/Content.Shared/DeviceNetwork/Components/DeviceNetworkJammerComponent.cs index ab320d6d3e..5ee04de0d1 100644 --- a/Content.Shared/DeviceNetwork/Components/DeviceNetworkJammerComponent.cs +++ b/Content.Shared/DeviceNetwork/Components/DeviceNetworkJammerComponent.cs @@ -23,4 +23,10 @@ public sealed partial class DeviceNetworkJammerComponent : Component [DataField, AutoNetworkedField] public HashSet JammableNetworks = []; + /// + /// Device networks frequencies that wont be jammed. + /// + [DataField] + public HashSet FrequenciesExcluded = []; + } diff --git a/Content.Shared/DeviceNetwork/Events/BeforePacketSentEvent.cs b/Content.Shared/DeviceNetwork/Events/BeforePacketSentEvent.cs index 5d5c038dbf..b34995a285 100644 --- a/Content.Shared/DeviceNetwork/Events/BeforePacketSentEvent.cs +++ b/Content.Shared/DeviceNetwork/Events/BeforePacketSentEvent.cs @@ -25,11 +25,17 @@ public sealed class BeforePacketSentEvent : CancellableEntityEventArgs /// public readonly string NetworkId; - public BeforePacketSentEvent(EntityUid sender, TransformComponent xform, Vector2 senderPosition, string networkId) + /// + /// The frequency the packet is sent on. + /// + public readonly uint Frequency; + + public BeforePacketSentEvent(EntityUid sender, TransformComponent xform, Vector2 senderPosition, string networkId, uint frequency) { Sender = sender; SenderTransform = xform; SenderPosition = senderPosition; NetworkId = networkId; + Frequency = frequency; } -} \ No newline at end of file +} diff --git a/Content.Shared/DeviceNetwork/Systems/SharedDeviceNetworkJammerSystem.cs b/Content.Shared/DeviceNetwork/Systems/SharedDeviceNetworkJammerSystem.cs index fc714ea34f..6ed770ffbc 100644 --- a/Content.Shared/DeviceNetwork/Systems/SharedDeviceNetworkJammerSystem.cs +++ b/Content.Shared/DeviceNetwork/Systems/SharedDeviceNetworkJammerSystem.cs @@ -60,4 +60,34 @@ public abstract class SharedDeviceNetworkJammerSystem : EntitySystem ent.Comp.JammableNetworks.Clear(); Dirty(ent); } + + /// + /// Enables this entity to stop packets with the specified frequency from being jammmed. + /// + public void AddExcludedFrequency(Entity ent, uint frequency) + { + if (ent.Comp.FrequenciesExcluded.Add(frequency)) + Dirty(ent); + } + + /// + /// Stops this entity to stop packets with the specified frequency from being jammmed. + /// + public void RemoveExcludedFrequency(Entity ent, uint frequency) + { + if (ent.Comp.FrequenciesExcluded.Remove(frequency)) + Dirty(ent); + } + + /// + /// Stops this entity to stop packets with any frequency from being jammmed. + /// + public void ClearExcludedFrequency(Entity ent) + { + if (ent.Comp.FrequenciesExcluded.Count == 0) + return; + + ent.Comp.FrequenciesExcluded.Clear(); + Dirty(ent); + } } diff --git a/Content.Shared/Radio/Components/ActiveRadioJammerComponent.cs b/Content.Shared/Radio/Components/ActiveRadioJammerComponent.cs index d5679f1189..87e4e0b3b3 100644 --- a/Content.Shared/Radio/Components/ActiveRadioJammerComponent.cs +++ b/Content.Shared/Radio/Components/ActiveRadioJammerComponent.cs @@ -4,7 +4,7 @@ using Robust.Shared.GameStates; namespace Content.Shared.Radio.Components; /// -/// Prevents all radio in range from sending messages +/// Prevents all non whitelisted radios from sending messages /// [RegisterComponent, NetworkedComponent] [Access(typeof(SharedJammerSystem))] diff --git a/Content.Shared/Radio/Components/RadioJammerComponent.cs b/Content.Shared/Radio/Components/RadioJammerComponent.cs index 8f3519cf7d..af4f9e45c8 100644 --- a/Content.Shared/Radio/Components/RadioJammerComponent.cs +++ b/Content.Shared/Radio/Components/RadioJammerComponent.cs @@ -46,6 +46,12 @@ public sealed partial class RadioJammerComponent : Component [DataField(required: true), ViewVariables(VVAccess.ReadOnly)] public RadioJamSetting[] Settings; + /// + /// Frequencies that are NOT jammed by this jammer. + /// + [DataField] + public HashSet FrequenciesExcluded = []; + /// /// Index of the currently selected setting. /// diff --git a/Resources/Prototypes/Entities/Objects/Tools/jammer.yml b/Resources/Prototypes/Entities/Objects/Tools/jammer.yml index 1fc42ad41f..2922a3d53e 100644 --- a/Resources/Prototypes/Entities/Objects/Tools/jammer.yml +++ b/Resources/Prototypes/Entities/Objects/Tools/jammer.yml @@ -56,6 +56,12 @@ id: XenoborgRadioJammer name: xenoborg radio jammer components: + - type: RadioJammer + frequenciesExcluded: + - 2002 # xenoborg radio + - 2003 # mothership radio + - 2004 # xenoborg network + - 2005 # mothership network - type: ItemSlots slots: cell_slot: