Repository: Goob-Station/Goob-Station
Pull request #2651: BSO command monitor with implanter + Small Bug fix
Author: login: Baptr0b0t
Labels: name: size/M
description: Denotes a PR that changes 100-999 lines.
name: S: Untriaged
description: A professional will be with you shortly.
name: S: Needs Review
Created: 2025-05-05T22:45:51Z | Merged: 2025-05-25T02:02:52Z

<!--
SPDX-FileCopyrightText: 2021 Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
SPDX-FileCopyrightText: 2021 Swept <sweptwastaken@protonmail.com>
SPDX-FileCopyrightText: 2021 mirrorcult <lunarautomaton6@gmail.com>
SPDX-FileCopyrightText: 2022 AJCM-git <60196617+AJCM-git@users.noreply.github.com>
SPDX-FileCopyrightText: 2022 Kara <lunarautomaton6@gmail.com>
SPDX-FileCopyrightText: 2023 DrSmugleaf <DrSmugleaf@users.noreply.github.com>
SPDX-FileCopyrightText: 2023 Kevin Zheng <kevinz5000@gmail.com>
SPDX-FileCopyrightText: 2024 Vasilis <vasilis@pikachu.systems>
SPDX-FileCopyrightText: 2024 lzk <124214523+lzk228@users.noreply.github.com>
SPDX-FileCopyrightText: 2025 Aiden <28298836+Aidenkrz@users.noreply.github.com>

SPDX-License-Identifier: AGPL-3.0-or-later
-->

<!-- Guidelines: https://docs.spacestation14.io/en/getting-started/pr-guideline -->
<!-- NOTE: All code submitted to this repository is ALWAYS licensed under the AGPL-3.0-or-later license. 
The REUSE Specification headers or separate .license files indicate a secondary license (e.g., MPL or MIT) solely to facilitate 
integration for projects that do not use the AGPL license. This secondary license does not replace the fact that AGPL-3.0-or-later remains the primary and binding license. 
Uncomment and modify the following line if you wish to change the license from the default of AGPL.-->
<!--- LICENSE: AGPL -->
## About the PR
<!-- What did you change? -->
The BSO tracker no longer relies on filtering the scanned person, which made it weaker than the Paramed's tracker. Instead, it now implants the target with a Tracking Implant that only the Command Monitor can see. 
Reduce the 15s doAfter.
Bug fix with crew monitoring server offline keeping the BSO monitor in a dead state.
Add popup for scan/implanting.

## Why / Balance
<!-- Discuss how this would affect game balance or explain why it was changed. Link any relevant discussions or issues. -->
Rebalance and fix PR: #2624
- Makes more sense for NT to inject a device that transmits the position privately than to use public tracking but with a filter.
- The relayed deathrattle already used the implant system, so it can be considered the same implant IC.
- Allows for an equivalent to the tracking implant previously offered in the BSO locker.
- Keeps the original spirit of the old PR, which requires BSO to ignore antag and do everything to simply protect commands.

