mirror of
https://github.com/space-syndicate/space-station-14.git
synced 2026-10-09 10:21:18 +03:00
Fix error spamming in update loop of artifact scanner (#46149)
* refactor: make relations etween node scanner and artifact more clear, remove errors on crushing artifact while scanner is attached, add generic `attached entities` collection for artifact to be used for other purposes * Apply xml-doc suggestion from @Tayrtahn Co-authored-by: Tayrtahn <tayrtahn@gmail.com> * fix: attaching scanner to other artifact now detaches it from original one * refactor: fix whitespaces in SharedXenoArtifactSystem * refactor: fix detaching artifact when scanning same artifact twice --------- Co-authored-by: Tayrtahn <tayrtahn@gmail.com>
This commit is contained in:
parent
458a3af6c1
commit
fca3302e3f
4 changed files with 109 additions and 13 deletions
|
|
@ -14,7 +14,8 @@ namespace Content.Shared.Xenoarchaeology.Artifact.Components;
|
|||
/// This is used for handling interactions with artifacts as well as
|
||||
/// storing data about artifact node graphs.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(SharedXenoArtifactSystem)), AutoGenerateComponentState, AutoGenerateComponentPause]
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, AutoGenerateComponentPause]
|
||||
[Access(typeof(SharedXenoArtifactSystem))]
|
||||
public sealed partial class XenoArtifactComponent : Component
|
||||
{
|
||||
public static string NodeContainerId = "node-container";
|
||||
|
|
@ -192,6 +193,15 @@ public sealed partial class XenoArtifactComponent : Component
|
|||
/// </summary>
|
||||
[DataField]
|
||||
public LocId? UnlockFailureMsg = "artifact-unlock-state-end-failure";
|
||||
|
||||
/// <summary>
|
||||
/// List of currently attached entities - node scanners, etc.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// TODO: replace with relationship system.
|
||||
/// </remarks>
|
||||
[DataField, AutoNetworkedField]
|
||||
public HashSet<EntityUid> AttachedEntities = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -40,6 +40,17 @@ public abstract partial class SharedXenoArtifactSystem : EntitySystem
|
|||
UpdateUnlock(frameTime);
|
||||
}
|
||||
|
||||
/// <summary> Clears all attached scanners. </summary>
|
||||
[SubscribeLocalEvent]
|
||||
private void OnShutdown(Entity<XenoArtifactComponent> ent, ref ComponentRemove shutdown)
|
||||
{
|
||||
var removedEvent = new XenoArtifactDestroyedEvent();
|
||||
foreach (var entity in ent.Comp.AttachedEntities)
|
||||
{
|
||||
RaiseLocalEvent(entity, ref removedEvent);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> As all artifacts have to contain nodes - we ensure that they are containers. </summary>
|
||||
private void OnStartup(Entity<XenoArtifactComponent> ent, ref ComponentStartup args)
|
||||
{
|
||||
|
|
@ -52,6 +63,51 @@ public abstract partial class SharedXenoArtifactSystem : EntitySystem
|
|||
args.Handled = TryActivateXenoArtifact(ent, ent, null, Transform(ent).Coordinates, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to remove an entity from the list of attached entities.
|
||||
/// This helps with tracking relationship.
|
||||
/// </summary>
|
||||
/// <param name="ent">Artifact entity.</param>
|
||||
/// <param name="entityToDetach">Entity to detach.</param>
|
||||
/// <returns>
|
||||
/// Returns false if <paramref name="ent"/> is not artifact,
|
||||
/// or if there is no such entity in list of attached ones.
|
||||
/// Otherwise, returns true.
|
||||
/// </returns>
|
||||
public bool TryDetachEntity(Entity<XenoArtifactComponent?> ent, EntityUid entityToDetach)
|
||||
{
|
||||
if (!Resolve(ent, ref ent.Comp))
|
||||
return false;
|
||||
|
||||
var result = ent.Comp.AttachedEntities.Remove(entityToDetach);
|
||||
if (result)
|
||||
Dirty(ent);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to add an entity to list of attached entities.
|
||||
/// This helps with tracking relationship.
|
||||
/// </summary>
|
||||
/// <param name="ent">Artifact entity.</param>
|
||||
/// <param name="entityToAttach">Entity to attach.</param>
|
||||
/// <returns>
|
||||
/// Returns False if <paramref name="ent"/> is not artifact,
|
||||
/// or entity is already added, otherwise true.
|
||||
/// </returns>
|
||||
public bool TryAttachEntity(Entity<XenoArtifactComponent?> ent, EntityUid entityToAttach)
|
||||
{
|
||||
if (!Resolve(ent, ref ent.Comp))
|
||||
return false;
|
||||
|
||||
var result = ent.Comp.AttachedEntities.Add(entityToAttach);
|
||||
if (result)
|
||||
Dirty(ent);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void SetSuppressed(Entity<XenoArtifactComponent> ent, bool val)
|
||||
{
|
||||
if (ent.Comp.Suppressed == val)
|
||||
|
|
@ -61,3 +117,7 @@ public abstract partial class SharedXenoArtifactSystem : EntitySystem
|
|||
Dirty(ent);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Event of artifact destruction. </summary>
|
||||
[ByRefEvent]
|
||||
public record struct XenoArtifactDestroyedEvent;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ public sealed partial class NodeScannerComponent : Component
|
|||
/// Component-marker that node scanner device (<see cref="NodeScannerComponent"/>) is connected to artifact.
|
||||
/// </summary>
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState(true), AutoGenerateComponentPause]
|
||||
[Access(typeof(NodeScannerSystem))]
|
||||
public sealed partial class NodeScannerConnectedComponent : Component
|
||||
{
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Timing.Systems;
|
||||
using Content.Shared.Verbs;
|
||||
using Content.Shared.Xenoarchaeology.Artifact;
|
||||
using Content.Shared.Xenoarchaeology.Artifact.Components;
|
||||
using Content.Shared.Xenoarchaeology.Equipment.Components;
|
||||
using Robust.Shared.Timing;
|
||||
|
|
@ -14,13 +15,7 @@ public sealed partial class NodeScannerSystem : EntitySystem
|
|||
[Dependency] private IGameTiming _timing = default!;
|
||||
[Dependency] private SharedUserInterfaceSystem _ui = default!;
|
||||
[Dependency] private SharedTransformSystem _transform = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<NodeScannerComponent, BeforeRangedInteractEvent>(OnBeforeRangedInteract);
|
||||
SubscribeLocalEvent<NodeScannerComponent, GetVerbsEvent<UtilityVerb>>(AddScanVerb);
|
||||
}
|
||||
[Dependency] private SharedXenoArtifactSystem _artifact = default!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Update(float frameTime)
|
||||
|
|
@ -43,7 +38,27 @@ public sealed partial class NodeScannerSystem : EntitySystem
|
|||
}
|
||||
}
|
||||
|
||||
private void OnBeforeRangedInteract(EntityUid uid, NodeScannerComponent component, BeforeRangedInteractEvent args)
|
||||
/// <summary> Disconnect if artifact is destroyed </summary>
|
||||
[SubscribeLocalEvent]
|
||||
private void OnArtifactRemoved(Entity<NodeScannerConnectedComponent> ent, ref XenoArtifactDestroyedEvent args)
|
||||
{
|
||||
RemCompDeferred(ent, ent.Comp);
|
||||
}
|
||||
|
||||
/// <summary> Detach if scanner is disconnected, or destroyed. </summary>
|
||||
[SubscribeLocalEvent]
|
||||
private void OnScannerRemoved(Entity<NodeScannerConnectedComponent> ent, ref ComponentRemove args)
|
||||
{
|
||||
var artifact = ent.Comp.AttachedTo;
|
||||
if (!TerminatingOrDeleted(artifact))
|
||||
{
|
||||
_artifact.TryDetachEntity((artifact, null), ent);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Attach scanner if target is fitting. </summary>
|
||||
[SubscribeLocalEvent]
|
||||
private void OnBeforeRangedInteract(Entity<NodeScannerComponent> ent, ref BeforeRangedInteractEvent args)
|
||||
{
|
||||
if (args.Handled || !args.CanReach || args.Target is not { } target || !HasComp<XenoArtifactComponent>(target))
|
||||
return;
|
||||
|
|
@ -52,22 +67,26 @@ public sealed partial class NodeScannerSystem : EntitySystem
|
|||
? (target, unlockingComponent)
|
||||
: (target, null);
|
||||
|
||||
Attach((uid, component), unlockingEnt, args.User);
|
||||
Attach(ent, unlockingEnt, args.User);
|
||||
|
||||
args.Handled = true;
|
||||
}
|
||||
|
||||
private void AddScanVerb(EntityUid uid, NodeScannerComponent component, GetVerbsEvent<UtilityVerb> args)
|
||||
/// <summary> Add `scan` verb if target is fitting. </summary>
|
||||
[SubscribeLocalEvent]
|
||||
private void AddScanVerb(Entity<NodeScannerComponent> ent, ref GetVerbsEvent<UtilityVerb> args)
|
||||
{
|
||||
if (!args.CanAccess)
|
||||
return;
|
||||
|
||||
if (!TryComp<XenoArtifactUnlockingComponent>(args.Target, out var unlockingComponent))
|
||||
var target = args.Target;
|
||||
if (!TryComp<XenoArtifactUnlockingComponent>(target, out var unlockingComponent))
|
||||
return;
|
||||
|
||||
var user = args.User;
|
||||
var verb = new UtilityVerb
|
||||
{
|
||||
Act = () => Attach((uid, component), (args.Target, unlockingComponent), args.User),
|
||||
Act = () => Attach(ent, (target, unlockingComponent), user),
|
||||
Text = Loc.GetString("node-scan-tooltip")
|
||||
};
|
||||
|
||||
|
|
@ -84,11 +103,17 @@ public sealed partial class NodeScannerSystem : EntitySystem
|
|||
return;
|
||||
|
||||
var connected = EnsureComp<NodeScannerConnectedComponent>(device);
|
||||
|
||||
EntityUid artifact = unlockingEnt;
|
||||
if (connected.AttachedTo != artifact)
|
||||
{
|
||||
// Remove connection from previous scanner.
|
||||
if (connected.AttachedTo.Valid)
|
||||
_artifact.TryDetachEntity(connected.AttachedTo, device);
|
||||
|
||||
connected.AttachedTo = artifact;
|
||||
Dirty(device, connected);
|
||||
_artifact.TryAttachEntity(artifact, device);
|
||||
}
|
||||
|
||||
_ui.TryOpenUi((device, null), NodeScannerUiKey.Key, actor, predicted: true);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue