]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Syndicate and CentComm Radio Implanters (#33533)
authorPreston Smith <92108534+thetolbean@users.noreply.github.com>
Thu, 30 Jan 2025 00:14:00 +0000 (18:14 -0600)
committerGitHub <noreply@github.com>
Thu, 30 Jan 2025 00:14:00 +0000 (01:14 +0100)
* Add Syndicate Radio Implant

* Fix description grammar

* remove unused var

* Update - Small fixes

* Un mess with imports

* Remove unused tag

* Correction

* Clear lists instead of remove

* Update 0 check

* Add Centcomm implant

* Correct centcom channel

* Correct params

* No more crying

* Update Content.Shared/Implants/Components/RadioImplantComponent.cs

* Update Content.Server/Implants/RadioImplantSystem.cs

* Update Content.Server/Implants/RadioImplantSystem.cs

---------

Co-authored-by: slarticodefast <161409025+slarticodefast@users.noreply.github.com>
Content.Server/Implants/RadioImplantSystem.cs [new file with mode: 0644]
Content.Shared/Implants/Components/RadioImplantComponent.cs [new file with mode: 0644]
Resources/Locale/en-US/store/uplink-catalog.ftl
Resources/Prototypes/Catalog/uplink_catalog.yml
Resources/Prototypes/Entities/Objects/Misc/implanters.yml
Resources/Prototypes/Entities/Objects/Misc/subdermal_implants.yml

diff --git a/Content.Server/Implants/RadioImplantSystem.cs b/Content.Server/Implants/RadioImplantSystem.cs
new file mode 100644 (file)
index 0000000..d9ba229
--- /dev/null
@@ -0,0 +1,76 @@
+using Content.Server.Radio.Components;
+using Content.Shared.Implants;
+using Content.Shared.Implants.Components;
+using Robust.Shared.Containers;
+
+namespace Content.Server.Implants;
+
+public sealed class RadioImplantSystem : EntitySystem
+{
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<RadioImplantComponent, ImplantImplantedEvent>(OnImplantImplanted);
+        SubscribeLocalEvent<RadioImplantComponent, EntGotRemovedFromContainerMessage>(OnRemove);
+    }
+
+    /// <summary>
+    /// If implanted with a radio implant, installs the necessary intrinsic radio components
+    /// </summary>
+    private void OnImplantImplanted(Entity<RadioImplantComponent> ent, ref ImplantImplantedEvent args)
+    {
+        if (args.Implanted == null)
+            return;
+
+        var activeRadio = EnsureComp<ActiveRadioComponent>(args.Implanted.Value);
+        foreach (var channel in ent.Comp.RadioChannels)
+        {
+            if (activeRadio.Channels.Add(channel))
+                ent.Comp.ActiveAddedChannels.Add(channel);
+        }
+
+        EnsureComp<IntrinsicRadioReceiverComponent>(args.Implanted.Value);
+
+        var intrinsicRadioTransmitter = EnsureComp<IntrinsicRadioTransmitterComponent>(args.Implanted.Value);
+        foreach (var channel in ent.Comp.RadioChannels)
+        {
+            if (intrinsicRadioTransmitter.Channels.Add(channel))
+                ent.Comp.TransmitterAddedChannels.Add(channel);
+        }
+    }
+
+    /// <summary>
+    /// Removes intrinsic radio components once the Radio Implant is removed
+    /// </summary>
+    private void OnRemove(Entity<RadioImplantComponent> ent, ref EntGotRemovedFromContainerMessage args)
+    {
+        if (TryComp<ActiveRadioComponent>(args.Container.Owner, out var activeRadioComponent))
+        {
+            foreach (var channel in ent.Comp.ActiveAddedChannels)
+            {
+                activeRadioComponent.Channels.Remove(channel);
+            }
+            ent.Comp.ActiveAddedChannels.Clear();
+
+            if (activeRadioComponent.Channels.Count == 0)
+            {
+                RemCompDeferred<ActiveRadioComponent>(args.Container.Owner);
+            }
+        }
+
+        if (!TryComp<IntrinsicRadioTransmitterComponent>(args.Container.Owner, out var radioTransmitterComponent))
+            return;
+
+        foreach (var channel in ent.Comp.TransmitterAddedChannels)
+        {
+            radioTransmitterComponent.Channels.Remove(channel);
+        }
+        ent.Comp.TransmitterAddedChannels.Clear();
+
+        if (radioTransmitterComponent.Channels.Count == 0 || activeRadioComponent?.Channels.Count == 0)
+        {
+            RemCompDeferred<IntrinsicRadioTransmitterComponent>(args.Container.Owner);
+        }
+    }
+}
diff --git a/Content.Shared/Implants/Components/RadioImplantComponent.cs b/Content.Shared/Implants/Components/RadioImplantComponent.cs
new file mode 100644 (file)
index 0000000..e0e7f55
--- /dev/null
@@ -0,0 +1,37 @@
+using Content.Shared.Radio;
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.Implants.Components;
+
+/// <summary>
+/// Gives the user access to a given channel without the need for a headset.
+/// </summary>
+[RegisterComponent]
+public sealed partial class RadioImplantComponent : Component
+{
+    /// <summary>
+    /// The radio channel(s) to grant access to.
+    /// </summary>
+    [DataField(required: true)]
+    public HashSet<ProtoId<RadioChannelPrototype>> RadioChannels = new();
+
+    /// <summary>
+    /// The radio channels that have been added by the implant to a user's ActiveRadioComponent.
+    /// Used to track which channels were successfully added (not already in user)
+    /// </summary>
+    /// <remarks>
+    /// Should not be modified outside RadioImplantSystem.cs
+    /// </remarks>
+    [DataField]
+    public HashSet<ProtoId<RadioChannelPrototype>> ActiveAddedChannels = new();
+
+    /// <summary>
+    /// The radio channels that have been added by the implant to a user's IntrinsicRadioTransmitterComponent.
+    /// Used to track which channels were successfully added (not already in user)
+    /// </summary>
+    /// <remarks>
+    /// Should not be modified outside RadioImplantSystem.cs
+    /// </remarks>
+    [DataField]
+    public HashSet<ProtoId<RadioChannelPrototype>> TransmitterAddedChannels = new();
+}
index 655c620e3073df08dc35a11b67a977c5a41cc3e7..29b778b9e924210cbbf59b99802e9a6b7f108f6d 100644 (file)
@@ -200,6 +200,9 @@ uplink-death-acidifier-implant-desc = Completely melts the user and their equipm
 uplink-micro-bomb-implanter-name = Micro Bomb Implanter
 uplink-micro-bomb-implanter-desc = Explode on death or manual activation with this implant. Destroys the body with all equipment.
 