## Technical details
<!-- Summary of code changes for easier review. -->
Tracking implant sending SuitStatut with IsCommand value. Normal monitor will ignore, bso monitor see.
## Media
<!-- Attach media if the PR makes ingame changes (clothing, items, features, etc).
Small fixes/refactors are exempt. Media may be used in SS14 progress reports with credit. -->
![image](https://github.com/user-attachments/assets/fcba7063-7bd7-4aa0-beb1-e40249cac955)
(Left) Paramedic Crew monitor: Sec Tracker implant + suit coords
(Right) BSO Crew monitor: Command Tracker implant


## Requirements
<!-- Confirm the following by placing an X in the brackets [X]: -->
- [X] I have read and am following the [Pull Request and Changelog Guidelines](https://docs.spacestation14.com/en/general-development/codebase-info/pull-request-guidelines.html). 
- I hope
- [X] I have added media to this PR or it does not require an ingame showcase.
<!-- You should understand that not following the above may get your PR closed at maintainer’s discretion -->

## Breaking changes
<!-- List any breaking changes, including namespaces, public class/method/field changes, prototype renames; and provide instructions for fixing them.
This will be posted in #codebase-changes. -->

**Changelog**
<!-- Add a Changelog entry to make players aware of new features or changes that could affect gameplay.
Make sure to read the guidelines and take this Changelog template out of the comment block in order for it to show up.
Changelog must have a :cl: symbol, so the bot recognizes the changes and adds them to the game's changelog. -->

:cl:
- tweak: Command monitor now uses a private tracker implant.
- fix: Command monitor no longer stays idle when the crew monitoring server is offline.




Diff:
diff --git a/Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs b/Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs
index f4d5d713af23..cf70299537d9 100644
--- a/Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs
+++ b/Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs
@@ -1,4 +1,6 @@
+// SPDX-FileCopyrightText: 2025 Baptr0b0t <152836416+Baptr0b0t@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2025 GoobBot <uristmchands@proton.me>
+// SPDX-FileCopyrightText: 2025 Ted Lukin <66275205+pheenty@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2025 pheenty <fedorlukin2006@gmail.com>
 //
 // SPDX-License-Identifier: AGPL-3.0-or-later
@@ -9,6 +11,10 @@
 using Content.Shared.Humanoid;
 using Content.Shared.Interaction;
 using Content.Shared.Whitelist;
+using Content.Shared.Implants;
+using Content.Shared.IdentityManagement;
+using Content.Server.Popups;
+using Content.Shared.Popups;
 
 namespace Content.Goobstation.Server.CrewMonitoring;
 
@@ -16,6 +22,13 @@ public sealed class CrewMonitorScanningSystem : EntitySystem
 {
     [Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
     [Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
+
+    [Dependency] private readonly SharedSubdermalImplantSystem _implantSystem = default!;
+    [Dependency] private readonly PopupSystem _popup = default!;
+
+    private const string CommandTrackerImplant = "CommandTrackingImplant";
+    private const string CommandTrackerImplantName = "command tracking implant";
+
     public override void Initialize()
     {
         base.Initialize();
@@ -28,22 +41,41 @@ private void OnScanAttempt(EntityUid uid, CrewMonitorScanningComponent comp, Aft
         if (args.Target == null || !args.CanReach || !HasComp<HumanoidAppearanceComponent>(args.Target))
             return;
 
+        var userName = Identity.Entity(args.User, EntityManager);
+        _popup.PopupEntity(Loc.GetString("injector-component-injecting-user"), args.Target.Value, args.User);
+        if (args.User != args.Target.Value)
+            _popup.PopupEntity(Loc.GetString("implanter-component-implanting-target", ("user", userName)), args.User, args.Target.Value, PopupType.LargeCaution);
+
         _doAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, comp.DoAfterTime, new CrewMonitorScanningDoAfterEvent(), uid, args.Target, uid) { NeedHand = true, BreakOnMove = true });
     }
 
     private void OnScanComplete(EntityUid uid, CrewMonitorScanningComponent comp, CrewMonitorScanningDoAfterEvent args)
     {
-        if (args.Cancelled || args.Handled || args.Target == null || comp.ScannedEntities.Contains(args.Target.Value))
+        if (args.Cancelled || args.Handled || args.Target == null)
             return;
+        var name = Identity.Name(args.Target.Value, EntityManager, args.User);
 
-        if (_whitelist.IsWhitelistFail(comp.Whitelist, args.Target.Value))
+        if (comp.ScannedEntities.Contains(args.Target.Value))
+        {
+            var msg = Loc.GetString("implanter-component-implant-already", ("implant", CommandTrackerImplantName), ("target", name));
+            _popup.PopupEntity(msg, args.Target.Value, args.User);
             return;
+        }
 
-        comp.ScannedEntities.Add(args.Target.Value);
-        if (!comp.ApplyDeathrattle)
+        if (_whitelist.IsWhitelistFail(comp.Whitelist, args.Target.Value))
+        {
+
+            var msg = Loc.GetString("implanter-component-implant-failed", ("implant", CommandTrackerImplantName), ("target", name));
+            _popup.PopupEntity(msg, args.Target.Value, args.User);
             return;
+        }
+
+        comp.ScannedEntities.Add(args.Target.Value); //Keep for don't double implant
+        _implantSystem.AddImplant(args.Target.Value, CommandTrackerImplant);
+
+        if (comp.ApplyDeathrattle)
+            EnsureComp<RelayedDeathrattleComponent>(args.Target.Value).Target = uid;
 
-        EnsureComp<RelayedDeathrattleComponent>(args.Target.Value).Target = uid;
         args.Handled = true;
     }
 }
diff --git a/Content.Goobstation.Server/RelayedDeathrattle/RelayedDeathrattleComponent.cs b/Content.Goobstation.Server/RelayedDeathrattle/RelayedDeathrattleComponent.cs
index 03e23989cc6f..98303c685819 100644
--- a/Content.Goobstation.Server/RelayedDeathrattle/RelayedDeathrattleComponent.cs
+++ b/Content.Goobstation.Server/RelayedDeathrattle/RelayedDeathrattleComponent.cs
@@ -1,4 +1,6 @@
+// SPDX-FileCopyrightText: 2025 Baptr0b0t <152836416+Baptr0b0t@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2025 GoobBot <uristmchands@proton.me>
+// SPDX-FileCopyrightText: 2025 Ted Lukin <66275205+pheenty@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2025 pheenty <fedorlukin2006@gmail.com>
 //
 // SPDX-License-Identifier: AGPL-3.0-or-later
@@ -17,6 +19,4 @@ public sealed partial class RelayedDeathrattleComponent : Component
     [DataField]
     public LocId DeathMessage = "deathrattle-implant-dead-message";
 
-    [DataField]
-    public bool RequireCrewMonitor = true;
 }
diff --git a/Content.Goobstation.Server/RelayedDeathrattle/RelayedDeathrattleSystem.cs b/Content.Goobstation.Server/RelayedDeathrattle/RelayedDeathrattleSystem.cs
index ba795c9a3b30..303f201775ae 100644
--- a/Content.Goobstation.Server/RelayedDeathrattle/RelayedDeathrattleSystem.cs
+++ b/Content.Goobstation.Server/RelayedDeathrattle/RelayedDeathrattleSystem.cs
@@ -1,4 +1,6 @@
+// SPDX-FileCopyrightText: 2025 Baptr0b0t <152836416+Baptr0b0t@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2025 GoobBot <uristmchands@proton.me>
+// SPDX-FileCopyrightText: 2025 Ted Lukin <66275205+pheenty@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2025 pheenty <fedorlukin2006@gmail.com>
 //
 // SPDX-License-Identifier: AGPL-3.0-or-later
@@ -26,24 +28,6 @@ private void OnMobStateChanged(EntityUid uid, RelayedDeathrattleComponent comp,
         if (comp.Target == null)
             return;
 
-        if (comp.RequireCrewMonitor && TryComp<CrewMonitoringConsoleComponent>(comp.Target, out var monitor))
-        {
-            var found = false;
-            foreach (var pair in monitor.ConnectedSensors)
-            {
-                if (found)
-                    continue;
-
-                var sensorUid = GetEntity(pair.Value.SuitSensorUid);
-                if (!HasComp<TransformComponent>(sensorUid))
-                    continue;
-
-                if (uid == Transform(sensorUid).ParentUid)
-                    found = true;
-            }
-            if (!found)
-                return;
-        }
 
         bool dead;
         var posText = FormattedMessage.RemoveMarkupOrThrow(_navMap.GetNearestBeaconString(uid));
diff --git a/Content.Goobstation.Shared/CrewMonitoring/CrewMonitorScanningComponent.cs b/Content.Goobstation.Shared/CrewMonitoring/CrewMonitorScanningComponent.cs
index 4504faf0e5a8..1484855c9c23 100644
--- a/Content.Goobstation.Shared/CrewMonitoring/CrewMonitorScanningComponent.cs
+++ b/Content.Goobstation.Shared/CrewMonitoring/CrewMonitorScanningComponent.cs
@@ -1,4 +1,6 @@
+// SPDX-FileCopyrightText: 2025 Baptr0b0t <152836416+Baptr0b0t@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2025 GoobBot <uristmchands@proton.me>
+// SPDX-FileCopyrightText: 2025 Ted Lukin <66275205+pheenty@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2025 pheenty <fedorlukin2006@gmail.com>
 //
 // SPDX-License-Identifier: AGPL-3.0-or-later
@@ -14,7 +16,7 @@ public sealed partial class CrewMonitorScanningComponent : Component
     public List<EntityUid> ScannedEntities = [];
 
     [DataField]
-    public TimeSpan DoAfterTime = TimeSpan.FromSeconds(15);
+    public TimeSpan DoAfterTime = TimeSpan.FromSeconds(8);
 
     [DataField]
     public bool ApplyDeathrattle = true;
diff --git a/Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs b/Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs
index fed3e6e20072..abbe821bd6b6 100644
--- a/Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs
+++ b/Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs
@@ -11,7 +11,9 @@
 // SPDX-FileCopyrightText: 2023 themias <89101928+themias@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2024 metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2025 Aiden <28298836+Aidenkrz@users.noreply.github.com>
+// SPDX-FileCopyrightText: 2025 Baptr0b0t <152836416+Baptr0b0t@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2025 GoobBot <uristmchands@proton.me>
+// SPDX-FileCopyrightText: 2025 Ted Lukin <66275205+pheenty@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2025 pheenty <fedorlukin2006@gmail.com>
 //
 // SPDX-License-Identifier: AGPL-3.0-or-later
@@ -59,24 +61,6 @@ private void OnPacketReceived(EntityUid uid, CrewMonitoringConsoleComponent comp
 
         if (!payload.TryGetValue(SuitSensorConstants.NET_STATUS_COLLECTION, out Dictionary<string, SuitSensorStatus>? sensorStatus))
             return;
-
-        // Goobstation - start
-        if (TryComp<CrewMonitorScanningComponent>(uid, out var scanned))
-        {
-            var newSensorStatus = new Dictionary<string, SuitSensorStatus>();
-            foreach (var pair in sensorStatus)
-            {
-                var sensorUid = GetEntity(pair.Value.SuitSensorUid);
-                if (!HasComp<TransformComponent>(sensorUid))
-                    continue;
-
-                if (scanned.ScannedEntities.Contains(Transform(sensorUid).ParentUid))
-                    newSensorStatus[pair.Key] = pair.Value;
-            }
-            sensorStatus = newSensorStatus;
-        }
-        // Goobstation - end
-
         component.ConnectedSensors = sensorStatus;
 
         UpdateUserInterface(uid, component);
@@ -105,7 +89,18 @@ private void UpdateUserInterface(EntityUid uid, CrewMonitoringConsoleComponent?
             EnsureComp<NavMapComponent>(xform.GridUid.Value);
 
         // Update all sensors info
-        var allSensors = component.ConnectedSensors.Values.ToList();
-        _uiSystem.SetUiState(uid, CrewMonitoringUIKey.Key, new CrewMonitoringState(allSensors));
+        // GoobStation - Start
+        var isCommandOnly = HasComp<CrewMonitorScanningComponent>(uid);
+
+        var filteredSensors = component.ConnectedSensors
+            .Where(pair => isCommandOnly
+                ? pair.Value.IsCommandTracker
+                : !pair.Value.IsCommandTracker)
+            .Select(pair => pair.Value)
+            .ToList();
+        _uiSystem.SetUiState(uid, CrewMonitoringUIKey.Key, new CrewMonitoringState(filteredSensors));
+        // GoobStation - End
+        //var allSensors = component.ConnectedSensors.Values.ToList();
+        //_uiSystem.SetUiState(uid, CrewMonitoringUIKey.Key, new CrewMonitoringState(allSensors));
     }
 }
diff --git a/Content.Server/Medical/SuitSensors/SuitSensorComponent.cs b/Content.Server/Medical/SuitSensors/SuitSensorComponent.cs
index 760777527dbd..1a2338660b11 100644
--- a/Content.Server/Medical/SuitSensors/SuitSensorComponent.cs
+++ b/Content.Server/Medical/SuitSensors/SuitSensorComponent.cs
@@ -15,6 +15,8 @@
 // SPDX-FileCopyrightText: 2024 nikthechampiongr <32041239+nikthechampiongr@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2024 themias <89101928+themias@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2025 Aiden <28298836+Aidenkrz@users.noreply.github.com>
+// SPDX-FileCopyrightText: 2025 Baptr0b0t <152836416+Baptr0b0t@users.noreply.github.com>
+// SPDX-FileCopyrightText: 2025 GoobBot <uristmchands@proton.me>
 //
 // SPDX-License-Identifier: AGPL-3.0-or-later
 
@@ -31,6 +33,13 @@ namespace Content.Server.Medical.SuitSensors;
 [Access(typeof(SuitSensorSystem))]
 public sealed partial class SuitSensorComponent : Component
 {
+    // GoobStation - Start
+    /// <summary>
+    ///     Is this suit sensor for commands, BSO use only
+    /// </summary>
+    [DataField]
+    public bool CommandTracker = false;
+    // GoobStation - End
     /// <summary>
     ///     Choose a random sensor mode when item is spawned.
     /// </summary>
@@ -112,4 +121,4 @@ public sealed partial class SuitSensorComponent : Component
     /// </summary>
     [DataField, ViewVariables]
     public bool PreviousControlsLocked = false;
-}
\ No newline at end of file
+}
diff --git a/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs b/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs
index 80561cd12753..a1c8f602aea5 100644
--- a/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs
+++ b/Content.Server/Medical/SuitSensors/SuitSensorSystem.cs
@@ -83,14 +83,16 @@
 // SPDX-FileCopyrightText: 2024 plykiya <plykiya@protonmail.com>
 // SPDX-FileCopyrightText: 2024 saintmuntzer <47153094+saintmuntzer@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2024 shamp <140359015+shampunj@users.noreply.github.com>
-// SPDX-FileCopyrightText: 2024 slarticodefast <161409025+slarticodefast@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2024 strO0pwafel <153459934+strO0pwafel@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2024 stroopwafel <j.o.luijkx@student.tudelft.nl>
 // SPDX-FileCopyrightText: 2024 themias <89101928+themias@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2024 to4no_fix <156101927+chavonadelal@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2024 voidnull000 <18663194+voidnull000@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2025 Aiden <28298836+Aidenkrz@users.noreply.github.com>
+// SPDX-FileCopyrightText: 2025 Baptr0b0t <152836416+Baptr0b0t@users.noreply.github.com>
+// SPDX-FileCopyrightText: 2025 GoobBot <uristmchands@proton.me>
 // SPDX-FileCopyrightText: 2025 Ignaz "Ian" Kraft <ignaz.k@live.de>
+// SPDX-FileCopyrightText: 2025 slarticodefast <161409025+slarticodefast@users.noreply.github.com>
 //
 // SPDX-License-Identifier: AGPL-3.0-or-later
 
@@ -537,6 +539,7 @@ public void SetAllSensors(EntityUid target, SuitSensorMode mode, SlotFlags slots
                 }
 
                 status.Coordinates = GetNetCoordinates(coordinates);
+                status.IsCommandTracker = sensor.CommandTracker; //Goob station
                 break;
         }
 
@@ -556,6 +559,7 @@ public NetworkPayload SuitSensorToPacket(SuitSensorStatus status)
             [SuitSensorConstants.NET_JOB_ICON] = status.JobIcon,
             [SuitSensorConstants.NET_JOB_DEPARTMENTS] = status.JobDepartments,
             [SuitSensorConstants.NET_IS_ALIVE] = status.IsAlive,
+            [SuitSensorConstants.NET_IS_COMMAND] = status.IsCommandTracker, //Goob station
             [SuitSensorConstants.NET_SUIT_SENSOR_UID] = status.SuitSensorUid,
         };
 
@@ -586,6 +590,7 @@ public NetworkPayload SuitSensorToPacket(SuitSensorStatus status)
         if (!payload.TryGetValue(SuitSensorConstants.NET_JOB_ICON, out string? jobIcon)) return null;
         if (!payload.TryGetValue(SuitSensorConstants.NET_JOB_DEPARTMENTS, out List<string>? jobDepartments)) return null;
         if (!payload.TryGetValue(SuitSensorConstants.NET_IS_ALIVE, out bool? isAlive)) return null;
+        if (!payload.TryGetValue(SuitSensorConstants.NET_IS_COMMAND, out bool iscommand)) return null; //Goob station
         if (!payload.TryGetValue(SuitSensorConstants.NET_SUIT_SENSOR_UID, out NetEntity suitSensorUid)) return null;
 
         // try get total damage and cords (optionals)
@@ -599,7 +604,8 @@ public NetworkPayload SuitSensorToPacket(SuitSensorStatus status)
             TotalDamage = totalDamage,
             TotalDamageThreshold = totalDamageThreshold,
             Coordinates = coords,
+            IsCommandTracker = iscommand,//Goob station
         };
         return status;
     }
