Blast door/shutter, timer and or gate device linking fixes (#16347)

This commit is contained in:
Julian Giebel
2023-05-12 00:16:02 +02:00
committed by GitHub
parent 59176df425
commit 5e0a96dfc7
16 changed files with 255 additions and 123 deletions

View File

@@ -1,7 +1,7 @@
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Server.MachineLinking.Components namespace Content.Server.DeviceLinking.Components
{ {
[RegisterComponent] [RegisterComponent]
public sealed class ActiveSignalTimerComponent : Component public sealed class ActiveSignalTimerComponent : Component

View File

@@ -1,8 +1,6 @@
using Content.Server.MachineLinking.Events; using Content.Server.MachineLinking.Events;
using Content.Shared.MachineLinking;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.MachineLinking.Components; namespace Content.Server.DeviceLinking.Components;
[RegisterComponent] [RegisterComponent]
public sealed class OrGateComponent : Component public sealed class OrGateComponent : Component
@@ -26,3 +24,11 @@ public sealed class OrGateComponent : Component
[ViewVariables] [ViewVariables]
public SignalState LastO2 = SignalState.Low; public SignalState LastO2 = SignalState.Low;
} }
public enum SignalState
{
Momentary, // Instantaneous pulse high, compatibility behavior
Low,
High
}

View File

@@ -2,7 +2,7 @@ using Content.Shared.MachineLinking;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.MachineLinking.Components; namespace Content.Server.DeviceLinking.Components;
[RegisterComponent] [RegisterComponent]
public sealed class SignalTimerComponent : Component public sealed class SignalTimerComponent : Component

View File

@@ -1,8 +1,6 @@
using Content.Server.DeviceLinking.Components; using Content.Server.DeviceLinking.Components;
using Content.Server.DeviceNetwork; using Content.Server.DeviceNetwork;
using Content.Server.Doors.Systems; using Content.Server.Doors.Systems;
using Content.Server.MachineLinking.Events;
using Content.Server.MachineLinking.System;
using Content.Shared.Doors.Components; using Content.Shared.Doors.Components;
using Content.Shared.Doors; using Content.Shared.Doors;
using JetBrains.Annotations; using JetBrains.Annotations;
@@ -17,8 +15,6 @@ namespace Content.Server.DeviceLinking.Systems
[Dependency] private readonly DoorSystem _doorSystem = default!; [Dependency] private readonly DoorSystem _doorSystem = default!;
[Dependency] private readonly DeviceLinkSystem _signalSystem = default!; [Dependency] private readonly DeviceLinkSystem _signalSystem = default!;
private const string DoorSignalState = "DoorState";
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
@@ -40,7 +36,7 @@ namespace Content.Server.DeviceLinking.Systems
return; return;
var state = SignalState.Momentary; var state = SignalState.Momentary;
args.Data?.TryGetValue(DoorSignalState, out state); args.Data?.TryGetValue(DeviceNetworkConstants.LogicState, out state);
if (args.Port == component.OpenPort) if (args.Port == component.OpenPort)
@@ -85,12 +81,12 @@ namespace Content.Server.DeviceLinking.Systems
{ {
var data = new NetworkPayload() var data = new NetworkPayload()
{ {
{ DoorSignalState, SignalState.Momentary } { DeviceNetworkConstants.LogicState, SignalState.Momentary }
}; };
if (args.State == DoorState.Closed) if (args.State == DoorState.Closed)
{ {
data[DoorSignalState] = SignalState.Low; data[DeviceNetworkConstants.LogicState] = SignalState.Low;
_signalSystem.InvokePort(uid, door.OutOpen, data); _signalSystem.InvokePort(uid, door.OutOpen, data);
} }
else if (args.State == DoorState.Open else if (args.State == DoorState.Open
@@ -98,7 +94,7 @@ namespace Content.Server.DeviceLinking.Systems
|| args.State == DoorState.Closing || args.State == DoorState.Closing
|| args.State == DoorState.Emagging) || args.State == DoorState.Emagging)
{ {
data[DoorSignalState] = SignalState.High; data[DeviceNetworkConstants.LogicState] = SignalState.High;
_signalSystem.InvokePort(uid, door.OutOpen, data); _signalSystem.InvokePort(uid, door.OutOpen, data);
} }
} }

View File

@@ -0,0 +1,84 @@
using Content.Server.DeviceLinking.Components;
using Content.Server.DeviceNetwork;
using Content.Server.MachineLinking.Events;
using JetBrains.Annotations;
using Robust.Shared.Utility;
using SignalReceivedEvent = Content.Server.DeviceLinking.Events.SignalReceivedEvent;
namespace Content.Server.DeviceLinking.Systems
{
[UsedImplicitly]
public sealed class OrGateSystem : EntitySystem
{
[Dependency] private readonly DeviceLinkSystem _signalSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<OrGateComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<OrGateComponent, SignalReceivedEvent>(OnSignalReceived);
}
private void OnInit(EntityUid uid, OrGateComponent component, ComponentInit args)
{
_signalSystem.EnsureSinkPorts(uid, "A1", "B1", "A2", "B2");
_signalSystem.EnsureSourcePorts(uid, "O1", "O2");
}
private void OnSignalReceived(EntityUid uid, OrGateComponent component, ref SignalReceivedEvent args)
{
var state = SignalState.Momentary;
args.Data?.TryGetValue(DeviceNetworkConstants.LogicState, out state);
switch (args.Port)
{
case "A1":
component.StateA1 = state;
break;
case "B1":
component.StateB1 = state;
break;
case "A2":
component.StateA2 = state;
break;
case "B2":
component.StateB2 = state;
break;
}
// O1 = A1 || B1
var v1 = SignalState.Low;
if (component.StateA1 == SignalState.High || component.StateB1 == SignalState.High)
v1 = SignalState.High;
if (v1 != component.LastO1)
{
var data = new NetworkPayload
{
[DeviceNetworkConstants.LogicState] = v1
};
_signalSystem.InvokePort(uid, "O1", data);
}
component.LastO1 = v1;
// O2 = A2 || B2
var v2 = SignalState.Low;
if (component.StateA2 == SignalState.High || component.StateB2 == SignalState.High)
v2 = SignalState.High;
if (v2 != component.LastO2)
{
var data = new NetworkPayload
{
[DeviceNetworkConstants.LogicState] = v2
};
_signalSystem.InvokePort(uid, "O2", data);
}
component.LastO2 = v2;
}
}
}

