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); } }