-}
\ No newline at end of file
+}
diff --git a/Content.Shared/Medical/SuitSensor/SharedSuitSensor.cs b/Content.Shared/Medical/SuitSensor/SharedSuitSensor.cs
index 4da6a21af758..13f8e122c000 100644
--- a/Content.Shared/Medical/SuitSensor/SharedSuitSensor.cs
+++ b/Content.Shared/Medical/SuitSensor/SharedSuitSensor.cs
@@ -12,6 +12,8 @@
 // SPDX-FileCopyrightText: 2024 Pspritechologist <81725545+Pspritechologist@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2024 Skye <57879983+Rainbeon@users.noreply.github.com>
 // SPDX-FileCopyrightText: 2025 Aiden <28298836+Aidenkrz@users.noreply.github.com>
+// SPDX-FileCopyrightText: 2025 Baptr0b0t <152836416+Baptr0b0t@users.noreply.github.com>
+// SPDX-FileCopyrightText: 2025 GoobBot <uristmchands@proton.me>
 //
 // SPDX-License-Identifier: AGPL-3.0-or-later
 
@@ -44,6 +46,7 @@ public SuitSensorStatus(NetEntity suitSensorUid, string name, string job, string
     public int? TotalDamageThreshold;
     public float? DamagePercentage => TotalDamageThreshold == null || TotalDamage == null ? null : TotalDamage / (float) TotalDamageThreshold;
     public NetCoordinates? Coordinates;
+    public bool IsCommandTracker = false; ///Goob station
 }
 
 [Serializable, NetSerializable]
@@ -82,6 +85,8 @@ public static class SuitSensorConstants
     public const string NET_COORDINATES = "coords";
     public const string NET_SUIT_SENSOR_UID = "uid";
 
+    public const string NET_IS_COMMAND = "iscommand"; ///Goob Sation
+
     ///Used by the CrewMonitoringServerSystem to send the status of all connected suit sensors to each crew monitor
     public const string NET_STATUS_COLLECTION = "suit-status-collection";
 }
@@ -97,4 +102,4 @@ public SuitSensorChangeDoAfterEvent(SuitSensorMode mode)
     }
 
     public override DoAfterEvent Clone() => this;
-}
\ No newline at end of file
+}
diff --git a/Resources/Prototypes/_Goobstation/Entities/Clothing/Eyes/glasses.yml b/Resources/Prototypes/_Goobstation/Entities/Clothing/Eyes/glasses.yml
index 60aace3e285e..835377a1c403 100644
--- a/Resources/Prototypes/_Goobstation/Entities/Clothing/Eyes/glasses.yml
+++ b/Resources/Prototypes/_Goobstation/Entities/Clothing/Eyes/glasses.yml
@@ -4,6 +4,7 @@
 # SPDX-FileCopyrightText: 2025 Aiden <28298836+Aidenkrz@users.noreply.github.com>
 # SPDX-FileCopyrightText: 2025 Aiden <aiden@djkraz.com>
 # SPDX-FileCopyrightText: 2025 Aidenkrz <aiden@djkraz.com>
+# SPDX-FileCopyrightText: 2025 Baptr0b0t <152836416+Baptr0b0t@users.noreply.github.com>
 # SPDX-FileCopyrightText: 2025 BombasterDS2 <shvalovdenis.workmail@gmail.com>
 # SPDX-FileCopyrightText: 2025 Creatorbot01 <creatorbot20@gmail.com>
 # SPDX-FileCopyrightText: 2025 GMWQ <garethquaile@gmail.com>
@@ -11,6 +12,7 @@
 # SPDX-FileCopyrightText: 2025 GoobBot <uristmchands@proton.me>
 # SPDX-FileCopyrightText: 2025 SX-7 <92227810+SX-7@users.noreply.github.com>
 # SPDX-FileCopyrightText: 2025 Solstice <solsticeofthewinter@gmail.com>
+# SPDX-FileCopyrightText: 2025 Ted Lukin <66275205+pheenty@users.noreply.github.com>
 # SPDX-FileCopyrightText: 2025 coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
 # SPDX-FileCopyrightText: 2025 gus <august.eymann@gmail.com>
 # SPDX-FileCopyrightText: 2025 pheenty <fedorlukin2006@gmail.com>
@@ -165,7 +167,7 @@
   parent: [ClothingEyesBase, ShowHealthRelatedIcons, BaseCentcommContraband, ClothingEyesGlassesSunglasses]
   id: ClothingEyesGlassesBSO
   name: blueshield officer glasses
-  description: Sunglasses with a medical, security and diagnostic hud.
+  description: Sunglasses with a medical, job and diagnostic hud.
   components:
   - type: Sprite
     sprite: _Goobstation/Clothing/Eyes/Glasses/bsoglasses.rsi
diff --git a/Resources/Prototypes/_Goobstation/Entities/Objects/Misc/implanters.yml b/Resources/Prototypes/_Goobstation/Entities/Objects/Misc/implanters.yml
index ceb2f7426e9d..8734e984bdd0 100644
--- a/Resources/Prototypes/_Goobstation/Entities/Objects/Misc/implanters.yml
+++ b/Resources/Prototypes/_Goobstation/Entities/Objects/Misc/implanters.yml
@@ -5,6 +5,7 @@
 # SPDX-FileCopyrightText: 2024 whateverusername0 <whateveremail>
 # SPDX-FileCopyrightText: 2025 Aiden <28298836+Aidenkrz@users.noreply.github.com>
 # SPDX-FileCopyrightText: 2025 Aiden <aiden@djkraz.com>
+# SPDX-FileCopyrightText: 2025 Baptr0b0t <152836416+Baptr0b0t@users.noreply.github.com>
 # SPDX-FileCopyrightText: 2025 GoobBot <uristmchands@proton.me>
 # SPDX-FileCopyrightText: 2025 Scruq445 <storchdamien@gmail.com>
 # SPDX-FileCopyrightText: 2025 Solstice <solsticeofthewinter@gmail.com>
@@ -102,6 +103,14 @@
   - type: Implanter
     implant: BluespaceLifelineImplant
 
+- type: entity
+  id: CommandTrackingImplanter
+  suffix: command tracker
+  parent: BaseImplantOnlyImplanterCentcomm
+  components:
+  - type: Implanter
+    implant: CommandTrackingImplant
+
 - type: entity
   id: CentcommFreedomImplanter
   suffix: freedom implant
diff --git a/Resources/Prototypes/_Goobstation/Entities/Objects/Misc/subdermal_implants.yml b/Resources/Prototypes/_Goobstation/Entities/Objects/Misc/subdermal_implants.yml
index c3a48d51d8c8..42d99102b4b7 100644
--- a/Resources/Prototypes/_Goobstation/Entities/Objects/Misc/subdermal_implants.yml
+++ b/Resources/Prototypes/_Goobstation/Entities/Objects/Misc/subdermal_implants.yml
@@ -6,6 +6,7 @@
 # SPDX-FileCopyrightText: 2025 Aiden <aiden@djkraz.com>
 # SPDX-FileCopyrightText: 2025 Aidenkrz <aiden@djkraz.com>
 # SPDX-FileCopyrightText: 2025 Aviu00 <93730715+Aviu00@users.noreply.github.com>
+# SPDX-FileCopyrightText: 2025 Baptr0b0t <152836416+Baptr0b0t@users.noreply.github.com>
 # SPDX-FileCopyrightText: 2025 GoobBot <uristmchands@proton.me>
 # SPDX-FileCopyrightText: 2025 Scruq445 <storchdamien@gmail.com>
 # SPDX-FileCopyrightText: 2025 Solstice <solsticeofthewinter@gmail.com>
@@ -39,6 +40,30 @@
     - SubdermalImplant
     - HideContextMenu
 
+- type: entity
+  parent: BaseSubdermalImplant
+  id: CommandTrackingImplant
+  name: Command tracking implant
+  description: This implant reserved for command has a tracking device attached to a private suit sensor network, as well as a condition monitor for the Command radio channel.
+  categories: [ HideSpawnMenu ]
+  components:
+    - type: SubdermalImplant
+      whitelist:
+        components:
+        - MobState # admeme implanting a chair with tracking implant needs to give the chair mobstate so it can die first
+    - type: SuitSensor
+      randomMode: false
+      controlsLocked: true
+      commandTracker: true #for BSO command monitor
+      mode: SensorCords
+      activationContainer: "implant"
+    - type: DeviceNetwork
+      deviceNetId: Wireless
+      transmitFrequencyId: SuitSensor
+    - type: StationLimitedNetwork
+    - type: WirelessNetworkConnection
+      range: 500
+
 - type: entity
   parent: BaseSubdermalImplant
   id: PacifismImplant
diff --git a/Resources/Prototypes/_Goobstation/Entities/Specific/bso.yml b/Resources/Prototypes/_Goobstation/Entities/Specific/bso.yml
index d5bd626b0185..901ef8d58d54 100644
--- a/Resources/Prototypes/_Goobstation/Entities/Specific/bso.yml
+++ b/Resources/Prototypes/_Goobstation/Entities/Specific/bso.yml
@@ -1,7 +1,10 @@
 # SPDX-FileCopyrightText: 2025 Aiden <28298836+Aidenkrz@users.noreply.github.com>
 # SPDX-FileCopyrightText: 2025 Aidenkrz <aiden@djkraz.com>
+# SPDX-FileCopyrightText: 2025 Baptr0b0t <152836416+Baptr0b0t@users.noreply.github.com>
+# SPDX-FileCopyrightText: 2025 GoobBot <uristmchands@proton.me>
 # SPDX-FileCopyrightText: 2025 Lincoln McQueen <lincoln.mcqueen@gmail.com>
 # SPDX-FileCopyrightText: 2025 Solstice <solsticeofthewinter@gmail.com>
+# SPDX-FileCopyrightText: 2025 Ted Lukin <66275205+pheenty@users.noreply.github.com>
 # SPDX-FileCopyrightText: 2025 gus <august.eymann@gmail.com>
 # SPDX-FileCopyrightText: 2025 pheenty <fedorlukin2006@gmail.com>
 #
@@ -27,7 +30,7 @@
   parent: [BaseItem, BaseCentcommContraband]
   id: HandheldCrewMonitorBSO
   name: handheld command monitor
-  description: A handheld crew monitor modified for blueshield officer's needs. Will only track scanned command personnel and alarm you about them being in danger. Works on a built-in microreactor cell.
+  description: A handheld crew monitor modified for blueshield officer's needs. Designed to inject a tracking device into command personnel and alarm you about them being in danger. Works on a built-in microreactor cell.
   components:
   - type: Sprite
     sprite: _Goobstation/Objects/Specific/Security/bso_monitor.rsi


Reviews:
user: login: pheenty
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T03:15:47Z
user: login: Baptr0b0t
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T06:52:33Z
user: login: Baptr0b0t
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T06:52:47Z
user: login: pheenty
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T07:20:39Z
user: login: pheenty
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T07:29:53Z
user: login: Baptr0b0t
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T07:54:41Z
user: login: Baptr0b0t
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T15:08:25Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 1**

