Add interlocking airlocks (#14177)
Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
@@ -38,6 +38,57 @@ public sealed class PrototypeSaveTest
|
|||||||
{
|
{
|
||||||
"Singularity", // physics collision uses "AllMask" (-1). The flag serializer currently fails to save this because this features un-named bits.
|
"Singularity", // physics collision uses "AllMask" (-1). The flag serializer currently fails to save this because this features un-named bits.
|
||||||
"constructionghost",
|
"constructionghost",
|
||||||
|
// URGH door pr but I just don't
|
||||||
|
"BlastDoorBridgeOpen",
|
||||||
|
"Windoor",
|
||||||
|
"WindoorSecure",
|
||||||
|
"WindoorSecureCargoLocked",
|
||||||
|
"WindoorTheatreLocked",
|
||||||
|
"BlastDoorBridge",
|
||||||
|
"WindoorSecureJanitorLocked",
|
||||||
|
"ShuttersWindow",
|
||||||
|
"WindoorScienceLocked",
|
||||||
|
"WindoorJanitorLocked",
|
||||||
|
"WindoorEngineeringLocked",
|
||||||
|
"BlastDoorExterior2",
|
||||||
|
"WindoorChemistryLocked",
|
||||||
|
"BlastDoorExterior3",
|
||||||
|
"WindoorMedicalLocked",
|
||||||
|
"ShuttersNormalOpen",
|
||||||
|
"WindoorBarKitchenLocked",
|
||||||
|
"BlastDoorOpen",
|
||||||
|
"ShuttersRadiationOpen",
|
||||||
|
"BlastDoorWindowsOpen",
|
||||||
|
"WindoorBarLocked",
|
||||||
|
"WindoorChapelLocked",
|
||||||
|
"WindoorArmoryLocked",
|
||||||
|
"BlastDoorExterior3Open",
|
||||||
|
"WindoorCargoLocked",
|
||||||
|
"WindoorSecurityLocked",
|
||||||
|
"WindoorExternalLocked",
|
||||||
|
"WindoorBrigLocked",
|
||||||
|
"WindoorHydroponicsLocked",
|
||||||
|
"ShuttersWindowOpen",
|
||||||
|
"WindoorKitchenHydroponicsLocked",
|
||||||
|
"WindoorSecureChapelLocked",
|
||||||
|
"BlastDoorExterior1Open",
|
||||||
|
"WindoorKitchenLocked",
|
||||||
|
"BlastDoor",
|
||||||
|
"BlastDoorWindows",
|
||||||
|
"BlastDoorExterior1",
|
||||||
|
"BlastDoorExterior2Open",
|
||||||
|
"WindoorSecureKitchenLocked",
|
||||||
|
"WindoorHeadOfPersonnelLocked",
|
||||||
|
"ShuttersRadiation",
|
||||||
|
"ShuttersNormal",
|
||||||
|
"WindoorSecureSalvageLocked",
|
||||||
|
"WindoorServiceLocked",
|
||||||
|
"WindoorCommandLocked",
|
||||||
|
"AirlockMaintMedLocked",
|
||||||
|
"AirlockArmoryGlassLocked",
|
||||||
|
"AirlockExternalGlassLocked",
|
||||||
|
"AirlockFreezerKitchenHydroLocked",
|
||||||
|
"AirlockGlassShuttle",
|
||||||
};
|
};
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
@@ -14,5 +14,11 @@ namespace Content.Server.DeviceLinking.Components
|
|||||||
|
|
||||||
[DataField("togglePort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))]
|
[DataField("togglePort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))]
|
||||||
public string TogglePort = "Toggle";
|
public string TogglePort = "Toggle";
|
||||||
|
|
||||||
|
[DataField("boltPort", customTypeSerializer: typeof(PrototypeIdSerializer<ReceiverPortPrototype>))]
|
||||||
|
public string InBolt = "DoorBolt";
|
||||||
|
|
||||||
|
[DataField("onOpenPort", customTypeSerializer: typeof(PrototypeIdSerializer<TransmitterPortPrototype>))]
|
||||||
|
public string OutOpen = "DoorStatus";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +1,37 @@
|
|||||||
using Content.Server.DeviceLinking.Components;
|
using Content.Server.DeviceLinking.Components;
|
||||||
using Content.Server.DeviceLinking.Events;
|
using Content.Server.DeviceNetwork;
|
||||||
using Content.Server.Doors.Systems;
|
using Content.Server.Doors.Systems;
|
||||||
|
using Content.Server.MachineLinking.Events;
|
||||||
using Content.Server.MachineLinking.System;
|
using Content.Server.MachineLinking.System;
|
||||||
using Content.Shared.Doors.Components;
|
using Content.Shared.Doors.Components;
|
||||||
|
using Content.Shared.Doors;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
using SignalReceivedEvent = Content.Server.DeviceLinking.Events.SignalReceivedEvent;
|
||||||
|
|
||||||
namespace Content.Server.DeviceLinking.Systems
|
namespace Content.Server.DeviceLinking.Systems
|
||||||
{
|
{
|
||||||
[UsedImplicitly]
|
[UsedImplicitly]
|
||||||
public sealed class DoorSignalControlSystem : EntitySystem
|
public sealed class DoorSignalControlSystem : EntitySystem
|
||||||
{
|
{
|
||||||
|
[Dependency] private readonly AirlockSystem _airlockSystem = default!;
|
||||||
[Dependency] private readonly DoorSystem _doorSystem = default!;
|
[Dependency] private readonly DoorSystem _doorSystem = default!;
|
||||||
[Dependency] private readonly DeviceLinkSystem _signalSystem = default!;
|
[Dependency] private readonly DeviceLinkSystem _signalSystem = default!;
|
||||||
|
|
||||||
|
private const string DoorSignalState = "DoorState";
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
SubscribeLocalEvent<DoorSignalControlComponent, ComponentInit>(OnInit);
|
SubscribeLocalEvent<DoorSignalControlComponent, ComponentInit>(OnInit);
|
||||||
SubscribeLocalEvent<DoorSignalControlComponent, SignalReceivedEvent>(OnSignalReceived);
|
SubscribeLocalEvent<DoorSignalControlComponent, SignalReceivedEvent>(OnSignalReceived);
|
||||||
|
SubscribeLocalEvent<DoorSignalControlComponent, DoorStateChangedEvent>(OnStateChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnInit(EntityUid uid, DoorSignalControlComponent component, ComponentInit args)
|
private void OnInit(EntityUid uid, DoorSignalControlComponent component, ComponentInit args)
|
||||||
{
|
{
|
||||||
|
|
||||||
_signalSystem.EnsureSinkPorts(uid, component.OpenPort, component.ClosePort, component.TogglePort);
|
_signalSystem.EnsureSinkPorts(uid, component.OpenPort, component.ClosePort, component.TogglePort);
|
||||||
|
_signalSystem.EnsureSourcePorts(uid, component.OutOpen);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnSignalReceived(EntityUid uid, DoorSignalControlComponent component, ref SignalReceivedEvent args)
|
private void OnSignalReceived(EntityUid uid, DoorSignalControlComponent component, ref SignalReceivedEvent args)
|
||||||
@@ -30,19 +39,67 @@ namespace Content.Server.DeviceLinking.Systems
|
|||||||
if (!TryComp(uid, out DoorComponent? door))
|
if (!TryComp(uid, out DoorComponent? door))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
var state = SignalState.Momentary;
|
||||||
|
args.Data?.TryGetValue(DoorSignalState, out state);
|
||||||
|
|
||||||
|
|
||||||
if (args.Port == component.OpenPort)
|
if (args.Port == component.OpenPort)
|
||||||
{
|
{
|
||||||
if (door.State != DoorState.Open)
|
if (state == SignalState.High || state == SignalState.Momentary)
|
||||||
_doorSystem.TryOpen(uid, door);
|
{
|
||||||
|
if (door.State != DoorState.Open)
|
||||||
|
_doorSystem.TryOpen(uid, door);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (args.Port == component.ClosePort)
|
else if (args.Port == component.ClosePort)
|
||||||
{
|
{
|
||||||
if (door.State != DoorState.Closed)
|
if (state == SignalState.High || state == SignalState.Momentary)
|
||||||
_doorSystem.TryClose(uid, door);
|
{
|
||||||
|
if (door.State != DoorState.Closed)
|
||||||
|
_doorSystem.TryClose(uid, door);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (args.Port == component.TogglePort)
|
else if (args.Port == component.TogglePort)
|
||||||
{
|
{
|
||||||
_doorSystem.TryToggleDoor(uid, door);
|
if (state == SignalState.High || state == SignalState.Momentary)
|
||||||
|
{
|
||||||
|
_doorSystem.TryToggleDoor(uid, door);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (args.Port == component.InBolt)
|
||||||
|
{
|
||||||
|
if (state == SignalState.High)
|
||||||
|
{
|
||||||
|
if(TryComp<AirlockComponent>(uid, out var airlockComponent))
|
||||||
|
_airlockSystem.SetBoltsWithAudio(uid, airlockComponent, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(TryComp<AirlockComponent>(uid, out var airlockComponent))
|
||||||
|
_airlockSystem.SetBoltsWithAudio(uid, airlockComponent, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnStateChanged(EntityUid uid, DoorSignalControlComponent door, DoorStateChangedEvent args)
|
||||||
|
{
|
||||||
|
var data = new NetworkPayload()
|
||||||
|
{
|
||||||
|
{ DoorSignalState, SignalState.Momentary }
|
||||||
|
};
|
||||||
|
|
||||||
|
if (args.State == DoorState.Closed)
|
||||||
|
{
|
||||||
|
data[DoorSignalState] = SignalState.Low;
|
||||||
|
_signalSystem.InvokePort(uid, door.OutOpen, data);
|
||||||
|
}
|
||||||
|
else if (args.State == DoorState.Open
|
||||||
|
|| args.State == DoorState.Opening
|
||||||
|
|| args.State == DoorState.Closing
|
||||||
|
|| args.State == DoorState.Emagging)
|
||||||
|
{
|
||||||
|
data[DoorSignalState] = SignalState.High;
|
||||||
|
_signalSystem.InvokePort(uid, door.OutOpen, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using Content.Server.Access;
|
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.Components;
|
||||||
using Content.Shared.Access.Systems;
|
using Content.Shared.Access.Systems;
|
||||||
@@ -30,9 +30,7 @@ public sealed class DoorSystem : SharedDoorSystem
|
|||||||
[Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!;
|
[Dependency] private readonly AccessReaderSystem _accessReaderSystem = default!;
|
||||||
[Dependency] private readonly AirlockSystem _airlock = default!;
|
[Dependency] private readonly AirlockSystem _airlock = default!;
|
||||||
[Dependency] private readonly AirtightSystem _airtightSystem = default!;
|
[Dependency] private readonly AirtightSystem _airtightSystem = default!;
|
||||||
[Dependency] private readonly ConstructionSystem _constructionSystem = default!;
|
|
||||||
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
|
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
|
||||||
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
|
|||||||
28
Content.Server/MachineLinking/Components/OrGateComponent.cs
Normal file
28
Content.Server/MachineLinking/Components/OrGateComponent.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using Content.Server.MachineLinking.Events;
|
||||||
|
using Content.Shared.MachineLinking;
|
||||||
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||||
|
|
||||||
|
namespace Content.Server.MachineLinking.Components;
|
||||||
|
|
||||||
|
[RegisterComponent]
|
||||||
|
public sealed class OrGateComponent : Component
|
||||||
|
{
|
||||||
|
// Initial state
|
||||||
|
[ViewVariables]
|
||||||
|
public SignalState StateA1 = SignalState.Low;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
public SignalState StateB1 = SignalState.Low;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
public SignalState LastO1 = SignalState.Low;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
public SignalState StateA2 = SignalState.Low;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
public SignalState StateB2 = SignalState.Low;
|
||||||
|
|
||||||
|
[ViewVariables]
|
||||||
|
public SignalState LastO2 = SignalState.Low;
|
||||||
|
}
|
||||||
@@ -20,5 +20,16 @@ namespace Content.Server.MachineLinking.Components
|
|||||||
[DataField("requiredQuality", customTypeSerializer: typeof(PrototypeIdSerializer<ToolQualityPrototype>))]
|
[DataField("requiredQuality", customTypeSerializer: typeof(PrototypeIdSerializer<ToolQualityPrototype>))]
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
public string? RequiredQuality;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Content.Server.MachineLinking.Events;
|
||||||
using Content.Server.MachineLinking.System;
|
using Content.Server.MachineLinking.System;
|
||||||
|
|
||||||
namespace Content.Server.MachineLinking.Components
|
namespace Content.Server.MachineLinking.Components
|
||||||
@@ -31,6 +32,13 @@ namespace Content.Server.MachineLinking.Components
|
|||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
public float TransmissionRange = 30f;
|
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")]
|
[DataField("outputs")]
|
||||||
[Access(typeof(SignalLinkerSystem), Other = AccessPermissions.ReadExecute)] // FIXME Friends
|
[Access(typeof(SignalLinkerSystem), Other = AccessPermissions.ReadExecute)] // FIXME Friends
|
||||||
public Dictionary<string, List<PortIdentifier>> Outputs = new();
|
public Dictionary<string, List<PortIdentifier>> Outputs = new();
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
namespace Content.Server.MachineLinking.Events
|
||||||
|
{
|
||||||
|
public enum SignalState
|
||||||
|
{
|
||||||
|
Momentary, // Instantaneous pulse high, compatibility behavior
|
||||||
|
Low,
|
||||||
|
High
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class SignalReceivedEvent : EntityEventArgs
|
||||||
|
{
|
||||||
|
public readonly string Port;
|
||||||
|
public readonly SignalState State;
|
||||||
|
public readonly EntityUid? Trigger;
|
||||||
|
|
||||||
|
public SignalReceivedEvent(string port, EntityUid? trigger, SignalState state)
|
||||||
|
{
|
||||||
|
Port = port;
|
||||||
|
Trigger = trigger;
|
||||||
|
State = state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
63
Content.Server/MachineLinking/System/OrGateSystem.cs
Normal file
63
Content.Server/MachineLinking/System/OrGateSystem.cs
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
using Content.Server.MachineLinking.Components;
|
||||||
|
using Content.Server.MachineLinking.Events;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
|
||||||
|
namespace Content.Server.MachineLinking.System
|
||||||
|
{
|
||||||
|
[UsedImplicitly]
|
||||||
|
public sealed class OrGateSystem : EntitySystem
|
||||||
|
{
|
||||||
|
[Dependency] private readonly SignalLinkerSystem _signalSystem = default!;
|
||||||
|
|
||||||
|
public override void Initialize()
|
||||||
|
{
|
||||||
|
base.Initialize();
|
||||||
|
SubscribeLocalEvent<OrGateComponent, ComponentInit>(OnInit);
|
||||||
|
SubscribeLocalEvent<OrGateComponent, SignalReceivedEvent>(OnSignalReceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnInit(EntityUid uid, OrGateComponent component, ComponentInit args)
|
||||||
|
{
|
||||||
|
_signalSystem.EnsureReceiverPorts(uid, "A1", "B1", "A2", "B2");
|
||||||
|
_signalSystem.EnsureTransmitterPorts(uid, "O1", "O2");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSignalReceived(EntityUid uid, OrGateComponent component, SignalReceivedEvent args)
|
||||||
|
{
|
||||||
|
if (args.Port == "A1")
|
||||||
|
{
|
||||||
|
component.StateA1 = args.State;
|
||||||
|
}
|
||||||
|
else if (args.Port == "B1")
|
||||||
|
{
|
||||||
|
component.StateB1 = args.State;
|
||||||
|
}
|
||||||
|
else if (args.Port == "A2")
|
||||||
|
{
|
||||||
|
component.StateA2 = args.State;
|
||||||
|
}
|
||||||
|
else if (args.Port == "B2")
|
||||||
|
{
|
||||||
|
component.StateB2 = args.State;
|
||||||
|
}
|
||||||
|
|
||||||
|
// O1 = A1 || B1
|
||||||
|
var v1 = SignalState.Low;
|
||||||
|
if (component.StateA1 == SignalState.High || component.StateB1 == SignalState.High)
|
||||||
|
v1 = SignalState.High;
|
||||||
|
|
||||||
|
if (v1 != component.LastO1)
|
||||||
|
_signalSystem.InvokePort(uid, "O1", v1);
|
||||||
|
component.LastO1 = v1;
|
||||||
|
|
||||||
|
// O2 = A2 || B2
|
||||||
|
var v2 = SignalState.Low;
|
||||||
|
if (component.StateA2 == SignalState.High || component.StateB2 == SignalState.High)
|
||||||
|
v2 = SignalState.High;
|
||||||
|
|
||||||
|
if (v2 != component.LastO2)
|
||||||
|
_signalSystem.InvokePort(uid, "O2", v2);
|
||||||
|
component.LastO2 = v2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using Content.Server.DeviceLinking.Events;
|
|
||||||
using Content.Server.MachineLinking.Components;
|
using Content.Server.MachineLinking.Components;
|
||||||
|
using Content.Server.MachineLinking.Events;
|
||||||
using Content.Server.Power.Components;
|
using Content.Server.Power.Components;
|
||||||
using Content.Server.Tools;
|
using Content.Server.Tools;
|
||||||
using Content.Shared.DeviceLinking.Events;
|
using Content.Shared.DeviceLinking.Events;
|
||||||
@@ -11,6 +11,7 @@ using Content.Shared.Popups;
|
|||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Content.Shared.Verbs;
|
using Content.Shared.Verbs;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
using SignalReceivedEvent = Content.Server.DeviceLinking.Events.SignalReceivedEvent;
|
||||||
|
|
||||||
namespace Content.Server.MachineLinking.System
|
namespace Content.Server.MachineLinking.System
|
||||||
{
|
{
|
||||||
@@ -49,7 +50,7 @@ namespace Content.Server.MachineLinking.System
|
|||||||
var comp = EnsureComp<SignalReceiverComponent>(uid);
|
var comp = EnsureComp<SignalReceiverComponent>(uid);
|
||||||
foreach (var port in ports)
|
foreach (var port in ports)
|
||||||
{
|
{
|
||||||
comp.Inputs.TryAdd(port, new());
|
comp.Inputs.TryAdd(port, new List<PortIdentifier>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +59,7 @@ namespace Content.Server.MachineLinking.System
|
|||||||
var comp = EnsureComp<SignalTransmitterComponent>(uid);
|
var comp = EnsureComp<SignalTransmitterComponent>(uid);
|
||||||
foreach (var port in ports)
|
foreach (var port in ports)
|
||||||
{
|
{
|
||||||
comp.Outputs.TryAdd(port, new());
|
comp.Outputs.TryAdd(port, new List<PortIdentifier>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,9 +73,11 @@ namespace Content.Server.MachineLinking.System
|
|||||||
|
|
||||||
if (!TryComp(args.Using, out SignalLinkerComponent? linker) ||
|
if (!TryComp(args.Using, out SignalLinkerComponent? linker) ||
|
||||||
!IsLinkerInteractable(args.Using.Value, linker))
|
!IsLinkerInteractable(args.Using.Value, linker))
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
AlternativeVerb verb = new()
|
var verb = new AlternativeVerb()
|
||||||
{
|
{
|
||||||
Text = Loc.GetString("signal-linking-verb-text-link-default"),
|
Text = Loc.GetString("signal-linking-verb-text-link-default"),
|
||||||
IconEntity = args.Using
|
IconEntity = args.Using
|
||||||
@@ -130,13 +133,25 @@ namespace Content.Server.MachineLinking.System
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void InvokePort(EntityUid uid, string port, SignalTransmitterComponent? component = null)
|
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))
|
if (!Resolve(uid, ref component))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (state != SignalState.Momentary && state == component.LastState)
|
||||||
|
{
|
||||||
|
// no change in output signal
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!component.Outputs.TryGetValue(port, out var receivers))
|
if (!component.Outputs.TryGetValue(port, out var receivers))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
component.LastState = state;
|
||||||
foreach (var receiver in receivers)
|
foreach (var receiver in receivers)
|
||||||
{
|
{
|
||||||
var eventArgs = new SignalReceivedEvent(receiver.Port, uid);
|
var eventArgs = new SignalReceivedEvent(receiver.Port, uid);
|
||||||
@@ -149,6 +164,7 @@ namespace Content.Server.MachineLinking.System
|
|||||||
// validate links
|
// validate links
|
||||||
Dictionary<EntityUid, SignalReceiverComponent?> uidCache = new();
|
Dictionary<EntityUid, SignalReceiverComponent?> uidCache = new();
|
||||||
foreach (var tport in transmitter.Outputs)
|
foreach (var tport in transmitter.Outputs)
|
||||||
|
{
|
||||||
foreach (var rport in tport.Value)
|
foreach (var rport in tport.Value)
|
||||||
{
|
{
|
||||||
if (!uidCache.TryGetValue(rport.Uid, out var receiver))
|
if (!uidCache.TryGetValue(rport.Uid, out var receiver))
|
||||||
@@ -158,6 +174,7 @@ namespace Content.Server.MachineLinking.System
|
|||||||
else if (!rpv.Contains(new(uid, tport.Key)))
|
else if (!rpv.Contains(new(uid, tport.Key)))
|
||||||
rpv.Add(new(uid, tport.Key));
|
rpv.Add(new(uid, tport.Key));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnReceiverStartup(EntityUid uid, SignalReceiverComponent receiver, ComponentStartup args)
|
private void OnReceiverStartup(EntityUid uid, SignalReceiverComponent receiver, ComponentStartup args)
|
||||||
@@ -208,12 +225,16 @@ namespace Content.Server.MachineLinking.System
|
|||||||
|
|
||||||
private void OnTransmitterInteractUsing(EntityUid uid, SignalTransmitterComponent transmitter, InteractUsingEvent args)
|
private void OnTransmitterInteractUsing(EntityUid uid, SignalTransmitterComponent transmitter, InteractUsingEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled) return;
|
if (args.Handled)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!TryComp(args.Used, out SignalLinkerComponent? linker) || !IsLinkerInteractable(args.Used, linker) ||
|
if (!TryComp(args.Used, out SignalLinkerComponent? linker) || !IsLinkerInteractable(args.Used, linker) ||
|
||||||
!TryComp(args.User, out ActorComponent? actor))
|
!TryComp(args.User, out ActorComponent? actor))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!linker.LinkTX())
|
||||||
|
return;
|
||||||
|
|
||||||
linker.SavedTransmitter = uid;
|
linker.SavedTransmitter = uid;
|
||||||
|
|
||||||
if (!TryComp(linker.SavedReceiver, out SignalReceiverComponent? receiver))
|
if (!TryComp(linker.SavedReceiver, out SignalReceiverComponent? receiver))
|
||||||
@@ -233,12 +254,16 @@ namespace Content.Server.MachineLinking.System
|
|||||||
|
|
||||||
private void OnReceiverInteractUsing(EntityUid uid, SignalReceiverComponent receiver, InteractUsingEvent args)
|
private void OnReceiverInteractUsing(EntityUid uid, SignalReceiverComponent receiver, InteractUsingEvent args)
|
||||||
{
|
{
|
||||||
if (args.Handled) return;
|
if (args.Handled)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!TryComp(args.Used, out SignalLinkerComponent? linker) || !IsLinkerInteractable(args.Used, linker) ||
|
if (!TryComp(args.Used, out SignalLinkerComponent? linker) || !IsLinkerInteractable(args.Used, linker) ||
|
||||||
!TryComp(args.User, out ActorComponent? actor))
|
!TryComp(args.User, out ActorComponent? actor))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!linker.LinkRX())
|
||||||
|
return;
|
||||||
|
|
||||||
linker.SavedReceiver = uid;
|
linker.SavedReceiver = uid;
|
||||||
|
|
||||||
if (!TryComp(linker.SavedTransmitter, out SignalTransmitterComponent? transmitter))
|
if (!TryComp(linker.SavedTransmitter, out SignalTransmitterComponent? transmitter))
|
||||||
@@ -274,10 +299,14 @@ namespace Content.Server.MachineLinking.System
|
|||||||
var outKeys = transmitter.Outputs.Keys.ToList();
|
var outKeys = transmitter.Outputs.Keys.ToList();
|
||||||
var inKeys = receiver.Inputs.Keys.ToList();
|
var inKeys = receiver.Inputs.Keys.ToList();
|
||||||
List<(int, int)> links = new();
|
List<(int, int)> links = new();
|
||||||
for (int i = 0; i < outKeys.Count; i++)
|
for (var i = 0; i < outKeys.Count; i++)
|
||||||
|
{
|
||||||
foreach (var re in transmitter.Outputs[outKeys[i]])
|
foreach (var re in transmitter.Outputs[outKeys[i]])
|
||||||
|
{
|
||||||
if (re.Uid == receiver.Owner)
|
if (re.Uid == receiver.Owner)
|
||||||
links.Add((i, inKeys.IndexOf(re.Port)));
|
links.Add((i, inKeys.IndexOf(re.Port)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bui.SetState(new SignalPortsState($"{Name(transmitter.Owner)} ({transmitter.Owner})", outKeys,
|
bui.SetState(new SignalPortsState($"{Name(transmitter.Owner)} ({transmitter.Owner})", outKeys,
|
||||||
$"{Name(receiver.Owner)} ({receiver.Owner})", inKeys, links));
|
$"{Name(receiver.Owner)} ({receiver.Owner})", inKeys, links));
|
||||||
@@ -289,7 +318,9 @@ namespace Content.Server.MachineLinking.System
|
|||||||
{
|
{
|
||||||
if (!transmitter.Outputs.TryGetValue(args.TransmitterPort, out var linkedReceivers) ||
|
if (!transmitter.Outputs.TryGetValue(args.TransmitterPort, out var linkedReceivers) ||
|
||||||
!receiver.Inputs.TryGetValue(args.ReceiverPort, out var linkedTransmitters))
|
!receiver.Inputs.TryGetValue(args.ReceiverPort, out var linkedTransmitters))
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
quiet |= !user.HasValue;
|
quiet |= !user.HasValue;
|
||||||
|
|
||||||
@@ -328,10 +359,12 @@ namespace Content.Server.MachineLinking.System
|
|||||||
linkedReceivers.Add(new(receiver.Owner, args.ReceiverPort));
|
linkedReceivers.Add(new(receiver.Owner, args.ReceiverPort));
|
||||||
linkedTransmitters.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", PortName<TransmitterPortPrototype>(args.TransmitterPort)),
|
("machine1", transmitter.Owner), ("port1", PortName<TransmitterPortPrototype>(args.TransmitterPort)),
|
||||||
("machine2", receiver.Owner), ("port2", PortName<ReceiverPortPrototype>(args.ReceiverPort))),
|
("machine2", receiver.Owner), ("port2", PortName<ReceiverPortPrototype>(args.ReceiverPort))),
|
||||||
user!.Value, PopupType.Medium);
|
user!.Value, PopupType.Medium);
|
||||||
|
}
|
||||||
|
|
||||||
var newLink = new NewLinkEvent(user, transmitter.Owner, args.TransmitterPort, receiver.Owner, args.ReceiverPort);
|
var newLink = new NewLinkEvent(user, transmitter.Owner, args.TransmitterPort, receiver.Owner, args.ReceiverPort);
|
||||||
RaiseLocalEvent(receiver.Owner, newLink);
|
RaiseLocalEvent(receiver.Owner, newLink);
|
||||||
@@ -353,12 +386,14 @@ namespace Content.Server.MachineLinking.System
|
|||||||
|
|
||||||
if (receivers.Contains(new(receiver.Owner, args.ReceiverPort)) ||
|
if (receivers.Contains(new(receiver.Owner, args.ReceiverPort)) ||
|
||||||
transmitters.Contains(new(transmitter.Owner, args.TransmitterPort)))
|
transmitters.Contains(new(transmitter.Owner, args.TransmitterPort)))
|
||||||
{ // link already exists, remove it
|
{
|
||||||
|
// link already exists, remove it
|
||||||
if (receivers.Remove(new(receiver.Owner, args.ReceiverPort)) &&
|
if (receivers.Remove(new(receiver.Owner, args.ReceiverPort)) &&
|
||||||
transmitters.Remove(new(transmitter.Owner, args.TransmitterPort)))
|
transmitters.Remove(new(transmitter.Owner, args.TransmitterPort)))
|
||||||
{
|
{
|
||||||
RaiseLocalEvent(receiver.Owner, new PortDisconnectedEvent(args.ReceiverPort), true);
|
RaiseLocalEvent(receiver.Owner, new PortDisconnectedEvent(args.ReceiverPort), true);
|
||||||
RaiseLocalEvent(transmitter.Owner, new PortDisconnectedEvent(args.TransmitterPort), true);
|
RaiseLocalEvent(transmitter.Owner, new PortDisconnectedEvent(args.TransmitterPort), true);
|
||||||
|
|
||||||
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-unlinked-port",
|
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-unlinked-port",
|
||||||
("machine1", transmitter.Owner), ("port1", PortName<TransmitterPortPrototype>(args.TransmitterPort)),
|
("machine1", transmitter.Owner), ("port1", PortName<TransmitterPortPrototype>(args.TransmitterPort)),
|
||||||
("machine2", receiver.Owner), ("port2", PortName<ReceiverPortPrototype>(args.ReceiverPort))),
|
("machine2", receiver.Owner), ("port2", PortName<ReceiverPortPrototype>(args.ReceiverPort))),
|
||||||
@@ -397,12 +432,16 @@ namespace Content.Server.MachineLinking.System
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (var (port, receivers) in transmitter.Outputs)
|
foreach (var (port, receivers) in transmitter.Outputs)
|
||||||
|
{
|
||||||
if (receivers.RemoveAll(id => id.Uid == receiver.Owner) > 0)
|
if (receivers.RemoveAll(id => id.Uid == receiver.Owner) > 0)
|
||||||
RaiseLocalEvent(transmitter.Owner, new PortDisconnectedEvent(port), true);
|
RaiseLocalEvent(transmitter.Owner, new PortDisconnectedEvent(port), true);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var (port, transmitters) in receiver.Inputs)
|
foreach (var (port, transmitters) in receiver.Inputs)
|
||||||
|
{
|
||||||
if (transmitters.RemoveAll(id => id.Uid == transmitter.Owner) > 0)
|
if (transmitters.RemoveAll(id => id.Uid == transmitter.Owner) > 0)
|
||||||
RaiseLocalEvent(receiver.Owner, new PortDisconnectedEvent(port), true);
|
RaiseLocalEvent(receiver.Owner, new PortDisconnectedEvent(port), true);
|
||||||
|
}
|
||||||
|
|
||||||
TryUpdateUI(linker, transmitter, receiver);
|
TryUpdateUI(linker, transmitter, receiver);
|
||||||
}
|
}
|
||||||
@@ -437,12 +476,16 @@ namespace Content.Server.MachineLinking.System
|
|||||||
|
|
||||||
// First, disconnect existing links.
|
// First, disconnect existing links.
|
||||||
foreach (var (port, receivers) in transmitter.Outputs)
|
foreach (var (port, receivers) in transmitter.Outputs)
|
||||||
|
{
|
||||||
if (receivers.RemoveAll(id => id.Uid == receiver.Owner) > 0)
|
if (receivers.RemoveAll(id => id.Uid == receiver.Owner) > 0)
|
||||||
RaiseLocalEvent(transmitter.Owner, new PortDisconnectedEvent(port), true);
|
RaiseLocalEvent(transmitter.Owner, new PortDisconnectedEvent(port), true);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (var (port, transmitters) in receiver.Inputs)
|
foreach (var (port, transmitters) in receiver.Inputs)
|
||||||
|
{
|
||||||
if (transmitters.RemoveAll(id => id.Uid == transmitter.Owner) > 0)
|
if (transmitters.RemoveAll(id => id.Uid == transmitter.Owner) > 0)
|
||||||
RaiseLocalEvent(receiver.Owner, new PortDisconnectedEvent(port), true);
|
RaiseLocalEvent(receiver.Owner, new PortDisconnectedEvent(port), true);
|
||||||
|
}
|
||||||
|
|
||||||
// Then make any valid default connections.
|
// Then make any valid default connections.
|
||||||
foreach (var outPort in transmitter.Outputs.Keys)
|
foreach (var outPort in transmitter.Outputs.Keys)
|
||||||
@@ -474,6 +517,7 @@ namespace Content.Server.MachineLinking.System
|
|||||||
transmitterPower.Provider?.Net == receiverPower.Provider?.Net)
|
transmitterPower.Provider?.Net == receiverPower.Provider?.Net)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// TODO: As elsewhere don't use mappos inrange.
|
||||||
return Comp<TransformComponent>(transmitterComponent.Owner).MapPosition.InRange(
|
return Comp<TransformComponent>(transmitterComponent.Owner).MapPosition.InRange(
|
||||||
Comp<TransformComponent>(receiverComponent.Owner).MapPosition, transmitterComponent.TransmissionRange);
|
Comp<TransformComponent>(receiverComponent.Owner).MapPosition, transmitterComponent.TransmissionRange);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -442,6 +442,7 @@ public abstract class SharedDeviceLinkSystem : EntitySystem
|
|||||||
|
|
||||||
private bool InRange(EntityUid sourceUid, EntityUid sinkUid, float range)
|
private bool InRange(EntityUid sourceUid, EntityUid sinkUid, float range)
|
||||||
{
|
{
|
||||||
|
// TODO: This should be using an existing method and also coordinates inrange instead.
|
||||||
return Transform(sourceUid).MapPosition.InRange(Transform(sinkUid).MapPosition, range);
|
return Transform(sourceUid).MapPosition.InRange(Transform(sinkUid).MapPosition, range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -131,6 +131,10 @@ public abstract class SharedDoorSystem : EntitySystem
|
|||||||
if (!Resolve(uid, ref door))
|
if (!Resolve(uid, ref door))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// If no change, return to avoid firing a new DoorStateChangedEvent.
|
||||||
|
if (state == door.State)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case DoorState.Opening:
|
case DoorState.Opening:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
signal-port-name-toggle = Autoclose
|
signal-port-name-autoclose = Autoclose
|
||||||
signal-port-description-toggle = Toggles whether the device should automatically close.
|
signal-port-description-autoclose = Toggles whether the device should automatically close.
|
||||||
|
|
||||||
signal-port-name-toggle = Toggle
|
signal-port-name-toggle = Toggle
|
||||||
signal-port-description-toggle = Toggles the state of a device.
|
signal-port-description-toggle = Toggles the state of a device.
|
||||||
@@ -22,6 +22,9 @@ signal-port-description-open = Opens a device.
|
|||||||
signal-port-name-close = Close
|
signal-port-name-close = Close
|
||||||
signal-port-description-close = Closes a device.
|
signal-port-description-close = Closes a device.
|
||||||
|
|
||||||
|
signal-port-name-doorbolt = Door bolt
|
||||||
|
signal-port-description-doorbolt = Toggles door bolt.
|
||||||
|
|
||||||
signal-port-name-trigger = Trigger
|
signal-port-name-trigger = Trigger
|
||||||
signal-port-description-trigger = Triggers some mechanism on the device.
|
signal-port-description-trigger = Triggers some mechanism on the device.
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ signal-port-description-left = This port is invoked whenever the lever is moved
|
|||||||
signal-port-name-right = Right
|
signal-port-name-right = Right
|
||||||
signal-port-description-right = This port is invoked whenever the lever is moved to the rightmost position.
|
signal-port-description-right = This port is invoked whenever the lever is moved to the rightmost position.
|
||||||
|
|
||||||
|
signal-port-name-doorstatus = Door status
|
||||||
|
signal-port-description-doorstatus = This port is invoked whenever the door's status changes.
|
||||||
|
|
||||||
signal-port-name-middle = Middle
|
signal-port-name-middle = Middle
|
||||||
signal-port-description-middle = This port is invoked whenever the lever is moved to the neutral position.
|
signal-port-description-middle = This port is invoked whenever the lever is moved to the neutral position.
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,11 @@
|
|||||||
name: signal-port-name-close
|
name: signal-port-name-close
|
||||||
description: signal-port-description-close
|
description: signal-port-description-close
|
||||||
|
|
||||||
|
- type: sinkPort
|
||||||
|
id: DoorBolt
|
||||||
|
name: signal-port-name-doorbolt
|
||||||
|
description: signal-port-description-doorbolt
|
||||||
|
|
||||||
- type: sinkPort
|
- type: sinkPort
|
||||||
id: Trigger
|
id: Trigger
|
||||||
name: signal-port-name-trigger
|
name: signal-port-name-trigger
|
||||||
|
|||||||
@@ -34,6 +34,11 @@
|
|||||||
description: signal-port-description-middle
|
description: signal-port-description-middle
|
||||||
defaultLinks: [ Off, Close ]
|
defaultLinks: [ Off, Close ]
|
||||||
|
|
||||||
|
- type: sourcePort
|
||||||
|
id: DoorStatus
|
||||||
|
name: signal-port-name-doorstatus
|
||||||
|
description: signal-port-description-status
|
||||||
|
|
||||||
- type: sourcePort
|
- type: sourcePort
|
||||||
id: OrderSender
|
id: OrderSender
|
||||||
name: signal-port-name-order-sender
|
name: signal-port-name-order-sender
|
||||||
|
|||||||
@@ -89,6 +89,10 @@
|
|||||||
- Close
|
- Close
|
||||||
- Toggle
|
- Toggle
|
||||||
- AutoClose
|
- AutoClose
|
||||||
|
- DoorBolt
|
||||||
|
- type: DeviceLinkSource
|
||||||
|
ports:
|
||||||
|
- DoorStatus
|
||||||
- type: UserInterface
|
- type: UserInterface
|
||||||
interfaces:
|
interfaces:
|
||||||
- key: enum.WiresUiKey.Key
|
- key: enum.WiresUiKey.Key
|
||||||
|
|||||||
26
Resources/Prototypes/Entities/Structures/gates.yml
Normal file
26
Resources/Prototypes/Entities/Structures/gates.yml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
- type: entity
|
||||||
|
id: OrGate
|
||||||
|
name: MS7432
|
||||||
|
description: Dual 2-Input OR Gate
|
||||||
|
parent: BaseItem
|
||||||
|
placement:
|
||||||
|
mode: SnapgridCenter
|
||||||
|
snap:
|
||||||
|
- Wallmount
|
||||||
|
components:
|
||||||
|
- type: Anchorable
|
||||||
|
- type: Sprite
|
||||||
|
sprite: Objects/Devices/gates.rsi
|
||||||
|
state: or
|
||||||
|
- type: Rotatable
|
||||||
|
- type: OrGate
|
||||||
|
- type: SignalReceiver
|
||||||
|
inputs:
|
||||||
|
A1: []
|
||||||
|
B1: []
|
||||||
|
A2: []
|
||||||
|
B2: []
|
||||||
|
- type: SignalTransmitter
|
||||||
|
outputs:
|
||||||
|
O1: []
|
||||||
|
O2: []
|
||||||
@@ -72,3 +72,28 @@
|
|||||||
id: ArtifactAnalyzerReceiver
|
id: ArtifactAnalyzerReceiver
|
||||||
name: signal-port-name-artifact-analyzer-receiver
|
name: signal-port-name-artifact-analyzer-receiver
|
||||||
description: signal-port-description-artifact-analyzer-receiver
|
description: signal-port-description-artifact-analyzer-receiver
|
||||||
|
|
||||||
|
- type: receiverPort
|
||||||
|
id: DoorBolt
|
||||||
|
name: "Bolt"
|
||||||
|
description: "Bolt door when HIGH."
|
||||||
|
|
||||||
|
- type: receiverPort
|
||||||
|
id: A1
|
||||||
|
name: "Input A1"
|
||||||
|
description: "Input A1"
|
||||||
|
|
||||||
|
- type: receiverPort
|
||||||
|
id: B1
|
||||||
|
name: "Input B1"
|
||||||
|
description: "Input B1"
|
||||||
|
|
||||||
|
- type: receiverPort
|
||||||
|
id: A2
|
||||||
|
name: "Input A2"
|
||||||
|
description: "Input A2"
|
||||||
|
|
||||||
|
- type: receiverPort
|
||||||
|
id: B2
|
||||||
|
name: "Input B2"
|
||||||
|
description: "Input B2"
|
||||||
|
|||||||
@@ -67,3 +67,18 @@
|
|||||||
name: signal-port-name-artifact-analyzer-sender
|
name: signal-port-name-artifact-analyzer-sender
|
||||||
description: signal-port-description-artifact-analyzer-sender
|
description: signal-port-description-artifact-analyzer-sender
|
||||||
defaultLinks: [ ArtifactAnalyzerReceiver ]
|
defaultLinks: [ ArtifactAnalyzerReceiver ]
|
||||||
|
|
||||||
|
- type: transmitterPort
|
||||||
|
id: DoorStatus
|
||||||
|
name: "Door Status"
|
||||||
|
description: "HIGH when door is open, LOW when door is closed."
|
||||||
|
|
||||||
|
- type: transmitterPort
|
||||||
|
id: O1
|
||||||
|
name: "Output 1"
|
||||||
|
description: "Output 1"
|
||||||
|
|
||||||
|
- type: transmitterPort
|
||||||
|
id: O2
|
||||||
|
name: "Output 2"
|
||||||
|
description: "Output 2"
|
||||||
|
|||||||
14
Resources/Textures/Objects/Devices/gates.rsi/meta.json
Normal file
14
Resources/Textures/Objects/Devices/gates.rsi/meta.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"license": "CC-BY-SA-3.0",
|
||||||
|
"copyright": "Kevin Zheng 2022",
|
||||||
|
"size": {
|
||||||
|
"x": 32,
|
||||||
|
"y": 32
|
||||||
|
},
|
||||||
|
"states": [
|
||||||
|
{
|
||||||
|
"name": "or"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
Resources/Textures/Objects/Devices/gates.rsi/or.png
Normal file
BIN
Resources/Textures/Objects/Devices/gates.rsi/or.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
Reference in New Issue
Block a user