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