Grid/Base/GridActivitableBase.cs
// ================================
// GridActivatableBase.cs
// ================================
using Sandbox;
using Sandbox.Grid.Base;
using System;
using System.Collections.Generic;
using System.Numerics;

public abstract class GridActivatableBase : GridActivatable
{
    [Property] public float ChainDelay { get; set; } = 2f;

    private readonly List<GridActivatable> linked = new();

    protected override void OnStart()
    {
        linked.Clear();

        foreach (var ga in Scene.GetAllComponents<GridActivatable>())
        {
            if (ga == this) continue;

            int dx = ga.GridX - GridX;
            int dy = ga.GridY - GridY;

            if (Math.Abs(dx) <= 1 && Math.Abs(dy) <= 1)
                linked.Add(ga);
        }
    }

    protected override IEnumerable<GridActivatable> GetLinkedActivatables()
    {
        // ortogonaaliset ensin
        foreach (var a in linked)
        {
            int dx = a.GridX - GridX;
            int dy = a.GridY - GridY;
            if ((Math.Abs(dx) == 1 && dy == 0) || (dx == 0 && Math.Abs(dy) == 1))
                yield return a;
        }

        // diagonaalit jälkeen
        foreach (var a in linked)
        {
            int dx = a.GridX - GridX;
            int dy = a.GridY - GridY;
            if (Math.Abs(dx) == 1 && Math.Abs(dy) == 1)
                yield return a;
        }
    }

    protected override Vector3 MoveTowards(Vector3 current, Vector3 target, float maxDelta)
    {
        var delta = target - current;
        float dist = delta.Length;
        if (dist <= maxDelta || dist == 0f) return target;
        return current + delta / dist * maxDelta;
    }
}