<details>
<summary>🧹 Nitpick comments (6)</summary><blockquote>

<details>
<summary>Content.Shared/Medical/SuitSensor/SharedSuitSensor.cs (1)</summary><blockquote>

`88-88`: **BEHOLD! A NEW NETWORK RUNE HAS BEEN INSCRIBED!**

The magical constant NET_IS_COMMAND shall serve as the arcane identifier for command tracking spells in the ethereal networks! 

However, I spy a minor spelling error in thy comment - "Goob Sation" instead of "Goob Station".

```diff
- public const string NET_IS_COMMAND = "iscommand"; ///Goob Sation
+ public const string NET_IS_COMMAND = "iscommand"; ///Goob Station
```

</blockquote></details>
<details>
<summary>Content.Server/Medical/SuitSensors/SuitSensorSystem.cs (2)</summary><blockquote>

`577-577`: **THE COMMAND TRACKING RUNE IS NOW EXTRACTED FROM THE ETHEREAL MESSAGE!**

Thy deserialization incantation now properly extracts the command tracking status from the received payload. However, the code uses `iscommand` as the local variable name, which differs slightly from other variable naming patterns in the method.

```diff
- if (!payload.TryGetValue(SuitSensorConstants.NET_IS_COMMAND, out bool iscommand)) return null; //Goob station
+ if (!payload.TryGetValue(SuitSensorConstants.NET_IS_COMMAND, out bool isCommandTracker)) return null; //Goob station
```

---

`591-591`: **THE COMMAND TRACKING STATUS IS PROPERLY RESTORED IN THE SENSOR STATUS SPELL!**

Thy code now assigns the extracted command tracking status to the IsCommandTracker property of the SuitSensorStatus object. Consider updating this line if you rename the variable in the previous comment.

```diff
- IsCommandTracker = iscommand,//Goob station
+ IsCommandTracker = isCommandTracker,//Goob station
```

</blockquote></details>
<details>
<summary>Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs (1)</summary><blockquote>

`103-103`: **THE ANCIENT CODE REMAINS AS A COMMENT, WHICH SERVES NO PURPOSE IN THE SPELL!**

This commented-out line appears to be leftover from a previous incantation attempt and no longer serves any purpose in the current magical formula.

```diff
- //_uiSystem.SetUiState(uid, CrewMonitoringUIKey.Key, new CrewMonitoringState(filteredSensors));
```

</blockquote></details>
<details>
<summary>Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs (1)</summary><blockquote>

`44-45`: **SIMPLIFY THIS ARCANE INVOCATION, WIZARD!**

The creation of a new string from the constant is an unnecessary ritual that consumes magical energy. The constant can be used directly without creating a new instance.

```diff
-        var implantProto = new string(CommandTrackerImplant);
+        var implantProto = CommandTrackerImplant;
```

Alternatively, you could eliminate the variable entirely:
```diff
-        var implantProto = new string(CommandTrackerImplant);
```
And later use the constant directly:
```diff
-        _implantSystem.AddImplant(args.Target.Value, implantProto);
+        _implantSystem.AddImplant(args.Target.Value, CommandTrackerImplant);
```

</blockquote></details>
<details>
<summary>Resources/Prototypes/_Goobstation/Entities/Objects/Misc/subdermal_implants.yml (1)</summary><blockquote>

`53-53`: **Nitpick: Clarify the MobState whitelist comment and formatting.**

The inline comment is verbose and missing a leading space after the `#`. Consider rewriting for clarity:

```diff
-        - MobState # admeme implanting a chair with tracking implant needs to give the chair mobstate so it can die first
+        - MobState # Only entities with MobState can be implanted for proper lifecycle handling
```

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between dc9a6317564fd75680a66c79a8757d41cfef1147 and 04261a10e3417e76bd2f20fac788b59d81884070.

</details>

<details>
<summary>📒 Files selected for processing (9)</summary>

