Grid/Base/GridActivatable.cs
// ================================
// GridActivatable.cs
// ================================
using Sandbox;
using System.Collections.Generic;
using System.Numerics;
using System.Threading.Tasks;

namespace Sandbox.Grid.Base
{
    public abstract class GridActivatable : Component
    {
        public int GridX { get; set; }
        public int GridY { get; set; }

        public async void ActivateChain(float delaySeconds = 0f)
        {
            var context = new ActivationContext();
            await ActivateInternalAsync(context, delaySeconds);
        }

        internal async Task ActivateInternalAsync(
            ActivationContext context,
            float delaySeconds
        )
        {
            if (!context.TryActivate(this))
                return;

            Activate();

            if (delaySeconds > 0f)
                await GameTask.DelaySeconds(delaySeconds);

            foreach (var neighbor in GetLinkedActivatables())
            {
                await neighbor.ActivateInternalAsync(context, delaySeconds);
            }
        }

        protected abstract IEnumerable<GridActivatable> GetLinkedActivatables();
        public abstract void Activate();
        public abstract void Deactivate();
        protected abstract Vector3 MoveTowards(Vector3 current, Vector3 target, float maxDelta);
    }
}