Sboku/Arena/Spawner.cs
using SWB.Demo;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;

namespace Sandbox.Sboku.Arena;

[Group("Sboku Arena")]
internal class Spawner : Component, Component.ITriggerListener
{
    private Queue<Vector3> spawnQueue = new();

    [Property] public float SpawnHeight { get; set; } = 64f;


    [Property]
    [Title("Spawn Character")]
    public char SpawnChar { get; set; } = 'X'; // Määrittelee mistä soluista spawnataan

    private List<Vector3> spawnCells;

    [Property]
    public PrefabScene Prefab { get; set; }
    [Property]
    public GameObject SpawnPoint { get; set; }
    //[Property]
    //[//Range(1f, 100f, step: 1f)]
    //public float SpawnInterval { get; set; } = 5f;
    [Property]
    public float DamageInterval { get; set; } = 0.5f;

    private HashSet<Collider> inside = new();
    /*private int spawnCounter = 0;
    private TimeSince lastSpawn = 0f;^*/
    private TimeSince sinceDamage = 0f;
    private TimeSince timer = 0f;

    private RoundManager roundManager;
    private bool isSpawning = false;
    protected override void OnStart()
    {
        //Log.Info("[Spawner] OnStart");
        if (!Networking.IsHost)
            return;
        roundManager = Scene.GetComponentInChildren<RoundManager>();
        if (roundManager == null)
        {
            Log.Error("Spawner: RoundManager not found!");
            Enabled = false;
            return;
        }
        RefreshSpawnCells();
        if (spawnCells.Count == 0)
            Log.Warning("[Spawner] No prison spawn markers found!");


    }

    public bool IsDone() => !isSpawning;
    public void RequestSpawn()
    {
        //Log.Info("[Spawner] RequestSpawn");

        if (!Networking.IsHost)
            return;

        if (spawnCells == null || spawnCells.Count == 0)
            RefreshSpawnCells();

        if (spawnCells == null || spawnCells.Count == 0)
            return;

        foreach (var cell in spawnCells)
            spawnQueue.Enqueue(cell);
    }

    private void RefreshSpawnCells()
    {
        spawnCells = Scene.GetAllComponents<PrisonSpawnMarker>()
            .Where(m => m.IsValid && m.PreferForBots)
            .Select(m => m.GameObject.WorldPosition)
            .ToList();

        if (spawnCells.Count > 0)
            return;

        var map = Scene.GetComponentInChildren<GridSpawner>()?.Map;
        if (map == null)
            return;

        spawnCells = map.GetAllSpawnPoints(SpawnChar)
            .Where(s => map.IsWalkable(s.x, s.y))
            .Select(s => map.GridToWorld(s.x, s.y, SpawnHeight))
            .ToList();
    }



    protected override void DrawGizmos()
    {
        if (SpawnPoint == null) return;

        Gizmo.Draw.Color = Color.Orange;
        Gizmo.Draw.SolidSphere(SpawnPoint.LocalPosition, 1);
    }
    private static int nextBotIndex = 1;
    protected override void OnFixedUpdate()
    {
        if (!Networking.IsHost)
            return;

        if (spawnQueue.Count == 0)
            return;
        
        var cell = spawnQueue.Dequeue();

        var bot = Prefab.Clone();
        var adapter = bot.Components.Get<BotAdapter>();
        if (adapter != null)
            adapter.BotIndex = nextBotIndex++;
   
        //Log.Info("[Spawner] Spawned a bot:" + adapter.BotIndex + "," + adapter.Id);
        bot.WorldPosition = cell + Vector3.Up * SpawnHeight;
        bot.NetworkSpawn();
    }

    public void OnTriggerEnter(Collider other) => inside.Add(other);
    public void OnTriggerExit(Collider other) => inside.Remove(other);

}