* `Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs` (3 hunks)
* `Content.Goobstation.Server/RelayedDeathrattle/RelayedDeathrattleComponent.cs` (2 hunks)
* `Content.Goobstation.Shared/CrewMonitoring/CrewMonitorScanningComponent.cs` (2 hunks)
* `Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs` (2 hunks)
* `Content.Server/Medical/SuitSensors/SuitSensorComponent.cs` (3 hunks)
* `Content.Server/Medical/SuitSensors/SuitSensorSystem.cs` (5 hunks)
* `Content.Shared/Medical/SuitSensor/SharedSuitSensor.cs` (4 hunks)
* `Resources/Prototypes/_Goobstation/Entities/Objects/Misc/implanters.yml` (2 hunks)
* `Resources/Prototypes/_Goobstation/Entities/Objects/Misc/subdermal_implants.yml` (2 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🧬 Code Graph Analysis (2)</summary>

<details>
<summary>Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs (1)</summary><blockquote>

<details>
<summary>Content.Shared/DoAfter/SharedDoAfterSystem.cs (1)</summary>

* `SharedDoAfterSystem` (119-523)

</details>

</blockquote></details>
<details>
<summary>Content.Server/Medical/SuitSensors/SuitSensorSystem.cs (1)</summary><blockquote>

<details>
<summary>Content.Shared/Medical/SuitSensor/SharedSuitSensor.cs (1)</summary>

* `SuitSensorConstants` (76-92)

</details>

</blockquote></details>

</details>

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (2)</summary>

* GitHub Check: Test Packaging
* GitHub Check: build (ubuntu-latest)

</details>

<details>
<summary>🔇 Additional comments (21)</summary><blockquote>

<details>
<summary>Content.Server/Medical/SuitSensors/SuitSensorComponent.cs (2)</summary>

`18-19`: **BEHOLD! THY SCROLLS OF COPYRIGHT HAVE BEEN INSCRIBED WITH NEW ARCANE SIGNATURES!**

The magical tomes now bear the marks of the wizards "Baptr0b0t" and "GoobBot", correctly dated for the mystical year of 2025.

---

`37-41`: **THE ARCANE FIELD OF COMMAND TRACKING HATH BEEN CONJURED!**

Thou hast crafted a new boolean field of power! This spell component shall enable the sacred tracking of command entities, accessible only to those versed in the dark arts of the BSO.

```diff
+ /// <summary>
+    ///     BSO only
+ /// </summary>
+ [DataField("commandtracker")]
+ public bool CommandTracker = false;
```

Thy field is properly documented and correctly decorated with the DataField attribute, making it known to the serialization spellcrafters.

</details>
<details>
<summary>Content.Shared/Medical/SuitSensor/SharedSuitSensor.cs (2)</summary>

`15-16`: **THINE COPYRIGHT INCANTATIONS HAVE BEEN PROPERLY INSCRIBED!**

The ancient tomes now bear the mystical signatures of the great wizards "Baptr0b0t" and "GoobBot", ensuring their magical contributions are recognized by the elders of the realm.

---

`49-49`: **HEAR YE! A NEW MAGICAL PROPERTY HATH BEEN BESTOWED UPON THE SENSOR STATUS ENCHANTMENT!**

The IsCommandTracker field has been added to the SuitSensorStatus incantation, enabling the distinction between common tracking spells and the more powerful command tracking divinations!

</details>
<details>
<summary>Content.Server/Medical/SuitSensors/SuitSensorSystem.cs (3)</summary>

`93-94`: **THE SCROLLS OF COPYRIGHT HAVE BEEN IMBUED WITH NEW MAGICAL SIGNATURES!**

The ancient tomes now carry the arcane marks of the wizards "Baptr0b0t" and "GoobBot", properly inscribed with the year 2025.

---

`526-526`: **THE COMMAND TRACKER ENCHANTMENT IS NOW PROPERLY TRANSMITTED!**

Thy code now sets the IsCommandTracker property based on the sensor's CommandTracker field when in SensorCords mode, ensuring the command tracking spell is properly carried through the SuitSensorStatus magical construct!

---

`546-546`: **THE COMMAND TRACKING RUNE IS NOW EMBEDDED IN THE ETHEREAL PAYLOAD!**

Thy network transmission spell now includes the IsCommandTracker property in its magical payload, ensuring the knowledge of command tracking is properly conveyed through the device network's mystical aether!

</details>
<details>
<summary>Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs (2)</summary>

`14-16`: **THE SCROLLS OF COPYRIGHT HAVE BEEN EXPANDED WITH NEW MYSTICAL SIGNATURES!**

The ancient tomes now bear the arcane marks of wizards "Baptr0b0t" and "Ted Lukin", properly inscribed for the year 2025.

---

`92-102`: **A POWERFUL FILTERING ENCHANTMENT HAS BEEN CAST UPON THE SENSOR DATA!**

The magic now distinguishes between command and non-command tracking sensors, ensuring that only the appropriate sensors appear on each monitoring device. Command monitors shall reveal only command trackers, while regular monitors shall show only non-command sensors!

This implementation respects the concerns raised in past discussions, as recorded in the ancient scrolls of review comments. Thy code properly addresses the issue without causing duplicate entries to appear.

</details>
<details>
<summary>Content.Goobstation.Server/RelayedDeathrattle/RelayedDeathrattleComponent.cs (2)</summary>

`1-3`: **BEHOLD! THE ARCANE SIGILS OF OWNERSHIP ARE PROPERLY INSCRIBED!**

The mystical copyright sigils have been properly added to mark the contributions of the wizards "Baptr0b0t" and "Ted Lukin" to this arcane scroll.

---

`23-23`: **THE SPELL HAS BEEN TRANSMUTED FROM REQUIRING CREW MONITOR TO NOT REQUIRING IT!**

The ancient requirement of `RequireCrewMonitor` has been transformed from `true` to `false`, aligning with the mystical implantation of tracking runes directly into the target's flesh rather than relying on the arcane arts of filtering. This change resonates with powerful intent!

</details>
<details>
<summary>Content.Goobstation.Shared/CrewMonitoring/CrewMonitorScanningComponent.cs (2)</summary>

`1-3`: **THE ARCANE COPYRIGHT RUNES HAVE BEEN PROPERLY INSCRIBED!**

The mystical sigils marking the contributions of the wizards "Baptr0b0t" and "Ted Lukin" have been correctly added to this scroll of power.

---

`19-19`: **THE TEMPORAL WARD HAS BEEN STRENGTHENED!**

The magical delay of scanning has been reduced from 15 seconds to a mere 8 seconds! This enchantment shall make the command tracking ritual much swifter, as befits the urgency of the Bureau of Security Operations! The scrolls of prophecy spoke true about reducing the 15-second doAfter delay!

</details>
<details>
<summary>Resources/Prototypes/_Goobstation/Entities/Objects/Misc/implanters.yml (2)</summary>

`8-8`: **A NEW MAGICAL SIGNATURE HAS BEEN ADDED TO THE ARCANE LEDGER!**

The mystical copyright rune for the wizard "Baptr0b0t" has been properly inscribed upon this scroll of entity definitions.

---

`106-113`: **A NEW MAGICAL DEVICE HAS BEEN FORGED IN THE FIRES OF CREATION!**

The arcane prototype for the `CommandTrackingImplanter` has been properly conjured, following the ancient patterns of other implanters before it. This device shall bestow upon its targets the mystical `CommandTrackingImplant`, allowing the Command Monitor to scry upon those implanted without revealing their location to lesser monitors!

</details>
<details>
<summary>Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs (5)</summary>

`1-3`: **THE ARCANE COPYRIGHT SIGILS HAVE BEEN PROPERLY INSCRIBED!**

The mystical marks of the wizards "Baptr0b0t" and "Ted Lukin" have been etched into the header of this scroll, granting them proper recognition for their enchantments.

---

`14-15`: **A NEW IMPORT SCROLL HAS BEEN ADDED TO THE SPELLBOOK!**

The incantation to summon the powers of `Content.Shared.Implants` has been correctly added, allowing this system to wield the magics of subdermal implantation.

---

`22-26`: **NEW MYSTICAL DEPENDENCIES AND CONSTANTS HAVE BEEN INSCRIBED!**

The system now draws power from the `SharedSubdermalImplantSystem` and defines the sacred name of the `CommandTrackerImplant`. These changes provide the foundation for the implantation ritual.

---

`51-53`: **THE IMPLANTATION RITUAL HAS BEEN PROPERLY CRAFTED!**

The mystical tracking device is now being implanted directly into the target's flesh, allowing the Bureau of Security Operations to scry upon their location without relying on public sensors. This powerful enchantment aligns with the scrolls of prophecy that spoke of implanting targets with a private Tracking Implant that only the Command Monitor can detect!

---

`54-56`: **THE CONDITIONAL DEATHRATTLE ENCHANTMENT IS WELL CRAFTED!**

The deathrattle component is now only attached if the `ApplyDeathrattle` flag is true, working in harmony with the changes to `RelayedDeathrattleComponent.RequireCrewMonitor`. This conditional spell-binding ensures the magical system works as intended while respecting configuration options.

</details>
<details>
<summary>Resources/Prototypes/_Goobstation/Entities/Objects/Misc/subdermal_implants.yml (1)</summary>

`9-9`: **Verily, the new SPDX entry is correct.**

This addition properly attributes the changes to Baptr0b0t and follows the existing SPDX header format.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T15:24:39Z
user: login: pheenty
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T15:34:16Z
user: login: pheenty
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T15:36:23Z
user: login: Baptr0b0t
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T15:40:57Z
user: login: pheenty
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T15:50:43Z
user: login: Baptr0b0t
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T15:53:57Z
user: login: SX-7
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-10T20:35:10Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 2**

<details>
<summary>🧹 Nitpick comments (1)</summary><blockquote>

<details>
<summary>Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs (1)</summary><blockquote>

`44-48`: **MESSAGE MISMATCH – injector vs. implanter verbiage.**  

Thy first popup chants “injector-component” whilst the second invokes “implanter-component”.  Consider harmonising these scroll keys to avoid confusing the apprentices who read them.

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**
**Cache: Disabled due to data retention organization setting**
**Knowledge Base: Disabled due to data retention organization setting**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 11b8d4f86421cfad2464f2d41844cb5e0dee7f9a and 03df9f1ca4312b425c99993ee751f8c7bc7c74ac.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs` (3 hunks)

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (5)</summary>

* GitHub Check: YAML Linter
* GitHub Check: build (ubuntu-latest)
* GitHub Check: build (ubuntu-latest)
* GitHub Check: YAML map schema validator
* GitHub Check: Test Packaging

</details>

<details>
<summary>🔇 Additional comments (1)</summary><blockquote>

<details>
<summary>Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs (1)</summary>

`61-72`: **LOCALISATION SPELL USES BAD CONSTANT AFTER FIX**  

When thou mendest the typo above, remember to wield the corrected `CommandTrackerImplantName` inside the localisation incantations lest they still reference a banished symbol and break at runtime.

```diff
-            var msg = Loc.GetString("implanter-component-implant-already", ("implant", CommandTrackerImplantNane), ("target", name));
+            var msg = Loc.GetString("implanter-component-implant-already", ("implant", CommandTrackerImplantName), ("target", name));
…
-            var msg = Loc.GetString("implanter-component-implant-failed", ("implant", CommandTrackerImplantNane), ("target", name));
+            var msg = Loc.GetString("implanter-component-implant-failed", ("implant", CommandTrackerImplantName), ("target", name));
```

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-19T19:37:18Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 3**

<details>
<summary>♻️ Duplicate comments (1)</summary><blockquote>

<details>
<summary>Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs (1)</summary><blockquote>

`26-31`: **THY DEPENDENCY INCANTATIONS AND RUNE CONSTANTS ARE WELL-CRAFTED!**

WITNESS THE POWER! The implant system and popup dependencies are properly bound to thy magical construct. The sacred constants for the Command Tracker Implant are properly named and shall serve thee well in thy spellcasting.

I SEE THE ANCIENT BUG HAS BEEN VANQUISHED! The cursed "CommandTrackerImplantNane" has been properly renamed to "CommandTrackerImplantName" as foretold in the prophecies of the previous code review.

</blockquote></details>

</blockquote></details>

<details>
<summary>🧹 Nitpick comments (1)</summary><blockquote>

<details>
<summary>Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs (1)</summary><blockquote>

`65-71`: **THE WHITELIST ENCHANTMENT IS CORRECT, BUT CONTAINS UNNECESSARY VOID SPACE!**

BEHOLD MORTAL, THY WHITELIST SPELL IS WELL-CRAFTED but contains an empty line that serves no purpose in the arcane arts! Though this affects not the function of thy spell, it disrupts the aesthetic symmetry of the magical code!


```diff
         if (_whitelist.IsWhitelistFail(comp.Whitelist, args.Target.Value))
         {
-
             var msg = Loc.GetString("implanter-component-implant-failed", ("implant", CommandTrackerImplantName), ("target", name));
             _popup.PopupEntity(msg, args.Target.Value, args.User);
             return;
         }
```

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**
**Cache: Disabled due to data retention organization setting**
**Knowledge Base: Disabled due to data retention organization setting**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 03df9f1ca4312b425c99993ee751f8c7bc7c74ac and af7fecfd6606f3d0a13a50095186eb1aaf1306ae.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs` (3 hunks)

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (5)</summary>

* GitHub Check: build (ubuntu-latest)
* GitHub Check: YAML Linter
* GitHub Check: Test Packaging
* GitHub Check: YAML map schema validator
* GitHub Check: build (ubuntu-latest)

</details>

<details>
<summary>🔇 Additional comments (3)</summary><blockquote>

<details>
<summary>Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs (3)</summary>

`1-6`: **THE ANCIENT SCROLLS OF COPYRIGHT HAVE BEEN PROPERLY INSCRIBED!**

BEHOLD, THE SACRED RUNES OF COPYRIGHT PROTECTION! These mystical inscriptions shall ward thy code against the dark forces of litigation. The arcane SPDX enchantments have been cast with precision.

---

`14-18`: **THY IMPORT SCROLLS HAVE BEEN PROPERLY UNFURLED!**

THE MAGIC GRIMOIRE EXPANDS! These arcane imports summon the powers of implants, identity, and popup enchantments - necessary components for thy implanting ritual. The spell components are well-chosen for the mystical working thou dost prepare.

---

`44-48`: _🛠️ Refactor suggestion_

**THE NOTIFICATION ENCHANTMENTS HAVE BEEN CAST, BUT LACK PROTECTION AGAINST THE VOID!**

THY POPUP SCROLLS ARE POWERFUL, but vulnerable to the dark forces of NULL! The args.User reference is not protected by an arcane null-ward before being passed to Identity.Entity()! This could summon a fearsome NullReferenceException demon if the user becomes NULL!


```diff
-        var userName = Identity.Entity(args.User, EntityManager);
+        if (args.User == null)
+            return;
+            
+        var userName = Identity.Entity(args.User, EntityManager);
```



> Likely an incorrect or invalid review comment.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-19T19:52:41Z
user: login: gluesniffler
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-25T02:01:59Z

Review comments:
diff_hunk: @@ -70,13 +72,13 @@ private void OnPacketReceived(EntityUid uid, CrewMonitoringConsoleComponent comp
                 if (!HasComp<TransformComponent>(sensorUid))
                     continue;
 
-                if (scanned.ScannedEntities.Contains(Transform(sensorUid).ParentUid))
+                if (pair.Value.IsCommandTracker)
                     newSensorStatus[pair.Key] = pair.Value;
             }
             sensorStatus = newSensorStatus;
         }
         // Goobstation - end
-
+        //Todo : Ignore Command member on non BSO tracker
path: Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs
user: login: pheenty
body: Don't. Being able to track people is an important part of antag paramed gameplay, and heads will have no reason not to turn their coords off if they are already tracked by BSO.
created_at: 2025-05-06T03:15:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -70,13 +72,13 @@ private void OnPacketReceived(EntityUid uid, CrewMonitoringConsoleComponent comp
                 if (!HasComp<TransformComponent>(sensorUid))
                     continue;
 
-                if (scanned.ScannedEntities.Contains(Transform(sensorUid).ParentUid))
+                if (pair.Value.IsCommandTracker)
                     newSensorStatus[pair.Key] = pair.Value;
             }
             sensorStatus = newSensorStatus;
         }
         // Goobstation - end
-
+        //Todo : Ignore Command member on non BSO tracker
path: Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs
user: login: Baptr0b0t
body: First of all, there are still plenty of reasons for heads to keep their coordinates on — BSO isn't the only one who can assist them. Security and Medical teams also rely on coordinates to respond quickly in emergencies. The Station AI often uses them to handle access requests, like when someone says “open the door, I’m stuck.”

Additionally, if a head has multiple tracking devices — such as a standard implant, a jumpsuit tracker, and a command tracking implant — they would show up 3 times on the monitor, which is cluttered and confusing.

Finally, I believe the case of an antagonist paramedic specifically needing to find a head (who, again, has no strong reason to turn their coords off) is rare enough that it’s not worth balancing around . Also, certain antagonist types like Heretics don’t rely on that mechanic at all. (PS: Heads are not hard to find after all, just go to his department and wait)

