Remove superseded machine linking code (#18244)

This commit is contained in:
Leon Friedrich
2023-07-24 14:07:35 +12:00
committed by GitHub
parent a4063a5e33
commit f2bfdd8e17
44 changed files with 58 additions and 1259 deletions

View File

@@ -1,89 +0,0 @@
using Content.Shared.MachineLinking;
using JetBrains.Annotations;
using Robust.Client.GameObjects;
namespace Content.Client.MachineLinking.UI
{
public sealed class SignalPortSelectorBoundUserInterface : BoundUserInterface
{
[ViewVariables]
private SignalPortSelectorMenu? _menu;
[ViewVariables]
private string? _selectedTransmitterPort;
[ViewVariables]
private string? _selectedReceiverPort;
public SignalPortSelectorBoundUserInterface([NotNull] EntityUid owner, [NotNull] Enum uiKey) : base(owner, uiKey)
{
}
protected override void Open()
{
base.Open();
_menu = new SignalPortSelectorMenu(this);
_menu.OnClose += Close;
_menu.OpenCentered();
}
protected override void UpdateState(BoundUserInterfaceState state)
{
base.UpdateState(state);
switch (state)
{
case SignalPortsState data:
_menu?.UpdateState(data);
_selectedTransmitterPort = null;
_selectedReceiverPort = null;
break;
}
}
public void OnTransmitterPortSelected(string port)
{
_selectedTransmitterPort = port;
if (_selectedReceiverPort != null)
{
SendMessage(new SignalPortSelected(_selectedTransmitterPort, _selectedReceiverPort));
_selectedTransmitterPort = null;
_selectedReceiverPort = null;
}
}
public void OnReceiverPortSelected(string port)
{
_selectedReceiverPort = port;
if (_selectedTransmitterPort != null)
{
SendMessage(new SignalPortSelected(_selectedTransmitterPort, _selectedReceiverPort));
_selectedTransmitterPort = null;
_selectedReceiverPort = null;
}
}
public void OnClearPressed()
{
_selectedTransmitterPort = null;
_selectedReceiverPort = null;
SendMessage(new LinkerClearSelected());
}
public void OnLinkDefaultPressed()
{
_selectedTransmitterPort = null;
_selectedReceiverPort = null;
SendMessage(new LinkerLinkDefaultSelected());
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (!disposing)
return;
_menu?.Dispose();
}
}
}

View File

@@ -1,19 +0,0 @@
<DefaultWindow xmlns="https://spacestation14.io" Title="{Loc signal-port-selector-menu-title}" MinSize="400 200">
<BoxContainer Orientation="Vertical" VerticalExpand="True">
<BoxContainer Orientation="Horizontal" HorizontalExpand="True" VerticalExpand="True">
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.3">
<RichTextLabel Name="HeaderLeft"/>
<BoxContainer Name="ButtonContainerLeft" Orientation="Vertical" VerticalExpand="True" HorizontalExpand="True"/>
</BoxContainer>
<BoxContainer Name="ContainerMiddle" Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.2"/>
<BoxContainer Orientation="Vertical" HorizontalExpand="True" SizeFlagsStretchRatio="0.3">
<RichTextLabel Name="HeaderRight"/>
<BoxContainer Name="ButtonContainerRight" Orientation="Vertical" VerticalExpand="True" HorizontalExpand="True"/>
</BoxContainer>
</BoxContainer>
<BoxContainer Orientation="Horizontal" HorizontalExpand="True">
<Button Name="ButtonClear" Text="{Loc signal-port-selector-menu-clear}"/>
<Button Name="ButtonLinkDefault" Text="{Loc signal-port-selector-menu-link-defaults}"/>
</BoxContainer>
</BoxContainer>
</DefaultWindow>

View File

@@ -1,97 +0,0 @@
using System.Numerics;
using Content.Shared.MachineLinking;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Client.Graphics;
using Robust.Shared.Prototypes;
namespace Content.Client.MachineLinking.UI
{
[GenerateTypedNameReferences]
public sealed partial class SignalPortSelectorMenu : DefaultWindow
{
private SignalPortSelectorBoundUserInterface _bui;
private LinksRender _links;
private ButtonGroup _buttonGroup = new();
private IPrototypeManager _protoMan;
public SignalPortSelectorMenu(SignalPortSelectorBoundUserInterface boundUserInterface)
{
RobustXamlLoader.Load(this);
_bui = boundUserInterface;
_links = new(ButtonContainerLeft, ButtonContainerRight);
ContainerMiddle.AddChild(_links);
ButtonClear.OnPressed += _ => _bui.OnClearPressed();
ButtonLinkDefault.OnPressed += _ => _bui.OnLinkDefaultPressed();
_protoMan = IoCManager.Resolve<IPrototypeManager>();
}
public void UpdateState(SignalPortsState state)
{
HeaderLeft.SetMessage(state.TransmitterName);
ButtonContainerLeft.DisposeAllChildren();
foreach (var port in state.TransmitterPorts)
{
var proto = _protoMan.Index<TransmitterPortPrototype>(port);
var portButton = new Button()
{
Text = Loc.GetString(proto.Name),
ToolTip = Loc.GetString(proto.Description),
ToggleMode = true,
Group = _buttonGroup
};
portButton.OnPressed += _ => _bui.OnTransmitterPortSelected(port);
ButtonContainerLeft.AddChild(portButton);
}
HeaderRight.SetMessage(state.ReceiverName);
ButtonContainerRight.DisposeAllChildren();
foreach (var port in state.ReceiverPorts)
{
var proto = _protoMan.Index<ReceiverPortPrototype>(port);
var portButton = new Button()
{
Text = Loc.GetString(proto.Name),
ToolTip = Loc.GetString(proto.Description),
ToggleMode = true,
Group = _buttonGroup
};
portButton.OnPressed += _ => _bui.OnReceiverPortSelected(port);
ButtonContainerRight.AddChild(portButton);
}
_links.Links = state.Links;
}
private sealed class LinksRender : Control
{
public List<(int, int)> Links = new();
public BoxContainer LeftButton;
public BoxContainer RightButton;
public LinksRender(BoxContainer leftButton, BoxContainer rightButton)
{
LeftButton = leftButton;
RightButton = rightButton;
}
protected override void Draw(DrawingHandleScreen handle)
{
var leftOffset = LeftButton.PixelPosition.Y;
var rightOffset = RightButton.PixelPosition.Y;
foreach (var (left, right) in Links)
{
var leftChild = LeftButton.GetChild(left);
var rightChild = RightButton.GetChild(right);
var y1 = leftChild.PixelPosition.Y + leftChild.PixelHeight / 2 + leftOffset;
var y2 = rightChild.PixelPosition.Y + rightChild.PixelHeight / 2 + rightOffset;
handle.DrawLine(new Vector2(0, y1), new Vector2(PixelWidth, y2), Color.Cyan);
}
}
}
}
}

View File

@@ -1,5 +1,5 @@
using Content.Server.Atmos.Piping.Binary.EntitySystems; using Content.Server.Atmos.Piping.Binary.EntitySystems;
using Content.Shared.MachineLinking; using Content.Shared.DeviceLinking;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.Atmos.Piping.Binary.Components; namespace Content.Server.Atmos.Piping.Binary.Components;
@@ -7,12 +7,12 @@ namespace Content.Server.Atmos.Piping.Binary.Components;
[RegisterComponent, Access(typeof(SignalControlledValveSystem))] [RegisterComponent, Access(typeof(SignalControlledValveSystem))]
public sealed class SignalControlledValveComponent : Component public sealed class SignalControlledValveComponent : Component
{ {
[DataField("openPort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))] [DataField("openPort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string OpenPort = "Open"; public string OpenPort = "Open";
[DataField("closePort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))] [DataField("closePort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string ClosePort = "Close"; public string ClosePort = "Close";
[DataField("togglePort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))] [DataField("togglePort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string TogglePort = "Toggle"; public string TogglePort = "Toggle";
} }

View File

@@ -1,7 +1,6 @@
using Content.Server.Atmos.Piping.Binary.Components; using Content.Server.Atmos.Piping.Binary.Components;
using Content.Server.DeviceLinking.Events; using Content.Server.DeviceLinking.Events;
using Content.Server.DeviceLinking.Systems; using Content.Server.DeviceLinking.Systems;
using Content.Server.MachineLinking.System;
namespace Content.Server.Atmos.Piping.Binary.EntitySystems; namespace Content.Server.Atmos.Piping.Binary.EntitySystems;

View File

@@ -1,6 +1,6 @@
using Content.Shared.Atmos; using Content.Shared.Atmos;
using Content.Shared.Atmos.Piping.Unary.Components; using Content.Shared.Atmos.Piping.Unary.Components;
using Content.Shared.MachineLinking; using Content.Shared.DeviceLinking;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.Atmos.Piping.Unary.Components namespace Content.Server.Atmos.Piping.Unary.Components
@@ -124,10 +124,10 @@ namespace Content.Server.Atmos.Piping.Unary.Components
[DataField("canLink")] [DataField("canLink")]
public readonly bool CanLink = false; public readonly bool CanLink = false;
[DataField("pressurizePort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))] [DataField("pressurizePort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string PressurizePort = "Pressurize"; public string PressurizePort = "Pressurize";
[DataField("depressurizePort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))] [DataField("depressurizePort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string DepressurizePort = "Depressurize"; public string DepressurizePort = "Depressurize";
[ViewVariables(VVAccess.ReadWrite)] [ViewVariables(VVAccess.ReadWrite)]

View File

@@ -33,11 +33,7 @@ using Robust.Shared.Random;
using Robust.Shared.Configuration; using Robust.Shared.Configuration;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Components;
using Content.Shared.Doors.Components;
using Content.Shared.Emag.Systems; using Content.Shared.Emag.Systems;
using Robust.Shared.Audio;
using System.Runtime.InteropServices;
using Content.Server.MachineLinking.Events;
using Content.Server.Popups; using Content.Server.Popups;
using Content.Server.Traits.Assorted; using Content.Server.Traits.Assorted;

View File

@@ -1,4 +1,4 @@
using Content.Shared.MachineLinking; using Content.Shared.DeviceLinking;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.DeviceLinking.Components namespace Content.Server.DeviceLinking.Components
@@ -6,19 +6,19 @@ namespace Content.Server.DeviceLinking.Components
[RegisterComponent] [RegisterComponent]
public sealed class DoorSignalControlComponent : Component public sealed class DoorSignalControlComponent : Component
{ {
[DataField("openPort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))] [DataField("openPort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string OpenPort = "Open"; public string OpenPort = "Open";
[DataField("closePort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))] [DataField("closePort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string ClosePort = "Close"; public string ClosePort = "Close";
[DataField("togglePort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))] [DataField("togglePort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string TogglePort = "Toggle"; public string TogglePort = "Toggle";
[DataField("boltPort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))] [DataField("boltPort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string InBolt = "DoorBolt"; public string InBolt = "DoorBolt";
[DataField("onOpenPort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))] [DataField("onOpenPort", customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>))]
public string OutOpen = "DoorStatus"; public string OutOpen = "DoorStatus";
} }
} }

View File

@@ -1,6 +1,5 @@
using Content.Server.DeviceLinking.Systems; using Content.Server.DeviceLinking.Systems;
using Content.Shared.DeviceLinking; using Content.Shared.DeviceLinking;
using Content.Shared.MachineLinking;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.DeviceLinking.Components; namespace Content.Server.DeviceLinking.Components;
@@ -15,19 +14,19 @@ public sealed class EdgeDetectorComponent : Component
/// <summary> /// <summary>
/// Name of the input port. /// Name of the input port.
/// </summary> /// </summary>
[DataField("inputPort", customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>))] [DataField("inputPort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string InputPort = "Input"; public string InputPort = "Input";
/// <summary> /// <summary>
/// Name of the rising edge output port. /// Name of the rising edge output port.
/// </summary> /// </summary>
[DataField("outputHighPort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))] [DataField("outputHighPort", customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>))]
public string OutputHighPort = "OutputHigh"; public string OutputHighPort = "OutputHigh";
/// <summary> /// <summary>
/// Name of the falling edge output port. /// Name of the falling edge output port.
/// </summary> /// </summary>
[DataField("outputLowPort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))] [DataField("outputLowPort", customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>))]
public string OutputLowPort = "OutputLow"; public string OutputLowPort = "OutputLow";
// Initial state // Initial state

View File

@@ -1,6 +1,5 @@
using Content.Server.DeviceLinking.Systems; using Content.Server.DeviceLinking.Systems;
using Content.Shared.DeviceLinking; using Content.Shared.DeviceLinking;
using Content.Shared.MachineLinking;
using Content.Shared.Tools; using Content.Shared.Tools;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
@@ -36,19 +35,19 @@ public sealed class LogicGateComponent : Component
/// <summary> /// <summary>
/// Name of the first input port. /// Name of the first input port.
/// </summary> /// </summary>
[DataField("inputPortA", customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>))] [DataField("inputPortA", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string InputPortA = "InputA"; public string InputPortA = "InputA";
/// <summary> /// <summary>
/// Name of the second input port. /// Name of the second input port.
/// </summary> /// </summary>
[DataField("inputPortB", customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>))] [DataField("inputPortB", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string InputPortB = "InputB"; public string InputPortB = "InputB";
/// <summary> /// <summary>
/// Name of the output port. /// Name of the output port.
/// </summary> /// </summary>
[DataField("outputPort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))] [DataField("outputPort", customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>))]
public string OutputPort = "Output"; public string OutputPort = "Output";
// Initial state // Initial state

View File

@@ -1,5 +1,5 @@
using Content.Server.DeviceLinking.Systems; using Content.Server.DeviceLinking.Systems;
using Content.Shared.MachineLinking; using Content.Shared.DeviceLinking;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
@@ -15,20 +15,20 @@ public sealed class SignalSwitchComponent : Component
/// <summary> /// <summary>
/// The port that gets signaled when the switch turns on. /// The port that gets signaled when the switch turns on.
/// </summary> /// </summary>
[DataField("onPort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))] [DataField("onPort", customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>))]
public string OnPort = "On"; public string OnPort = "On";
/// <summary> /// <summary>
/// The port that gets signaled when the switch turns off. /// The port that gets signaled when the switch turns off.
/// </summary> /// </summary>
[DataField("offPort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))] [DataField("offPort", customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>))]
public string OffPort = "Off"; public string OffPort = "Off";
/// <summary> /// <summary>
/// The port that gets signaled with the switch's current status. /// 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. /// This is only used if OnPort is different from OffPort, not in the case of a toggle switch.
/// </summary> /// </summary>
[DataField("statusPort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))] [DataField("statusPort", customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>))]
public string StatusPort = "Status"; public string StatusPort = "Status";
[DataField("state")] [DataField("state")]

View File

@@ -1,4 +1,4 @@
using Content.Shared.MachineLinking; using Content.Shared.DeviceLinking;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
@@ -25,13 +25,13 @@ public sealed class SignalTimerComponent : Component
/// <summary> /// <summary>
/// The port that gets signaled when the timer triggers. /// The port that gets signaled when the timer triggers.
/// </summary> /// </summary>
[DataField("triggerPort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>)), ViewVariables(VVAccess.ReadWrite)] [DataField("triggerPort", customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>)), ViewVariables(VVAccess.ReadWrite)]
public string TriggerPort = "Timer"; public string TriggerPort = "Timer";
/// <summary> /// <summary>
/// The port that gets signaled when the timer starts. /// The port that gets signaled when the timer starts.
/// </summary> /// </summary>
[DataField("startPort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>)), ViewVariables(VVAccess.ReadWrite)] [DataField("startPort", customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>)), ViewVariables(VVAccess.ReadWrite)]
public string StartPort = "Start"; public string StartPort = "Start";
/// <summary> /// <summary>

View File

@@ -1,4 +1,4 @@
using Content.Shared.MachineLinking; using Content.Shared.DeviceLinking;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.DeviceLinking.Components namespace Content.Server.DeviceLinking.Components
@@ -12,7 +12,7 @@ namespace Content.Server.DeviceLinking.Components
/// <summary> /// <summary>
/// The port that gets signaled when the switch turns on. /// The port that gets signaled when the switch turns on.
/// </summary> /// </summary>
[DataField("port", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))] [DataField("port", customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>))]
public string Port = "Pressed"; public string Port = "Pressed";
} }
} }

View File

@@ -1,5 +1,4 @@
using Content.Shared.DeviceLinking; using Content.Shared.DeviceLinking;
using Content.Shared.MachineLinking;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.DeviceLinking.Components namespace Content.Server.DeviceLinking.Components
@@ -13,13 +12,13 @@ namespace Content.Server.DeviceLinking.Components
[DataField("nextSignalLeft")] [DataField("nextSignalLeft")]
public bool NextSignalLeft; public bool NextSignalLeft;
[DataField("leftPort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))] [DataField("leftPort", customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>))]
public string LeftPort = "Left"; public string LeftPort = "Left";
[DataField("rightPort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))] [DataField("rightPort", customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>))]
public string RightPort = "Right"; public string RightPort = "Right";
[DataField("middlePort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))] [DataField("middlePort", customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>))]
public string MiddlePort = "Middle"; public string MiddlePort = "Middle";
} }
} }

View File

@@ -1,5 +1,4 @@
using Content.Server.DeviceLinking.Components; using Content.Server.DeviceLinking.Components;
using Content.Server.MachineLinking.System;
namespace Content.Server.DeviceLinking.Systems; namespace Content.Server.DeviceLinking.Systems;

View File

@@ -2,9 +2,7 @@
using Content.Server.DeviceNetwork; using Content.Server.DeviceNetwork;
using Content.Server.DeviceNetwork.Components; using Content.Server.DeviceNetwork.Components;
using Content.Server.DeviceNetwork.Systems; using Content.Server.DeviceNetwork.Systems;
using Content.Server.MachineLinking.Components;
using Content.Shared.DeviceLinking; using Content.Shared.DeviceLinking;
using Robust.Shared.Utility;
namespace Content.Server.DeviceLinking.Systems; namespace Content.Server.DeviceLinking.Systems;
@@ -15,7 +13,6 @@ public sealed class DeviceLinkSystem : SharedDeviceLinkSystem
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
SubscribeLocalEvent<SignalTransmitterComponent, ComponentStartup>(OnTransmitterStartup);
SubscribeLocalEvent<DeviceLinkSinkComponent, DeviceNetworkPacketEvent>(OnPacketReceived); SubscribeLocalEvent<DeviceLinkSinkComponent, DeviceNetworkPacketEvent>(OnPacketReceived);
} }
@@ -36,33 +33,7 @@ public sealed class DeviceLinkSystem : SharedDeviceLinkSystem
} }
} }
/// <summary> #region Sending & Receiving
/// Moves existing links from machine linking to device linking to ensure linked things still work even when the map wasn't updated yet
/// </summary>
public void OnTransmitterStartup(EntityUid sourceUid, SignalTransmitterComponent transmitterComponent, ComponentStartup args)
{
var sourceComponent = EnsureComp<DeviceLinkSourceComponent>(sourceUid);
Dictionary<EntityUid, List<(string, string)>> outputs = new();
foreach (var (transmitterPort, receiverPorts) in transmitterComponent.Outputs)
{
foreach (var receiverPort in receiverPorts)
{
// Throw error if component is missing.
EnsureComp<DeviceLinkSinkComponent>(receiverPort.Uid);
outputs.GetOrNew(receiverPort.Uid).Add((transmitterPort, receiverPort.Port));
}
}
foreach (var (sinkUid, links) in outputs)
{
SaveLinks(null, sourceUid, sinkUid, links, sourceComponent);
}
RemCompDeferred<SignalTransmitterComponent>(sourceUid);
}
#region Sending & Receiving
/// <summary> /// <summary>
/// Sends a network payload directed at the sink entity. /// Sends a network payload directed at the sink entity.
/// Just raises a <see cref="SignalReceivedEvent"/> without data if the source or the sink doesn't have a <see cref="DeviceNetworkComponent"/> /// Just raises a <see cref="SignalReceivedEvent"/> without data if the source or the sink doesn't have a <see cref="DeviceNetworkComponent"/>

View File

@@ -1,6 +1,5 @@
using Content.Server.DeviceLinking.Components; using Content.Server.DeviceLinking.Components;
using Content.Server.DeviceNetwork; using Content.Server.DeviceNetwork;
using Content.Server.MachineLinking.Events;
using SignalReceivedEvent = Content.Server.DeviceLinking.Events.SignalReceivedEvent; using SignalReceivedEvent = Content.Server.DeviceLinking.Events.SignalReceivedEvent;
namespace Content.Server.DeviceLinking.Systems; namespace Content.Server.DeviceLinking.Systems;

View File

@@ -1,13 +1,10 @@
using Content.Server.DeviceLinking.Components; using Content.Server.DeviceLinking.Components;
using Content.Server.DeviceNetwork; using Content.Server.DeviceNetwork;
using Content.Server.MachineLinking.Events;
using Content.Shared.DeviceLinking; using Content.Shared.DeviceLinking;
using Content.Shared.Examine; using Content.Shared.Examine;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Tools; using Content.Shared.Tools;
using Content.Shared.Popups; using Content.Shared.Popups;
using Robust.Shared.Audio;
using Robust.Shared.Utility;
using SignalReceivedEvent = Content.Server.DeviceLinking.Events.SignalReceivedEvent; using SignalReceivedEvent = Content.Server.DeviceLinking.Events.SignalReceivedEvent;
namespace Content.Server.DeviceLinking.Systems; namespace Content.Server.DeviceLinking.Systems;

View File

@@ -1,10 +1,7 @@
using Content.Server.DeviceLinking.Components; using Content.Server.DeviceLinking.Components;
using Content.Server.DeviceNetwork; using Content.Server.DeviceNetwork;
using Content.Server.MachineLinking.System;
using Content.Shared.Audio;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Player;
namespace Content.Server.DeviceLinking.Systems; namespace Content.Server.DeviceLinking.Systems;

View File

@@ -9,7 +9,6 @@ using Content.Shared.Doors.Systems;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Robust.Server.GameObjects; using Robust.Server.GameObjects;
using Content.Shared.Wires; using Content.Shared.Wires;
using Content.Server.MachineLinking.System;
namespace Content.Server.Doors.Systems namespace Content.Server.Doors.Systems
{ {
@@ -17,7 +16,6 @@ namespace Content.Server.Doors.Systems
{ {
[Dependency] private readonly WiresSystem _wiresSystem = default!; [Dependency] private readonly WiresSystem _wiresSystem = default!;
[Dependency] private readonly PowerReceiverSystem _power = default!; [Dependency] private readonly PowerReceiverSystem _power = default!;
[Dependency] private readonly SignalLinkerSystem _signalSystem = default!;
[Dependency] private readonly DoorBoltSystem _bolts = default!; [Dependency] private readonly DoorBoltSystem _bolts = default!;
public override void Initialize() public override void Initialize()

View File

@@ -2,10 +2,7 @@ using Content.Server.Access;
using Content.Server.Atmos.Components; using Content.Server.Atmos.Components;
using Content.Server.Atmos.EntitySystems; using Content.Server.Atmos.EntitySystems;
using Content.Server.Construction; using Content.Server.Construction;
using Content.Server.MachineLinking.System;
using Content.Server.Tools.Systems; using Content.Server.Tools.Systems;
using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
using Content.Shared.Database; using Content.Shared.Database;
using Content.Shared.Doors; using Content.Shared.Doors;
using Content.Shared.Doors.Components; using Content.Shared.Doors.Components;
@@ -15,8 +12,6 @@ using Content.Shared.Interaction;
using Content.Shared.Tools.Components; using Content.Shared.Tools.Components;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Containers;
using System.Linq;
using Content.Server.Administration.Logs; using Content.Server.Administration.Logs;
using Content.Server.Power.EntitySystems; using Content.Server.Power.EntitySystems;
using Content.Shared.Tools; using Content.Shared.Tools;

View File

@@ -1,4 +1,4 @@
using Content.Shared.MachineLinking; using Content.Shared.DeviceLinking;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Server.Explosion.Components namespace Content.Server.Explosion.Components
@@ -9,7 +9,7 @@ namespace Content.Server.Explosion.Components
[RegisterComponent] [RegisterComponent]
public sealed class TriggerOnSignalComponent : Component public sealed class TriggerOnSignalComponent : Component
{ {
[DataField("port", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))] [DataField("port", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string Port = "Trigger"; public string Port = "Trigger";
} }
} }

View File

@@ -1,8 +1,7 @@
using System.Threading;
using Content.Server.Light.EntitySystems; using Content.Server.Light.EntitySystems;
using Content.Shared.Damage; using Content.Shared.Damage;
using Content.Shared.DeviceLinking;
using Content.Shared.Light.Component; using Content.Shared.Light.Component;
using Content.Shared.MachineLinking;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Containers; using Robust.Shared.Containers;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
@@ -55,13 +54,13 @@ namespace Content.Server.Light.Components
[ViewVariables] [ViewVariables]
public TimeSpan? LastGhostBlink; public TimeSpan? LastGhostBlink;
[DataField("onPort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))] [DataField("onPort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string OnPort = "On"; public string OnPort = "On";
[DataField("offPort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))] [DataField("offPort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string OffPort = "Off"; public string OffPort = "Off";
[DataField("togglePort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))] [DataField("togglePort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string TogglePort = "Toggle"; public string TogglePort = "Toggle";
/// <summary> /// <summary>

View File

@@ -1,35 +0,0 @@
using Content.Shared.Tools;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Utility;
namespace Content.Server.MachineLinking.Components
{
[RegisterComponent]
public sealed class SignalLinkerComponent : Component
{
[ViewVariables]
public EntityUid? SavedTransmitter;
[ViewVariables]
public EntityUid? SavedReceiver;
/// <summary>
/// Optional tool quality required for linker to work.
/// If linker entity doesn't have this quality it will ignore any interaction.
/// </summary>
[DataField("requiredQuality", customTypeSerializer: typeof(PrototypeIdSerializer<ToolQualityPrototype>))]
[ViewVariables(VVAccess.ReadWrite)]
public string? RequiredQuality;
// Utility functions below to deal with linking entities with both Transmit and Receive components.
public bool LinkTX()
{
return SavedTransmitter == null;
}
public bool LinkRX()
{
return SavedTransmitter != null && SavedReceiver == null;
}
}
}

View File

@@ -1,12 +0,0 @@
using Content.Server.MachineLinking.System;
namespace Content.Server.MachineLinking.Components
{
[RegisterComponent]
[Access(typeof(SignalLinkerSystem))]
public sealed class SignalReceiverComponent : Component
{
[DataField("inputs")]
public Dictionary<string, List<PortIdentifier>> Inputs = new();
}
}

View File

@@ -1,47 +0,0 @@
using Content.Server.DeviceLinking.Components;
using Content.Server.MachineLinking.Events;
using Content.Server.MachineLinking.System;
namespace Content.Server.MachineLinking.Components
{
[DataDefinition]
public readonly struct PortIdentifier
{
[DataField("uid")]
public readonly EntityUid Uid;
[DataField("port")]
public readonly string Port;
public PortIdentifier(EntityUid uid, string port)
{
Uid = uid;
Port = port;
}
}
[RegisterComponent]
[Access(typeof(SignalLinkerSystem))]
public sealed class SignalTransmitterComponent : Component
{
/// <summary>
/// How far the device can transmit a signal wirelessly.
/// Devices farther than this range can still transmit if they are
/// on the same powernet.
/// </summary>
[DataField("transmissionRange")]
[ViewVariables(VVAccess.ReadWrite)]
public float TransmissionRange = 30f;
/*
* Remember last output state to avoid re-raising a SignalChangedEvent if the signal
* level hasn't actually changed.
*/
[ViewVariables(VVAccess.ReadWrite)]
public SignalState LastState = SignalState.Low;
[DataField("outputs")]
[Access(typeof(SignalLinkerSystem), Other = AccessPermissions.ReadExecute)] // FIXME Friends
public Dictionary<string, List<PortIdentifier>> Outputs = new();
}
}

View File

@@ -1,18 +0,0 @@
using Content.Server.DeviceLinking.Components;
namespace Content.Server.MachineLinking.Events
{
public sealed class SignalReceivedEvent : EntityEventArgs
{
public readonly string Port;
public readonly SignalState State;
public readonly EntityUid? Trigger;
public SignalReceivedEvent(string port, EntityUid? trigger, SignalState state)
{
Port = port;
Trigger = trigger;
State = state;
}
}
}

View File

@@ -1,7 +0,0 @@
namespace Content.Server.MachineLinking.Exceptions
{
public sealed class InvalidPortValueException : Exception
{
}
}

View File

@@ -1,7 +0,0 @@
namespace Content.Server.MachineLinking.Exceptions
{
public sealed class LinkAlreadyRegisteredException : Exception
{
}
}

View File

@@ -1,7 +0,0 @@
namespace Content.Server.MachineLinking.Exceptions
{
public sealed class NoSignalValueProvidedException : Exception
{
}
}

View File

@@ -1,7 +0,0 @@
namespace Content.Server.MachineLinking.Exceptions
{
public sealed class PortNotFoundException : Exception
{
}
}

View File

@@ -1,515 +0,0 @@
using System.Linq;
using System.Diagnostics.CodeAnalysis;
using Content.Server.DeviceLinking.Components;
using Content.Server.MachineLinking.Components;
using Content.Server.Power.Components;
using Content.Server.Tools;
using Content.Shared.DeviceLinking.Events;
using Content.Shared.Interaction;
using Content.Shared.MachineLinking;
using Content.Shared.Popups;
using Robust.Server.GameObjects;
using Content.Shared.Verbs;
using Robust.Shared.Prototypes;
using SignalReceivedEvent = Content.Server.DeviceLinking.Events.SignalReceivedEvent;
namespace Content.Server.MachineLinking.System
{
public sealed class SignalLinkerSystem : EntitySystem
{
[Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!;
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
[Dependency] private readonly IPrototypeManager _protoMan = default!;
[Dependency] private readonly ToolSystem _tools = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<SignalTransmitterComponent, ComponentRemove>(OnTransmitterRemoved);
SubscribeLocalEvent<SignalTransmitterComponent, InteractUsingEvent>(OnTransmitterInteractUsing);
SubscribeLocalEvent<SignalTransmitterComponent, GetVerbsEvent<AlternativeVerb>>(OnGetTransmitterVerbs);
SubscribeLocalEvent<SignalReceiverComponent, ComponentStartup>(OnReceiverStartup);
SubscribeLocalEvent<SignalReceiverComponent, ComponentRemove>(OnReceiverRemoved);
SubscribeLocalEvent<SignalReceiverComponent, InteractUsingEvent>(OnReceiverInteractUsing);
SubscribeLocalEvent<SignalReceiverComponent, GetVerbsEvent<AlternativeVerb>>(OnGetReceiverVerbs);
SubscribeLocalEvent<SignalLinkerComponent, SignalPortSelected>(OnSignalPortSelected);
SubscribeLocalEvent<SignalLinkerComponent, LinkerClearSelected>(OnLinkerClearSelected);
SubscribeLocalEvent<SignalLinkerComponent, LinkerLinkDefaultSelected>(OnLinkerLinkDefaultSelected);
SubscribeLocalEvent<SignalLinkerComponent, BoundUIClosedEvent>(OnLinkerUIClosed);
}
/// <summary>
/// Convenience function to add several ports to an entity.
/// </summary>
public void EnsureReceiverPorts(EntityUid uid, params string[] ports)
{
var comp = EnsureComp<SignalReceiverComponent>(uid);
foreach (var port in ports)
{
comp.Inputs.TryAdd(port, new List<PortIdentifier>());
}
}
public void EnsureTransmitterPorts(EntityUid uid, params string[] ports)
{
var comp = EnsureComp<SignalTransmitterComponent>(uid);
foreach (var port in ports)
{
comp.Outputs.TryAdd(port, new List<PortIdentifier>());
}
}
/// <summary>
/// Add an alt-click verb to allow users to link the default ports, without needing to open the UI.
/// </summary>
private void OnGetReceiverVerbs(EntityUid uid, SignalReceiverComponent component, GetVerbsEvent<AlternativeVerb> args)
{
if (!args.CanAccess || !args.CanInteract)
return;
if (!TryComp(args.Using, out SignalLinkerComponent? linker) ||
!IsLinkerInteractable(args.Using.Value, linker))
{
return;
}
var verb = new AlternativeVerb()
{
Text = Loc.GetString("signal-linking-verb-text-link-default"),
IconEntity = args.Using
};
args.Verbs.Add(verb);
if (linker.SavedTransmitter != null)
{
verb.Act = () =>
{
var msg = TryLinkDefaults(uid, linker.SavedTransmitter.Value, args.User, component)
? Loc.GetString("signal-linking-verb-success", ("machine", linker.SavedTransmitter.Value))
: Loc.GetString("signal-linking-verb-fail", ("machine", linker.SavedTransmitter.Value));
_popupSystem.PopupEntity(msg, uid, args.User);
};
return;
}
verb.Disabled = true;
verb.Message = Loc.GetString("signal-linking-verb-disabled-no-transmitter");
}
private void OnGetTransmitterVerbs(EntityUid uid, SignalTransmitterComponent component, GetVerbsEvent<AlternativeVerb> args)
{
if (!args.CanAccess || !args.CanInteract)
return;
if (!TryComp(args.Using, out SignalLinkerComponent? linker)
|| !IsLinkerInteractable(args.Using.Value, linker))
return;
AlternativeVerb verb = new()
{
Text = Loc.GetString("signal-linking-verb-text-link-default"),
IconEntity = args.Using
};
args.Verbs.Add(verb);
if (linker.SavedReceiver != null)
{
verb.Act = () =>
{
var msg = TryLinkDefaults(linker.SavedReceiver.Value, uid, args.User, null, component)
? Loc.GetString("signal-linking-verb-success", ("machine", linker.SavedReceiver.Value))
: Loc.GetString("signal-linking-verb-fail", ("machine", linker.SavedReceiver.Value));
_popupSystem.PopupEntity(msg, uid, args.User);
};
return;
}
verb.Disabled = true;
verb.Message = Loc.GetString("signal-linking-verb-disabled-no-receiver");
}
public void InvokePort(EntityUid uid, string port, SignalTransmitterComponent? component = null)
{
InvokePort(uid, port, SignalState.Momentary, component);
}
public void InvokePort(EntityUid uid, string port, SignalState state, SignalTransmitterComponent? component = null)
{
if (!Resolve(uid, ref component))
return;
if (state != SignalState.Momentary && state == component.LastState)
{
// no change in output signal
return;
}
if (!component.Outputs.TryGetValue(port, out var receivers))
return;
component.LastState = state;
foreach (var receiver in receivers)
{
var eventArgs = new SignalReceivedEvent(receiver.Port, uid);
RaiseLocalEvent(receiver.Uid, ref eventArgs);
}
}
private void OnReceiverStartup(EntityUid uid, SignalReceiverComponent receiver, ComponentStartup args)
{
RemCompDeferred<SignalReceiverComponent>(uid);
}
private void OnTransmitterRemoved(EntityUid uid, SignalTransmitterComponent transmitter, ComponentRemove args)
{
Dictionary<EntityUid, SignalReceiverComponent?> uidCache = new();
foreach (var tport in transmitter.Outputs)
foreach (var rport in tport.Value)
{
if (!uidCache.TryGetValue(rport.Uid, out var receiver))
uidCache.Add(rport.Uid, receiver = CompOrNull<SignalReceiverComponent>(rport.Uid));
if (receiver != null && receiver.Inputs.TryGetValue(rport.Port, out var rpv))
rpv.Remove(new(uid, tport.Key));
}
}
private void OnReceiverRemoved(EntityUid uid, SignalReceiverComponent component, ComponentRemove args)
{
Dictionary<EntityUid, SignalTransmitterComponent?> uidCache = new();
foreach (var rport in component.Inputs)
foreach (var tport in rport.Value)
{
if (!uidCache.TryGetValue(tport.Uid, out var transmitter))
uidCache.Add(tport.Uid, transmitter = CompOrNull<SignalTransmitterComponent>(tport.Uid));
if (transmitter != null && transmitter.Outputs.TryGetValue(tport.Port, out var receivers))
receivers.Remove(new(uid, rport.Key));
}
}
private void OnTransmitterInteractUsing(EntityUid uid, SignalTransmitterComponent transmitter, InteractUsingEvent args)
{
if (args.Handled)
return;
if (!TryComp(args.Used, out SignalLinkerComponent? linker) || !IsLinkerInteractable(args.Used, linker) ||
!TryComp(args.User, out ActorComponent? actor))
return;
if (!linker.LinkTX())
return;
linker.SavedTransmitter = uid;
if (!TryComp(linker.SavedReceiver, out SignalReceiverComponent? receiver))
{
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-saved", ("machine", uid)),
args.User, PopupType.Medium);
args.Handled = true;
return;
}
if (TryGetOrOpenUI(args.Used, out var bui, actor))
{
TryUpdateUI(args.Used, uid, linker.SavedReceiver!.Value, bui, transmitter, receiver);
args.Handled = true;
}
}
private void OnReceiverInteractUsing(EntityUid uid, SignalReceiverComponent receiver, InteractUsingEvent args)
{
if (args.Handled)
return;
if (!TryComp(args.Used, out SignalLinkerComponent? linker) || !IsLinkerInteractable(args.Used, linker) ||
!TryComp(args.User, out ActorComponent? actor))
return;
if (!linker.LinkRX())
return;
linker.SavedReceiver = uid;
if (!TryComp(linker.SavedTransmitter, out SignalTransmitterComponent? transmitter))
{
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-saved", ("machine", uid)),
args.User, PopupType.Medium);
args.Handled = true;
return;
}
if (TryGetOrOpenUI(args.Used, out var bui, actor))
{
TryUpdateUI(args.Used, linker.SavedTransmitter!.Value, uid, bui, transmitter, receiver);
args.Handled = true;
}
}
private bool TryGetOrOpenUI(EntityUid linkerUid, [NotNullWhen(true)] out BoundUserInterface? bui, ActorComponent actor)
{
if (_userInterfaceSystem.TryGetUi(linkerUid, SignalLinkerUiKey.Key, out bui))
{
_userInterfaceSystem.OpenUi(bui, actor.PlayerSession);
return true;
}
return false;
}
private bool TryUpdateUI(EntityUid linkerUid, EntityUid transmitterUid, EntityUid receiverUid, BoundUserInterface? bui = null, SignalTransmitterComponent? transmitter = null, SignalReceiverComponent? receiver = null)
{
if (!Resolve(transmitterUid, ref transmitter) || !Resolve(receiverUid, ref receiver))
return false;
if (bui == null && !_userInterfaceSystem.TryGetUi(linkerUid, SignalLinkerUiKey.Key, out bui))
return false;
var outKeys = transmitter.Outputs.Keys.ToList();
var inKeys = receiver.Inputs.Keys.ToList();
List<(int, int)> links = new();
for (var i = 0; i < outKeys.Count; i++)
{
foreach (var re in transmitter.Outputs[outKeys[i]])
{
if (re.Uid == receiverUid)
links.Add((i, inKeys.IndexOf(re.Port)));
}
}
UserInterfaceSystem.SetUiState(bui, new SignalPortsState(
$"{Name(transmitterUid)} ({transmitterUid})",
outKeys,
$"{Name(receiverUid)} ({receiverUid})",
inKeys,
links
));
return true;
}
private bool TryLink(EntityUid transmitterUid, EntityUid receiverUid, SignalPortSelected args, EntityUid? user, bool quiet = false, bool checkRange = true, SignalTransmitterComponent? transmitter = null, SignalReceiverComponent? receiver = null)
{
if (!Resolve(transmitterUid, ref transmitter) || !Resolve(receiverUid, ref receiver))
return false;
if (!transmitter.Outputs.TryGetValue(args.TransmitterPort, out var linkedReceivers)
|| !receiver.Inputs.TryGetValue(args.ReceiverPort, out var linkedTransmitters))
return false;
quiet |= !user.HasValue;
// Does the link already exist? Under the assumption that nothing has broken, lets only check the
// transmitter ports.
foreach (var identifier in linkedTransmitters)
{
if (identifier.Uid == transmitterUid && identifier.Port == args.TransmitterPort)
return true;
}
if (checkRange && !IsInRange(transmitterUid, receiverUid, transmitter, receiver))
{
if (!quiet)
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-out-of-range"), user!.Value);
return false;
}
// allow other systems to refuse the connection
var linkAttempt = new LinkAttemptEvent(user, transmitterUid, args.TransmitterPort, receiverUid, args.ReceiverPort);
RaiseLocalEvent(transmitterUid, linkAttempt, true);
if (linkAttempt.Cancelled)
{
if (!quiet)
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-connection-refused", ("machine", transmitterUid)), user!.Value);
return false;
}
RaiseLocalEvent(receiverUid, linkAttempt, true);
if (linkAttempt.Cancelled)
{
if (!quiet)
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-connection-refused", ("machine", receiverUid)), user!.Value);
return false;
}
linkedReceivers.Add(new(receiverUid, args.ReceiverPort));
linkedTransmitters.Add(new(transmitterUid, args.TransmitterPort));
if (!quiet)
{
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-linked-port",
("machine1", transmitterUid), ("port1", PortName<TransmitterPortPrototype>(args.TransmitterPort)),
("machine2", receiverUid), ("port2", PortName<ReceiverPortPrototype>(args.ReceiverPort))),
user!.Value, PopupType.Medium);
}
var newLink = new NewLinkEvent(user, transmitterUid, args.TransmitterPort, receiverUid, args.ReceiverPort);
RaiseLocalEvent(receiverUid, newLink);
RaiseLocalEvent(transmitterUid, newLink);
return true;
}
private void OnSignalPortSelected(EntityUid uid, SignalLinkerComponent linker, SignalPortSelected args)
{
if (!TryComp(linker.SavedTransmitter, out SignalTransmitterComponent? transmitter) ||
!TryComp(linker.SavedReceiver, out SignalReceiverComponent? receiver) ||
!transmitter.Outputs.TryGetValue(args.TransmitterPort, out var receivers) ||
!receiver.Inputs.TryGetValue(args.ReceiverPort, out var transmitters))
return;
if (args.Session.AttachedEntity is not { Valid: true } attached)
return;
var receiverUid = linker.SavedReceiver.Value;
var transmitterUid = linker.SavedTransmitter.Value;
if (receivers.Contains(new(receiverUid, args.ReceiverPort)) ||
transmitters.Contains(new(transmitterUid, args.TransmitterPort)))
{
// link already exists, remove it
if (receivers.Remove(new(receiverUid, args.ReceiverPort)) &&
transmitters.Remove(new(transmitterUid, args.TransmitterPort)))
{
RaiseLocalEvent(receiverUid, new PortDisconnectedEvent(args.ReceiverPort), true);
RaiseLocalEvent(transmitterUid, new PortDisconnectedEvent(args.TransmitterPort), true);
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-unlinked-port",
("machine1", transmitterUid), ("port1", PortName<TransmitterPortPrototype>(args.TransmitterPort)),
("machine2", receiverUid), ("port2", PortName<ReceiverPortPrototype>(args.ReceiverPort))),
attached, PopupType.Medium);
}
else
{ // something weird happened
// TODO log error
}
}
else
{
TryLink(transmitterUid, receiverUid, args, attached, transmitter: transmitter, receiver: receiver);
}
TryUpdateUI(uid, transmitterUid, receiverUid, transmitter: transmitter, receiver: receiver);
}
/// <summary>
/// Convenience function to retrieve the name of a port prototype.
/// </summary>
/// <param name="port"></param>
/// <returns></returns>
public string PortName<TPort>(string port) where TPort : MachinePortPrototype, IPrototype
{
if (!_protoMan.TryIndex<TPort>(port, out var proto))
return port;
return Loc.GetString(proto.Name);
}
private void OnLinkerClearSelected(EntityUid uid, SignalLinkerComponent linker, LinkerClearSelected args)
{
if (!TryComp(linker.SavedTransmitter, out SignalTransmitterComponent? transmitter) ||
!TryComp(linker.SavedReceiver, out SignalReceiverComponent? receiver))
return;
var transmitterUid = linker.SavedTransmitter.Value;
var receiverUid = linker.SavedReceiver.Value;
foreach (var (port, receivers) in transmitter.Outputs)
{
if (receivers.RemoveAll(id => id.Uid == receiverUid) > 0)
RaiseLocalEvent(transmitterUid, new PortDisconnectedEvent(port), true);
}
foreach (var (port, transmitters) in receiver.Inputs)
{
if (transmitters.RemoveAll(id => id.Uid == transmitterUid) > 0)
RaiseLocalEvent(receiverUid, new PortDisconnectedEvent(port), true);
}
TryUpdateUI(uid, transmitterUid, receiverUid, transmitter: transmitter, receiver: receiver);
}
private void OnLinkerLinkDefaultSelected(EntityUid uid, SignalLinkerComponent linker, LinkerLinkDefaultSelected args)
{
if (!TryComp(linker.SavedTransmitter, out SignalTransmitterComponent? transmitter) ||
!TryComp(linker.SavedReceiver, out SignalReceiverComponent? receiver))
return;
if (args.Session.AttachedEntity is not { Valid: true } user)
return;
var transmitterUid = linker.SavedTransmitter!.Value;
var receiverUid = linker.SavedReceiver!.Value;
TryLinkDefaults(receiverUid, transmitterUid, user, receiver, transmitter);
TryUpdateUI(uid, transmitterUid, receiverUid, transmitter: transmitter, receiver: receiver);
}
/// <summary>
/// Attempt to link all default ports connections. Returns true if all links succeeded. Otherwise returns
/// false.
/// </summary>
public bool TryLinkDefaults(EntityUid receiverUid, EntityUid transmitterUid, EntityUid? user,
SignalReceiverComponent? receiver = null, SignalTransmitterComponent? transmitter = null)
{
if (!Resolve(receiverUid, ref receiver, false) || !Resolve(transmitterUid, ref transmitter, false))
return false;
if (!IsInRange(transmitterUid, receiverUid, transmitter, receiver))
return false;
var allLinksSucceeded = true;
// First, disconnect existing links.
foreach (var (port, receivers) in transmitter.Outputs)
{
if (receivers.RemoveAll(id => id.Uid == receiverUid) > 0)
RaiseLocalEvent(transmitterUid, new PortDisconnectedEvent(port), true);
}
foreach (var (port, transmitters) in receiver.Inputs)
{
if (transmitters.RemoveAll(id => id.Uid == transmitterUid) > 0)
RaiseLocalEvent(receiverUid, new PortDisconnectedEvent(port), true);
}
// Then make any valid default connections.
foreach (var outPort in transmitter.Outputs.Keys)
{
var prototype = _protoMan.Index<TransmitterPortPrototype>(outPort);
if (prototype.DefaultLinks == null)
continue;
foreach (var inPort in prototype.DefaultLinks)
{
if (receiver.Inputs.ContainsKey(inPort))
allLinksSucceeded &= TryLink(transmitterUid, receiverUid, new(outPort, inPort), user, quiet: true, checkRange: false, transmitter: transmitter, receiver: receiver);
}
}
return allLinksSucceeded;
}
private void OnLinkerUIClosed(EntityUid uid, SignalLinkerComponent component, BoundUIClosedEvent args)
{
component.SavedTransmitter = null;
component.SavedReceiver = null;
}
private bool IsInRange(EntityUid transmitterUid, EntityUid receiverUid, SignalTransmitterComponent transmitterComponent, SignalReceiverComponent _)
{
if (TryComp(transmitterUid, out ApcPowerReceiverComponent? transmitterPower) &&
TryComp(receiverUid, out ApcPowerReceiverComponent? receiverPower) &&
transmitterPower.Provider?.Net == receiverPower.Provider?.Net)
return true;
// TODO: As elsewhere don't use mappos inrange.
return Comp<TransformComponent>(transmitterUid).MapPosition.InRange(
Comp<TransformComponent>(receiverUid).MapPosition, transmitterComponent.TransmissionRange);
}
private bool IsLinkerInteractable(EntityUid uid, SignalLinkerComponent linkerComponent)
{
var quality = linkerComponent.RequiredQuality;
return quality == null || _tools.HasQuality(uid, quality);
}
}
}

View File

@@ -1,7 +1,5 @@
using Content.Server.DeviceLinking.Events; using Content.Server.DeviceLinking.Events;
using Content.Server.DeviceLinking.Systems; using Content.Server.DeviceLinking.Systems;
using Content.Server.MachineLinking.System;
using Content.Server.Materials; using Content.Server.Materials;
using Content.Server.Power.Components; using Content.Server.Power.Components;
using Content.Shared.Conveyor; using Content.Shared.Conveyor;

View File

@@ -1,8 +1,7 @@
using Content.Shared.MachineLinking; using Content.Shared.DeviceLinking;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Utility;
namespace Content.Server.Xenoarchaeology.Equipment.Components; namespace Content.Server.Xenoarchaeology.Equipment.Components;
@@ -22,7 +21,7 @@ public sealed class AnalysisConsoleComponent : Component
/// <summary> /// <summary>
/// The machine linking port for the analyzer /// The machine linking port for the analyzer
/// </summary> /// </summary>
[DataField("linkingPort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))] [DataField("linkingPort", customTypeSerializer: typeof(PrototypeIdSerializer<SourcePortPrototype>))]
public readonly string LinkingPort = "ArtifactAnalyzerSender"; public readonly string LinkingPort = "ArtifactAnalyzerSender";
/// <summary> /// <summary>

View File

@@ -1,6 +1,5 @@
using System.Linq; using System.Linq;
using Content.Server.Construction; using Content.Server.Construction;
using Content.Server.MachineLinking.Components;
using Content.Server.Paper; using Content.Server.Paper;
using Content.Server.Power.Components; using Content.Server.Power.Components;
using Content.Server.Research.Systems; using Content.Server.Research.Systems;
@@ -9,6 +8,7 @@ using Content.Server.Xenoarchaeology.Equipment.Components;
using Content.Server.Xenoarchaeology.XenoArtifacts; using Content.Server.Xenoarchaeology.XenoArtifacts;
using Content.Server.Xenoarchaeology.XenoArtifacts.Events; using Content.Server.Xenoarchaeology.XenoArtifacts.Events;
using Content.Shared.Audio; using Content.Shared.Audio;
using Content.Shared.DeviceLinking;
using Content.Shared.DeviceLinking.Events; using Content.Shared.DeviceLinking.Events;
using Content.Shared.Popups; using Content.Shared.Popups;
using Content.Shared.Research.Components; using Content.Shared.Research.Components;
@@ -153,14 +153,14 @@ public sealed class ArtifactAnalyzerSystem : EntitySystem
private void OnMapInit(EntityUid uid, ArtifactAnalyzerComponent component, MapInitEvent args) private void OnMapInit(EntityUid uid, ArtifactAnalyzerComponent component, MapInitEvent args)
{ {
if (!TryComp<SignalReceiverComponent>(uid, out var receiver)) if (!TryComp<DeviceLinkSinkComponent>(uid, out var sink))
return; return;
foreach (var port in receiver.Inputs.Values.SelectMany(ports => ports)) foreach (var source in sink.LinkedSources)
{ {
if (!TryComp<AnalysisConsoleComponent>(port.Uid, out var analysis)) if (!TryComp<AnalysisConsoleComponent>(source, out var analysis))
continue; continue;
component.Console = port.Uid; component.Console = source;
analysis.AnalyzerEntity = uid; analysis.AnalyzerEntity = uid;
return; return;
} }

View File

@@ -1,5 +1,5 @@
using Content.Shared.Construction.Prototypes; using Content.Shared.Construction.Prototypes;
using Content.Shared.MachineLinking; using Content.Shared.DeviceLinking;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
@@ -55,6 +55,6 @@ public sealed class CargoTelepadComponent : Component
[DataField("printerOutput", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>)), ViewVariables(VVAccess.ReadWrite)] [DataField("printerOutput", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>)), ViewVariables(VVAccess.ReadWrite)]
public string PrinterOutput = "PaperCargoInvoice"; public string PrinterOutput = "PaperCargoInvoice";
[DataField("receiverPort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>)), ViewVariables(VVAccess.ReadWrite)] [DataField("receiverPort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>)), ViewVariables(VVAccess.ReadWrite)]
public string ReceiverPort = "OrderReceiver"; public string ReceiverPort = "OrderReceiver";
} }

View File

@@ -1,4 +1,4 @@
using Content.Shared.MachineLinking; using Content.Shared.DeviceLinking;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
@@ -31,13 +31,13 @@ public sealed class ConveyorComponent : Component
[ViewVariables] [ViewVariables]
public bool Powered; public bool Powered;
[DataField("forwardPort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))] [DataField("forwardPort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string ForwardPort = "Forward"; public string ForwardPort = "Forward";
[DataField("reversePort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))] [DataField("reversePort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string ReversePort = "Reverse"; public string ReversePort = "Reverse";
[DataField("offPort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))] [DataField("offPort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string OffPort = "Off"; public string OffPort = "Off";
[ViewVariables] [ViewVariables]

View File

@@ -153,6 +153,7 @@ public abstract class SharedDeviceLinkSystem : EntitySystem
foreach (var port in ports) foreach (var port in ports)
{ {
DebugTools.Assert(_prototypeManager.HasIndex<SourcePortPrototype>(port));
comp.Ports?.Add(port); comp.Ports?.Add(port);
} }
} }
@@ -167,6 +168,7 @@ public abstract class SharedDeviceLinkSystem : EntitySystem
foreach (var port in ports) foreach (var port in ports)
{ {
DebugTools.Assert(_prototypeManager.HasIndex<SinkPortPrototype>(port));
comp.Ports?.Add(port); comp.Ports?.Add(port);
} }
} }
@@ -321,6 +323,9 @@ public abstract class SharedDeviceLinkSystem : EntitySystem
RemoveSinkFromSource(sourceUid, sinkUid, sourceComponent); RemoveSinkFromSource(sourceUid, sinkUid, sourceComponent);
foreach (var (source, sink) in links) foreach (var (source, sink) in links)
{ {
DebugTools.Assert(_prototypeManager.HasIndex<SourcePortPrototype>(source));
DebugTools.Assert(_prototypeManager.HasIndex<SinkPortPrototype>(sink));
if (!sourceComponent.Ports.Contains(source) || !sinkComponent.Ports.Contains(sink)) if (!sourceComponent.Ports.Contains(source) || !sinkComponent.Ports.Contains(sink))
continue; continue;

View File

@@ -1,6 +1,5 @@
using Content.Shared.DeviceLinking;
using Content.Shared.Doors.Systems; using Content.Shared.Doors.Systems;
using Content.Shared.MachineLinking;
using Robust.Shared.Audio;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
@@ -65,7 +64,7 @@ public sealed class AirlockComponent : Component
/// <summary> /// <summary>
/// The receiver port for turning off automatic closing. /// The receiver port for turning off automatic closing.
/// </summary> /// </summary>
[DataField("autoClosePort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))] [DataField("autoClosePort", customTypeSerializer: typeof(PrototypeIdSerializer<SinkPortPrototype>))]
public string AutoClosePort = "AutoClose"; public string AutoClosePort = "AutoClose";
#region Graphics #region Graphics

View File

@@ -1,9 +1,6 @@
using Content.Shared.Doors.Systems; using Content.Shared.Doors.Systems;
using Content.Shared.MachineLinking;
using Robust.Shared.Audio; using Robust.Shared.Audio;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
namespace Content.Shared.Doors.Components; namespace Content.Shared.Doors.Components;

View File

@@ -1,44 +0,0 @@
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set;
namespace Content.Shared.MachineLinking;
/// <summary>
/// A prototype for a machine port, for use with machine linking.
/// </summary>
public abstract class MachinePortPrototype
{
/// <summary>
/// Localization string for the port name. Displayed in the linking UI.
/// </summary>
[DataField("name", required:true)]
public string Name = default!;
/// <summary>
/// Localization string for a description of the ports functionality. Should either indicate when a transmitter
/// port is fired, or what function a receiver port serves. Displayed as a tooltip in the linking UI.
/// </summary>
[DataField("description", required: true)]
public string Description = default!;
}
[Prototype("receiverPort")]
public sealed class ReceiverPortPrototype : MachinePortPrototype, IPrototype
{
[IdDataField]
public string ID { get; } = default!;
}
[Prototype("transmitterPort")]
public sealed class TransmitterPortPrototype : MachinePortPrototype, IPrototype
{
[IdDataField]
public string ID { get; } = default!;
/// <summary>
/// This is a set of receiver ports that this transmitter port will attempt to link to when using the
/// default-link functionality.
/// </summary>
[DataField("defaultLinks", customTypeSerializer: typeof(PrototypeIdHashSetSerializer<ReceiverPortPrototype>))]
public HashSet<string>? DefaultLinks;
}

View File

@@ -1,50 +0,0 @@
using Robust.Shared.Serialization;
namespace Content.Shared.MachineLinking
{
[Serializable, NetSerializable]
public sealed class SignalPortsState : BoundUserInterfaceState
{
public readonly string TransmitterName;
/// <summary>
/// A List of all ports on the selected transmitter
/// </summary>
public readonly List<string> TransmitterPorts;
public readonly string ReceiverName;
/// <summary>
/// A List of all ports on the selected receiver
/// </summary>
public readonly List<string> ReceiverPorts;
public readonly List<(int, int)> Links;
public SignalPortsState(string transmitterName, List<string> transmitterPorts, string receiverName, List<string> receiverPorts, List<(int, int)> links)
{
TransmitterName = transmitterName;
TransmitterPorts = transmitterPorts;
ReceiverName = receiverName;
ReceiverPorts = receiverPorts;
Links = links;
}
}
[Serializable, NetSerializable]
public sealed class SignalPortSelected : BoundUserInterfaceMessage
{
public readonly string TransmitterPort;
public readonly string ReceiverPort;
public SignalPortSelected(string transmitterPort, string receiverPort)
{
TransmitterPort = transmitterPort;
ReceiverPort = receiverPort;
}
}
[Serializable, NetSerializable]
public sealed class LinkerClearSelected : BoundUserInterfaceMessage { }
[Serializable, NetSerializable]
public sealed class LinkerLinkDefaultSelected : BoundUserInterfaceMessage { }
}

View File

@@ -1,94 +0,0 @@
- type: receiverPort
id: Toggle
name: signal-port-name-toggle
description: signal-port-description-toggle
- type: receiverPort
id: On
name: signal-port-name-on-receiver
description: signal-port-description-on-receiver
- type: receiverPort
id: Off
name: signal-port-name-off-receiver
description: signal-port-description-off-receiver
- type: receiverPort
id: Forward
name: signal-port-name-forward
description: signal-port-description-forward
- type: receiverPort
id: Reverse
name: signal-port-name-reverse
description: signal-port-description-reverse
- type: receiverPort
id: Open
name: signal-port-name-open
description: signal-port-description-open
- type: receiverPort
id: Close
name: signal-port-name-close
description: signal-port-description-close
- type: receiverPort
id: Trigger
name: signal-port-name-trigger
description: signal-port-description-trigger
- type: receiverPort
id: OrderReceiver
name: signal-port-name-order-receiver
description: signal-port-description-order-receiver
- type: receiverPort
id: Pressurize
name: signal-port-name-pressurize
description: signal-port-description-pressurize
- type: receiverPort
id: Depressurize
name: signal-port-name-depressurize
description: signal-port-description-depressurize
- type: receiverPort
id: CloningPodReceiver
name: signal-port-name-pod-receiver
description: signal-port-description-pod-receiver
- type: receiverPort
id: MedicalScannerReceiver
name: signal-port-name-med-scanner-receiver
description: signal-port-description-med-scanner-receiver
- type: receiverPort
id: AutoClose
name: signal-port-name-hold-open
description: signal-port-description-hold-open
- type: receiverPort
id: ArtifactAnalyzerReceiver
name: signal-port-name-artifact-analyzer-receiver
description: signal-port-description-artifact-analyzer-receiver
- type: receiverPort
id: DoorBolt
name: signal-port-name-doorbolt
description: signal-port-description-doorbolt
- type: receiverPort
id: InputA
name: signal-port-name-logic-input-a
description: signal-port-description-logic-input-a
- type: receiverPort
id: InputB
name: signal-port-name-logic-input-b
description: signal-port-description-logic-input-b
- type: receiverPort
id: Input
name: signal-port-name-logic-input
description: signal-port-description-logic-input

View File

@@ -1,98 +0,0 @@
- type: transmitterPort
id: Pressed
name: signal-port-name-pressed
description: signal-port-description-pressed
defaultLinks: [ Toggle, Trigger ]
- type: transmitterPort
id: On
name: signal-port-name-on-transmitter
description: signal-port-description-on-transmitter
defaultLinks: [ On, Open, Forward, Trigger ]
- type: transmitterPort
id: Off
name: signal-port-name-off-transmitter
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
description: signal-port-description-left
defaultLinks: [ On, Open, Forward, Trigger ]
- type: transmitterPort
id: Right
name: signal-port-name-right
description: signal-port-description-right
defaultLinks: [ On, Open, Reverse, Trigger ]
- type: transmitterPort
id: Middle
name: signal-port-name-middle
description: signal-port-description-middle
defaultLinks: [ Off, Close ]
- type: transmitterPort
id: DoorStatus
name: signal-port-name-doorstatus
description: signal-port-description-doorstatus
defaultLinks: [ DoorBolt ]
- type: transmitterPort
id: OrderSender
name: signal-port-name-order-sender
description: signal-port-description-order-sender
defaultLinks: [ OrderReceiver ]
- type: transmitterPort
id: CloningPodSender
name: signal-port-name-pod-receiver
description: signal-port-description-pod-sender
- type: transmitterPort
id: MedicalScannerSender
name: signal-port-name-med-scanner-sender
description: signal-port-description-med-scanner-sender
- type: transmitterPort
id: Timer
name: signal-port-name-timer-trigger
description: signal-port-description-timer-trigger
defaultLinks: [ AutoClose, On, Open, Forward, Trigger ]
- type: transmitterPort
id: Start
name: signal-port-name-timer-start
description: signal-port-description-timer-start
defaultLinks: [ Close, Off ]
- type: transmitterPort
id: ArtifactAnalyzerSender
name: signal-port-name-artifact-analyzer-sender
description: signal-port-description-artifact-analyzer-sender
defaultLinks: [ ArtifactAnalyzerReceiver ]
- type: transmitterPort
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 ]