diff --git a/Content.Server/DeviceLinking/Components/SignalSwitchComponent.cs b/Content.Server/DeviceLinking/Components/SignalSwitchComponent.cs
index 4259ba6c6c..5dc1d69aeb 100644
--- a/Content.Server/DeviceLinking/Components/SignalSwitchComponent.cs
+++ b/Content.Server/DeviceLinking/Components/SignalSwitchComponent.cs
@@ -1,32 +1,39 @@
+using Content.Server.DeviceLinking.Systems;
using Content.Shared.MachineLinking;
using Robust.Shared.Audio;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
-namespace Content.Server.DeviceLinking.Components
+namespace Content.Server.DeviceLinking.Components;
+
+///
+/// Simple switch that will fire ports when toggled on or off. A button is jsut a switch that signals on the
+/// same port regardless of its state.
+///
+[RegisterComponent, Access(typeof(SignalSwitchSystem))]
+public sealed class SignalSwitchComponent : Component
{
///
- /// Simple switch that will fire ports when toggled on or off. A button is jsut a switch that signals on the
- /// same port regardless of its state.
+ /// The port that gets signaled when the switch turns on.
///
- [RegisterComponent]
- public sealed class SignalSwitchComponent : Component
- {
- ///
- /// The port that gets signaled when the switch turns on.
- ///
- [DataField("onPort", customTypeSerializer: typeof(PrototypeIdSerializer))]
- public string OnPort = "On";
+ [DataField("onPort", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public string OnPort = "On";
- ///
- /// The port that gets signaled when the switch turns off.
- ///
- [DataField("offPort", customTypeSerializer: typeof(PrototypeIdSerializer))]
- public string OffPort = "Off";
+ ///
+ /// The port that gets signaled when the switch turns off.
+ ///
+ [DataField("offPort", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public string OffPort = "Off";
- [DataField("state")]
- public bool State;
+ ///
+ /// The port that gets signaled with the switch's current status.
+ /// This is only used if OnPort is different from OffPort, not in the case of a toggle switch.
+ ///
+ [DataField("statusPort", customTypeSerializer: typeof(PrototypeIdSerializer))]
+ public string StatusPort = "Status";
- [DataField("clickSound")]
- public SoundSpecifier ClickSound { get; set; } = new SoundPathSpecifier("/Audio/Machines/lightswitch.ogg");
- }
+ [DataField("state")]
+ public bool State;
+
+ [DataField("clickSound")]
+ public SoundSpecifier ClickSound = new SoundPathSpecifier("/Audio/Machines/lightswitch.ogg");
}
diff --git a/Content.Server/DeviceLinking/Systems/LogicGateSystem.cs b/Content.Server/DeviceLinking/Systems/LogicGateSystem.cs
index 70e9ede1f2..b32f5694a2 100644
--- a/Content.Server/DeviceLinking/Systems/LogicGateSystem.cs
+++ b/Content.Server/DeviceLinking/Systems/LogicGateSystem.cs
@@ -32,6 +32,26 @@ public sealed class LogicGateSystem : EntitySystem
SubscribeLocalEvent(OnSignalReceived);
}
+ public override void Update(float deltaTime)
+ {
+ var query = EntityQueryEnumerator();
+ while (query.MoveNext(out var uid, out var comp))
+ {
+ // handle momentary pulses - high when received then low the next tick
+ if (comp.StateA == SignalState.Momentary)
+ {
+ comp.StateA = SignalState.Low;
+ }
+ if (comp.StateB == SignalState.Momentary)
+ {
+ comp.StateB = SignalState.High;
+ }
+
+ // output most likely changed so update it
+ UpdateOutput(uid, comp);
+ }
+ }
+
private void OnInit(EntityUid uid, LogicGateComponent comp, ComponentInit args)
{
_deviceLink.EnsureSinkPorts(uid, comp.InputPortA, comp.InputPortB);
@@ -92,8 +112,9 @@ public sealed class LogicGateSystem : EntitySystem
private void UpdateOutput(EntityUid uid, LogicGateComponent comp)
{
// get the new output value now that it's changed
- var a = comp.StateA == SignalState.High;
- var b = comp.StateB == SignalState.High;
+ // momentary is treated as high for the current tick, after updating it will be reset to low
+ var a = comp.StateA != SignalState.Low;
+ var b = comp.StateB != SignalState.Low;
var output = false;
switch (comp.Gate)
{
diff --git a/Content.Server/DeviceLinking/Systems/SignalSwitchSystem.cs b/Content.Server/DeviceLinking/Systems/SignalSwitchSystem.cs
index acb3acb4aa..8e70aad706 100644
--- a/Content.Server/DeviceLinking/Systems/SignalSwitchSystem.cs
+++ b/Content.Server/DeviceLinking/Systems/SignalSwitchSystem.cs
@@ -1,40 +1,51 @@
using Content.Server.DeviceLinking.Components;
+using Content.Server.DeviceNetwork;
using Content.Server.MachineLinking.System;
using Content.Shared.Audio;
using Content.Shared.Interaction;
using Robust.Shared.Audio;
using Robust.Shared.Player;
-namespace Content.Server.DeviceLinking.Systems
+namespace Content.Server.DeviceLinking.Systems;
+
+public sealed class SignalSwitchSystem : EntitySystem
{
- public sealed class SignalSwitchSystem : EntitySystem
+ [Dependency] private readonly DeviceLinkSystem _deviceLink = default!;
+ [Dependency] private readonly SharedAudioSystem _audio = default!;
+
+ public override void Initialize()
{
- [Dependency] private readonly DeviceLinkSystem _signalSystem = default!;
+ base.Initialize();
- public override void Initialize()
+ SubscribeLocalEvent(OnInit);
+ SubscribeLocalEvent(OnActivated);
+ }
+
+ private void OnInit(EntityUid uid, SignalSwitchComponent comp, ComponentInit args)
+ {
+ _deviceLink.EnsureSourcePorts(uid, comp.OnPort, comp.OffPort, comp.StatusPort);
+ }
+
+ private void OnActivated(EntityUid uid, SignalSwitchComponent comp, ActivateInWorldEvent args)
+ {
+ if (args.Handled)
+ return;
+
+ comp.State = !comp.State;
+ _deviceLink.InvokePort(uid, comp.State ? comp.OnPort : comp.OffPort);
+ var data = new NetworkPayload
{
- base.Initialize();
+ [DeviceNetworkConstants.LogicState] = comp.State ? SignalState.High : SignalState.Low
+ };
- SubscribeLocalEvent(OnInit);
- SubscribeLocalEvent(OnActivated);
+ // only send status if it's a toggle switch and not a button
+ if (comp.OnPort != comp.OffPort)
+ {
+ _deviceLink.InvokePort(uid, comp.StatusPort, data);
}
- private void OnInit(EntityUid uid, SignalSwitchComponent component, ComponentInit args)
- {
- _signalSystem.EnsureSourcePorts(uid, component.OnPort, component.OffPort);
- }
+ _audio.PlayPvs(comp.ClickSound, uid, AudioParams.Default.WithVariation(0.125f).WithVolume(8f));
- private void OnActivated(EntityUid uid, SignalSwitchComponent component, ActivateInWorldEvent args)
- {
- if (args.Handled)
- return;
-
- component.State = !component.State;
- _signalSystem.InvokePort(uid, component.State ? component.OnPort : component.OffPort);
- SoundSystem.Play(component.ClickSound.GetSound(), Filter.Pvs(component.Owner), component.Owner,
- AudioHelpers.WithVariation(0.125f).WithVolume(8f));
-
- args.Handled = true;
- }
+ args.Handled = true;
}
}
diff --git a/Resources/Locale/en-US/machine-linking/transmitter_ports.ftl b/Resources/Locale/en-US/machine-linking/transmitter_ports.ftl
index 909c0dae87..02ede1e1b6 100644
--- a/Resources/Locale/en-US/machine-linking/transmitter_ports.ftl
+++ b/Resources/Locale/en-US/machine-linking/transmitter_ports.ftl
@@ -7,6 +7,9 @@ signal-port-description-on-transmitter = This port is invoked whenever the trans
signal-port-name-off-transmitter = Off
signal-port-description-off-transmitter = This port is invoked whenever the transmitter is turned off.
+signal-port-name-status-transmitter = Status
+signal-port-description-logic-output = This port is invoked with HIGH or LOW depending on the transmitter status.
+
signal-port-name-left = Left
signal-port-description-left = This port is invoked whenever the lever is moved to the leftmost position.
@@ -14,7 +17,7 @@ signal-port-name-right = Right
signal-port-description-right = This port is invoked whenever the lever is moved to the rightmost position.
signal-port-name-doorstatus = Door status
-signal-port-description-doorstatus = This port is invoked with HIGH when the door opens and LOW when the door closes.
+signal-port-description-doorstatus = This port is invoked with HIGH when the door opens and LOW when the door finishes closing.
signal-port-name-middle = Middle
signal-port-description-middle = This port is invoked whenever the lever is moved to the neutral position.
diff --git a/Resources/Prototypes/DeviceLinking/source_ports.yml b/Resources/Prototypes/DeviceLinking/source_ports.yml
index 151ba9c26f..45ee812f2e 100644
--- a/Resources/Prototypes/DeviceLinking/source_ports.yml
+++ b/Resources/Prototypes/DeviceLinking/source_ports.yml
@@ -16,6 +16,11 @@
description: signal-port-description-off-transmitter
defaultLinks: [ Off, Close ]
+- type: sourcePort
+ id: Status
+ name: signal-port-name-status-transmitter
+ description: signal-port-description-status-transmitter
+
- type: sourcePort
id: Left
name: signal-port-name-left
@@ -78,13 +83,16 @@
id: Output
name: signal-port-name-logic-output
description: signal-port-description-logic-output
+ defaultLinks: [ Input ]
- type: sourcePort
id: OutputHigh
name: signal-port-name-logic-output-high
description: signal-port-description-logic-output-high
+ defaultLinks: [ On, Open, Forward, Trigger ]
- type: sourcePort
id: OutputLow
name: signal-port-name-logic-output-low
description: signal-port-description-logic-output-low
+ defaultLinks: [ Off, Close ]
diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/switch.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/switch.yml
index db6825b96e..012870a56e 100644
--- a/Resources/Prototypes/Entities/Structures/Wallmounts/switch.yml
+++ b/Resources/Prototypes/Entities/Structures/Wallmounts/switch.yml
@@ -30,8 +30,9 @@
range: 200
- type: DeviceLinkSource
ports:
- - On
- - Off
+ - On
+ - Off
+ - Status
- type: entity
id: SignalButton
@@ -56,6 +57,7 @@
- type: SignalSwitch
onPort: Pressed
offPort: Pressed
+ statusPort: Pressed
- type: Rotatable
- type: Construction
graph: SignalButtonGraph
diff --git a/Resources/Prototypes/MachineLinking/transmitter_ports.yml b/Resources/Prototypes/MachineLinking/transmitter_ports.yml
index 4949097134..c97b324652 100644
--- a/Resources/Prototypes/MachineLinking/transmitter_ports.yml
+++ b/Resources/Prototypes/MachineLinking/transmitter_ports.yml
@@ -16,6 +16,11 @@
description: signal-port-description-off-transmitter
defaultLinks: [ Off, Close ]
+- type: transmitterPort
+ id: Status
+ name: signal-port-name-status-transmitter
+ description: signal-port-description-status-transmitter
+
- type: transmitterPort
id: Left
name: signal-port-name-left
@@ -78,13 +83,16 @@
id: Output
name: signal-port-name-logic-output
description: signal-port-description-logic-output
+ defaultLinks: [ Input ]
- type: transmitterPort
id: OutputHigh
name: signal-port-name-logic-output-high
description: signal-port-description-logic-output-high
+ defaultLinks: [ On, Open, Forward, Trigger ]
- type: transmitterPort
id: OutputLow
name: signal-port-name-logic-output-low
description: signal-port-description-logic-output-low
+ defaultLinks: [ Off, Close ]