using System.Collections.Generic; using Godot; using GodotComponentTest.components; using GodotComponentTest.entities; using NodePair = System.Tuple; public class InteractionSystem : Node { private List _activeInteractions; // Called when the node enters the scene tree for the first time. public override void _Ready() { _activeInteractions = new List(); } public override void _Process(float delta) { base._Process(delta); List endedInteractions = new(); foreach (InteractionComponent interaction in _activeInteractions) { Spatial owningEntity = interaction.OwningEntity; Spatial targetEntity = interaction.TargetEntity; if (owningEntity == null || owningEntity.IsQueuedForDeletion() || targetEntity == null || targetEntity.IsQueuedForDeletion()) { interaction.hasStopped = true; } if (interaction.hasStopped) { IInteractionInterface interactableA = owningEntity as IInteractionInterface; if (interactableA != null) { interactableA.OnInteractionEnd(); interactableA.InteractionComponent = null; } IInteractionInterface interactableB = targetEntity as IInteractionInterface; if (interactableB != null) { interactableB.OnInteractionEnd(); interactableB.InteractionComponent = null; } endedInteractions.Add(interaction); } } foreach (InteractionComponent interaction in endedInteractions) _activeInteractions.Remove(interaction); } public void OnStartInteraction(Entity owningEntity, Entity targetEntity) { InteractionComponent interactionComponent = new(); interactionComponent.OwningEntity = owningEntity; interactionComponent.TargetEntity = targetEntity; ConnectInteractionSignals(owningEntity, interactionComponent); ConnectInteractionSignals(targetEntity, interactionComponent); interactionComponent.EmitSignal("InteractionStart"); _activeInteractions.Add(interactionComponent); } private static void ConnectInteractionSignals(Entity entity, InteractionComponent interactionComponent) { IInteractionInterface interactable = entity as IInteractionInterface; if (interactable != null) { interactable.InteractionComponent = interactionComponent; interactionComponent.Connect("InteractionStart", entity, nameof(interactable.OnInteractionStart)); interactionComponent.Connect("InteractionEnd", entity, nameof(interactable.OnInteractionEnd)); } } }