GodotComponentTest/systems/InteractionSystem.cs

87 lines
3.1 KiB
C#

using Godot;
using System;
using System.Collections.Generic;
using Godot.Collections;
using GodotComponentTest.components;
using GodotComponentTest.entities;
using Array = System.Array;
using NodePair = System.Tuple<Godot.Node, Godot.Node>;
public class InteractionSystem : Node
{
private List<InteractionComponent> _activeInteractions;
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
_activeInteractions = new List<InteractionComponent>();
}
public override void _Process(float delta)
{
base._Process(delta);
List<NodePair> invalidInteractionPairs = new List<NodePair>();
List<InteractionComponent> endedInteractions = new List<InteractionComponent>();
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();
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));
}
}
}