That said, it’s true that heads wouldn’t be required to have their coords on — but just like the rest of the crew, it would be left to individual choice or habit. (Personally, I keep mine on at all times.)
created_at: 2025-05-06T06:52:33Z
author_association: CONTRIBUTOR
diff_hunk: @@ -70,13 +72,13 @@ private void OnPacketReceived(EntityUid uid, CrewMonitoringConsoleComponent comp
                 if (!HasComp<TransformComponent>(sensorUid))
                     continue;
 
-                if (scanned.ScannedEntities.Contains(Transform(sensorUid).ParentUid))
+                if (pair.Value.IsCommandTracker)
                     newSensorStatus[pair.Key] = pair.Value;
             }
             sensorStatus = newSensorStatus;
         }
         // Goobstation - end
-
+        //Todo : Ignore Command member on non BSO tracker
path: Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs
user: login: Baptr0b0t
body: ![image](https://github.com/user-attachments/assets/e5faa57d-29e1-49d4-887e-44e4db8911bb)


created_at: 2025-05-06T06:52:47Z
author_association: CONTRIBUTOR
diff_hunk: @@ -70,13 +72,13 @@ private void OnPacketReceived(EntityUid uid, CrewMonitoringConsoleComponent comp
                 if (!HasComp<TransformComponent>(sensorUid))
                     continue;
 
-                if (scanned.ScannedEntities.Contains(Transform(sensorUid).ParentUid))
+                if (pair.Value.IsCommandTracker)
                     newSensorStatus[pair.Key] = pair.Value;
             }
             sensorStatus = newSensorStatus;
         }
         // Goobstation - end
-
+        //Todo : Ignore Command member on non BSO tracker
path: Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs
user: login: pheenty
body: Okay true 
created_at: 2025-05-06T07:20:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -70,13 +72,13 @@ private void OnPacketReceived(EntityUid uid, CrewMonitoringConsoleComponent comp
                 if (!HasComp<TransformComponent>(sensorUid))
                     continue;
 
-                if (scanned.ScannedEntities.Contains(Transform(sensorUid).ParentUid))
+                if (pair.Value.IsCommandTracker)
                     newSensorStatus[pair.Key] = pair.Value;
             }
             sensorStatus = newSensorStatus;
         }
         // Goobstation - end
-
+        //Todo : Ignore Command member on non BSO tracker
path: Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs
user: login: pheenty
body: You should probably then iterate for each sensor:
If there is already sensor with such name + job icon + coordinates, continue
Is this is a command tracker and non-command monitor, continue
If this is non-command tracker and command monitor, continue
Otherwise show it
created_at: 2025-05-06T07:29:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -70,13 +72,13 @@ private void OnPacketReceived(EntityUid uid, CrewMonitoringConsoleComponent comp
                 if (!HasComp<TransformComponent>(sensorUid))
                     continue;
 
-                if (scanned.ScannedEntities.Contains(Transform(sensorUid).ParentUid))
+                if (pair.Value.IsCommandTracker)
                     newSensorStatus[pair.Key] = pair.Value;
             }
             sensorStatus = newSensorStatus;
         }
         // Goobstation - end
-
+        //Todo : Ignore Command member on non BSO tracker
path: Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs
user: login: Baptr0b0t
body: > If there is already sensor with such name + job icon + coordinates, continue

This would change how the tracking monitor works for everyone, not just BSO. It would fix the old duplicate bug from tracking implants + suitcoords.

But implementing this likely requires building a list and looping through all sensors to compare and filter duplicates — picking the “best” one, not the first one received.
created_at: 2025-05-06T07:54:41Z
author_association: CONTRIBUTOR
diff_hunk: @@ -70,13 +72,13 @@ private void OnPacketReceived(EntityUid uid, CrewMonitoringConsoleComponent comp
                 if (!HasComp<TransformComponent>(sensorUid))
                     continue;
 
-                if (scanned.ScannedEntities.Contains(Transform(sensorUid).ParentUid))
+                if (pair.Value.IsCommandTracker)
                     newSensorStatus[pair.Key] = pair.Value;
             }
             sensorStatus = newSensorStatus;
         }
         // Goobstation - end
-
+        //Todo : Ignore Command member on non BSO tracker
path: Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs
user: login: Baptr0b0t
body: > Is this is a command tracker and non-command monitor, continue
> If this is non-command tracker and command monitor, continue

Solved using a filter
created_at: 2025-05-06T15:08:25Z
author_association: CONTRIBUTOR
diff_hunk: @@ -39,6 +40,37 @@
     - SubdermalImplant
     - HideContextMenu
 
+- type: entity
+  parent: BaseSubdermalImplant
+  id: CommandTrackingImplant
+  name: Command tracking implant
+  description: This implant reserved for command has a tracking device attached to a private suit sensor network, as well as a condition monitor for the Command radio channel.
+  categories: [ HideSpawnMenu ]
+  components:
+    - type: SubdermalImplant
+      whitelist:
+        components:
+        - MobState # admeme implanting a chair with tracking implant needs to give the chair mobstate so it can die first
+    - type: SuitSensor
+      randomMode: false
+      controlsLocked: true
+      commandtracker: true #BSO only
path: Resources/Prototypes/_Goobstation/Entities/Objects/Misc/subdermal_implants.yml
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**Critical: Proper casing of `commandTracker` is required.**

The YAML key `commandtracker` must be `commandTracker` to bind to the C# `CommandTracker` property. Without the correct casing, the implant’s command tracking flag may not be enabled at runtime.  
Apply the following diff:

```diff
-      commandtracker: true #BSO only
+      commandTracker: true # BSO only
```



<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
      commandTracker: true # BSO only
`````

</details>

<!-- suggestion_end -->

<details>
<summary>🤖 Prompt for AI Agents (early access)</summary>

```
In Resources/Prototypes/_Goobstation/Entities/Objects/Misc/subdermal_implants.yml at line 57, the key `commandtracker` is incorrectly cased and should be changed to `commandTracker` to correctly bind to the C# property. Update the YAML key to `commandTracker` to ensure the implant’s command tracking flag is enabled at runtime.
```

</details>

<!-- This is an auto-generated comment by CodeRabbit -->

✅ Addressed in commits b997e49 to c7dcfe6
created_at: 2025-05-06T15:24:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -18,5 +20,5 @@ public sealed partial class RelayedDeathrattleComponent : Component
     public LocId DeathMessage = "deathrattle-implant-dead-message";
 
     [DataField]
-    public bool RequireCrewMonitor = true;
+    public bool RequireCrewMonitor = false;
path: Content.Goobstation.Server/RelayedDeathrattle/RelayedDeathrattleComponent.cs
user: login: pheenty
body: You can actually remove this and the logic behind this altogether. I shitcoded it for aviu's request and didn't even test it properly so it doesn't even work
created_at: 2025-05-06T15:34:16Z
author_association: CONTRIBUTOR
diff_hunk: @@ -105,7 +89,17 @@ private void UpdateUserInterface(EntityUid uid, CrewMonitoringConsoleComponent?
             EnsureComp<NavMapComponent>(xform.GridUid.Value);
 
         // Update all sensors info
-        var allSensors = component.ConnectedSensors.Values.ToList();
-        _uiSystem.SetUiState(uid, CrewMonitoringUIKey.Key, new CrewMonitoringState(allSensors));
+        // GoobStation - Start
+        var isCommandOnly = HasComp<CrewMonitorScanningComponent>(uid);
+
+        var filteredSensors = component.ConnectedSensors
+            .Where(pair => isCommandOnly
+                ? pair.Value.IsCommandTracker
+                : !pair.Value.IsCommandTracker)
+            .Select(pair => pair.Value)
+            .ToList();
+        _uiSystem.SetUiState(uid, CrewMonitoringUIKey.Key, new CrewMonitoringState(filteredSensors));
+        // GoobStation - Stop
+        //_uiSystem.SetUiState(uid, CrewMonitoringUIKey.Key, new CrewMonitoringState(filteredSensors));
path: Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs
user: login: pheenty
body: I think the commented line is supposed to be original
_uiSystem.SetUiState(uid, CrewMonitoringUIKey.Key, new CrewMonitoringState(allSensors));
but who cares
also it's usually goobstation - end
but again who cares
created_at: 2025-05-06T15:36:23Z
author_association: CONTRIBUTOR
diff_hunk: @@ -105,7 +89,17 @@ private void UpdateUserInterface(EntityUid uid, CrewMonitoringConsoleComponent?
             EnsureComp<NavMapComponent>(xform.GridUid.Value);
 
         // Update all sensors info
-        var allSensors = component.ConnectedSensors.Values.ToList();
-        _uiSystem.SetUiState(uid, CrewMonitoringUIKey.Key, new CrewMonitoringState(allSensors));
+        // GoobStation - Start
+        var isCommandOnly = HasComp<CrewMonitorScanningComponent>(uid);
+
+        var filteredSensors = component.ConnectedSensors
+            .Where(pair => isCommandOnly
+                ? pair.Value.IsCommandTracker
+                : !pair.Value.IsCommandTracker)
+            .Select(pair => pair.Value)
+            .ToList();
+        _uiSystem.SetUiState(uid, CrewMonitoringUIKey.Key, new CrewMonitoringState(filteredSensors));
+        // GoobStation - Stop
+        //_uiSystem.SetUiState(uid, CrewMonitoringUIKey.Key, new CrewMonitoringState(filteredSensors));
path: Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs
user: login: Baptr0b0t
body: No i CAN'T leave that, thx
created_at: 2025-05-06T15:40:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -39,6 +40,31 @@
     - SubdermalImplant
     - HideContextMenu
 
+- type: entity
+  parent: BaseSubdermalImplant
+  id: CommandTrackingImplant
+  name: Command tracking implant
+  description: This implant reserved for command has a tracking device attached to a private suit sensor network, as well as a condition monitor for the Command radio channel.
+  categories: [ HideSpawnMenu ]
+  components:
+    - type: SubdermalImplant
+      whitelist:
+        components:
+        - MobState # admeme implanting a chair with tracking implant needs to give the chair mobstate so it can die first
+    - type: SuitSensor
+      randomMode: false
+      controlsLocked: true
+      commandTracker: true #for BSO command monitor
+      mode: SensorCords
+      activationContainer: "implant"
+    - type: DeviceNetwork
+      deviceNetId: Wireless
+      transmitFrequencyId: SuitSensor
+    - type: StationLimitedNetwork
+    - type: WirelessNetworkConnection
+      range: 500
+    - type: MansusGraspBlockTrigger
path: Resources/Prototypes/_Goobstation/Entities/Objects/Misc/subdermal_implants.yml
user: login: pheenty
body: it doesn't trigger, what does your mansus grasp do
created_at: 2025-05-06T15:50:43Z
author_association: CONTRIBUTOR
diff_hunk: @@ -39,6 +40,31 @@
     - SubdermalImplant
     - HideContextMenu
 
+- type: entity
+  parent: BaseSubdermalImplant
+  id: CommandTrackingImplant
+  name: Command tracking implant
+  description: This implant reserved for command has a tracking device attached to a private suit sensor network, as well as a condition monitor for the Command radio channel.
+  categories: [ HideSpawnMenu ]
+  components:
+    - type: SubdermalImplant
+      whitelist:
+        components:
+        - MobState # admeme implanting a chair with tracking implant needs to give the chair mobstate so it can die first
+    - type: SuitSensor
+      randomMode: false
+      controlsLocked: true
+      commandTracker: true #for BSO command monitor
+      mode: SensorCords
+      activationContainer: "implant"
+    - type: DeviceNetwork
+      deviceNetId: Wireless
+      transmitFrequencyId: SuitSensor
+    - type: StationLimitedNetwork
+    - type: WirelessNetworkConnection
+      range: 500
+    - type: MansusGraspBlockTrigger
path: Resources/Prototypes/_Goobstation/Entities/Objects/Misc/subdermal_implants.yml
user: login: Baptr0b0t
body: true, removed.
created_at: 2025-05-06T15:53:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -105,7 +89,18 @@ private void UpdateUserInterface(EntityUid uid, CrewMonitoringConsoleComponent?
             EnsureComp<NavMapComponent>(xform.GridUid.Value);
 
         // Update all sensors info
-        var allSensors = component.ConnectedSensors.Values.ToList();
-        _uiSystem.SetUiState(uid, CrewMonitoringUIKey.Key, new CrewMonitoringState(allSensors));
+        // GoobStation - Start
+        var isCommandOnly = HasComp<CrewMonitorScanningComponent>(uid);
+
+        var filteredSensors = component.ConnectedSensors
+            .Where(pair => isCommandOnly
+                ? pair.Value.IsCommandTracker
+                : !pair.Value.IsCommandTracker)
+            .Select(pair => pair.Value)
+            .ToList();
path: Content.Server/Medical/CrewMonitoring/CrewMonitoringConsoleSystem.cs
user: login: SX-7
body: evil
created_at: 2025-05-10T20:34:30Z
author_association: CONTRIBUTOR
diff_hunk: @@ -9,13 +11,24 @@
 using Content.Shared.Humanoid;
 using Content.Shared.Interaction;
 using Content.Shared.Whitelist;
+using Content.Shared.Implants;
+using Content.Shared.IdentityManagement;
+using Content.Server.Popups;
+using Content.Shared.Popups;
 
 namespace Content.Goobstation.Server.CrewMonitoring;
 
 public sealed class CrewMonitorScanningSystem : EntitySystem
 {
     [Dependency] private readonly SharedDoAfterSystem _doAfter = default!;
     [Dependency] private readonly EntityWhitelistSystem _whitelist = default!;
+
+    [Dependency] private readonly SharedSubdermalImplantSystem _implantSystem = default!;
+    [Dependency] private readonly PopupSystem _popup = default!;
+
+    private const string CommandTrackerImplant = "CommandTrackingImplant";
+    private const string CommandTrackerImplantNane = "command tracking implant";
+
path: Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**MISSPELLED CONSTANT – the rune ‘Nane’ confounds the compiler.**  

By the beard of Arch-mage Kernighan!  The charm `CommandTrackerImplantNane` bears a typographical blight.  When this token is whispered into localisation scrolls it shall spew forth “nane” instead of the intended “name”, bewildering both scribe and player alike.

```diff
-    private const string CommandTrackerImplantNane = "command tracking implant";
+    private const string CommandTrackerImplantName = "command tracking implant";
```

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
In Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs at
lines 29 to 31, the constant name CommandTrackerImplantNane is misspelled and
should be CommandTrackerImplantName. Rename the constant to fix the typo so it
correctly reflects "name" instead of "nane" to avoid compiler confusion and
ensure proper localization.
```

