Add interlocking airlocks (#14177)

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
Kevin Zheng
2023-05-06 22:49:11 -08:00
committed by GitHub
parent ea5d7d5421
commit 4e5adc2b86
22 changed files with 415 additions and 21 deletions

View File

@@ -1,7 +1,7 @@
using System.Linq;
using System.Diagnostics.CodeAnalysis;
using Content.Server.DeviceLinking.Events;
using Content.Server.MachineLinking.Components;
using Content.Server.MachineLinking.Events;
using Content.Server.Power.Components;
using Content.Server.Tools;
using Content.Shared.DeviceLinking.Events;
@@ -11,6 +11,7 @@ using Content.Shared.Popups;
using Robust.Server.GameObjects;
using Content.Shared.Verbs;
using Robust.Shared.Prototypes;
using SignalReceivedEvent = Content.Server.DeviceLinking.Events.SignalReceivedEvent;
namespace Content.Server.MachineLinking.System
{
@@ -49,7 +50,7 @@ namespace Content.Server.MachineLinking.System
var comp = EnsureComp<SignalReceiverComponent>(uid);
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);
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) ||
!IsLinkerInteractable(args.Using.Value, linker))
{
return;
}
AlternativeVerb verb = new()
var verb = new AlternativeVerb()
{
Text = Loc.GetString("signal-linking-verb-text-link-default"),
IconEntity = args.Using
@@ -130,13 +133,25 @@ namespace Content.Server.MachineLinking.System
}
public void InvokePort(EntityUid uid, string port, SignalTransmitterComponent? component = null)
{
InvokePort(uid, port, SignalState.Momentary, component);
}
public void InvokePort(EntityUid uid, string port, SignalState state, SignalTransmitterComponent? component = null)
{
if (!Resolve(uid, ref component))
return;
if (state != SignalState.Momentary && state == component.LastState)
{
// no change in output signal
return;
}
if (!component.Outputs.TryGetValue(port, out var receivers))
return;
component.LastState = state;
foreach (var receiver in receivers)
{
var eventArgs = new SignalReceivedEvent(receiver.Port, uid);
@@ -149,6 +164,7 @@ namespace Content.Server.MachineLinking.System
// validate links
Dictionary<EntityUid, SignalReceiverComponent?> uidCache = new();
foreach (var tport in transmitter.Outputs)
{
foreach (var rport in tport.Value)
{
if (!uidCache.TryGetValue(rport.Uid, out var receiver))
@@ -158,6 +174,7 @@ namespace Content.Server.MachineLinking.System
else if (!rpv.Contains(new(uid, tport.Key)))
rpv.Add(new(uid, tport.Key));
}
}
}
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)
{
if (args.Handled) return;
if (args.Handled)
return;
if (!TryComp(args.Used, out SignalLinkerComponent? linker) || !IsLinkerInteractable(args.Used, linker) ||
!TryComp(args.User, out ActorComponent? actor))
return;
if (!linker.LinkTX())
return;
linker.SavedTransmitter = uid;
if (!TryComp(linker.SavedReceiver, out SignalReceiverComponent? receiver))
@@ -233,12 +254,16 @@ namespace Content.Server.MachineLinking.System
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) ||
!TryComp(args.User, out ActorComponent? actor))
return;
if (!linker.LinkRX())
return;
linker.SavedReceiver = uid;
if (!TryComp(linker.SavedTransmitter, out SignalTransmitterComponent? transmitter))
@@ -274,10 +299,14 @@ namespace Content.Server.MachineLinking.System
var outKeys = transmitter.Outputs.Keys.ToList();
var inKeys = receiver.Inputs.Keys.ToList();
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]])
{
if (re.Uid == receiver.Owner)
links.Add((i, inKeys.IndexOf(re.Port)));
}
}
bui.SetState(new SignalPortsState($"{Name(transmitter.Owner)} ({transmitter.Owner})", outKeys,
$"{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) ||
!receiver.Inputs.TryGetValue(args.ReceiverPort, out var linkedTransmitters))
{
return false;
}
quiet |= !user.HasValue;
@@ -328,10 +359,12 @@ namespace Content.Server.MachineLinking.System
linkedReceivers.Add(new(receiver.Owner, args.ReceiverPort));
linkedTransmitters.Add(new(transmitter.Owner, args.TransmitterPort));
if (!quiet)
{
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-linked-port",
("machine1", transmitter.Owner), ("port1", PortName<TransmitterPortPrototype>(args.TransmitterPort)),
("machine2", receiver.Owner), ("port2", PortName<ReceiverPortPrototype>(args.ReceiverPort))),
("machine1", transmitter.Owner), ("port1", PortName<TransmitterPortPrototype>(args.TransmitterPort)),
("machine2", receiver.Owner), ("port2", PortName<ReceiverPortPrototype>(args.ReceiverPort))),
user!.Value, PopupType.Medium);
}
var newLink = new NewLinkEvent(user, transmitter.Owner, args.TransmitterPort, receiver.Owner, args.ReceiverPort);
RaiseLocalEvent(receiver.Owner, newLink);
@@ -353,12 +386,14 @@ namespace Content.Server.MachineLinking.System
if (receivers.Contains(new(receiver.Owner, args.ReceiverPort)) ||
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)) &&
transmitters.Remove(new(transmitter.Owner, args.TransmitterPort)))
{
RaiseLocalEvent(receiver.Owner, new PortDisconnectedEvent(args.ReceiverPort), true);
RaiseLocalEvent(transmitter.Owner, new PortDisconnectedEvent(args.TransmitterPort), true);
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-unlinked-port",
("machine1", transmitter.Owner), ("port1", PortName<TransmitterPortPrototype>(args.TransmitterPort)),
("machine2", receiver.Owner), ("port2", PortName<ReceiverPortPrototype>(args.ReceiverPort))),
@@ -397,12 +432,16 @@ namespace Content.Server.MachineLinking.System
return;
foreach (var (port, receivers) in transmitter.Outputs)
{
if (receivers.RemoveAll(id => id.Uid == receiver.Owner) > 0)
RaiseLocalEvent(transmitter.Owner, new PortDisconnectedEvent(port), true);
}
foreach (var (port, transmitters) in receiver.Inputs)
{
if (transmitters.RemoveAll(id => id.Uid == transmitter.Owner) > 0)
RaiseLocalEvent(receiver.Owner, new PortDisconnectedEvent(port), true);
}
TryUpdateUI(linker, transmitter, receiver);
}
@@ -437,12 +476,16 @@ namespace Content.Server.MachineLinking.System
// First, disconnect existing links.
foreach (var (port, receivers) in transmitter.Outputs)
{
if (receivers.RemoveAll(id => id.Uid == receiver.Owner) > 0)
RaiseLocalEvent(transmitter.Owner, new PortDisconnectedEvent(port), true);
}
foreach (var (port, transmitters) in receiver.Inputs)
{
if (transmitters.RemoveAll(id => id.Uid == transmitter.Owner) > 0)
RaiseLocalEvent(receiver.Owner, new PortDisconnectedEvent(port), true);
}
// Then make any valid default connections.
foreach (var outPort in transmitter.Outputs.Keys)
@@ -474,6 +517,7 @@ namespace Content.Server.MachineLinking.System
transmitterPower.Provider?.Net == receiverPower.Provider?.Net)
return true;
// TODO: As elsewhere don't use mappos inrange.
return Comp<TransformComponent>(transmitterComponent.Owner).MapPosition.InRange(
Comp<TransformComponent>(receiverComponent.Owner).MapPosition, transmitterComponent.TransmissionRange);
}