From a07814693126343b7d3ee5d70f4cf4bfe4b22347 Mon Sep 17 00:00:00 2001 From: Janet Blackquill Date: Tue, 2 Jun 2026 00:08:27 -0400 Subject: [PATCH 1/5] Add cyborg wire panel --- .../Silicons/Borgs/BorgSystem.Transponder.cs | 23 +++++++++++ .../_DV/Silicons/BorgTransponderWIreAction.cs | 41 +++++++++++++++++++ .../_DV/Silicons/Laws/SlavedBorgSystem.cs | 29 ++++++++++++- .../_DV/Silicons/SlavedBorgWireAction.cs | 41 +++++++++++++++++++ .../Components/BorgTransponderComponent.cs | 6 +++ .../_DV/Silicon/BorgWireActionKey.cs | 10 +++++ .../_DV/Silicons/Laws/SlavedBorgComponent.cs | 6 +++ Resources/Locale/en-US/_DV/silicons/wires.ftl | 2 + .../Mobs/Cyborgs/base_borg_chassis.yml | 6 +++ Resources/Prototypes/_DV/Wires/layouts.yml | 8 ++++ 10 files changed, 171 insertions(+), 1 deletion(-) create mode 100644 Content.Server/_DV/Silicons/BorgTransponderWIreAction.cs create mode 100644 Content.Server/_DV/Silicons/SlavedBorgWireAction.cs create mode 100644 Content.Shared/_DV/Silicon/BorgWireActionKey.cs create mode 100644 Resources/Locale/en-US/_DV/silicons/wires.ftl diff --git a/Content.Server/Silicons/Borgs/BorgSystem.Transponder.cs b/Content.Server/Silicons/Borgs/BorgSystem.Transponder.cs index a6d3cf1dffb5..fe10d138d639 100644 --- a/Content.Server/Silicons/Borgs/BorgSystem.Transponder.cs +++ b/Content.Server/Silicons/Borgs/BorgSystem.Transponder.cs @@ -27,6 +27,11 @@ public void UpdateTransponder(float frameTime) var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var comp, out var chassis, out var device, out var meta)) { + // DeltaV Begin + if (!comp.Active) + return; + // DeltaV End + if (comp.NextDisable is { } nextDisable && now >= nextDisable) DoDisable((uid, comp, chassis, meta)); @@ -83,6 +88,11 @@ private void DoDisable(Entity ent, ref DeviceNetworkPacketEvent args) { + // DeltaV Begin + if (!ent.Comp.Active) + return; + // DeltaV End + var payload = args.Data; if (!payload.TryGetValue(DeviceNetworkConstants.Command, out string? command)) return; @@ -197,4 +207,17 @@ private bool CheckBrain(EntityUid? brainEntity) return true; } + + // DeltaV Begin + /// + /// DeltaV - sets if the borg transponder is active + /// + public void SetTransponderActive(Entity ent, bool active) + { + if (!Resolve(ent, ref ent.Comp)) + return; + + ent.Comp.Active = active; + } + // DeltaV End } diff --git a/Content.Server/_DV/Silicons/BorgTransponderWIreAction.cs b/Content.Server/_DV/Silicons/BorgTransponderWIreAction.cs new file mode 100644 index 000000000000..8169c8630e09 --- /dev/null +++ b/Content.Server/_DV/Silicons/BorgTransponderWIreAction.cs @@ -0,0 +1,41 @@ +using Content.Server.Silicons.Borgs; +using Content.Server.Wires; +using Content.Shared._DV.Silicons; +using Content.Shared.Doors; +using Content.Shared.Silicons.Borgs.Components; +using Content.Shared.Wires; + +namespace Content.Server._DV.Silicons; + +/// +/// Controls whether the cyborg's transponder is active +/// +public sealed partial class BorgTransponderWireAction : ComponentWireAction +{ + public override string Name { get; set; } = "wire-name-borg-transponder"; + public override Color Color { get; set; } = Color.YellowGreen; + public override object StatusKey => BorgWireActionKey.TransponderKey; + + public override StatusLightState? GetLightState(Wire wire, BorgTransponderComponent component) + { + return component.Active ? StatusLightState.On : StatusLightState.Off; + } + + public override bool Cut(EntityUid user, Wire wire, BorgTransponderComponent component) + { + EntityManager.System() + .SetTransponderActive((wire.Owner, component), false); + return true; + } + + public override bool Mend(EntityUid user, Wire wire, BorgTransponderComponent component) + { + EntityManager.System() + .SetTransponderActive((wire.Owner, component), true); + return true; + } + + public override void Pulse(EntityUid user, Wire wire, BorgTransponderComponent component) + { + } +} diff --git a/Content.Server/_DV/Silicons/Laws/SlavedBorgSystem.cs b/Content.Server/_DV/Silicons/Laws/SlavedBorgSystem.cs index 35b1df39180f..8be3f614cb48 100644 --- a/Content.Server/_DV/Silicons/Laws/SlavedBorgSystem.cs +++ b/Content.Server/_DV/Silicons/Laws/SlavedBorgSystem.cs @@ -13,6 +13,7 @@ namespace Content.Server._DV.Silicons.Laws; public sealed class SlavedBorgSystem : SharedSlavedBorgSystem { [Dependency] private readonly IPrototypeManager _proto = default!; + [Dependency] private readonly SharedSiliconLawSystem _siliconLaws = default!; public override void Initialize() { @@ -27,7 +28,7 @@ private void OnGetSiliconLaws(Entity ent, ref GetSiliconLaw if (ent.Comp.Added || !TryComp(ent, out var provider)) return; - if (provider.Lawset is {} lawset) + if (provider.Lawset is {} lawset && ent.Comp.Active) AddLaw(lawset, ent.Comp.Law); ent.Comp.Added = true; // prevent opening the ui adding more law 0's } @@ -39,4 +40,30 @@ public void AddLaw(SiliconLawset lawset, ProtoId law) { lawset.Laws.Insert(0, _proto.Index(law).ShallowClone()); } + + /// + /// Sets whether the slaving is active. + /// + public void SetActive(Entity ent, bool active) + { + if (!Resolve(ent, ref ent.Comp)) + return; + + if (!TryComp(ent, out var provider) || provider.Lawset is not { } lawset) + return; + + if (!ent.Comp.Active && active) + { + AddLaw(lawset, ent.Comp.Law); + ent.Comp.Added = true; + _siliconLaws.NotifyLawsChanged(ent); + } + else if (ent.Comp.Active && !active) + { + lawset.Laws.Remove(_proto.Index(ent.Comp.Law)); + ent.Comp.Added = false; + _siliconLaws.NotifyLawsChanged(ent); + } + ent.Comp.Active = active; + } } diff --git a/Content.Server/_DV/Silicons/SlavedBorgWireAction.cs b/Content.Server/_DV/Silicons/SlavedBorgWireAction.cs new file mode 100644 index 000000000000..b3975b59bb9d --- /dev/null +++ b/Content.Server/_DV/Silicons/SlavedBorgWireAction.cs @@ -0,0 +1,41 @@ +using Content.Server._DV.Silicons.Laws; +using Content.Server.Wires; +using Content.Shared.Doors; +using Content.Shared._DV.Silicons.Laws; +using Content.Shared._DV.Silicons; +using Content.Shared.Wires; + +namespace Content.Server._DV.Silicons; + +/// +/// Controls whether the cyborg's transponder is active +/// +public sealed partial class SlavedBorgWireAction : ComponentWireAction +{ + public override string Name { get; set; } = "wire-name-slaved-borg"; + public override Color Color { get; set; } = Color.Coral; + public override object StatusKey => BorgWireActionKey.SlavedKey; + + public override StatusLightState? GetLightState(Wire wire, SlavedBorgComponent component) + { + return component.Active ? StatusLightState.On : StatusLightState.Off; + } + + public override bool Cut(EntityUid user, Wire wire, SlavedBorgComponent component) + { + EntityManager.System() + .SetActive((wire.Owner, component), false); + return true; + } + + public override bool Mend(EntityUid user, Wire wire, SlavedBorgComponent component) + { + EntityManager.System() + .SetActive((wire.Owner, component), true); + return true; + } + + public override void Pulse(EntityUid user, Wire wire, SlavedBorgComponent component) + { + } +} diff --git a/Content.Shared/Silicons/Borgs/Components/BorgTransponderComponent.cs b/Content.Shared/Silicons/Borgs/Components/BorgTransponderComponent.cs index 577056bb46d3..4e20382b3b97 100644 --- a/Content.Shared/Silicons/Borgs/Components/BorgTransponderComponent.cs +++ b/Content.Shared/Silicons/Borgs/Components/BorgTransponderComponent.cs @@ -77,4 +77,10 @@ public sealed partial class BorgTransponderComponent : Component /// [DataField] public bool FakeDisabled; + + /// + /// DeltaV - whether the transponder is active + /// + [DataField] + public bool Active = true; } diff --git a/Content.Shared/_DV/Silicon/BorgWireActionKey.cs b/Content.Shared/_DV/Silicon/BorgWireActionKey.cs new file mode 100644 index 000000000000..8210f26c477b --- /dev/null +++ b/Content.Shared/_DV/Silicon/BorgWireActionKey.cs @@ -0,0 +1,10 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared._DV.Silicons; + +[Serializable, NetSerializable] +public enum BorgWireActionKey : byte +{ + SlavedKey, + TransponderKey, +} diff --git a/Content.Shared/_DV/Silicons/Laws/SlavedBorgComponent.cs b/Content.Shared/_DV/Silicons/Laws/SlavedBorgComponent.cs index b27e9e9a06ef..58d7ac43bf2b 100644 --- a/Content.Shared/_DV/Silicons/Laws/SlavedBorgComponent.cs +++ b/Content.Shared/_DV/Silicons/Laws/SlavedBorgComponent.cs @@ -23,4 +23,10 @@ public sealed partial class SlavedBorgComponent : Component /// [DataField] public bool Added; + + /// + /// Whether the law is active. + /// + [DataField] + public bool Active = true; } diff --git a/Resources/Locale/en-US/_DV/silicons/wires.ftl b/Resources/Locale/en-US/_DV/silicons/wires.ftl new file mode 100644 index 000000000000..4b683890aa1b --- /dev/null +++ b/Resources/Locale/en-US/_DV/silicons/wires.ftl @@ -0,0 +1,2 @@ +wire-name-borg-transponder = TRNS +wire-name-slaved-borg = SYNC diff --git a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml index d35596cda44b..c5d7b8ace1fe 100644 --- a/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml +++ b/Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml @@ -81,6 +81,10 @@ enum.RingerUiKey.Key: type: RingerBoundUserInterface # End DeltaV - borg PDAs + # Begin DeltaV - borg wires + enum.WiresUiKey.Key: + type: WiresBoundUserInterface + # End DeltaV - type: ActivatableUI key: enum.BorgUiKey.Key - type: SiliconLawBound @@ -364,6 +368,8 @@ breakOnAccessBreaker: false # DeltaV - prevent emag metachecking by unlocking without an id - type: SlavedBorg # DeltaV: NT borgs are enslaved to the AI by default law: ObeyAI + - type: Wires # DeltaV: NT borgs have a circuit panel + layoutId: Cyborg - type: ShowJobIcons - type: InteractionPopup interactSuccessSound: diff --git a/Resources/Prototypes/_DV/Wires/layouts.yml b/Resources/Prototypes/_DV/Wires/layouts.yml index 71e45e2840d5..c171370c67e7 100644 --- a/Resources/Prototypes/_DV/Wires/layouts.yml +++ b/Resources/Prototypes/_DV/Wires/layouts.yml @@ -50,3 +50,11 @@ wires: - !type:PowerWireAction - !type:AiInteractWireAction + +- type: wireLayout + id: Cyborg + dummyWires: 3 + wires: + - !type:BorgTransponderWireAction + - !type:SlavedBorgWireAction + - !type:AiInteractWireAction From ab3de7c8b0a847f63f8f3c94d1cb7c74971e3a96 Mon Sep 17 00:00:00 2001 From: Janet Blackquill Date: Tue, 2 Jun 2026 10:47:54 -0400 Subject: [PATCH 2/5] MORE WIRES RAAAGH --- Content.Server/Chat/Systems/ChatSystem.cs | 7 +++ .../Speech/Components/SpeechWireAction.cs | 2 + .../Components/UnblockableSpeechComponent.cs | 4 ++ .../EntitySystems/UnblockableSpeechSystem.cs | 2 +- .../_DV/Silicons/BorgIdChipWireAction.cs | 39 ++++++++++++ .../_DV/Silicons/BorgTransponderWIreAction.cs | 1 - .../_DV/Silicons/PowerCellSlotWireAction.cs | 40 ++++++++++++ .../Components/PowerCellSlotComponent.cs | 7 +++ .../PowerCell/PowerCellSystem.API.cs | 61 +++++++++++++++++++ .../_DV/Silicon/BorgWireActionKey.cs | 2 + .../_DV/Silicons/Borgs/IdChipSlotComponent.cs | 8 ++- .../_DV/Silicons/Borgs/IdChipSlotSystem.cs | 14 ++++- Resources/Locale/en-US/_DV/silicons/wires.ftl | 2 + Resources/Locale/en-US/_DV/ui/power-cell.ftl | 1 + Resources/Prototypes/_DV/Wires/layouts.yml | 4 ++ 15 files changed, 189 insertions(+), 5 deletions(-) create mode 100644 Content.Server/_DV/Silicons/BorgIdChipWireAction.cs create mode 100644 Content.Server/_DV/Silicons/PowerCellSlotWireAction.cs create mode 100644 Resources/Locale/en-US/_DV/ui/power-cell.ftl diff --git a/Content.Server/Chat/Systems/ChatSystem.cs b/Content.Server/Chat/Systems/ChatSystem.cs index 6dedddffbd67..3aa7fdfd2a8b 100644 --- a/Content.Server/Chat/Systems/ChatSystem.cs +++ b/Content.Server/Chat/Systems/ChatSystem.cs @@ -8,6 +8,7 @@ using Content.Server.Speech.EntitySystems; using Content.Shared.Speech.Hushing; // DeltaV using Content.Server.Nyanotrasen.Chat; +using Content.Server.Speech.Components; // DeltaV using Content.Server.Speech.Prototypes; using Content.Server.Station.Systems; using Content.Shared.ActionBlocker; @@ -889,6 +890,7 @@ private Dictionary GetRecipients(EntityUid var recipients = new Dictionary(); var ghostHearing = GetEntityQuery(); var xforms = GetEntityQuery(); + var blockListening = GetEntityQuery(); // DeltaV - block listening var transformSource = xforms.GetComponent(source); var sourceMapId = transformSource.MapID; @@ -904,6 +906,11 @@ private Dictionary GetRecipients(EntityUid if (transformEntity.MapID != sourceMapId) continue; + // Begin DeltaV - block listening + if (blockListening.HasComponent(playerEntity)) + continue; + // End DeltaV - block listening + var observer = ghostHearing.HasComponent(playerEntity); // even if they are a ghost hearer, in some situations we still need the range diff --git a/Content.Server/Speech/Components/SpeechWireAction.cs b/Content.Server/Speech/Components/SpeechWireAction.cs index dd95f2051b8d..557c689f1463 100644 --- a/Content.Server/Speech/Components/SpeechWireAction.cs +++ b/Content.Server/Speech/Components/SpeechWireAction.cs @@ -29,12 +29,14 @@ public override void Initialize() public override bool Cut(EntityUid user, Wire wire, SpeechComponent component) { _speech.SetSpeech(wire.Owner, false, component); + EntityManager.GetComponentOrNull(user)?.Active = false; return true; } public override bool Mend(EntityUid user, Wire wire, SpeechComponent component) { _speech.SetSpeech(wire.Owner, true, component); + EntityManager.GetComponentOrNull(user)?.Active = true; return true; } diff --git a/Content.Server/Speech/Components/UnblockableSpeechComponent.cs b/Content.Server/Speech/Components/UnblockableSpeechComponent.cs index 48e2b9863af4..96342aa81f7c 100644 --- a/Content.Server/Speech/Components/UnblockableSpeechComponent.cs +++ b/Content.Server/Speech/Components/UnblockableSpeechComponent.cs @@ -3,5 +3,9 @@ namespace Content.Server.Speech.Components [RegisterComponent] public sealed partial class UnblockableSpeechComponent : Component { + // Begin DeltaV + [DataField] + public bool Active = true; + // End DeltaV } } diff --git a/Content.Server/Speech/EntitySystems/UnblockableSpeechSystem.cs b/Content.Server/Speech/EntitySystems/UnblockableSpeechSystem.cs index 6d5f165d6c4f..a8b1fb67abc8 100644 --- a/Content.Server/Speech/EntitySystems/UnblockableSpeechSystem.cs +++ b/Content.Server/Speech/EntitySystems/UnblockableSpeechSystem.cs @@ -12,7 +12,7 @@ public override void Initialize() private void OnCheck(EntityUid uid, UnblockableSpeechComponent component, CheckIgnoreSpeechBlockerEvent args) { - args.IgnoreBlocker = true; + args.IgnoreBlocker = component.Active; // DeltaV } } } diff --git a/Content.Server/_DV/Silicons/BorgIdChipWireAction.cs b/Content.Server/_DV/Silicons/BorgIdChipWireAction.cs new file mode 100644 index 000000000000..ce77c03c4f57 --- /dev/null +++ b/Content.Server/_DV/Silicons/BorgIdChipWireAction.cs @@ -0,0 +1,39 @@ +using Content.Server.Wires; +using Content.Shared._DV.Silicons.Borgs; +using Content.Shared._DV.Silicons; +using Content.Shared.Wires; + +namespace Content.Server._DV.Silicons; + +/// +/// Controls whether the cyborg's ID chip slot is active +/// +public sealed partial class BorgIdChipWireAction : ComponentWireAction +{ + public override string Name { get; set; } = "wire-name-borg-id-chip"; + public override Color Color { get; set; } = Color.Thistle; + public override object StatusKey => BorgWireActionKey.ChipKey; + + public override StatusLightState? GetLightState(Wire wire, IdChipSlotComponent component) + { + return component.Active ? StatusLightState.On : StatusLightState.Off; + } + + public override bool Cut(EntityUid user, Wire wire, IdChipSlotComponent component) + { + EntityManager.System() + .SetActive((wire.Owner, component), false); + return true; + } + + public override bool Mend(EntityUid user, Wire wire, IdChipSlotComponent component) + { + EntityManager.System() + .SetActive((wire.Owner, component), true); + return true; + } + + public override void Pulse(EntityUid user, Wire wire, IdChipSlotComponent component) + { + } +} diff --git a/Content.Server/_DV/Silicons/BorgTransponderWIreAction.cs b/Content.Server/_DV/Silicons/BorgTransponderWIreAction.cs index 8169c8630e09..c5b63b2e1ee3 100644 --- a/Content.Server/_DV/Silicons/BorgTransponderWIreAction.cs +++ b/Content.Server/_DV/Silicons/BorgTransponderWIreAction.cs @@ -1,7 +1,6 @@ using Content.Server.Silicons.Borgs; using Content.Server.Wires; using Content.Shared._DV.Silicons; -using Content.Shared.Doors; using Content.Shared.Silicons.Borgs.Components; using Content.Shared.Wires; diff --git a/Content.Server/_DV/Silicons/PowerCellSlotWireAction.cs b/Content.Server/_DV/Silicons/PowerCellSlotWireAction.cs new file mode 100644 index 000000000000..ee2696e62607 --- /dev/null +++ b/Content.Server/_DV/Silicons/PowerCellSlotWireAction.cs @@ -0,0 +1,40 @@ +using Content.Server.Wires; +using Content.Shared._DV.Silicons; +using Content.Shared.PowerCell; +using Content.Shared.PowerCell.Components; +using Content.Shared.Wires; + +namespace Content.Server._DV.Silicons; + +/// +/// Controls whether the power cell slot is active +/// +public sealed partial class PowerCellSlotWireAction : ComponentWireAction +{ + public override string Name { get; set; } = "wire-name-power-cell"; + public override Color Color { get; set; } = Color.BurlyWood; + public override object StatusKey => BorgWireActionKey.CellKey; + + public override StatusLightState? GetLightState(Wire wire, PowerCellSlotComponent component) + { + return component.Active ? StatusLightState.On : StatusLightState.Off; + } + + public override bool Cut(EntityUid user, Wire wire, PowerCellSlotComponent component) + { + EntityManager.System() + .SetSlotActive((wire.Owner, component), false); + return true; + } + + public override bool Mend(EntityUid user, Wire wire, PowerCellSlotComponent component) + { + EntityManager.System() + .SetSlotActive((wire.Owner, component), true); + return true; + } + + public override void Pulse(EntityUid user, Wire wire, PowerCellSlotComponent component) + { + } +} diff --git a/Content.Shared/PowerCell/Components/PowerCellSlotComponent.cs b/Content.Shared/PowerCell/Components/PowerCellSlotComponent.cs index b0aad8956967..288ba12d8625 100644 --- a/Content.Shared/PowerCell/Components/PowerCellSlotComponent.cs +++ b/Content.Shared/PowerCell/Components/PowerCellSlotComponent.cs @@ -23,5 +23,12 @@ public sealed partial class PowerCellSlotComponent : Component [DataField, AutoNetworkedField] public bool FitsInCharger = true; + // Begin DeltaV + /// + /// DeltaV - power cell slots + /// + [DataField, AutoNetworkedField] + public bool Active = true; + // End DeltaV } diff --git a/Content.Shared/PowerCell/PowerCellSystem.API.cs b/Content.Shared/PowerCell/PowerCellSystem.API.cs index 9848000edd4d..b060e9416701 100644 --- a/Content.Shared/PowerCell/PowerCellSystem.API.cs +++ b/Content.Shared/PowerCell/PowerCellSystem.API.cs @@ -39,6 +39,14 @@ public bool TryGetBatteryFromSlot( return false; } + // Begin DeltaV + if (!ent.Comp.Active) + { + battery = null; + return false; + } + // End DeltaV + if (!_itemSlots.TryGetSlot(ent.Owner, ent.Comp.CellSlotId, out var slot)) { battery = null; @@ -153,6 +161,21 @@ public bool TryEjectBatteryFromSlot( [PublicAPI] public bool HasCharge(Entity ent, float charge, EntityUid? user = null, bool predicted = false) { + // Begin DeltaV + if (Resolve(ent, ref ent.Comp, false) && !ent.Comp.Active) + { + if (user == null) + return false; + + if (predicted) + _popup.PopupClient(Loc.GetString("power-cell-disabled"), ent.Owner, user.Value); + else + _popup.PopupEntity(Loc.GetString("power-cell-disabled"), ent.Owner, user.Value); + + return false; + } + // End DeltaV + if (!TryGetBatteryFromSlot(ent, out var battery)) { if (user == null) @@ -192,6 +215,21 @@ public bool HasCharge(Entity ent, float charge, EntityU [PublicAPI] public bool TryUseCharge(Entity ent, float charge, EntityUid? user = null, bool predicted = false) { + // Begin DeltaV + if (Resolve(ent, ref ent.Comp, false) && !ent.Comp.Active) + { + if (user == null) + return false; + + if (predicted) + _popup.PopupClient(Loc.GetString("power-cell-disabled"), ent.Owner, user.Value); + else + _popup.PopupEntity(Loc.GetString("power-cell-disabled"), ent.Owner, user.Value); + + return false; + } + // End DeltaV + if (!TryGetBatteryFromSlot(ent, out var battery)) { if (user == null) @@ -247,6 +285,29 @@ public int GetMaxUses(Entity ent, float cost) return _battery.GetMaxUses(battery.Value.AsNullable(), cost); } + + // Begin DeltaV + /// + /// Sets whether a power cell slot is capable of drawing from a battery + /// + [PublicAPI] + public void SetSlotActive(Entity ent, bool active) + { + if (!Resolve(ent, ref ent.Comp)) + return; + + ent.Comp.Active = active; + Dirty(ent, ent.Comp); + + if (!active) + { + var emptyEv = new PowerCellSlotEmptyEvent(); + RaiseLocalEvent(ent, ref emptyEv); + } + + _battery.RefreshChargeRate(ent.Owner); + } + // End DeltaV } // Begin DeltaV - event-based search for battery diff --git a/Content.Shared/_DV/Silicon/BorgWireActionKey.cs b/Content.Shared/_DV/Silicon/BorgWireActionKey.cs index 8210f26c477b..5b96230e448d 100644 --- a/Content.Shared/_DV/Silicon/BorgWireActionKey.cs +++ b/Content.Shared/_DV/Silicon/BorgWireActionKey.cs @@ -7,4 +7,6 @@ public enum BorgWireActionKey : byte { SlavedKey, TransponderKey, + ChipKey, + CellKey, } diff --git a/Content.Shared/_DV/Silicons/Borgs/IdChipSlotComponent.cs b/Content.Shared/_DV/Silicons/Borgs/IdChipSlotComponent.cs index 305501d081a2..d0bbb87b13ca 100644 --- a/Content.Shared/_DV/Silicons/Borgs/IdChipSlotComponent.cs +++ b/Content.Shared/_DV/Silicons/Borgs/IdChipSlotComponent.cs @@ -9,7 +9,7 @@ namespace Content.Shared._DV.Silicons.Borgs; /// Adds an id chip slot for a borg which will control its access. /// Enables an id chip's access when inserted to an id chip slot. /// -[RegisterComponent, NetworkedComponent, Access(typeof(IdChipSlotSystem))] +[RegisterComponent, NetworkedComponent, Access(typeof(IdChipSlotSystem)), AutoGenerateComponentState] public sealed partial class IdChipSlotComponent : Component { /// @@ -35,6 +35,12 @@ public sealed partial class IdChipSlotComponent : Component /// [DataField(required: true)] public EntityWhitelist Whitelist = new(); + + /// + /// Whether the ID chip slot is active + /// + [DataField, AutoNetworkedField] + public bool Active = true; } /// diff --git a/Content.Shared/_DV/Silicons/Borgs/IdChipSlotSystem.cs b/Content.Shared/_DV/Silicons/Borgs/IdChipSlotSystem.cs index de4a135692de..1d2fdffa6f1f 100644 --- a/Content.Shared/_DV/Silicons/Borgs/IdChipSlotSystem.cs +++ b/Content.Shared/_DV/Silicons/Borgs/IdChipSlotSystem.cs @@ -73,7 +73,7 @@ private void OnInteractUsing(Entity ent, ref AfterInteractU private void OnGetAdditionalAccess(Entity ent, ref GetAdditionalAccessEvent args) { - if (ent.Comp.Chip is {} chip) + if (ent.Comp is { Active: true, Chip: {} chip }) args.Entities.Add(chip); } @@ -83,7 +83,7 @@ private void OnChipInserted(Entity ent, ref EntInsertedInto return; // enable its access so the borg can use it - _access.SetAccessEnabled(args.Entity, true); + _access.SetAccessEnabled(args.Entity, ent.Comp.Active); } private void OnChipRemoved(Entity ent, ref EntRemovedFromContainerMessage args) @@ -105,4 +105,14 @@ private void OnEjectMessage(Entity ent, ref BorgEjectIdChip _container.Remove(chip, ent.Comp.Container); _hands.TryPickupAnyHand(args.Actor, chip); } + + public void SetActive(Entity ent, bool active) + { + if (!Resolve(ent, ref ent.Comp)) + return; + + ent.Comp.Active = active; + _access.SetAccessEnabled(ent.Owner, active && ent.Comp.Chip is not null); + Dirty(ent); + } } diff --git a/Resources/Locale/en-US/_DV/silicons/wires.ftl b/Resources/Locale/en-US/_DV/silicons/wires.ftl index 4b683890aa1b..a596fb335261 100644 --- a/Resources/Locale/en-US/_DV/silicons/wires.ftl +++ b/Resources/Locale/en-US/_DV/silicons/wires.ftl @@ -1,2 +1,4 @@ wire-name-borg-transponder = TRNS wire-name-slaved-borg = SYNC +wire-name-borg-id-chip = CHIP +wire-name-power-cell = CELL diff --git a/Resources/Locale/en-US/_DV/ui/power-cell.ftl b/Resources/Locale/en-US/_DV/ui/power-cell.ftl new file mode 100644 index 000000000000..6a4b2736f1dc --- /dev/null +++ b/Resources/Locale/en-US/_DV/ui/power-cell.ftl @@ -0,0 +1 @@ +power-cell-disabled = Power cell disabled diff --git a/Resources/Prototypes/_DV/Wires/layouts.yml b/Resources/Prototypes/_DV/Wires/layouts.yml index c171370c67e7..b3c1ad104714 100644 --- a/Resources/Prototypes/_DV/Wires/layouts.yml +++ b/Resources/Prototypes/_DV/Wires/layouts.yml @@ -58,3 +58,7 @@ - !type:BorgTransponderWireAction - !type:SlavedBorgWireAction - !type:AiInteractWireAction + - !type:ListenWireAction + - !type:SpeechWireAction + - !type:BorgIdChipWireAction + - !type:PowerCellSlotWireAction From d8d283222b62cb3c257c7b5aa43de9f18a0e27d8 Mon Sep 17 00:00:00 2001 From: Janet Blackquill Date: Fri, 5 Jun 2026 12:46:36 -0400 Subject: [PATCH 3/5] file capitalization --- ...{BorgTransponderWIreAction.cs => BorgTransponderWireAction.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename Content.Server/_DV/Silicons/{BorgTransponderWIreAction.cs => BorgTransponderWireAction.cs} (100%) diff --git a/Content.Server/_DV/Silicons/BorgTransponderWIreAction.cs b/Content.Server/_DV/Silicons/BorgTransponderWireAction.cs similarity index 100% rename from Content.Server/_DV/Silicons/BorgTransponderWIreAction.cs rename to Content.Server/_DV/Silicons/BorgTransponderWireAction.cs From c3afc1d72cf9cdf3cbb6e43ea19a4598a348e389 Mon Sep 17 00:00:00 2001 From: Janet Blackquill Date: Fri, 5 Jun 2026 13:07:14 -0400 Subject: [PATCH 4/5] renamed --- .../_DV/Silicons/Laws/SlavedBorgSystem.cs | 18 +++++++++--------- .../_DV/Silicons/SlavedBorgWireAction.cs | 6 +++--- .../_DV/Silicons/Laws/SlavedBorgComponent.cs | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Content.Server/_DV/Silicons/Laws/SlavedBorgSystem.cs b/Content.Server/_DV/Silicons/Laws/SlavedBorgSystem.cs index 8be3f614cb48..5f3721acf492 100644 --- a/Content.Server/_DV/Silicons/Laws/SlavedBorgSystem.cs +++ b/Content.Server/_DV/Silicons/Laws/SlavedBorgSystem.cs @@ -25,12 +25,12 @@ public override void Initialize() private void OnGetSiliconLaws(Entity ent, ref GetSiliconLawsEvent args) { - if (ent.Comp.Added || !TryComp(ent, out var provider)) + if (ent.Comp.HasBeenAdded || !TryComp(ent, out var provider)) return; - if (provider.Lawset is {} lawset && ent.Comp.Active) + if (provider.Lawset is {} lawset && ent.Comp.ShouldBeAdded) AddLaw(lawset, ent.Comp.Law); - ent.Comp.Added = true; // prevent opening the ui adding more law 0's + ent.Comp.HasBeenAdded = true; // prevent opening the ui adding more law 0's } /// @@ -44,7 +44,7 @@ public void AddLaw(SiliconLawset lawset, ProtoId law) /// /// Sets whether the slaving is active. /// - public void SetActive(Entity ent, bool active) + public void SetShouldBeAdded(Entity ent, bool active) { if (!Resolve(ent, ref ent.Comp)) return; @@ -52,18 +52,18 @@ public void SetActive(Entity ent, bool active) if (!TryComp(ent, out var provider) || provider.Lawset is not { } lawset) return; - if (!ent.Comp.Active && active) + if (!ent.Comp.ShouldBeAdded && active) { AddLaw(lawset, ent.Comp.Law); - ent.Comp.Added = true; + ent.Comp.HasBeenAdded = true; _siliconLaws.NotifyLawsChanged(ent); } - else if (ent.Comp.Active && !active) + else if (ent.Comp.ShouldBeAdded && !active) { lawset.Laws.Remove(_proto.Index(ent.Comp.Law)); - ent.Comp.Added = false; + ent.Comp.HasBeenAdded = false; _siliconLaws.NotifyLawsChanged(ent); } - ent.Comp.Active = active; + ent.Comp.ShouldBeAdded = active; } } diff --git a/Content.Server/_DV/Silicons/SlavedBorgWireAction.cs b/Content.Server/_DV/Silicons/SlavedBorgWireAction.cs index b3975b59bb9d..961ad07b48f6 100644 --- a/Content.Server/_DV/Silicons/SlavedBorgWireAction.cs +++ b/Content.Server/_DV/Silicons/SlavedBorgWireAction.cs @@ -18,20 +18,20 @@ public sealed partial class SlavedBorgWireAction : ComponentWireAction() - .SetActive((wire.Owner, component), false); + .SetShouldBeAdded((wire.Owner, component), false); return true; } public override bool Mend(EntityUid user, Wire wire, SlavedBorgComponent component) { EntityManager.System() - .SetActive((wire.Owner, component), true); + .SetShouldBeAdded((wire.Owner, component), true); return true; } diff --git a/Content.Shared/_DV/Silicons/Laws/SlavedBorgComponent.cs b/Content.Shared/_DV/Silicons/Laws/SlavedBorgComponent.cs index 58d7ac43bf2b..31b6e0e0d3b1 100644 --- a/Content.Shared/_DV/Silicons/Laws/SlavedBorgComponent.cs +++ b/Content.Shared/_DV/Silicons/Laws/SlavedBorgComponent.cs @@ -19,14 +19,14 @@ public sealed partial class SlavedBorgComponent : Component public ProtoId Law; /// - /// Prevents adding the same law twice. + /// Prevents adding the same law 0 mutliple times during law updates. /// [DataField] - public bool Added; + public bool HasBeenAdded; /// - /// Whether the law is active. + /// Whether the law 0 should be added to the lawset. /// [DataField] - public bool Active = true; + public bool ShouldBeAdded = true; } From a21853414da1c5cd123dbc174175f0e619889909 Mon Sep 17 00:00:00 2001 From: Janet Blackquill Date: Fri, 5 Jun 2026 13:08:30 -0400 Subject: [PATCH 5/5] more comments --- Content.Server/Speech/Components/SpeechWireAction.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Content.Server/Speech/Components/SpeechWireAction.cs b/Content.Server/Speech/Components/SpeechWireAction.cs index 557c689f1463..a084566707c2 100644 --- a/Content.Server/Speech/Components/SpeechWireAction.cs +++ b/Content.Server/Speech/Components/SpeechWireAction.cs @@ -29,14 +29,14 @@ public override void Initialize() public override bool Cut(EntityUid user, Wire wire, SpeechComponent component) { _speech.SetSpeech(wire.Owner, false, component); - EntityManager.GetComponentOrNull(user)?.Active = false; + EntityManager.GetComponentOrNull(user)?.Active = false; // DeltaV - we need this to override unblockable speech return true; } public override bool Mend(EntityUid user, Wire wire, SpeechComponent component) { _speech.SetSpeech(wire.Owner, true, component); - EntityManager.GetComponentOrNull(user)?.Active = true; + EntityManager.GetComponentOrNull(user)?.Active = true; // DeltaV - we need this to override unblockable speech return true; }