using Content.Shared.Interaction;
using Content.Shared.Timing;
using Content.Shared.Verbs;
using Content.Shared.Xenoarchaeology.Artifact.Components;
using Content.Shared.Xenoarchaeology.Equipment.Components;
using Robust.Shared.Timing;
namespace Content.Shared.Xenoarchaeology.Equipment;
/// Controls behaviour of artifact node scanner device.
public sealed class NodeScannerSystem : EntitySystem
{
[Dependency] private readonly UseDelaySystem _useDelay = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly SharedUserInterfaceSystem _ui = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
///
public override void Initialize()
{
SubscribeLocalEvent(OnBeforeRangedInteract);
SubscribeLocalEvent>(AddScanVerb);
}
///
public override void Update(float frameTime)
{
var scannerQuery = EntityQueryEnumerator();
while (scannerQuery.MoveNext(out var uid, out var connected, out var scanner, out var transform))
{
if (connected.NextUpdate > _timing.CurTime)
continue;
connected.NextUpdate = _timing.CurTime + connected.LinkUpdateInterval;
var attachedArtifact = connected.AttachedTo;
var artifactCoordinates = Transform(attachedArtifact).Coordinates;
if (!_transform.InRange(artifactCoordinates, transform.Coordinates, scanner.MaxLinkedRange))
{
//scanner is too far, disconnect
RemCompDeferred(uid, connected);
}
}
}
private void OnBeforeRangedInteract(EntityUid uid, NodeScannerComponent component, BeforeRangedInteractEvent args)
{
if (args.Handled || !args.CanReach || args.Target is not { } target || !HasComp(target))
return;
Entity unlockingEnt = TryComp(target, out var unlockingComponent)
? (target, unlockingComponent)
: (target, null);
Attach((uid, component), unlockingEnt, args.User);
args.Handled = true;
}
private void AddScanVerb(EntityUid uid, NodeScannerComponent component, GetVerbsEvent args)
{
if (!args.CanAccess)
return;
if (!TryComp(args.Target, out var unlockingComponent))
return;
var verb = new UtilityVerb
{
Act = () => Attach((uid, component), (args.Target, unlockingComponent), args.User),
Text = Loc.GetString("node-scan-tooltip")
};
args.Verbs.Add(verb);
}
private void Attach(
Entity device,
Entity unlockingEnt,
EntityUid actor
)
{
if (!_timing.IsFirstTimePredicted)
return;
if (TryComp(device, out UseDelayComponent? useDelay)
&& !_useDelay.TryResetDelay((device, useDelay), true))
return;
var connected = EnsureComp(device);
EntityUid artifact = unlockingEnt;
if (connected.AttachedTo != artifact)
{
connected.AttachedTo = artifact;
Dirty(device, connected);
}
_ui.TryOpenUi((device, null), NodeScannerUiKey.Key, actor, predicted: true);
}
}