using Content.Shared.Xenoarchaeology.Artifact.Components;
using Robust.Shared.Timing;
namespace Content.Shared.Xenoarchaeology.Artifact.XAT;
///
/// Base type for xeno artifact trigger systems. Each system should work with 1 trigger mechanics.
///
/// Type of XAT component that system will work with.
public abstract class BaseXATSystem : EntitySystem where T : Component
{
[Dependency] protected readonly IGameTiming Timing = default!;
[Dependency] protected readonly SharedXenoArtifactSystem XenoArtifact = default!;
private EntityQuery _unlockingQuery;
///
public override void Initialize()
{
base.Initialize();
_unlockingQuery = GetEntityQuery();
}
///
/// Subscribes to event occurring on artifact (and by relaying - on node).
///
/// Type of event to sub for.
/// Delegate that handles event.
protected void XATSubscribeDirectEvent(XATEventHandler eventHandler) where TEvent : notnull
{
SubscribeLocalEvent>((uid, component, args) =>
{
var nodeComp = Comp(uid);
if (!CanTrigger(args.Artifact, (uid, nodeComp)))
return;
var node = new Entity(uid, component, nodeComp);
eventHandler.Invoke(args.Artifact, node, ref args.Args);
});
}
///
/// Checks if node can be triggered.
///
/// Artifact entity.
/// Node from .
protected bool CanTrigger(Entity artifact, Entity node)
{
if (Timing.CurTime < artifact.Comp.NextUnlockTime)
return false;
if (_unlockingQuery.TryComp(artifact, out var unlocking) &&
unlocking.TriggeredNodeIndexes.Contains(XenoArtifact.GetIndex(artifact, node)))
return false;
if (!XenoArtifact.CanUnlockNode((node, node)))
return false;
return true;
}
///
/// Triggers node. Triggered nodes participate in node unlocking.
///
protected void Trigger(Entity artifact, Entity node)
{
if (!Timing.IsFirstTimePredicted)
return;
Log.Debug($"Activated trigger {typeof(T).Name} on node {ToPrettyString(node)} for {ToPrettyString(artifact)}");
XenoArtifact.TriggerXenoArtifact(artifact, (node.Owner, node.Comp2));
}
///
/// Delegate for handling relayed artifact trigger events.
///
/// Event type to be handled.
/// Artifact, on which event occurred.
/// Node which for which event were relayed.
/// Event data.
protected delegate void XATEventHandler(
Entity artifact,
Entity node,
ref TEvent args
) where TEvent : notnull;
}