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);
}