Add default link verb for machine linking (#7413)
This commit is contained in:
@@ -1,15 +1,12 @@
|
|||||||
using Robust.Shared.GameObjects;
|
|
||||||
using Robust.Shared.ViewVariables;
|
|
||||||
|
|
||||||
namespace Content.Server.MachineLinking.Components
|
namespace Content.Server.MachineLinking.Components
|
||||||
{
|
{
|
||||||
[RegisterComponent]
|
[RegisterComponent]
|
||||||
public sealed class SignalLinkerComponent : Component
|
public sealed class SignalLinkerComponent : Component
|
||||||
{
|
{
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public EntityUid? savedTransmitter;
|
public EntityUid? SavedTransmitter;
|
||||||
|
|
||||||
[ViewVariables]
|
[ViewVariables]
|
||||||
public EntityUid? savedReceiver;
|
public EntityUid? SavedReceiver;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using Content.Shared.Popups;
|
|||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
using Robust.Shared.Player;
|
using Robust.Shared.Player;
|
||||||
|
using Content.Shared.Verbs;
|
||||||
|
|
||||||
namespace Content.Server.MachineLinking.System
|
namespace Content.Server.MachineLinking.System
|
||||||
{
|
{
|
||||||
@@ -37,10 +38,12 @@ namespace Content.Server.MachineLinking.System
|
|||||||
SubscribeLocalEvent<SignalTransmitterComponent, ComponentStartup>(OnTransmitterStartup);
|
SubscribeLocalEvent<SignalTransmitterComponent, ComponentStartup>(OnTransmitterStartup);
|
||||||
SubscribeLocalEvent<SignalTransmitterComponent, ComponentRemove>(OnTransmitterRemoved);
|
SubscribeLocalEvent<SignalTransmitterComponent, ComponentRemove>(OnTransmitterRemoved);
|
||||||
SubscribeLocalEvent<SignalTransmitterComponent, InteractUsingEvent>(OnTransmitterInteractUsing);
|
SubscribeLocalEvent<SignalTransmitterComponent, InteractUsingEvent>(OnTransmitterInteractUsing);
|
||||||
|
SubscribeLocalEvent<SignalTransmitterComponent, GetVerbsEvent<AlternativeVerb>>(OnGetTransmitterVerbs);
|
||||||
|
|
||||||
SubscribeLocalEvent<SignalReceiverComponent, ComponentStartup>(OnReceiverStartup);
|
SubscribeLocalEvent<SignalReceiverComponent, ComponentStartup>(OnReceiverStartup);
|
||||||
SubscribeLocalEvent<SignalReceiverComponent, ComponentRemove>(OnReceiverRemoved);
|
SubscribeLocalEvent<SignalReceiverComponent, ComponentRemove>(OnReceiverRemoved);
|
||||||
SubscribeLocalEvent<SignalReceiverComponent, InteractUsingEvent>(OnReceiverInteractUsing);
|
SubscribeLocalEvent<SignalReceiverComponent, InteractUsingEvent>(OnReceiverInteractUsing);
|
||||||
|
SubscribeLocalEvent<SignalReceiverComponent, GetVerbsEvent<AlternativeVerb>>(OnGetReceiverVerbs);
|
||||||
|
|
||||||
SubscribeLocalEvent<SignalLinkerComponent, SignalPortSelected>(OnSignalPortSelected);
|
SubscribeLocalEvent<SignalLinkerComponent, SignalPortSelected>(OnSignalPortSelected);
|
||||||
SubscribeLocalEvent<SignalLinkerComponent, LinkerClearSelected>(OnLinkerClearSelected);
|
SubscribeLocalEvent<SignalLinkerComponent, LinkerClearSelected>(OnLinkerClearSelected);
|
||||||
@@ -48,6 +51,71 @@ namespace Content.Server.MachineLinking.System
|
|||||||
SubscribeLocalEvent<SignalLinkerComponent, BoundUIClosedEvent>(OnLinkerUIClosed);
|
SubscribeLocalEvent<SignalLinkerComponent, BoundUIClosedEvent>(OnLinkerUIClosed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add an alt-click verb to allow users to link the default ports, without needing to open the UI.
|
||||||
|
/// </summary>
|
||||||
|
private void OnGetReceiverVerbs(EntityUid uid, SignalReceiverComponent component, GetVerbsEvent<AlternativeVerb> args)
|
||||||
|
{
|
||||||
|
if (!args.CanAccess || !args.CanInteract)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!TryComp(args.Using, out SignalLinkerComponent? linker))
|
||||||
|
return;
|
||||||
|
|
||||||
|
AlternativeVerb verb = new()
|
||||||
|
{
|
||||||
|
Text = Loc.GetString("signal-linking-verb-text-link-default"),
|
||||||
|
IconEntity = args.Using
|
||||||
|
};
|
||||||
|
args.Verbs.Add(verb);
|
||||||
|
|
||||||
|
if (linker.SavedTransmitter != null)
|
||||||
|
{
|
||||||
|
verb.Act = () =>
|
||||||
|
{
|
||||||
|
var msg = TryLinkDefaults(uid, linker.SavedTransmitter.Value, component)
|
||||||
|
? Loc.GetString("signal-linking-verb-success", ("machine", linker.SavedTransmitter.Value))
|
||||||
|
: Loc.GetString("signal-linking-verb-fail", ("machine", linker.SavedTransmitter.Value));
|
||||||
|
_popupSystem.PopupEntity(msg, uid, Filter.Entities(args.User));
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
verb.Disabled = true;
|
||||||
|
verb.Message = Loc.GetString("signal-linking-verb-disabled-no-transmitter");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnGetTransmitterVerbs(EntityUid uid, SignalTransmitterComponent component, GetVerbsEvent<AlternativeVerb> args)
|
||||||
|
{
|
||||||
|
if (!args.CanAccess || !args.CanInteract)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!TryComp(args.Using, out SignalLinkerComponent? linker))
|
||||||
|
return;
|
||||||
|
|
||||||
|
AlternativeVerb verb = new()
|
||||||
|
{
|
||||||
|
Text = Loc.GetString("signal-linking-verb-text-link-default"),
|
||||||
|
IconEntity = args.Using
|
||||||
|
};
|
||||||
|
args.Verbs.Add(verb);
|
||||||
|
|
||||||
|
if (linker.SavedReceiver != null)
|
||||||
|
{
|
||||||
|
verb.Act = () =>
|
||||||
|
{
|
||||||
|
var msg = TryLinkDefaults(linker.SavedReceiver.Value, uid, null, component)
|
||||||
|
? Loc.GetString("signal-linking-verb-success", ("machine", linker.SavedReceiver.Value))
|
||||||
|
: Loc.GetString("signal-linking-verb-fail", ("machine", linker.SavedReceiver.Value));
|
||||||
|
_popupSystem.PopupEntity(msg, uid, Filter.Entities(args.User));
|
||||||
|
};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
verb.Disabled = true;
|
||||||
|
verb.Message = Loc.GetString("signal-linking-verb-disabled-no-receiver");
|
||||||
|
}
|
||||||
|
|
||||||
private void OnTransmitterInvokePort(EntityUid uid, SignalTransmitterComponent component, InvokePortEvent args)
|
private void OnTransmitterInvokePort(EntityUid uid, SignalTransmitterComponent component, InvokePortEvent args)
|
||||||
{
|
{
|
||||||
foreach (var receiver in component.Outputs[args.Port])
|
foreach (var receiver in component.Outputs[args.Port])
|
||||||
@@ -120,9 +188,9 @@ namespace Content.Server.MachineLinking.System
|
|||||||
!TryComp(args.User, out ActorComponent? actor))
|
!TryComp(args.User, out ActorComponent? actor))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
linker.savedTransmitter = uid;
|
linker.SavedTransmitter = uid;
|
||||||
|
|
||||||
if (!TryComp(linker.savedReceiver, out SignalReceiverComponent? receiver))
|
if (!TryComp(linker.SavedReceiver, out SignalReceiverComponent? receiver))
|
||||||
{
|
{
|
||||||
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-saved", ("machine", uid)),
|
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-saved", ("machine", uid)),
|
||||||
Filter.Entities(args.User));
|
Filter.Entities(args.User));
|
||||||
@@ -146,9 +214,9 @@ namespace Content.Server.MachineLinking.System
|
|||||||
!TryComp(args.User, out ActorComponent? actor))
|
!TryComp(args.User, out ActorComponent? actor))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
linker.savedReceiver = uid;
|
linker.SavedReceiver = uid;
|
||||||
|
|
||||||
if (!TryComp(linker.savedTransmitter, out SignalTransmitterComponent? transmitter))
|
if (!TryComp(linker.SavedTransmitter, out SignalTransmitterComponent? transmitter))
|
||||||
{
|
{
|
||||||
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-saved", ("machine", uid)),
|
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-saved", ("machine", uid)),
|
||||||
Filter.Entities(args.User));
|
Filter.Entities(args.User));
|
||||||
@@ -193,13 +261,13 @@ namespace Content.Server.MachineLinking.System
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryLink(SignalTransmitterComponent transmitter, SignalReceiverComponent receiver, SignalPortSelected args, EntityUid? popupUid = null)
|
private bool TryLink(SignalTransmitterComponent transmitter, SignalReceiverComponent receiver, SignalPortSelected args, EntityUid? popupUid = null, bool checkRange = true)
|
||||||
{
|
{
|
||||||
if (!transmitter.Outputs.TryGetValue(args.TransmitterPort, out var receivers) ||
|
if (!transmitter.Outputs.TryGetValue(args.TransmitterPort, out var receivers) ||
|
||||||
!receiver.Inputs.TryGetValue(args.ReceiverPort, out var transmitters))
|
!receiver.Inputs.TryGetValue(args.ReceiverPort, out var transmitters))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!IsInRange(transmitter, receiver))
|
if (checkRange && !IsInRange(transmitter, receiver))
|
||||||
{
|
{
|
||||||
if (popupUid.HasValue)
|
if (popupUid.HasValue)
|
||||||
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-out-of-range"),
|
_popupSystem.PopupCursor(Loc.GetString("signal-linker-component-out-of-range"),
|
||||||
@@ -239,8 +307,8 @@ namespace Content.Server.MachineLinking.System
|
|||||||
|
|
||||||
private void OnSignalPortSelected(EntityUid uid, SignalLinkerComponent linker, SignalPortSelected args)
|
private void OnSignalPortSelected(EntityUid uid, SignalLinkerComponent linker, SignalPortSelected args)
|
||||||
{
|
{
|
||||||
if (!TryComp(linker.savedTransmitter, out SignalTransmitterComponent? transmitter) ||
|
if (!TryComp(linker.SavedTransmitter, out SignalTransmitterComponent? transmitter) ||
|
||||||
!TryComp(linker.savedReceiver, out SignalReceiverComponent? receiver) ||
|
!TryComp(linker.SavedReceiver, out SignalReceiverComponent? receiver) ||
|
||||||
!transmitter.Outputs.TryGetValue(args.TransmitterPort, out var receivers) ||
|
!transmitter.Outputs.TryGetValue(args.TransmitterPort, out var receivers) ||
|
||||||
!receiver.Inputs.TryGetValue(args.ReceiverPort, out var transmitters))
|
!receiver.Inputs.TryGetValue(args.ReceiverPort, out var transmitters))
|
||||||
return;
|
return;
|
||||||
@@ -277,8 +345,8 @@ namespace Content.Server.MachineLinking.System
|
|||||||
|
|
||||||
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) ||
|
||||||
!TryComp(linker.savedReceiver, out SignalReceiverComponent? receiver))
|
!TryComp(linker.SavedReceiver, out SignalReceiverComponent? receiver))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach (var (port, receivers) in transmitter.Outputs)
|
foreach (var (port, receivers) in transmitter.Outputs)
|
||||||
@@ -294,12 +362,28 @@ namespace Content.Server.MachineLinking.System
|
|||||||
|
|
||||||
private void OnLinkerLinkDefaultSelected(EntityUid uid, SignalLinkerComponent linker, LinkerLinkDefaultSelected args)
|
private void OnLinkerLinkDefaultSelected(EntityUid uid, SignalLinkerComponent linker, LinkerLinkDefaultSelected args)
|
||||||
{
|
{
|
||||||
if (!TryComp(linker.savedTransmitter, out SignalTransmitterComponent? transmitter) ||
|
if (!TryComp(linker.SavedTransmitter, out SignalTransmitterComponent? transmitter) ||
|
||||||
!TryComp(linker.savedReceiver, out SignalReceiverComponent? receiver) ||
|
!TryComp(linker.SavedReceiver, out SignalReceiverComponent? receiver))
|
||||||
args.Session.AttachedEntity is not EntityUid attached || attached == default ||
|
|
||||||
!TryComp(attached, out ActorComponent? actor))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
TryLinkDefaults(linker.SavedReceiver!.Value, linker.SavedTransmitter!.Value, receiver, transmitter);
|
||||||
|
TryUpdateUI(linker, transmitter, receiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempt to link all default ports connections. Returns true if all links succeeded. Otherwise returns
|
||||||
|
/// false.
|
||||||
|
/// </summary>
|
||||||
|
public bool TryLinkDefaults(EntityUid receiverUid, EntityUid transmitterUid, SignalReceiverComponent? receiver = null, SignalTransmitterComponent? transmitter = null)
|
||||||
|
{
|
||||||
|
if (!Resolve(receiverUid, ref receiver, false) || !Resolve(transmitterUid, ref transmitter, false))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!IsInRange(transmitter, receiver))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var allLinksSucceeded = true;
|
||||||
|
|
||||||
if (_defaultMappings.TryFirstOrDefault(map => !map.ExceptBy(transmitter.Outputs.Keys, item => item.Item1).Any() &&
|
if (_defaultMappings.TryFirstOrDefault(map => !map.ExceptBy(transmitter.Outputs.Keys, item => item.Item1).Any() &&
|
||||||
!map.ExceptBy(receiver.Inputs.Keys, item => item.Item2).Any(), out var mapping))
|
!map.ExceptBy(receiver.Inputs.Keys, item => item.Item2).Any(), out var mapping))
|
||||||
{
|
{
|
||||||
@@ -312,16 +396,16 @@ namespace Content.Server.MachineLinking.System
|
|||||||
RaiseLocalEvent(receiver.Owner, new PortDisconnectedEvent(port));
|
RaiseLocalEvent(receiver.Owner, new PortDisconnectedEvent(port));
|
||||||
|
|
||||||
foreach (var (t, r) in mapping)
|
foreach (var (t, r) in mapping)
|
||||||
TryLink(transmitter, receiver, new(t, r));
|
allLinksSucceeded &= TryLink(transmitter, receiver, new(t, r), checkRange: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
TryUpdateUI(linker, transmitter, receiver);
|
return allLinksSucceeded;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnLinkerUIClosed(EntityUid uid, SignalLinkerComponent component, BoundUIClosedEvent args)
|
private void OnLinkerUIClosed(EntityUid uid, SignalLinkerComponent component, BoundUIClosedEvent args)
|
||||||
{
|
{
|
||||||
component.savedTransmitter = null;
|
component.SavedTransmitter = null;
|
||||||
component.savedReceiver = null;
|
component.SavedReceiver = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsInRange(SignalTransmitterComponent transmitterComponent, SignalReceiverComponent receiverComponent)
|
private bool IsInRange(SignalTransmitterComponent transmitterComponent, SignalReceiverComponent receiverComponent)
|
||||||
|
|||||||
@@ -8,3 +8,10 @@ signal-linker-component-max-connections-transmitter = Maximum connections reache
|
|||||||
signal-linker-component-type-mismatch = The port's type does not match the type of the saved port!
|
signal-linker-component-type-mismatch = The port's type does not match the type of the saved port!
|
||||||
|
|
||||||
signal-linker-component-out-of-range = Connection is out of range!
|
signal-linker-component-out-of-range = Connection is out of range!
|
||||||
|
|
||||||
|
# Verbs
|
||||||
|
signal-linking-verb-text-link-default = Link default ports
|
||||||
|
signal-linking-verb-success = Connected all default {$machine} links.
|
||||||
|
signal-linking-verb-fail = Failed to connect all default {$machine} links.
|
||||||
|
signal-linking-verb-disabled-no-transmitter = You first need to interact with a transmitter.
|
||||||
|
signal-linking-verb-disabled-no-receiver = You first need to interact with a receiver.
|
||||||
Reference in New Issue
Block a user