Machine Port Prototypes (#7659)
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
@@ -197,7 +197,6 @@ namespace Content.Client.Entry
|
|||||||
"SignalReceiver",
|
"SignalReceiver",
|
||||||
"SignalSwitch",
|
"SignalSwitch",
|
||||||
"SignalTransmitter",
|
"SignalTransmitter",
|
||||||
"SignalButton",
|
|
||||||
"SignalLinker",
|
"SignalLinker",
|
||||||
"ItemCabinet",
|
"ItemCabinet",
|
||||||
"FireExtinguisher",
|
"FireExtinguisher",
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Robust.Client.UserInterface.Controls;
|
|||||||
using Robust.Client.UserInterface.CustomControls;
|
using Robust.Client.UserInterface.CustomControls;
|
||||||
using Robust.Client.UserInterface.XAML;
|
using Robust.Client.UserInterface.XAML;
|
||||||
using Robust.Client.Graphics;
|
using Robust.Client.Graphics;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Client.MachineLinking.UI
|
namespace Content.Client.MachineLinking.UI
|
||||||
{
|
{
|
||||||
@@ -12,18 +13,20 @@ namespace Content.Client.MachineLinking.UI
|
|||||||
public sealed partial class SignalPortSelectorMenu : DefaultWindow
|
public sealed partial class SignalPortSelectorMenu : DefaultWindow
|
||||||
{
|
{
|
||||||
private SignalPortSelectorBoundUserInterface _bui;
|
private SignalPortSelectorBoundUserInterface _bui;
|
||||||
private LinksRender links;
|
private LinksRender _links;
|
||||||
|
|
||||||
private ButtonGroup buttonGroup = new();
|
private ButtonGroup _buttonGroup = new();
|
||||||
|
private IPrototypeManager _protoMan;
|
||||||
|
|
||||||
public SignalPortSelectorMenu(SignalPortSelectorBoundUserInterface boundUserInterface)
|
public SignalPortSelectorMenu(SignalPortSelectorBoundUserInterface boundUserInterface)
|
||||||
{
|
{
|
||||||
RobustXamlLoader.Load(this);
|
RobustXamlLoader.Load(this);
|
||||||
_bui = boundUserInterface;
|
_bui = boundUserInterface;
|
||||||
links = new(ButtonContainerLeft, ButtonContainerRight);
|
_links = new(ButtonContainerLeft, ButtonContainerRight);
|
||||||
ContainerMiddle.AddChild(links);
|
ContainerMiddle.AddChild(_links);
|
||||||
ButtonClear.OnPressed += _ => _bui.OnClearPressed();
|
ButtonClear.OnPressed += _ => _bui.OnClearPressed();
|
||||||
ButtonLinkDefault.OnPressed += _ => _bui.OnLinkDefaultPressed();
|
ButtonLinkDefault.OnPressed += _ => _bui.OnLinkDefaultPressed();
|
||||||
|
_protoMan = IoCManager.Resolve<IPrototypeManager>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateState(SignalPortsState state)
|
public void UpdateState(SignalPortsState state)
|
||||||
@@ -32,7 +35,14 @@ namespace Content.Client.MachineLinking.UI
|
|||||||
ButtonContainerLeft.DisposeAllChildren();
|
ButtonContainerLeft.DisposeAllChildren();
|
||||||
foreach (var port in state.TransmitterPorts)
|
foreach (var port in state.TransmitterPorts)
|
||||||
{
|
{
|
||||||
var portButton = new Button() { Text = port, ToggleMode = true, Group = buttonGroup };
|
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);
|
portButton.OnPressed += _ => _bui.OnTransmitterPortSelected(port);
|
||||||
ButtonContainerLeft.AddChild(portButton);
|
ButtonContainerLeft.AddChild(portButton);
|
||||||
}
|
}
|
||||||
@@ -41,12 +51,19 @@ namespace Content.Client.MachineLinking.UI
|
|||||||
ButtonContainerRight.DisposeAllChildren();
|
ButtonContainerRight.DisposeAllChildren();
|
||||||
foreach (var port in state.ReceiverPorts)
|
foreach (var port in state.ReceiverPorts)
|
||||||
{
|
{
|
||||||
var portButton = new Button() { Text = port, ToggleMode = true, Group = buttonGroup };
|
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);
|
portButton.OnPressed += _ => _bui.OnReceiverPortSelected(port);
|
||||||
ButtonContainerRight.AddChild(portButton);
|
ButtonContainerRight.AddChild(portButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
links.Links = state.Links;
|
_links.Links = state.Links;
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed class LinksRender : Control
|
private sealed class LinksRender : Control
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ namespace Content.Client.Popups
|
|||||||
_userInterfaceManager.PopupRoot.AddChild(label);
|
_userInterfaceManager.PopupRoot.AddChild(label);
|
||||||
label.Measure(Vector2.Infinity);
|
label.Measure(Vector2.Infinity);
|
||||||
|
|
||||||
var mapCoordinates = _eyeManager.ScreenToMap(coordinates.Position / label.UIScale - label.DesiredSize / 2);
|
var mapCoordinates = _eyeManager.ScreenToMap(coordinates.Position);
|
||||||
label.InitialPos = mapCoordinates;
|
label.InitialPos = mapCoordinates;
|
||||||
LayoutContainer.SetPosition(label, label.InitialPos.Position);
|
LayoutContainer.SetPosition(label, label.InitialPos.Position);
|
||||||
_aliveLabels.Add(label);
|
_aliveLabels.Add(label);
|
||||||
@@ -204,7 +204,7 @@ namespace Content.Client.Popups
|
|||||||
|
|
||||||
Vector2 position;
|
Vector2 position;
|
||||||
if (Entity == null)
|
if (Entity == null)
|
||||||
position = InitialPos.Position;
|
position = _eyeManager.WorldToScreen(InitialPos.Position) / UIScale - DesiredSize / 2;
|
||||||
else if (_entityManager.TryGetComponent(Entity.Value, out TransformComponent xform))
|
else if (_entityManager.TryGetComponent(Entity.Value, out TransformComponent xform))
|
||||||
position = (_eyeManager.CoordinatesToScreen(xform.Coordinates).Position / UIScale) - DesiredSize / 2;
|
position = (_eyeManager.CoordinatesToScreen(xform.Coordinates).Position / UIScale) - DesiredSize / 2;
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
using Content.Shared.Conveyor;
|
using Content.Shared.Conveyor;
|
||||||
using Robust.Shared.Analyzers;
|
using Content.Shared.MachineLinking;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Serialization.Manager.Attributes;
|
|
||||||
using Robust.Shared.ViewVariables;
|
|
||||||
|
|
||||||
namespace Content.Server.Conveyor
|
namespace Content.Server.Conveyor
|
||||||
{
|
{
|
||||||
@@ -30,5 +27,14 @@ namespace Content.Server.Conveyor
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
public ConveyorState State;
|
public ConveyorState State;
|
||||||
|
|
||||||
|
[DataField("forwardPort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))]
|
||||||
|
public string ForwardPort = "Forward";
|
||||||
|
|
||||||
|
[DataField("reversePort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))]
|
||||||
|
public string ReversePort = "Reverse";
|
||||||
|
|
||||||
|
[DataField("offPort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))]
|
||||||
|
public string OffPort = "Off";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,19 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Content.Server.MachineLinking.Components;
|
using Content.Server.MachineLinking.Components;
|
||||||
using Content.Server.MachineLinking.Events;
|
using Content.Server.MachineLinking.Events;
|
||||||
|
using Content.Server.MachineLinking.System;
|
||||||
using Content.Server.Power.Components;
|
using Content.Server.Power.Components;
|
||||||
using Content.Server.Recycling;
|
using Content.Server.Recycling;
|
||||||
using Content.Server.Recycling.Components;
|
using Content.Server.Recycling.Components;
|
||||||
using Content.Shared.Conveyor;
|
using Content.Shared.Conveyor;
|
||||||
using Content.Shared.Item;
|
using Content.Shared.Item;
|
||||||
using Content.Shared.Movement.Components;
|
|
||||||
using Content.Shared.Popups;
|
|
||||||
using Robust.Shared.Containers;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Localization;
|
|
||||||
using Robust.Shared.Maths;
|
|
||||||
using Robust.Shared.Physics;
|
|
||||||
|
|
||||||
namespace Content.Server.Conveyor
|
namespace Content.Server.Conveyor
|
||||||
{
|
{
|
||||||
public sealed class ConveyorSystem : EntitySystem
|
public sealed class ConveyorSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private RecyclerSystem _recycler = default!;
|
[Dependency] private RecyclerSystem _recycler = default!;
|
||||||
|
[Dependency] private readonly SignalLinkerSystem _signalSystem = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
@@ -31,13 +25,9 @@ namespace Content.Server.Conveyor
|
|||||||
|
|
||||||
private void OnInit(EntityUid uid, ConveyorComponent component, ComponentInit args)
|
private void OnInit(EntityUid uid, ConveyorComponent component, ComponentInit args)
|
||||||
{
|
{
|
||||||
var receiver = EnsureComp<SignalReceiverComponent>(uid);
|
_signalSystem.EnsureReceiverPorts(uid, component.ReversePort, component.ForwardPort, component.OffPort);
|
||||||
foreach (string port in Enum.GetNames<ConveyorState>())
|
|
||||||
if (!receiver.Inputs.ContainsKey(port))
|
|
||||||
receiver.AddPort(port);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void OnPowerChanged(EntityUid uid, ConveyorComponent component, PowerChangedEvent args)
|
private void OnPowerChanged(EntityUid uid, ConveyorComponent component, PowerChangedEvent args)
|
||||||
{
|
{
|
||||||
UpdateAppearance(component);
|
UpdateAppearance(component);
|
||||||
@@ -60,8 +50,12 @@ namespace Content.Server.Conveyor
|
|||||||
|
|
||||||
private void OnSignalReceived(EntityUid uid, ConveyorComponent component, SignalReceivedEvent args)
|
private void OnSignalReceived(EntityUid uid, ConveyorComponent component, SignalReceivedEvent args)
|
||||||
{
|
{
|
||||||
if (Enum.TryParse(args.Port, out ConveyorState state))
|
if (args.Port == component.OffPort)
|
||||||
SetState(component, state);
|
SetState(component, ConveyorState.Off);
|
||||||
|
else if (args.Port == component.ForwardPort)
|
||||||
|
SetState(component, ConveyorState.Forward);
|
||||||
|
else if (args.Port == component.ReversePort)
|
||||||
|
SetState(component, ConveyorState.Reverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetState(ConveyorComponent component, ConveyorState state)
|
private void SetState(ConveyorComponent component, ConveyorState state)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Robust.Shared.GameObjects;
|
using Content.Shared.MachineLinking;
|
||||||
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
|
|
||||||
namespace Content.Server.Explosion.Components
|
namespace Content.Server.Explosion.Components
|
||||||
{
|
{
|
||||||
@@ -8,6 +9,7 @@ namespace Content.Server.Explosion.Components
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public sealed class TriggerOnSignalComponent : Component
|
public sealed class TriggerOnSignalComponent : Component
|
||||||
{
|
{
|
||||||
public const string Port = "Trigger";
|
[DataField("port", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))]
|
||||||
|
public string Port = "Trigger";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,14 @@
|
|||||||
using Content.Server.Explosion.Components;
|
using Content.Server.Explosion.Components;
|
||||||
using Content.Server.MachineLinking.Events;
|
using Content.Server.MachineLinking.Events;
|
||||||
using Content.Server.MachineLinking.Components;
|
using Content.Server.MachineLinking.Components;
|
||||||
|
using Content.Server.MachineLinking.System;
|
||||||
|
|
||||||
namespace Content.Server.Explosion.EntitySystems
|
namespace Content.Server.Explosion.EntitySystems
|
||||||
{
|
{
|
||||||
public sealed partial class TriggerSystem
|
public sealed partial class TriggerSystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly SignalLinkerSystem _signalSystem = default!;
|
||||||
|
|
||||||
private void InitializeSignal()
|
private void InitializeSignal()
|
||||||
{
|
{
|
||||||
SubscribeLocalEvent<TriggerOnSignalComponent,SignalReceivedEvent>(OnSignalReceived);
|
SubscribeLocalEvent<TriggerOnSignalComponent,SignalReceivedEvent>(OnSignalReceived);
|
||||||
@@ -14,16 +17,14 @@ namespace Content.Server.Explosion.EntitySystems
|
|||||||
|
|
||||||
private void OnSignalReceived(EntityUid uid, TriggerOnSignalComponent component, SignalReceivedEvent args)
|
private void OnSignalReceived(EntityUid uid, TriggerOnSignalComponent component, SignalReceivedEvent args)
|
||||||
{
|
{
|
||||||
if (args.Port != TriggerOnSignalComponent.Port)
|
if (args.Port != component.Port)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Trigger(uid);
|
Trigger(uid);
|
||||||
}
|
}
|
||||||
private void OnInit(EntityUid uid, TriggerOnSignalComponent component, ComponentInit args)
|
private void OnInit(EntityUid uid, TriggerOnSignalComponent component, ComponentInit args)
|
||||||
{
|
{
|
||||||
var receiver = EnsureComp<SignalReceiverComponent>(uid);
|
_signalSystem.EnsureReceiverPorts(uid, component.Port);
|
||||||
if (!receiver.Inputs.ContainsKey(TriggerOnSignalComponent.Port))
|
|
||||||
receiver.AddPort(TriggerOnSignalComponent.Port);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,7 @@ using Robust.Shared.Serialization.Manager.Attributes;
|
|||||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.ViewVariables;
|
using Robust.Shared.ViewVariables;
|
||||||
|
using Content.Shared.MachineLinking;
|
||||||
|
|
||||||
namespace Content.Server.Light.Components
|
namespace Content.Server.Light.Components
|
||||||
{
|
{
|
||||||
@@ -61,5 +62,14 @@ namespace Content.Server.Light.Components
|
|||||||
public TimeSpan LastThunk;
|
public TimeSpan LastThunk;
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public TimeSpan? LastGhostBlink;
|
public TimeSpan? LastGhostBlink;
|
||||||
|
|
||||||
|
[DataField("onPort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))]
|
||||||
|
public string OnPort = "On";
|
||||||
|
|
||||||
|
[DataField("offPort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))]
|
||||||
|
public string OffPort = "Off";
|
||||||
|
|
||||||
|
[DataField("togglePort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))]
|
||||||
|
public string TogglePort = "Toggle";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,15 @@
|
|||||||
using System;
|
|
||||||
using Content.Server.Administration.Logs;
|
using Content.Server.Administration.Logs;
|
||||||
using Content.Server.DeviceNetwork;
|
using Content.Server.DeviceNetwork;
|
||||||
using Content.Server.DeviceNetwork.Systems;
|
using Content.Server.DeviceNetwork.Systems;
|
||||||
using Content.Server.Ghost;
|
using Content.Server.Ghost;
|
||||||
using Content.Server.Light.Components;
|
using Content.Server.Light.Components;
|
||||||
using Content.Server.MachineLinking.Events;
|
using Content.Server.MachineLinking.Events;
|
||||||
using Content.Server.MachineLinking.Components;
|
using Content.Server.MachineLinking.System;
|
||||||
using Content.Server.Power.Components;
|
using Content.Server.Power.Components;
|
||||||
using Content.Server.Temperature.Components;
|
using Content.Server.Temperature.Components;
|
||||||
using Content.Shared.Audio;
|
using Content.Shared.Audio;
|
||||||
using Content.Shared.Damage;
|
using Content.Shared.Damage;
|
||||||
using Content.Shared.Database;
|
using Content.Shared.Database;
|
||||||
using Content.Shared.Hands.Components;
|
|
||||||
using Content.Shared.Hands.EntitySystems;
|
using Content.Shared.Hands.EntitySystems;
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.Light;
|
using Content.Shared.Light;
|
||||||
@@ -25,7 +23,7 @@ using Robust.Shared.Timing;
|
|||||||
namespace Content.Server.Light.EntitySystems
|
namespace Content.Server.Light.EntitySystems
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// System for the PoweredLightComponens
|
/// System for the PoweredLightComponents
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class PoweredLightSystem : EntitySystem
|
public sealed class PoweredLightSystem : EntitySystem
|
||||||
{
|
{
|
||||||
@@ -36,8 +34,11 @@ namespace Content.Server.Light.EntitySystems
|
|||||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||||
[Dependency] private readonly AdminLogSystem _logSystem = default!;
|
[Dependency] private readonly AdminLogSystem _logSystem = default!;
|
||||||
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
|
[Dependency] private readonly SharedHandsSystem _handsSystem = default!;
|
||||||
|
[Dependency] private readonly SignalLinkerSystem _signalSystem = default!;
|
||||||
|
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
||||||
|
|
||||||
private static readonly TimeSpan ThunkDelay = TimeSpan.FromSeconds(2);
|
private static readonly TimeSpan ThunkDelay = TimeSpan.FromSeconds(2);
|
||||||
|
public const string LightBulbContainer = "light_bulb";
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -58,12 +59,8 @@ namespace Content.Server.Light.EntitySystems
|
|||||||
|
|
||||||
private void OnInit(EntityUid uid, PoweredLightComponent light, ComponentInit args)
|
private void OnInit(EntityUid uid, PoweredLightComponent light, ComponentInit args)
|
||||||
{
|
{
|
||||||
light.LightBulbContainer = light.Owner.EnsureContainer<ContainerSlot>("light_bulb");
|
light.LightBulbContainer = _containerSystem.EnsureContainer<ContainerSlot>(uid, LightBulbContainer);
|
||||||
|
_signalSystem.EnsureReceiverPorts(uid, light.OnPort, light.OffPort, light.TogglePort);
|
||||||
var receiver = EnsureComp<SignalReceiverComponent>(uid);
|
|
||||||
foreach (string port in new[] { "On", "Off", "Toggle" })
|
|
||||||
if (!receiver.Inputs.ContainsKey(port))
|
|
||||||
receiver.AddPort(port);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMapInit(EntityUid uid, PoweredLightComponent light, MapInitEvent args)
|
private void OnMapInit(EntityUid uid, PoweredLightComponent light, MapInitEvent args)
|
||||||
@@ -335,12 +332,12 @@ namespace Content.Server.Light.EntitySystems
|
|||||||
|
|
||||||
private void OnSignalReceived(EntityUid uid, PoweredLightComponent component, SignalReceivedEvent args)
|
private void OnSignalReceived(EntityUid uid, PoweredLightComponent component, SignalReceivedEvent args)
|
||||||
{
|
{
|
||||||
switch (args.Port)
|
if (args.Port == component.OffPort)
|
||||||
{
|
SetState(uid, false, component);
|
||||||
case "On": SetState(uid, true, component); break;
|
else if (args.Port == component.OnPort)
|
||||||
case "Off": SetState(uid, false, component); break;
|
SetState(uid, true, component);
|
||||||
case "Toggle": ToggleLight(uid, component); break;
|
else if (args.Port == component.TogglePort)
|
||||||
}
|
ToggleLight(uid, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,9 +1,18 @@
|
|||||||
using Robust.Shared.GameObjects;
|
using Content.Shared.MachineLinking;
|
||||||
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
|
|
||||||
namespace Content.Server.MachineLinking.Components
|
namespace Content.Server.MachineLinking.Components
|
||||||
{
|
{
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public sealed class DoorSignalControlComponent : Component
|
public sealed class DoorSignalControlComponent : Component
|
||||||
{
|
{
|
||||||
|
[DataField("openPort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))]
|
||||||
|
public string OpenPort = "Open";
|
||||||
|
|
||||||
|
[DataField("closePort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))]
|
||||||
|
public string ClosePort = "Close";
|
||||||
|
|
||||||
|
[DataField("togglePort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))]
|
||||||
|
public string TogglePort = "Toggle";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
using Robust.Shared.GameObjects;
|
|
||||||
|
|
||||||
namespace Content.Server.MachineLinking.Components
|
|
||||||
{
|
|
||||||
[RegisterComponent]
|
|
||||||
public sealed class SignalButtonComponent : Component
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +1,12 @@
|
|||||||
using System;
|
using Content.Server.MachineLinking.System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Serialization.Manager.Attributes;
|
|
||||||
using Robust.Shared.ViewVariables;
|
|
||||||
|
|
||||||
namespace Content.Server.MachineLinking.Components
|
namespace Content.Server.MachineLinking.Components
|
||||||
{
|
{
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
|
[Friend(typeof(SignalLinkerSystem))]
|
||||||
public sealed class SignalReceiverComponent : Component
|
public sealed class SignalReceiverComponent : Component
|
||||||
{
|
{
|
||||||
[DataField("inputs")]
|
[DataField("inputs")]
|
||||||
private Dictionary<string, List<PortIdentifier>> _inputs = new();
|
public Dictionary<string, List<PortIdentifier>> Inputs = new();
|
||||||
|
|
||||||
public void AddPort(string name)
|
|
||||||
{
|
|
||||||
_inputs.Add(name, new());
|
|
||||||
}
|
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
public IReadOnlyDictionary<string, List<PortIdentifier>> Inputs => _inputs;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,28 @@
|
|||||||
using Robust.Shared.GameObjects;
|
using Content.Shared.MachineLinking;
|
||||||
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
|
|
||||||
namespace Content.Server.MachineLinking.Components
|
namespace Content.Server.MachineLinking.Components
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Simple switch that will fire ports when toggled on or off. A button is jsut a switch that signals on the
|
||||||
|
/// same port regardless of its state.
|
||||||
|
/// </summary>
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public sealed class SignalSwitchComponent : Component
|
public sealed class SignalSwitchComponent : Component
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The port that gets signaled when the switch turns on.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("onPort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))]
|
||||||
|
public string OnPort = "On";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The port that gets signaled when the switch turns off.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("offPort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))]
|
||||||
|
public string OffPort = "Off";
|
||||||
|
|
||||||
|
[DataField("state")]
|
||||||
public bool State;
|
public bool State;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.Serialization.Manager.Attributes;
|
|
||||||
using Robust.Shared.ViewVariables;
|
|
||||||
using Content.Server.MachineLinking.System;
|
using Content.Server.MachineLinking.System;
|
||||||
|
|
||||||
namespace Content.Server.MachineLinking.Components
|
namespace Content.Server.MachineLinking.Components
|
||||||
@@ -24,6 +19,7 @@ namespace Content.Server.MachineLinking.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
|
[Friend(typeof(SignalLinkerSystem))]
|
||||||
public sealed class SignalTransmitterComponent : Component
|
public sealed class SignalTransmitterComponent : Component
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -35,14 +31,6 @@ namespace Content.Server.MachineLinking.Components
|
|||||||
public float TransmissionRange = 30f;
|
public float TransmissionRange = 30f;
|
||||||
|
|
||||||
[DataField("outputs")]
|
[DataField("outputs")]
|
||||||
private Dictionary<string, List<PortIdentifier>> _outputs = new();
|
public Dictionary<string, List<PortIdentifier>> Outputs = new();
|
||||||
|
|
||||||
[ViewVariables]
|
|
||||||
public IReadOnlyDictionary<string, List<PortIdentifier>> Outputs => _outputs;
|
|
||||||
|
|
||||||
public void AddPort(string name)
|
|
||||||
{
|
|
||||||
_outputs.Add(name, new());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Robust.Shared.GameObjects;
|
using Content.Shared.MachineLinking;
|
||||||
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
|
|
||||||
namespace Content.Server.MachineLinking.Components
|
namespace Content.Server.MachineLinking.Components
|
||||||
{
|
{
|
||||||
@@ -8,6 +9,10 @@ namespace Content.Server.MachineLinking.Components
|
|||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public sealed class SignallerComponent : Component
|
public sealed class SignallerComponent : Component
|
||||||
{
|
{
|
||||||
public const string Port = "Pressed";
|
/// <summary>
|
||||||
|
/// The port that gets signaled when the switch turns on.
|
||||||
|
/// </summary>
|
||||||
|
[DataField("port", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))]
|
||||||
|
public string Port = "Pressed";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,24 @@
|
|||||||
using Content.Shared.MachineLinking;
|
using Content.Shared.MachineLinking;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
|
|
||||||
namespace Content.Server.MachineLinking.Components
|
namespace Content.Server.MachineLinking.Components
|
||||||
{
|
{
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public sealed class TwoWayLeverComponent : Component
|
public sealed class TwoWayLeverComponent : Component
|
||||||
{
|
{
|
||||||
|
[DataField("state")]
|
||||||
public TwoWayLeverState State;
|
public TwoWayLeverState State;
|
||||||
|
|
||||||
|
[DataField("nextSignalLeft")]
|
||||||
public bool NextSignalLeft;
|
public bool NextSignalLeft;
|
||||||
|
|
||||||
|
[DataField("leftPort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))]
|
||||||
|
public string LeftPort = "Left";
|
||||||
|
|
||||||
|
[DataField("rightPort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))]
|
||||||
|
public string RightPort = "Right";
|
||||||
|
|
||||||
|
[DataField("middlePort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))]
|
||||||
|
public string MiddlePort = "Middle";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
using Robust.Shared.GameObjects;
|
|
||||||
|
|
||||||
namespace Content.Server.MachineLinking.Events
|
|
||||||
{
|
|
||||||
public sealed class InvokePortEvent : EntityEventArgs
|
|
||||||
{
|
|
||||||
public readonly string Port;
|
|
||||||
|
|
||||||
public InvokePortEvent(string port)
|
|
||||||
{
|
|
||||||
Port = port;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,9 +2,7 @@ using Content.Server.MachineLinking.Components;
|
|||||||
using Content.Server.MachineLinking.Events;
|
using Content.Server.MachineLinking.Events;
|
||||||
using Content.Server.Doors.Systems;
|
using Content.Server.Doors.Systems;
|
||||||
using Content.Shared.Doors.Components;
|
using Content.Shared.Doors.Components;
|
||||||
using Content.Shared.Interaction;
|
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
|
|
||||||
namespace Content.Server.MachineLinking.System
|
namespace Content.Server.MachineLinking.System
|
||||||
{
|
{
|
||||||
@@ -12,6 +10,8 @@ namespace Content.Server.MachineLinking.System
|
|||||||
public sealed class DoorSignalControlSystem : EntitySystem
|
public sealed class DoorSignalControlSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly DoorSystem _doorSystem = default!;
|
[Dependency] private readonly DoorSystem _doorSystem = default!;
|
||||||
|
[Dependency] private readonly SignalLinkerSystem _signalSystem = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
@@ -21,20 +21,27 @@ namespace Content.Server.MachineLinking.System
|
|||||||
|
|
||||||
private void OnInit(EntityUid uid, DoorSignalControlComponent component, ComponentInit args)
|
private void OnInit(EntityUid uid, DoorSignalControlComponent component, ComponentInit args)
|
||||||
{
|
{
|
||||||
var receiver = EnsureComp<SignalReceiverComponent>(uid);
|
_signalSystem.EnsureReceiverPorts(uid, component.OpenPort, component.ClosePort, component.TogglePort);
|
||||||
foreach (string port in new[] { "Open", "Close", "Toggle" })
|
|
||||||
if (!receiver.Inputs.ContainsKey(port))
|
|
||||||
receiver.AddPort(port);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnSignalReceived(EntityUid uid, DoorSignalControlComponent component, SignalReceivedEvent args)
|
private void OnSignalReceived(EntityUid uid, DoorSignalControlComponent component, SignalReceivedEvent args)
|
||||||
{
|
{
|
||||||
if (!TryComp(uid, out DoorComponent? door)) return;
|
if (!TryComp(uid, out DoorComponent? door))
|
||||||
switch (args.Port)
|
return;
|
||||||
|
|
||||||
|
if (args.Port == component.OpenPort)
|
||||||
{
|
{
|
||||||
case "Open": if (door.State != DoorState.Open) _doorSystem.TryOpen(uid, door); break;
|
if (door.State != DoorState.Open)
|
||||||
case "Close": if (door.State != DoorState.Closed) _doorSystem.TryClose(uid, door); break;
|
_doorSystem.TryOpen(uid, door);
|
||||||
case "Toggle": _doorSystem.TryToggleDoor(uid); break;
|
}
|
||||||
|
else if (args.Port == component.ClosePort)
|
||||||
|
{
|
||||||
|
if (door.State != DoorState.Closed)
|
||||||
|
_doorSystem.TryClose(uid, door);
|
||||||
|
}
|
||||||
|
else if (args.Port == component.TogglePort)
|
||||||
|
{
|
||||||
|
_doorSystem.TryToggleDoor(uid, door);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
using Content.Server.MachineLinking.Components;
|
|
||||||
using Content.Server.MachineLinking.Events;
|
|
||||||
using Content.Shared.Interaction;
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Content.Shared.Interaction.Events;
|
|
||||||
|
|
||||||
namespace Content.Server.MachineLinking.System
|
|
||||||
{
|
|
||||||
[UsedImplicitly]
|
|
||||||
public sealed class SignalButtonSystem : EntitySystem
|
|
||||||
{
|
|
||||||
public override void Initialize()
|
|
||||||
{
|
|
||||||
base.Initialize();
|
|
||||||
SubscribeLocalEvent<SignalButtonComponent, ComponentInit>(OnInit);
|
|
||||||
SubscribeLocalEvent<SignalButtonComponent, ActivateInWorldEvent>(OnActivated);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnInit(EntityUid uid, SignalButtonComponent component, ComponentInit args)
|
|
||||||
{
|
|
||||||
var transmitter = EnsureComp<SignalTransmitterComponent>(uid);
|
|
||||||
if (!transmitter.Outputs.ContainsKey("Pressed"))
|
|
||||||
transmitter.AddPort("Pressed");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnActivated(EntityUid uid, SignalButtonComponent component, ActivateInWorldEvent args)
|
|
||||||
{
|
|
||||||
RaiseLocalEvent(uid, new InvokePortEvent("Pressed"), false);
|
|
||||||
args.Handled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,9 +7,9 @@ using Content.Shared.Interaction;
|
|||||||
using Content.Shared.MachineLinking;
|
using Content.Shared.MachineLinking;
|
||||||
using Content.Shared.Popups;
|
using Content.Shared.Popups;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Utility;
|
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
using Content.Shared.Verbs;
|
using Content.Shared.Verbs;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
using Content.Shared.MachineLinking.Events;
|
using Content.Shared.MachineLinking.Events;
|
||||||
|
|
||||||
namespace Content.Server.MachineLinking.System
|
namespace Content.Server.MachineLinking.System
|
||||||
@@ -18,24 +18,12 @@ namespace Content.Server.MachineLinking.System
|
|||||||
{
|
{
|
||||||
[Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!;
|
[Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!;
|
||||||
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _protoMan = default!;
|
||||||
private static readonly (string, string)[][] _defaultMappings =
|
|
||||||
{
|
|
||||||
new [] { ("Pressed", "Toggle") },
|
|
||||||
new [] { ("On", "On"), ("Off", "Off") },
|
|
||||||
new [] { ("On", "Open"), ("Off", "Close") },
|
|
||||||
new [] { ("On", "Forward"), ("Off", "Off") },
|
|
||||||
new [] { ("Left", "On"), ("Right", "On"), ("Middle", "Off") },
|
|
||||||
new [] { ("Left", "Open"), ("Right", "Open"), ("Middle", "Close") },
|
|
||||||
new [] { ("Left", "Forward"), ("Right", "Reverse"), ("Middle", "Off") },
|
|
||||||
};
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
SubscribeLocalEvent<SignalTransmitterComponent, InvokePortEvent>(OnTransmitterInvokePort);
|
|
||||||
|
|
||||||
SubscribeLocalEvent<SignalTransmitterComponent, ComponentStartup>(OnTransmitterStartup);
|
SubscribeLocalEvent<SignalTransmitterComponent, ComponentStartup>(OnTransmitterStartup);
|
||||||
SubscribeLocalEvent<SignalTransmitterComponent, ComponentRemove>(OnTransmitterRemoved);
|
SubscribeLocalEvent<SignalTransmitterComponent, ComponentRemove>(OnTransmitterRemoved);
|
||||||
SubscribeLocalEvent<SignalTransmitterComponent, InteractUsingEvent>(OnTransmitterInteractUsing);
|
SubscribeLocalEvent<SignalTransmitterComponent, InteractUsingEvent>(OnTransmitterInteractUsing);
|
||||||
@@ -52,6 +40,27 @@ namespace Content.Server.MachineLinking.System
|
|||||||
SubscribeLocalEvent<SignalLinkerComponent, BoundUIClosedEvent>(OnLinkerUIClosed);
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EnsureTransmitterPorts(EntityUid uid, params string[] ports)
|
||||||
|
{
|
||||||
|
var comp = EnsureComp<SignalTransmitterComponent>(uid);
|
||||||
|
foreach (var port in ports)
|
||||||
|
{
|
||||||
|
comp.Outputs.TryAdd(port, new());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add an alt-click verb to allow users to link the default ports, without needing to open the UI.
|
/// Add an alt-click verb to allow users to link the default ports, without needing to open the UI.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -117,9 +126,15 @@ namespace Content.Server.MachineLinking.System
|
|||||||
verb.Message = Loc.GetString("signal-linking-verb-disabled-no-receiver");
|
verb.Message = Loc.GetString("signal-linking-verb-disabled-no-receiver");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnTransmitterInvokePort(EntityUid uid, SignalTransmitterComponent component, InvokePortEvent args)
|
public void InvokePort(EntityUid uid, string port, SignalTransmitterComponent? component = null)
|
||||||
{
|
{
|
||||||
foreach (var receiver in component.Outputs[args.Port])
|
if (!Resolve(uid, ref component))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!component.Outputs.TryGetValue(port, out var receivers))
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var receiver in receivers)
|
||||||
RaiseLocalEvent(receiver.Uid, new SignalReceivedEvent(receiver.Port), false);
|
RaiseLocalEvent(receiver.Uid, new SignalReceivedEvent(receiver.Port), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,10 +279,18 @@ namespace Content.Server.MachineLinking.System
|
|||||||
|
|
||||||
private bool TryLink(SignalTransmitterComponent transmitter, SignalReceiverComponent receiver, SignalPortSelected args, EntityUid user, bool quiet = false, bool checkRange = true)
|
private bool TryLink(SignalTransmitterComponent transmitter, SignalReceiverComponent receiver, SignalPortSelected args, EntityUid user, bool quiet = false, bool checkRange = true)
|
||||||
{
|
{
|
||||||
if (!transmitter.Outputs.TryGetValue(args.TransmitterPort, out var receivers) ||
|
if (!transmitter.Outputs.TryGetValue(args.TransmitterPort, out var linkedReceivers) ||
|
||||||
!receiver.Inputs.TryGetValue(args.ReceiverPort, out var transmitters))
|
!receiver.Inputs.TryGetValue(args.ReceiverPort, out var linkedTransmitters))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// 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 == transmitter.Owner && identifier.Port == args.TransmitterPort)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (checkRange && !IsInRange(transmitter, receiver))
|
if (checkRange && !IsInRange(transmitter, receiver))
|
||||||
{
|
{
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
@@ -295,12 +318,12 @@ namespace Content.Server.MachineLinking.System
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
receivers.Add(new(receiver.Owner, args.ReceiverPort));
|
linkedReceivers.Add(new(receiver.Owner, args.ReceiverPort));
|
||||||
transmitters.Add(new(transmitter.Owner, args.TransmitterPort));
|
linkedTransmitters.Add(new(transmitter.Owner, args.TransmitterPort));
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-linked-port",
|
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-linked-port",
|
||||||
("machine1", transmitter.Owner), ("port1", args.TransmitterPort),
|
("machine1", transmitter.Owner), ("port1", PortName<TransmitterPortPrototype>(args.TransmitterPort)),
|
||||||
("machine2", receiver.Owner), ("port2", args.ReceiverPort)),
|
("machine2", receiver.Owner), ("port2", PortName<ReceiverPortPrototype>(args.ReceiverPort))),
|
||||||
Filter.Entities(user));
|
Filter.Entities(user));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -326,8 +349,8 @@ namespace Content.Server.MachineLinking.System
|
|||||||
RaiseLocalEvent(receiver.Owner, new PortDisconnectedEvent(args.ReceiverPort));
|
RaiseLocalEvent(receiver.Owner, new PortDisconnectedEvent(args.ReceiverPort));
|
||||||
RaiseLocalEvent(transmitter.Owner, new PortDisconnectedEvent(args.TransmitterPort));
|
RaiseLocalEvent(transmitter.Owner, new PortDisconnectedEvent(args.TransmitterPort));
|
||||||
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-unlinked-port",
|
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-unlinked-port",
|
||||||
("machine1", transmitter.Owner), ("port1", args.TransmitterPort),
|
("machine1", transmitter.Owner), ("port1", PortName<TransmitterPortPrototype>(args.TransmitterPort)),
|
||||||
("machine2", receiver.Owner), ("port2", args.ReceiverPort)),
|
("machine2", receiver.Owner), ("port2", PortName<ReceiverPortPrototype>(args.ReceiverPort))),
|
||||||
Filter.Entities(attached));
|
Filter.Entities(attached));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -343,6 +366,19 @@ namespace Content.Server.MachineLinking.System
|
|||||||
TryUpdateUI(linker, transmitter, receiver);
|
TryUpdateUI(linker, transmitter, 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)
|
private void OnLinkerClearSelected(EntityUid uid, SignalLinkerComponent linker, LinkerClearSelected args)
|
||||||
{
|
{
|
||||||
if (!TryComp(linker.SavedTransmitter, out SignalTransmitterComponent? transmitter) ||
|
if (!TryComp(linker.SavedTransmitter, out SignalTransmitterComponent? transmitter) ||
|
||||||
@@ -388,19 +424,27 @@ namespace Content.Server.MachineLinking.System
|
|||||||
|
|
||||||
var allLinksSucceeded = true;
|
var allLinksSucceeded = true;
|
||||||
|
|
||||||
if (_defaultMappings.TryFirstOrDefault(map => !map.ExceptBy(transmitter.Outputs.Keys, item => item.Item1).Any() &&
|
// First, disconnect existing links.
|
||||||
!map.ExceptBy(receiver.Inputs.Keys, item => item.Item2).Any(), out var mapping))
|
foreach (var (port, receivers) in transmitter.Outputs)
|
||||||
|
if (receivers.RemoveAll(id => id.Uid == receiver.Owner) > 0)
|
||||||
|
RaiseLocalEvent(transmitter.Owner, new PortDisconnectedEvent(port));
|
||||||
|
|
||||||
|
foreach (var (port, transmitters) in receiver.Inputs)
|
||||||
|
if (transmitters.RemoveAll(id => id.Uid == transmitter.Owner) > 0)
|
||||||
|
RaiseLocalEvent(receiver.Owner, new PortDisconnectedEvent(port));
|
||||||
|
|
||||||
|
// Then make any valid default connections.
|
||||||
|
foreach (var outPort in transmitter.Outputs.Keys)
|
||||||
{
|
{
|
||||||
foreach (var (port, receivers) in transmitter.Outputs)
|
var prototype = _protoMan.Index<TransmitterPortPrototype>(outPort);
|
||||||
if (receivers.RemoveAll(id => id.Uid == receiver.Owner) > 0)
|
if (prototype.DefaultLinks == null)
|
||||||
RaiseLocalEvent(transmitter.Owner, new PortDisconnectedEvent(port));
|
continue;
|
||||||
|
|
||||||
foreach (var (port, transmitters) in receiver.Inputs)
|
foreach (var inPort in prototype.DefaultLinks)
|
||||||
if (transmitters.RemoveAll(id => id.Uid == transmitter.Owner) > 0)
|
{
|
||||||
RaiseLocalEvent(receiver.Owner, new PortDisconnectedEvent(port));
|
if (receiver.Inputs.ContainsKey(inPort))
|
||||||
|
allLinksSucceeded &= TryLink(transmitter, receiver, new(outPort, inPort), user, quiet: true, checkRange: false);
|
||||||
foreach (var (t, r) in mapping)
|
}
|
||||||
allLinksSucceeded &= !TryLink(transmitter, receiver, new(t, r), user, quiet: true, checkRange: false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return allLinksSucceeded;
|
return allLinksSucceeded;
|
||||||
|
|||||||
@@ -1,32 +1,33 @@
|
|||||||
using Content.Server.MachineLinking.Components;
|
using Content.Server.MachineLinking.Components;
|
||||||
using Content.Server.MachineLinking.Events;
|
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
|
|
||||||
namespace Content.Server.MachineLinking.System
|
namespace Content.Server.MachineLinking.System
|
||||||
{
|
{
|
||||||
public sealed class SignalSwitchSystem : EntitySystem
|
public sealed class SignalSwitchSystem : EntitySystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly SignalLinkerSystem _signalSystem = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
SubscribeLocalEvent<SignalSwitchComponent, ComponentInit>(OnInit);
|
SubscribeLocalEvent<SignalSwitchComponent, ComponentInit>(OnInit);
|
||||||
SubscribeLocalEvent<SignalSwitchComponent, ActivateInWorldEvent>(OnActivated);
|
SubscribeLocalEvent<SignalSwitchComponent, ActivateInWorldEvent>(OnActivated);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnInit(EntityUid uid, SignalSwitchComponent component, ComponentInit args)
|
private void OnInit(EntityUid uid, SignalSwitchComponent component, ComponentInit args)
|
||||||
{
|
{
|
||||||
var transmitter = EnsureComp<SignalTransmitterComponent>(uid);
|
_signalSystem.EnsureTransmitterPorts(uid, component.OnPort, component.OffPort);
|
||||||
foreach (string port in new[] { "On", "Off" })
|
|
||||||
if (!transmitter.Outputs.ContainsKey(port))
|
|
||||||
transmitter.AddPort(port);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnActivated(EntityUid uid, SignalSwitchComponent component, ActivateInWorldEvent args)
|
private void OnActivated(EntityUid uid, SignalSwitchComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled)
|
||||||
|
return;
|
||||||
|
|
||||||
component.State = !component.State;
|
component.State = !component.State;
|
||||||
RaiseLocalEvent(uid, new InvokePortEvent(component.State ? "On" : "Off"), false);
|
_signalSystem.InvokePort(uid, component.State ? component.OnPort : component.OffPort);
|
||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
using Content.Server.MachineLinking.Components;
|
using Content.Server.MachineLinking.Components;
|
||||||
using Content.Server.MachineLinking.Events;
|
|
||||||
using Content.Shared.Interaction;
|
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Content.Shared.Interaction.Events;
|
using Content.Shared.Interaction.Events;
|
||||||
|
|
||||||
namespace Content.Server.MachineLinking.System
|
namespace Content.Server.MachineLinking.System
|
||||||
@@ -10,6 +7,7 @@ namespace Content.Server.MachineLinking.System
|
|||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
public sealed class SignallerSystem : EntitySystem
|
public sealed class SignallerSystem : EntitySystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly SignalLinkerSystem _signalSystem = default!;
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
@@ -19,16 +17,14 @@ namespace Content.Server.MachineLinking.System
|
|||||||
|
|
||||||
private void OnInit(EntityUid uid, SignallerComponent component, ComponentInit args)
|
private void OnInit(EntityUid uid, SignallerComponent component, ComponentInit args)
|
||||||
{
|
{
|
||||||
var transmitter = EnsureComp<SignalTransmitterComponent>(uid);
|
_signalSystem.EnsureTransmitterPorts(uid, component.Port);
|
||||||
if (!transmitter.Outputs.ContainsKey(SignallerComponent.Port))
|
|
||||||
transmitter.AddPort(SignallerComponent.Port);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnUseInHand(EntityUid uid, SignallerComponent component, UseInHandEvent args)
|
private void OnUseInHand(EntityUid uid, SignallerComponent component, UseInHandEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled)
|
if (args.Handled)
|
||||||
return;
|
return;
|
||||||
RaiseLocalEvent(uid, new InvokePortEvent(SignallerComponent.Port), false);
|
_signalSystem.InvokePort(uid, component.Port);
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using Content.Server.MachineLinking.Components;
|
using Content.Server.MachineLinking.Components;
|
||||||
using Content.Server.MachineLinking.Events;
|
|
||||||
using Content.Shared.Interaction;
|
using Content.Shared.Interaction;
|
||||||
using Content.Shared.MachineLinking;
|
using Content.Shared.MachineLinking;
|
||||||
using Robust.Shared.GameObjects;
|
|
||||||
|
|
||||||
namespace Content.Server.MachineLinking.System
|
namespace Content.Server.MachineLinking.System
|
||||||
{
|
{
|
||||||
public sealed class TwoWayLeverSystem : EntitySystem
|
public sealed class TwoWayLeverSystem : EntitySystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly SignalLinkerSystem _signalSystem = default!;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
@@ -18,14 +18,14 @@ namespace Content.Server.MachineLinking.System
|
|||||||
|
|
||||||
private void OnInit(EntityUid uid, TwoWayLeverComponent component, ComponentInit args)
|
private void OnInit(EntityUid uid, TwoWayLeverComponent component, ComponentInit args)
|
||||||
{
|
{
|
||||||
var transmitter = EnsureComp<SignalTransmitterComponent>(uid);
|
_signalSystem.EnsureTransmitterPorts(uid, component.LeftPort, component.RightPort, component.MiddlePort);
|
||||||
foreach (string state in Enum.GetNames<TwoWayLeverState>())
|
|
||||||
if (!transmitter.Outputs.ContainsKey(state))
|
|
||||||
transmitter.AddPort(state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnActivated(EntityUid uid, TwoWayLeverComponent component, ActivateInWorldEvent args)
|
private void OnActivated(EntityUid uid, TwoWayLeverComponent component, ActivateInWorldEvent args)
|
||||||
{
|
{
|
||||||
|
if (args.Handled)
|
||||||
|
return;
|
||||||
|
|
||||||
component.State = component.State switch
|
component.State = component.State switch
|
||||||
{
|
{
|
||||||
TwoWayLeverState.Middle => component.NextSignalLeft ? TwoWayLeverState.Left : TwoWayLeverState.Right,
|
TwoWayLeverState.Middle => component.NextSignalLeft ? TwoWayLeverState.Left : TwoWayLeverState.Right,
|
||||||
@@ -35,16 +35,20 @@ namespace Content.Server.MachineLinking.System
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (component.State == TwoWayLeverState.Middle)
|
if (component.State == TwoWayLeverState.Middle)
|
||||||
{
|
|
||||||
component.NextSignalLeft = !component.NextSignalLeft;
|
component.NextSignalLeft = !component.NextSignalLeft;
|
||||||
}
|
|
||||||
|
|
||||||
if (EntityManager.TryGetComponent<AppearanceComponent>(uid, out var appearanceComponent))
|
if (TryComp(uid, out AppearanceComponent? appearanceComponent))
|
||||||
{
|
|
||||||
appearanceComponent.SetData(TwoWayLeverVisuals.State, component.State);
|
appearanceComponent.SetData(TwoWayLeverVisuals.State, component.State);
|
||||||
}
|
|
||||||
|
|
||||||
RaiseLocalEvent(uid, new InvokePortEvent(component.State.ToString()));
|
var port = component.State switch
|
||||||
|
{
|
||||||
|
TwoWayLeverState.Left => component.LeftPort,
|
||||||
|
TwoWayLeverState.Right => component.RightPort,
|
||||||
|
TwoWayLeverState.Middle => component.MiddlePort,
|
||||||
|
_ => throw new ArgumentOutOfRangeException()
|
||||||
|
};
|
||||||
|
|
||||||
|
_signalSystem.InvokePort(uid, port);
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
44
Content.Shared/MachineLinking/MachinePortPrototype.cs
Normal file
44
Content.Shared/MachineLinking/MachinePortPrototype.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
23
Resources/Locale/en-US/machine-linking/receiver_ports.ftl
Normal file
23
Resources/Locale/en-US/machine-linking/receiver_ports.ftl
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
signal-port-name-toggle = Toggle
|
||||||
|
signal-port-description-toggle = Toggles the state of a device.
|
||||||
|
|
||||||
|
signal-port-name-on-receiver = On
|
||||||
|
signal-port-description-on-receiver = Turns a device on.
|
||||||
|
|
||||||
|
signal-port-name-off-receiver = Off
|
||||||
|
signal-port-description-off-receiver = Turns a device off.
|
||||||
|
|
||||||
|
signal-port-name-forward = Forward
|
||||||
|
signal-port-description-forward = Makes a device (e.g. conveyer) operate in the normal direction.
|
||||||
|
|
||||||
|
signal-port-name-reverse = Reverse
|
||||||
|
signal-port-description-reverse = Makes a device (e.g. conveyer) operate in the reverse direction.
|
||||||
|
|
||||||
|
signal-port-name-open = Open
|
||||||
|
signal-port-description-open = Opens a device.
|
||||||
|
|
||||||
|
signal-port-name-close = Close
|
||||||
|
signal-port-description-close = Closes a device.
|
||||||
|
|
||||||
|
signal-port-name-trigger = Trigger
|
||||||
|
signal-port-description-trigger = Triggers some mechanism on the device.
|
||||||
17
Resources/Locale/en-US/machine-linking/transmitter_ports.ftl
Normal file
17
Resources/Locale/en-US/machine-linking/transmitter_ports.ftl
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
signal-port-name-pressed = Pressed
|
||||||
|
signal-port-description-pressed = This port is invoked whenever the transmitter is activated.
|
||||||
|
|
||||||
|
signal-port-name-on-transmitter = On
|
||||||
|
signal-port-description-on-transmitter = This port is invoked whenever the transmitter is turned on.
|
||||||
|
|
||||||
|
signal-port-name-off-transmitter = Off
|
||||||
|
signal-port-description-off-transmitter = This port is invoked whenever the transmitter is turned off.
|
||||||
|
|
||||||
|
signal-port-name-left = Left
|
||||||
|
signal-port-description-left = This port is invoked whenever the lever is moved to the leftmost position.
|
||||||
|
|
||||||
|
signal-port-name-right = Right
|
||||||
|
signal-port-description-right = This port is invoked whenever the lever is moved to the rightmost position.
|
||||||
|
|
||||||
|
signal-port-name-middle = Middle
|
||||||
|
signal-port-description-middle = This port is invoked whenever the lever is moved to the neutral position.
|
||||||
@@ -40,9 +40,11 @@
|
|||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Structures/Wallmounts/switch.rsi
|
sprite: Structures/Wallmounts/switch.rsi
|
||||||
state: dead
|
state: dead
|
||||||
- type: SignalButton
|
|
||||||
- type: UseDelay
|
- type: UseDelay
|
||||||
delay: 0.5 # prevent light-toggling auto-clickers.
|
delay: 0.5 # prevent light-toggling auto-clickers.
|
||||||
|
- type: SignalSwitch
|
||||||
|
onPort: Pressed
|
||||||
|
offPort: Pressed
|
||||||
- type: Rotatable
|
- type: Rotatable
|
||||||
- type: Construction
|
- type: Construction
|
||||||
graph: SignalButtonGraph
|
graph: SignalButtonGraph
|
||||||
|
|||||||
39
Resources/Prototypes/MachineLinking/receiver_ports.yml
Normal file
39
Resources/Prototypes/MachineLinking/receiver_ports.yml
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
- 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
|
||||||
35
Resources/Prototypes/MachineLinking/transmitter_ports.yml
Normal file
35
Resources/Prototypes/MachineLinking/transmitter_ports.yml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
- 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: 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]
|
||||||
Reference in New Issue
Block a user