AutoLink port from Outer Rim (#10967)

* C# half of Outer Rim commit 5081906bd17e715ecae422dd7a003d9f103e6884 "autolink gaming."

Ported from Outer Rim with permission.

* YAML half of Outer Rim commit 5081906bd17e715ecae422dd7a003d9f103e6884 "autolink gaming."

Ported from Outer Rim with permission.

* commit fixed AL summary

Co-authored-by: Moony <moonheart08@users.noreply.github.com>

* NewLinkEvent.User & LinkAttemptEvent.User now nullable, fix possible AccessReaderSystem AutoLink bug

Co-authored-by: Moony <moonheart08@users.noreply.github.com>
This commit is contained in:
20kdc
2022-09-03 19:30:57 +01:00
committed by GitHub
parent dbc5ffa9e7
commit 547af7c7e8
9 changed files with 212 additions and 15 deletions

View File

@@ -0,0 +1,12 @@
namespace Content.Server.MachineLinking.Components;
/// <summary>
/// This is used for automatic linkage with buttons and other transmitters.
/// </summary>
[RegisterComponent]
public sealed class AutoLinkReceiverComponent : Component
{
[DataField("channel", required: true, readOnly: true)]
public string AutoLinkChannel = default!;
}

View File

@@ -0,0 +1,12 @@
namespace Content.Server.MachineLinking.Components;
/// <summary>
/// This is used for automatic linkage with various receivers, like shutters.
/// </summary>
[RegisterComponent]
public sealed class AutoLinkTransmitterComponent : Component
{
[DataField("channel", required: true, readOnly: true)]
public string AutoLinkChannel = default!;
}

View File

@@ -0,0 +1,36 @@
using Content.Server.MachineLinking.Components;
namespace Content.Server.MachineLinking.System;
/// <summary>
/// This handles automatically linking autolinked entities at round-start.
/// </summary>
public sealed class AutoLinkSystem : EntitySystem
{
[Dependency] private readonly SignalLinkerSystem _signalLinkerSystem = default!;
/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<AutoLinkTransmitterComponent, MapInitEvent>(OnAutoLinkMapInit);
}
private void OnAutoLinkMapInit(EntityUid uid, AutoLinkTransmitterComponent component, MapInitEvent args)
{
var xform = Transform(uid);
foreach (var receiver in EntityQuery<AutoLinkReceiverComponent>())
{
if (receiver.AutoLinkChannel != component.AutoLinkChannel)
continue; // Not ours.
var rxXform = Transform(receiver.Owner);
if (rxXform.GridUid != xform.GridUid)
continue;
_signalLinkerSystem.TryLinkDefaults(receiver.Owner, uid, null);
}
}
}

View File

@@ -277,12 +277,15 @@ 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 linkedReceivers) ||
!receiver.Inputs.TryGetValue(args.ReceiverPort, out var linkedTransmitters))
return false;
// Accounts for possibly missing user & the quiet option.
var alertFilter = (!quiet && user != null) ? Filter.Entities(user.Value) : null;
// Does the link already exist? Under the assumption that nothing has broken, lets only check the
// transmitter ports.
foreach (var identifier in linkedTransmitters)
@@ -293,9 +296,9 @@ namespace Content.Server.MachineLinking.System
if (checkRange && !IsInRange(transmitter, receiver))
{
if (!quiet)
if (alertFilter != null)
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-out-of-range"),
Filter.Entities(user));
alertFilter);
return false;
}
@@ -304,27 +307,27 @@ namespace Content.Server.MachineLinking.System
RaiseLocalEvent(transmitter.Owner, linkAttempt, true);
if (linkAttempt.Cancelled)
{
if (!quiet)
if (alertFilter != null)
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-connection-refused", ("machine", transmitter.Owner)),
Filter.Entities(user));
alertFilter);
return false;
}
RaiseLocalEvent(receiver.Owner, linkAttempt, true);
if (linkAttempt.Cancelled)
{
if (!quiet)
if (alertFilter != null)
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-connection-refused", ("machine", receiver.Owner)),
Filter.Entities(user));
alertFilter);
return false;
}
linkedReceivers.Add(new(receiver.Owner, args.ReceiverPort));
linkedTransmitters.Add(new(transmitter.Owner, args.TransmitterPort));
if (!quiet)
if (alertFilter != null)
_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))),
Filter.Entities(user), PopupType.Medium);
alertFilter, PopupType.Medium);
var newLink = new NewLinkEvent(user, transmitter.Owner, args.TransmitterPort, receiver.Owner, args.ReceiverPort);
RaiseLocalEvent(receiver.Owner, newLink);
@@ -417,7 +420,7 @@ namespace Content.Server.MachineLinking.System
/// Attempt to link all default ports connections. Returns true if all links succeeded. Otherwise returns
/// false.
/// </summary>
public bool TryLinkDefaults(EntityUid receiverUid, EntityUid transmitterUid, EntityUid user,
public bool TryLinkDefaults(EntityUid receiverUid, EntityUid transmitterUid, EntityUid? user,
SignalReceiverComponent? receiver = null, SignalTransmitterComponent? transmitter = null)
{
if (!Resolve(receiverUid, ref receiver, false) || !Resolve(transmitterUid, ref transmitter, false))