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;
namespace Content.Server.MachineLinking.Components
namespace Content.Server.DeviceLinking.Components
{
[RegisterComponent]
public sealed class ActiveSignalTimerComponent : Component

View File

@@ -1,8 +1,6 @@
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]
public sealed class OrGateComponent : Component
@@ -26,3 +24,11 @@ public sealed class OrGateComponent : Component
[ViewVariables]
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.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.MachineLinking.Components;
namespace Content.Server.DeviceLinking.Components;
[RegisterComponent]
public sealed class SignalTimerComponent : Component

View File

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

View File

@@ -8,6 +8,11 @@ namespace Content.Server.DeviceNetwork
/// </summary>
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
/// <summary>

View File

@@ -500,15 +500,31 @@ public sealed class NetworkConfiguratorSystem : SharedNetworkConfiguratorSystem
if (!configurator.ActiveDeviceLink.HasValue || !configurator.DeviceLinkTarget.HasValue)
return;
if (HasComp<DeviceLinkSourceComponent>(configurator.ActiveDeviceLink))
if (HasComp<DeviceLinkSourceComponent>(configurator.ActiveDeviceLink) && HasComp<DeviceLinkSinkComponent>(configurator.DeviceLinkTarget))
{
_deviceLinkSystem.RemoveSinkFromSource(configurator.ActiveDeviceLink.Value, configurator.DeviceLinkTarget.Value);
UpdateLinkUiState(uid, configurator.ActiveDeviceLink.Value, configurator.DeviceLinkTarget.Value);
_deviceLinkSystem.RemoveSinkFromSource(
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);
UpdateLinkUiState(uid, configurator.DeviceLinkTarget.Value, configurator.ActiveDeviceLink.Value);
_deviceLinkSystem.RemoveSinkFromSource(
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)
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);
}
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);
UpdateLinkUiState(uid, configurator.DeviceLinkTarget.Value, configurator.ActiveDeviceLink.Value, targetSource);
_deviceLinkSystem.ToggleLink(
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)
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);
UpdateLinkUiState(uid, configurator.ActiveDeviceLink.Value, configurator.DeviceLinkTarget.Value, activeSource);
_deviceLinkSystem.SaveLinks(
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);
UpdateLinkUiState(uid, configurator.DeviceLinkTarget.Value, configurator.ActiveDeviceLink.Value, targetSource);
_deviceLinkSystem.SaveLinks(
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);
_uiSystem.TrySetUiState(
component.Owner,
uid,
NetworkConfiguratorUiKey.Configure,
new DeviceListUserInterfaceState(
_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.System;

View File

@@ -1,12 +1,7 @@
using Content.Server.DeviceLinking.Components;
namespace Content.Server.MachineLinking.Events
{
public enum SignalState
{
Momentary, // Instantaneous pulse high, compatibility behavior
Low,
High
}
public sealed class SignalReceivedEvent : EntityEventArgs
{
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.Diagnostics.CodeAnalysis;
using Content.Server.DeviceLinking.Components;
using Content.Server.MachineLinking.Components;
using Content.Server.MachineLinking.Events;
using Content.Server.Power.Components;

View File

@@ -77,3 +77,23 @@
id: ArtifactAnalyzerReceiver
name: signal-port-name-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
description: signal-port-description-artifact-analyzer-sender
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: SignalTimer
canEditLabel: false
- type: SignalTransmitter
outputs:
Start: []
Timer: []
- type: DeviceLinkSource
ports:
- Start
- Timer
- type: ActivatableUI
key: enum.SignalTimerUiKey.Key
- type: UserInterface

View File

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