View File

@@ -1,19 +1,19 @@
using Robust.Shared.Timing; using Content.Server.DeviceLinking.Components;
using Content.Server.MachineLinking.Components; using Content.Server.Interaction;
using Content.Shared.TextScreen;
using Robust.Server.GameObjects;
using Content.Shared.MachineLinking;
using Content.Server.UserInterface; using Content.Server.UserInterface;
using Content.Shared.Access.Systems; using Content.Shared.Access.Systems;
using Content.Server.Interaction; using Content.Shared.MachineLinking;
using Content.Shared.TextScreen;
using Robust.Server.GameObjects;
using Robust.Shared.Timing;
namespace Content.Server.MachineLinking.System; namespace Content.Server.DeviceLinking.Systems;
public sealed class SignalTimerSystem : EntitySystem public sealed class SignalTimerSystem : EntitySystem
{ {
[Dependency] private readonly SharedAudioSystem _audio = default!; [Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!; [Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly SignalLinkerSystem _signalSystem = default!; [Dependency] private readonly DeviceLinkSystem _signalSystem = default!;
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!; [Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;
[Dependency] private readonly UserInterfaceSystem _ui = default!; [Dependency] private readonly UserInterfaceSystem _ui = default!;
[Dependency] private readonly AccessReaderSystem _accessReader = default!; [Dependency] private readonly AccessReaderSystem _accessReader = default!;

View File

@@ -8,6 +8,11 @@ namespace Content.Server.DeviceNetwork
/// </summary> /// </summary>
public static class DeviceNetworkConstants public static class DeviceNetworkConstants
{ {
/// <summary>
/// Used by logic gates to transmit the state of their ports
/// </summary>
public const string LogicState = "logic_state";
#region Commands #region Commands
/// <summary> /// <summary>

View File

@@ -500,15 +500,31 @@ public sealed class NetworkConfiguratorSystem : SharedNetworkConfiguratorSystem
if (!configurator.ActiveDeviceLink.HasValue || !configurator.DeviceLinkTarget.HasValue) if (!configurator.ActiveDeviceLink.HasValue || !configurator.DeviceLinkTarget.HasValue)
return; return;
if (HasComp<DeviceLinkSourceComponent>(configurator.ActiveDeviceLink)) if (HasComp<DeviceLinkSourceComponent>(configurator.ActiveDeviceLink) && HasComp<DeviceLinkSinkComponent>(configurator.DeviceLinkTarget))
{ {
_deviceLinkSystem.RemoveSinkFromSource(configurator.ActiveDeviceLink.Value, configurator.DeviceLinkTarget.Value); _deviceLinkSystem.RemoveSinkFromSource(
UpdateLinkUiState(uid, configurator.ActiveDeviceLink.Value, configurator.DeviceLinkTarget.Value); configurator.ActiveDeviceLink.Value,
configurator.DeviceLinkTarget.Value
);
UpdateLinkUiState(
uid,
configurator.ActiveDeviceLink.Value,
configurator.DeviceLinkTarget.Value
);
} }
else if (HasComp<DeviceLinkSourceComponent>(configurator.DeviceLinkTarget)) else if (HasComp<DeviceLinkSourceComponent>(configurator.DeviceLinkTarget) && HasComp<DeviceLinkSinkComponent>(configurator.ActiveDeviceLink))
{ {
_deviceLinkSystem.RemoveSinkFromSource(configurator.DeviceLinkTarget.Value, configurator.ActiveDeviceLink.Value); _deviceLinkSystem.RemoveSinkFromSource(
UpdateLinkUiState(uid, configurator.DeviceLinkTarget.Value, configurator.ActiveDeviceLink.Value); configurator.DeviceLinkTarget.Value,
configurator.ActiveDeviceLink.Value
);
UpdateLinkUiState(
uid,
configurator.DeviceLinkTarget.Value,
configurator.ActiveDeviceLink.Value
);
} }
} }
@@ -517,15 +533,33 @@ public sealed class NetworkConfiguratorSystem : SharedNetworkConfiguratorSystem
if (!configurator.ActiveDeviceLink.HasValue || !configurator.DeviceLinkTarget.HasValue) if (!configurator.ActiveDeviceLink.HasValue || !configurator.DeviceLinkTarget.HasValue)
return; return;
if (TryComp(configurator.ActiveDeviceLink, out DeviceLinkSourceComponent? activeSource)) if (TryComp(configurator.ActiveDeviceLink, out DeviceLinkSourceComponent? activeSource) && TryComp(configurator.DeviceLinkTarget, out DeviceLinkSinkComponent? targetSink))
{ {
_deviceLinkSystem.ToggleLink(args.Session.AttachedEntity, configurator.ActiveDeviceLink.Value, configurator.DeviceLinkTarget.Value, args.Source, args.Sink, activeSource); _deviceLinkSystem.ToggleLink(
args.Session.AttachedEntity,
configurator.ActiveDeviceLink.Value,
configurator.DeviceLinkTarget.Value,
args.Source, args.Sink,
activeSource, targetSink);
UpdateLinkUiState(uid, configurator.ActiveDeviceLink.Value, configurator.DeviceLinkTarget.Value, activeSource); UpdateLinkUiState(uid, configurator.ActiveDeviceLink.Value, configurator.DeviceLinkTarget.Value, activeSource);
} }
else if (TryComp(configurator.DeviceLinkTarget, out DeviceLinkSourceComponent? targetSource)) else if (TryComp(configurator.DeviceLinkTarget, out DeviceLinkSourceComponent? targetSource) && TryComp(configurator.ActiveDeviceLink, out DeviceLinkSinkComponent? activeSink))
{ {
_deviceLinkSystem.ToggleLink(args.Session.AttachedEntity, configurator.DeviceLinkTarget.Value, configurator.ActiveDeviceLink.Value, args.Source, args.Sink, targetSource); _deviceLinkSystem.ToggleLink(
UpdateLinkUiState(uid, configurator.DeviceLinkTarget.Value, configurator.ActiveDeviceLink.Value, targetSource); args.Session.AttachedEntity,
configurator.DeviceLinkTarget.Value,
configurator.ActiveDeviceLink.Value,
args.Source, args.Sink,
targetSource, activeSink
);
UpdateLinkUiState(
uid,
configurator.DeviceLinkTarget.Value,
configurator.ActiveDeviceLink.Value,
targetSource
);
} }
} }
@@ -537,15 +571,41 @@ public sealed class NetworkConfiguratorSystem : SharedNetworkConfiguratorSystem
if (!configurator.ActiveDeviceLink.HasValue || !configurator.DeviceLinkTarget.HasValue) if (!configurator.ActiveDeviceLink.HasValue || !configurator.DeviceLinkTarget.HasValue)
return; return;
if (TryComp(configurator.ActiveDeviceLink, out DeviceLinkSourceComponent? activeSource)) if (TryComp(configurator.ActiveDeviceLink, out DeviceLinkSourceComponent? activeSource) && TryComp(configurator.DeviceLinkTarget, out DeviceLinkSinkComponent? targetSink))
{ {
_deviceLinkSystem.SaveLinks(args.Session.AttachedEntity, configurator.ActiveDeviceLink.Value, configurator.DeviceLinkTarget.Value, args.Links, activeSource); _deviceLinkSystem.SaveLinks(
UpdateLinkUiState(uid, configurator.ActiveDeviceLink.Value, configurator.DeviceLinkTarget.Value, activeSource); args.Session.AttachedEntity,
configurator.ActiveDeviceLink.Value,
configurator.DeviceLinkTarget.Value,
args.Links,
activeSource,
targetSink
);
UpdateLinkUiState(
uid,
configurator.ActiveDeviceLink.Value,
configurator.DeviceLinkTarget.Value,
activeSource
);
} }
else if (TryComp(configurator.DeviceLinkTarget, out DeviceLinkSourceComponent? targetSource)) else if (TryComp(configurator.DeviceLinkTarget, out DeviceLinkSourceComponent? targetSource) && TryComp(configurator.ActiveDeviceLink, out DeviceLinkSinkComponent? activeSink))
{ {
_deviceLinkSystem.SaveLinks(args.Session.AttachedEntity, configurator.DeviceLinkTarget.Value, configurator.ActiveDeviceLink.Value, args.Links, targetSource); _deviceLinkSystem.SaveLinks(
UpdateLinkUiState(uid, configurator.DeviceLinkTarget.Value, configurator.ActiveDeviceLink.Value, targetSource); args.Session.AttachedEntity,
configurator.DeviceLinkTarget.Value,
configurator.ActiveDeviceLink.Value,
args.Links,
targetSource,
activeSink
);
UpdateLinkUiState(
uid,
configurator.DeviceLinkTarget.Value,
configurator.ActiveDeviceLink.Value,
targetSource
);
} }
} }
@@ -587,7 +647,7 @@ public sealed class NetworkConfiguratorSystem : SharedNetworkConfiguratorSystem
_popupSystem.PopupCursor(Loc.GetString(resultText), args.Session, PopupType.Medium); _popupSystem.PopupCursor(Loc.GetString(resultText), args.Session, PopupType.Medium);
_uiSystem.TrySetUiState( _uiSystem.TrySetUiState(
component.Owner, uid,
NetworkConfiguratorUiKey.Configure, NetworkConfiguratorUiKey.Configure,
new DeviceListUserInterfaceState( new DeviceListUserInterfaceState(
_deviceListSystem.GetDeviceList(component.ActiveDeviceList.Value) _deviceListSystem.GetDeviceList(component.ActiveDeviceList.Value)

View File

@@ -1,3 +1,4 @@
using Content.Server.DeviceLinking.Components;
using Content.Server.MachineLinking.Events; using Content.Server.MachineLinking.Events;
using Content.Server.MachineLinking.System; using Content.Server.MachineLinking.System;

View File

@@ -1,12 +1,7 @@
using Content.Server.DeviceLinking.Components;
namespace Content.Server.MachineLinking.Events namespace Content.Server.MachineLinking.Events
{ {
public enum SignalState
{
Momentary, // Instantaneous pulse high, compatibility behavior
Low,
High
}
public sealed class SignalReceivedEvent : EntityEventArgs public sealed class SignalReceivedEvent : EntityEventArgs
{ {
public readonly string Port; public readonly string Port;

View File

@@ -1,63 +0,0 @@
using Content.Server.MachineLinking.Components;
using Content.Server.MachineLinking.Events;
using JetBrains.Annotations;
namespace Content.Server.MachineLinking.System
{
[UsedImplicitly]
public sealed class OrGateSystem : EntitySystem
{
[Dependency] private readonly SignalLinkerSystem _signalSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<OrGateComponent, ComponentInit>(OnInit);
SubscribeLocalEvent<OrGateComponent, SignalReceivedEvent>(OnSignalReceived);
}
private void OnInit(EntityUid uid, OrGateComponent component, ComponentInit args)
{
_signalSystem.EnsureReceiverPorts(uid, "A1", "B1", "A2", "B2");
_signalSystem.EnsureTransmitterPorts(uid, "O1", "O2");
}
private void OnSignalReceived(EntityUid uid, OrGateComponent component, SignalReceivedEvent args)
{
if (args.Port == "A1")
{
component.StateA1 = args.State;
}
else if (args.Port == "B1")
{
component.StateB1 = args.State;
}
else if (args.Port == "A2")
{
component.StateA2 = args.State;
}
else if (args.Port == "B2")
{
component.StateB2 = args.State;
}
// O1 = A1 || B1
var v1 = SignalState.Low;
if (component.StateA1 == SignalState.High || component.StateB1 == SignalState.High)
v1 = SignalState.High;
if (v1 != component.LastO1)
_signalSystem.InvokePort(uid, "O1", v1);
component.LastO1 = v1;
// O2 = A2 || B2
var v2 = SignalState.Low;
if (component.StateA2 == SignalState.High || component.StateB2 == SignalState.High)
v2 = SignalState.High;
if (v2 != component.LastO2)
_signalSystem.InvokePort(uid, "O2", v2);
component.LastO2 = v2;
}
}
}

View File

@@ -1,5 +1,6 @@
using System.Linq; using System.Linq;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using Content.Server.DeviceLinking.Components;
using Content.Server.MachineLinking.Components; using Content.Server.MachineLinking.Components;
using Content.Server.MachineLinking.Events; using Content.Server.MachineLinking.Events;
using Content.Server.Power.Components; using Content.Server.Power.Components;

View File

@@ -77,3 +77,23 @@
id: ArtifactAnalyzerReceiver id: ArtifactAnalyzerReceiver
name: signal-port-name-artifact-analyzer-receiver name: signal-port-name-artifact-analyzer-receiver
description: signal-port-description-artifact-analyzer-receiver description: signal-port-description-artifact-analyzer-receiver
- type: sinkPort
id: A1
name: "Input A1"
description: "Input A1"
- type: sinkPort
id: B1
name: "Input B1"
description: "Input B1"
- type: sinkPort
id: A2
name: "Input A2"
description: "Input A2"
- type: sinkPort
id: B2
name: "Input B2"
description: "Input B2"

View File

@@ -60,3 +60,25 @@
name: signal-port-name-artifact-analyzer-sender name: signal-port-name-artifact-analyzer-sender
description: signal-port-description-artifact-analyzer-sender description: signal-port-description-artifact-analyzer-sender
defaultLinks: [ ArtifactAnalyzerReceiver ] defaultLinks: [ ArtifactAnalyzerReceiver ]
- type: sourcePort
id: Timer
name: signal-port-name-timer-trigger
description: signal-port-description-timer-trigger
defaultLinks: [ AutoClose, On, Open, Forward, Trigger ]
- type: sourcePort
id: Start
name: signal-port-name-timer-start
description: signal-port-description-timer-start
defaultLinks: [ Close, Off ]
- type: sourcePort
id: O1
name: "Output 1"
description: "Output 1"
- type: sourcePort
id: O2
name: "Output 2"
description: "Output 2"

View File

@@ -21,10 +21,10 @@
- type: Rotatable - type: Rotatable
- type: SignalTimer - type: SignalTimer
canEditLabel: false canEditLabel: false
- type: SignalTransmitter - type: DeviceLinkSource
outputs: ports:
Start: [] - Start
Timer: [] - Timer
- type: ActivatableUI - type: ActivatableUI
key: enum.SignalTimerUiKey.Key key: enum.SignalTimerUiKey.Key
- type: UserInterface - type: UserInterface

View File

@@ -14,13 +14,18 @@
state: or state: or
- type: Rotatable - type: Rotatable
- type: OrGate - type: OrGate
- type: SignalReceiver - type: DeviceNetwork
inputs: deviceNetId: Wireless
A1: [] receiveFrequencyId: BasicDevice
B1: [] - type: WirelessNetworkConnection
A2: [] range: 200
B2: [] - type: DeviceLinkSink
- type: SignalTransmitter ports:
outputs: - A1
O1: [] - B1
O2: [] - A2
- B2
- type: DeviceLinkSource
ports:
- O1
- O2