+uplink-radio-implanter-name = Radio Implanter
+uplink-radio-implanter-desc = Implants a Syndicate radio, allowing covert communication without a headset.
+
 # Bundles
 uplink-observation-kit-name = Observation Kit
 uplink-observation-kit-desc = Includes surveillance camera monitor board and security hud disguised as sunglasses.
index f3ace5b0bb2bf7891cae73d7758817d73452dccc..6eafed2bc8942f8c8fc6738767ddd1c9ce14397f 100644 (file)
   categories:
     - UplinkImplants
 
+- type: listing
+  id: UplinkRadioImplanter
+  name: uplink-radio-implanter-name
+  description: uplink-radio-implanter-desc
+  icon: { sprite: /Textures/Objects/Devices/encryption_keys.rsi, state: synd_label }
+  productEntity: RadioImplanter
+  discountCategory: usualDiscounts
+  discountDownTo:
+    Telecrystal: 1
+  cost:
+    Telecrystal: 2
+  categories:
+  - UplinkImplants
+
 - type: listing
   id: UplinkMicroBombImplanter
   name: uplink-micro-bomb-implanter-name
index b8ab92e5e9981ebeb18ff13c5dcf325d8f25a976..d40f48dc7d906101b10362d0b31dc19a1ed553ee 100644 (file)
     - type: Implanter
       implant: FreedomImplant
 
+- type: entity
+  id: RadioImplanter
+  suffix: radio Syndicate
+  parent: BaseImplantOnlyImplanterSyndi
+  components:
+  - type: Implanter
+    implant: RadioImplant
+
 - type: entity
   id: UplinkImplanter
   suffix: uplink
   components:
     - type: Implanter
       implant: MindShieldImplant
+
+# Centcomm implanters
+
+- type: entity
+  id: RadioImplanterCentcomm
+  suffix: radio Centcomm
+  parent: BaseImplantOnlyImplanter
+  components:
+  - type: Implanter
+    implant: RadioImplantCentcomm
index 5d93cefd5dd7124758125e1da5d6e242636bee1a..c4e270176927aa90f04bc494d507879a29f6b59f 100644 (file)
         components:
         - Cuffable # useless if you cant be cuffed
 
+- type: entity
+  parent: BaseSubdermalImplant
+  id: RadioImplant
+  name: radio implant
+  description: This implant grants access to the Syndicate channel without a headset.
+  categories: [ HideSpawnMenu ]
+  components:
+  - type: SubdermalImplant
+  - type: RadioImplant
+    radioChannels:
+    - Syndicate
+
 - type: entity
   parent: [ BaseSubdermalImplant, StorePresetUplink ]
   id: UplinkImplant
    - type: Tag
      tags:
        - MindShield
+
+# Centcomm implants
+
+- type: entity
+  parent: BaseSubdermalImplant
+  id: RadioImplantCentcomm
+  name: radio implant
+  description: This implant grants access to the Centcomm channel without a headset. Only authorized for Centcomm employees.
+  categories: [ HideSpawnMenu ]
+  components:
+  - type: SubdermalImplant
+  - type: RadioImplant
+    radioChannels:
+    - CentCom