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:
@@ -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!;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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!;
|
||||||
|
}
|
||||||
|
|
||||||
36
Content.Server/MachineLinking/System/AutoLinkSystem.cs
Normal file
36
Content.Server/MachineLinking/System/AutoLinkSystem.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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) ||
|
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;
|
||||||
|
|
||||||
|
// 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
|
// Does the link already exist? Under the assumption that nothing has broken, lets only check the
|
||||||
// transmitter ports.
|
// transmitter ports.
|
||||||
foreach (var identifier in linkedTransmitters)
|
foreach (var identifier in linkedTransmitters)
|
||||||
@@ -293,9 +296,9 @@ namespace Content.Server.MachineLinking.System
|
|||||||
|
|
||||||
if (checkRange && !IsInRange(transmitter, receiver))
|
if (checkRange && !IsInRange(transmitter, receiver))
|
||||||
{
|
{
|
||||||
if (!quiet)
|
if (alertFilter != null)
|
||||||
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-out-of-range"),
|
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-out-of-range"),
|
||||||
Filter.Entities(user));
|
alertFilter);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,27 +307,27 @@ namespace Content.Server.MachineLinking.System
|
|||||||
RaiseLocalEvent(transmitter.Owner, linkAttempt, true);
|
RaiseLocalEvent(transmitter.Owner, linkAttempt, true);
|
||||||
if (linkAttempt.Cancelled)
|
if (linkAttempt.Cancelled)
|
||||||
{
|
{
|
||||||
if (!quiet)
|
if (alertFilter != null)
|
||||||
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-connection-refused", ("machine", transmitter.Owner)),
|
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-connection-refused", ("machine", transmitter.Owner)),
|
||||||
Filter.Entities(user));
|
alertFilter);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
RaiseLocalEvent(receiver.Owner, linkAttempt, true);
|
RaiseLocalEvent(receiver.Owner, linkAttempt, true);
|
||||||
if (linkAttempt.Cancelled)
|
if (linkAttempt.Cancelled)
|
||||||
{
|
{
|
||||||
if (!quiet)
|
if (alertFilter != null)
|
||||||
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-connection-refused", ("machine", receiver.Owner)),
|
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-connection-refused", ("machine", receiver.Owner)),
|
||||||
Filter.Entities(user));
|
alertFilter);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 (alertFilter != null)
|
||||||
_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))),
|
||||||
Filter.Entities(user), PopupType.Medium);
|
alertFilter, 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);
|
||||||
@@ -417,7 +420,7 @@ namespace Content.Server.MachineLinking.System
|
|||||||
/// Attempt to link all default ports connections. Returns true if all links succeeded. Otherwise returns
|
/// Attempt to link all default ports connections. Returns true if all links succeeded. Otherwise returns
|
||||||
/// false.
|
/// false.
|
||||||
/// </summary>
|
/// </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)
|
SignalReceiverComponent? receiver = null, SignalTransmitterComponent? transmitter = null)
|
||||||
{
|
{
|
||||||
if (!Resolve(receiverUid, ref receiver, false) || !Resolve(transmitterUid, ref transmitter, false))
|
if (!Resolve(receiverUid, ref receiver, false) || !Resolve(transmitterUid, ref transmitter, false))
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ namespace Content.Shared.Access.Systems
|
|||||||
|
|
||||||
private void OnLinkAttempt(EntityUid uid, AccessReaderComponent component, LinkAttemptEvent args)
|
private void OnLinkAttempt(EntityUid uid, AccessReaderComponent component, LinkAttemptEvent args)
|
||||||
{
|
{
|
||||||
if (component.Enabled && !IsAllowed(args.User, component))
|
if (args.User == null) // AutoLink (and presumably future external linkers) have no user.
|
||||||
|
return;
|
||||||
|
if (component.Enabled && !IsAllowed(args.User.Value, component))
|
||||||
args.Cancel();
|
args.Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ namespace Content.Shared.MachineLinking.Events
|
|||||||
{
|
{
|
||||||
public readonly EntityUid Transmitter;
|
public readonly EntityUid Transmitter;
|
||||||
public readonly EntityUid Receiver;
|
public readonly EntityUid Receiver;
|
||||||
public readonly EntityUid User;
|
public readonly EntityUid? User;
|
||||||
public readonly string TransmitterPort;
|
public readonly string TransmitterPort;
|
||||||
public readonly string ReceiverPort;
|
public readonly string ReceiverPort;
|
||||||
|
|
||||||
public LinkAttemptEvent(EntityUid user, EntityUid transmitter, string transmitterPort, EntityUid receiver, string receiverPort)
|
public LinkAttemptEvent(EntityUid? user, EntityUid transmitter, string transmitterPort, EntityUid receiver, string receiverPort)
|
||||||
{
|
{
|
||||||
User = user;
|
User = user;
|
||||||
Transmitter = transmitter;
|
Transmitter = transmitter;
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ namespace Content.Shared.MachineLinking.Events
|
|||||||
{
|
{
|
||||||
public readonly EntityUid Transmitter;
|
public readonly EntityUid Transmitter;
|
||||||
public readonly EntityUid Receiver;
|
public readonly EntityUid Receiver;
|
||||||
public readonly EntityUid User;
|
public readonly EntityUid? User;
|
||||||
public readonly string TransmitterPort;
|
public readonly string TransmitterPort;
|
||||||
public readonly string ReceiverPort;
|
public readonly string ReceiverPort;
|
||||||
|
|
||||||
public NewLinkEvent(EntityUid user, EntityUid transmitter, string transmitterPort, EntityUid receiver, string receiverPort)
|
public NewLinkEvent(EntityUid? user, EntityUid transmitter, string transmitterPort, EntityUid receiver, string receiverPort)
|
||||||
{
|
{
|
||||||
User = user;
|
User = user;
|
||||||
Transmitter = transmitter;
|
Transmitter = transmitter;
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
# AutoLink variants of BlastDoor (from Outer Rim)
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: BlastDoorExterior1
|
||||||
|
parent: BlastDoor
|
||||||
|
suffix: Autolink, Ext1
|
||||||
|
components:
|
||||||
|
- type: AutoLinkReceiver
|
||||||
|
channel: Ext1
|
||||||
|
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: BlastDoorExterior1Open
|
||||||
|
parent: BlastDoorOpen
|
||||||
|
suffix: Open, Autolink, Ext1
|
||||||
|
components:
|
||||||
|
- type: AutoLinkReceiver
|
||||||
|
channel: Ext1
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: BlastDoorExterior2
|
||||||
|
parent: BlastDoor
|
||||||
|
suffix: Autolink, Ext2
|
||||||
|
components:
|
||||||
|
- type: AutoLinkReceiver
|
||||||
|
channel: Ext2
|
||||||
|
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: BlastDoorExterior2Open
|
||||||
|
parent: BlastDoorOpen
|
||||||
|
suffix: Open, Autolink, Ext2
|
||||||
|
components:
|
||||||
|
- type: AutoLinkReceiver
|
||||||
|
channel: Ext2
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: BlastDoorExterior3
|
||||||
|
parent: BlastDoor
|
||||||
|
suffix: Autolink, Ext3
|
||||||
|
components:
|
||||||
|
- type: AutoLinkReceiver
|
||||||
|
channel: Ext3
|
||||||
|
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: BlastDoorExterior3Open
|
||||||
|
parent: BlastDoorOpen
|
||||||
|
suffix: Open, Autolink, Ext3
|
||||||
|
components:
|
||||||
|
- type: AutoLinkReceiver
|
||||||
|
channel: Ext3
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: BlastDoorBridge
|
||||||
|
parent: BlastDoor
|
||||||
|
suffix: Autolink, Bridge
|
||||||
|
components:
|
||||||
|
- type: AutoLinkReceiver
|
||||||
|
channel: Bridge
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: BlastDoorBridgeOpen
|
||||||
|
parent: BlastDoorOpen
|
||||||
|
suffix: Open, Autolink, Bridge
|
||||||
|
components:
|
||||||
|
- type: AutoLinkReceiver
|
||||||
|
channel: Bridge
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: BlastDoorWindows
|
||||||
|
parent: BlastDoor
|
||||||
|
suffix: Autolink, Windows
|
||||||
|
components:
|
||||||
|
- type: AutoLinkReceiver
|
||||||
|
channel: Windows
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: BlastDoorWindowsOpen
|
||||||
|
parent: BlastDoorOpen
|
||||||
|
suffix: Open, Autolink, Windows
|
||||||
|
components:
|
||||||
|
- type: AutoLinkReceiver
|
||||||
|
channel: Windows
|
||||||
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# AutoLink variants of SignalButton (from Outer Rim)
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: SignalButtonExt1
|
||||||
|
parent: SignalButton
|
||||||
|
name: exterior button 1
|
||||||
|
suffix: Autolink, Ext1
|
||||||
|
components:
|
||||||
|
- type: AutoLinkTransmitter
|
||||||
|
channel: Ext1
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: SignalButtonExt2
|
||||||
|
parent: SignalButton
|
||||||
|
name: exterior button 2
|
||||||
|
suffix: Autolink, Ext2
|
||||||
|
components:
|
||||||
|
- type: AutoLinkTransmitter
|
||||||
|
channel: Ext2
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: SignalButtonExt3
|
||||||
|
parent: SignalButton
|
||||||
|
name: exterior button 3
|
||||||
|
suffix: Autolink, Ext3
|
||||||
|
components:
|
||||||
|
- type: AutoLinkTransmitter
|
||||||
|
channel: Ext3
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: SignalButtonBridge
|
||||||
|
parent: SignalButton
|
||||||
|
name: bridge windows button
|
||||||
|
suffix: Autolink, Bridge
|
||||||
|
components:
|
||||||
|
- type: AutoLinkTransmitter
|
||||||
|
channel: Bridge
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
id: SignalButtonWindows
|
||||||
|
parent: SignalButton
|
||||||
|
name: exterior windows button
|
||||||
|
suffix: Autolink, Windows
|
||||||
|
components:
|
||||||
|
- type: AutoLinkTransmitter
|
||||||
|
channel: Windows
|
||||||
|
|
||||||
Reference in New Issue
Block a user