</details>

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-19T19:37:17Z
author_association: CONTRIBUTOR
diff_hunk: @@ -28,22 +41,42 @@ private void OnScanAttempt(EntityUid uid, CrewMonitorScanningComponent comp, Aft
         if (args.Target == null || !args.CanReach || !HasComp<HumanoidAppearanceComponent>(args.Target))
             return;
 
+        var userName = Identity.Entity(args.User, EntityManager);
+        _popup.PopupEntity(Loc.GetString("injector-component-injecting-user"), args.Target.Value, args.User);
+        if (args.User != args.Target.Value)
+            _popup.PopupEntity(Loc.GetString("implanter-component-implanting-target", ("user", userName)), args.User, args.Target.Value, PopupType.LargeCaution);
+
         _doAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, comp.DoAfterTime, new CrewMonitorScanningDoAfterEvent(), uid, args.Target, uid) { NeedHand = true, BreakOnMove = true });
     }
 
     private void OnScanComplete(EntityUid uid, CrewMonitorScanningComponent comp, CrewMonitorScanningDoAfterEvent args)
     {
-        if (args.Cancelled || args.Handled || args.Target == null || comp.ScannedEntities.Contains(args.Target.Value))
+        var implantProto = new string(CommandTrackerImplant);
+        if (args.Cancelled || args.Handled || args.Target == null)
             return;
path: Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**ILLEGAL CONSTRUCTOR – `new string(someString)` summons a compilation daemon.**  

Lo!  In C-Sharp sorcery there existeth no overload to conjure a fresh string from another string.  Attempting `new string(CommandTrackerImplant)` shall invoke the dread CS1503 error and halt the build.  The constant can simply be passed along unaltered.

```diff
-        var implantProto = new string(CommandTrackerImplant);
+        var implantProto = CommandTrackerImplant;
```



<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion
        var implantProto = CommandTrackerImplant;
        if (args.Cancelled || args.Handled || args.Target == null)
            return;
```

</details>

<!-- suggestion_end -->

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
In Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs around
lines 54 to 56, remove the invalid use of 'new string(CommandTrackerImplant)'
since C# does not allow constructing a string from another string using a
constructor. Instead, directly use the existing string variable
'CommandTrackerImplant' without creating a new string instance.
```

</details>

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-19T19:37:17Z
author_association: CONTRIBUTOR
diff_hunk: @@ -28,22 +41,41 @@ private void OnScanAttempt(EntityUid uid, CrewMonitorScanningComponent comp, Aft
         if (args.Target == null || !args.CanReach || !HasComp<HumanoidAppearanceComponent>(args.Target))
             return;
 
+        var userName = Identity.Entity(args.User, EntityManager);
+        _popup.PopupEntity(Loc.GetString("injector-component-injecting-user"), args.Target.Value, args.User);
+        if (args.User != args.Target.Value)
+            _popup.PopupEntity(Loc.GetString("implanter-component-implanting-target", ("user", userName)), args.User, args.Target.Value, PopupType.LargeCaution);
+
         _doAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, comp.DoAfterTime, new CrewMonitorScanningDoAfterEvent(), uid, args.Target, uid) { NeedHand = true, BreakOnMove = true });
     }
 
     private void OnScanComplete(EntityUid uid, CrewMonitorScanningComponent comp, CrewMonitorScanningDoAfterEvent args)
     {
-        if (args.Cancelled || args.Handled || args.Target == null || comp.ScannedEntities.Contains(args.Target.Value))
+        if (args.Cancelled || args.Handled || args.Target == null)
             return;
+        var name = Identity.Name(args.Target.Value, EntityManager, args.User);
 
-        if (_whitelist.IsWhitelistFail(comp.Whitelist, args.Target.Value))
+        if (comp.ScannedEntities.Contains(args.Target.Value))
+        {
+            var msg = Loc.GetString("implanter-component-implant-already", ("implant", CommandTrackerImplantName), ("target", name));
+            _popup.PopupEntity(msg, args.Target.Value, args.User);
             return;
+        }
 
-        comp.ScannedEntities.Add(args.Target.Value);
-        if (!comp.ApplyDeathrattle)
+        if (_whitelist.IsWhitelistFail(comp.Whitelist, args.Target.Value))
+        {
+
+            var msg = Loc.GetString("implanter-component-implant-failed", ("implant", CommandTrackerImplantName), ("target", name));
+            _popup.PopupEntity(msg, args.Target.Value, args.User);
             return;
+        }
+
+        comp.ScannedEntities.Add(args.Target.Value); //Keep for don't double implant
+        _implantSystem.AddImplant(args.Target.Value, CommandTrackerImplant);
+
path: Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**THE IMPLANTATION RITUAL LACKS PROTECTION AGAINST PROTOTYPE UNAVAILABILITY!**

FOOLISH MORTAL! Thou dost not verify if the CommandTrackingImplant prototype exists before attempting to summon it! Should the prototype be absent from the arcane repository, thy spell shall fail with a most terrible exception! Cast a protection ward to check its existence first!


```diff
-        comp.ScannedEntities.Add(args.Target.Value); //Keep for don't double implant
-        _implantSystem.AddImplant(args.Target.Value, CommandTrackerImplant);
+        comp.ScannedEntities.Add(args.Target.Value); //Keep for don't double implant
+        
+        // Verify the implant prototype exists before attempting to add it
+        if (!_prototypeManager.HasIndex<EntityPrototype>(CommandTrackerImplant))
+        {
+            var errorMsg = Loc.GetString("implanter-component-implant-missing", ("implant", CommandTrackerImplantName));
+            _popup.PopupEntity(errorMsg, args.Target.Value, args.User);
+            return;
+        }
+        
+        _implantSystem.AddImplant(args.Target.Value, CommandTrackerImplant);
```

OBSERVE! This requires adding a dependency on the PrototypeManager:

```csharp
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
```

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
In Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs around
lines 73 to 75, the code attempts to add the CommandTrackerImplant without
verifying if its prototype exists, risking an exception if the prototype is
missing. To fix this, inject the IPrototypeManager dependency into the class,
then before calling _implantSystem.AddImplant, check if the
CommandTrackerImplant prototype exists using
_prototypeManager.HasIndex<YourPrototypeType>(CommandTrackerImplant). Only
proceed with adding the implant if the prototype is confirmed to exist.
```

</details>

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-19T19:52:40Z
author_association: CONTRIBUTOR
diff_hunk: @@ -28,22 +41,41 @@ private void OnScanAttempt(EntityUid uid, CrewMonitorScanningComponent comp, Aft
         if (args.Target == null || !args.CanReach || !HasComp<HumanoidAppearanceComponent>(args.Target))
             return;
 
+        var userName = Identity.Entity(args.User, EntityManager);
+        _popup.PopupEntity(Loc.GetString("injector-component-injecting-user"), args.Target.Value, args.User);
+        if (args.User != args.Target.Value)
+            _popup.PopupEntity(Loc.GetString("implanter-component-implanting-target", ("user", userName)), args.User, args.Target.Value, PopupType.LargeCaution);
+
         _doAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, comp.DoAfterTime, new CrewMonitorScanningDoAfterEvent(), uid, args.Target, uid) { NeedHand = true, BreakOnMove = true });
     }
 
     private void OnScanComplete(EntityUid uid, CrewMonitorScanningComponent comp, CrewMonitorScanningDoAfterEvent args)
     {
-        if (args.Cancelled || args.Handled || args.Target == null || comp.ScannedEntities.Contains(args.Target.Value))
+        if (args.Cancelled || args.Handled || args.Target == null)
             return;
+        var name = Identity.Name(args.Target.Value, EntityManager, args.User);
 
-        if (_whitelist.IsWhitelistFail(comp.Whitelist, args.Target.Value))
+        if (comp.ScannedEntities.Contains(args.Target.Value))
+        {
+            var msg = Loc.GetString("implanter-component-implant-already", ("implant", CommandTrackerImplantName), ("target", name));
+            _popup.PopupEntity(msg, args.Target.Value, args.User);
             return;
+        }
 
-        comp.ScannedEntities.Add(args.Target.Value);
-        if (!comp.ApplyDeathrattle)
+        if (_whitelist.IsWhitelistFail(comp.Whitelist, args.Target.Value))
+        {
+
+            var msg = Loc.GetString("implanter-component-implant-failed", ("implant", CommandTrackerImplantName), ("target", name));
+            _popup.PopupEntity(msg, args.Target.Value, args.User);
             return;
+        }
+
+        comp.ScannedEntities.Add(args.Target.Value); //Keep for don't double implant
+        _implantSystem.AddImplant(args.Target.Value, CommandTrackerImplant);
+
+        if (comp.ApplyDeathrattle)
+            EnsureComp<RelayedDeathrattleComponent>(args.Target.Value).Target = uid;
path: Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**THY DEATHRATTLE COMPONENT CONJURATION LACKS PROTECTION AGAINST TARGET TRANSMUTATION!**

HARKEN, SPELLWEAVER! Should the target entity be destroyed between when thou verifies its presence and when thou attempts to add the deathrattle component, thy magic shall unleash chaos! Wrap this enchantment in a protective ward to ensure the target still exists in the mortal realm!


```diff
-        if (comp.ApplyDeathrattle)
-            EnsureComp<RelayedDeathrattleComponent>(args.Target.Value).Target = uid;
+        if (comp.ApplyDeathrattle && !Deleted(args.Target.Value))
+            EnsureComp<RelayedDeathrattleComponent>(args.Target.Value).Target = uid;
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion
        if (comp.ApplyDeathrattle && !Deleted(args.Target.Value))
            EnsureComp<RelayedDeathrattleComponent>(args.Target.Value).Target = uid;
```

</details>

<!-- suggestion_end -->

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
In Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs around
lines 76 to 77, the code assigns a target to the RelayedDeathrattleComponent
without verifying if the target entity still exists, risking errors if the
target is destroyed in between. To fix this, add a check to confirm that
args.Target.Value is still a valid, existing entity before calling EnsureComp
and assigning the Target property, thereby preventing operations on a
non-existent entity.
```

</details>

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-19T19:52:40Z
author_association: CONTRIBUTOR
diff_hunk: @@ -28,22 +41,41 @@ private void OnScanAttempt(EntityUid uid, CrewMonitorScanningComponent comp, Aft
         if (args.Target == null || !args.CanReach || !HasComp<HumanoidAppearanceComponent>(args.Target))
             return;
 
+        var userName = Identity.Entity(args.User, EntityManager);
+        _popup.PopupEntity(Loc.GetString("injector-component-injecting-user"), args.Target.Value, args.User);
+        if (args.User != args.Target.Value)
+            _popup.PopupEntity(Loc.GetString("implanter-component-implanting-target", ("user", userName)), args.User, args.Target.Value, PopupType.LargeCaution);
+
         _doAfter.TryStartDoAfter(new DoAfterArgs(EntityManager, args.User, comp.DoAfterTime, new CrewMonitorScanningDoAfterEvent(), uid, args.Target, uid) { NeedHand = true, BreakOnMove = true });
     }
 
     private void OnScanComplete(EntityUid uid, CrewMonitorScanningComponent comp, CrewMonitorScanningDoAfterEvent args)
     {
-        if (args.Cancelled || args.Handled || args.Target == null || comp.ScannedEntities.Contains(args.Target.Value))
+        if (args.Cancelled || args.Handled || args.Target == null)
             return;
+        var name = Identity.Name(args.Target.Value, EntityManager, args.User);
 
path: Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs
user: login: coderabbitai[bot]
body: _🛠️ Refactor suggestion_

**THE TARGET IDENTITY SPELL MAY CRUMBLE WHEN FACING ENTITIES WITHOUT IDENTITIES!**

BEWARE, MORTAL PROGRAMMER! Thy Identity.Name() incantation assumes the presence of an identity component on the entity! Entities without such mystical components will cause thy spell to falter! Cast a protection ward to ensure the identity exists or provide a fallback name!


```diff
-        var name = Identity.Name(args.Target.Value, EntityManager, args.User);
+        var name = args.Target.Value != null && HasComp<MetaDataComponent>(args.Target.Value)
+            ? Identity.Name(args.Target.Value, EntityManager, args.User)
+            : "<unknown>";
```


> Committable suggestion skipped: line range outside the PR's diff.

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
In Content.Goobstation.Server/CrewMonitoring/CrewMonitorScanningSystem.cs around
lines 54 to 57, the call to Identity.Name(args.Target.Value, EntityManager,
args.User) assumes the target entity has an identity component, which may not
always be true and can cause errors. Before calling Identity.Name, check if the
target entity actually has an identity component using
EntityManager.HasComponent or a similar method. If it does not, provide a safe
fallback name or handle the absence gracefully to prevent runtime failures.
```

</details>

<!-- This is an auto-generated comment by CodeRabbit -->
created_at: 2025-05-19T19:52:40Z
author_association: CONTRIBUTOR

PR comments:
user: login: coderabbitai[bot]
created_at: 2025-05-06T15:24:35Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- walkthrough_start -->

## Walkthrough

A new subdermal implant named "CommandTrackingImplant" and its corresponding implanter have been added to the realm of code. The CrewMonitorScanningSystem now implants scanned entities with this command tracking implant upon successful scan completion, providing popup feedback for implanting actions and failures. Suit sensors have been extended with a new boolean flag `CommandTracker` that is propagated through sensor status creation, network serialization, and deserialization. The CrewMonitoringConsoleSystem filters displayed sensors based on this command tracker flag, showing command trackers only if the console possesses a CrewMonitorScanningComponent. The `RequireCrewMonitor` boolean field was removed from the RelayedDeathrattleComponent and related conditional checks were expunged from the RelayedDeathrattleSystem. Additionally, the default scan time was reduced from 15 to 8 seconds, and various SPDX copyright attributions were inscribed.

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant CrewMonitor
    participant TargetEntity
    participant ImplantSystem
    participant SuitSensorSystem
    participant UI

    CrewMonitor->>TargetEntity: Initiate Scan Attempt
    CrewMonitor->>CrewMonitor: Check if Already Scanned or Whitelisted
    alt Already Scanned or Not Whitelisted
        CrewMonitor->>User: Show Failure Popup
    else
        CrewMonitor->>ImplantSystem: Add CommandTrackingImplant to TargetEntity
        ImplantSystem-->>TargetEntity: Implant Applied (SuitSensor enabled)
        alt ApplyDeathrattle True
            CrewMonitor->>TargetEntity: Add RelayedDeathrattleComponent
        end
        CrewMonitor->>User: Show Success Popup
    end
    SuitSensorSystem->>UI: Send Sensor Status (filtered by IsCommandTracker)
    UI-->>User: Display Command Tracker Info (if applicable)
```

## Suggested labels

`Small Bug`

<!-- walkthrough_end -->

<!-- announcements_start -->

> [!NOTE]
> <details>
> <summary>⚡️ AI Code Reviews for VS Code, Cursor, Windsurf</summary>
> 
> CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
> Learn more [here](http://coderabbit.ai/ide).
> 
> </details>

---

> [!NOTE]
> <details>
> <summary>⚡️ Faster reviews with caching</summary>
> 
> CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure `Review - Disable Cache` at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the `Data Retention` setting under your Organization Settings.
> Enjoy the performance boost—your workflow just got faster.
> 
> </details>

<!-- announcements_end -->
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings
<details open="true">
<summary>🧪 Generate Unit Tests</summary>

- [ ] <!-- {"checkboxId": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} -->   Create PR with Unit Tests
- [ ] <!-- {"checkboxId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} -->   Commit Unit Tests in branch `bso-rebalance`
- [ ] <!-- {"checkboxId": "07f1e7d6-8a8e-4e23-9900-8731c2c87f58", "radioGroupId": "utg-output-choice-group-unknown_comment_id"} -->   Post Copyable Unit Tests in Comment

</details>

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=Goob-Station/Goob-Station&utm_content=2651):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai generate unit tests` to generate unit tests for this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: CONTRIBUTOR
user: login: pheenty
created_at: 2025-05-06T16:07:24Z
body: alright cool
i don't really like the idea of implanting implant out of your ass, perhaps the infinite implanter should be a distinct item, but whatever

author_association: CONTRIBUTOR
user: login: Baptr0b0t
created_at: 2025-05-06T16:08:13Z
body: @pheenty 
I know this is less related to this PR, but it's connected to your modification on BSO’s PDA. I noticed it hasn't been applied to NTR, which still includes Wanted Cartridge, Logprobre, and AstroNav. Is there a specific reason for this, or was it simply an oversight?
author_association: CONTRIBUTOR
user: login: Baptr0b0t
created_at: 2025-05-06T16:09:18Z
body: > alright cool i don't really like the idea of implanting implant out of your ass, perhaps the infinite implanter should be a distinct item, but whatever

Bluespace tech, could need a description change, also need for the bso sun glass still saying he show security
author_association: CONTRIBUTOR
user: login: pheenty
created_at: 2025-05-06T16:19:19Z
body: > @pheenty I know this is less related to this PR, but it's connected to your modification on BSO’s PDA. I noticed it hasn't been applied to NTR, which still includes Wanted Cartridge, Logprobre, and AstroNav. Is there a specific reason for this, or was it simply an oversight?

NTR is basically station's overseer and gets nothing to validhunt with, so I think its fine
author_association: CONTRIBUTOR