using AceFieldNewHorizon.Scripts.Entities; using Godot; namespace AceFieldNewHorizon.Scripts.Tiles; public partial class EnemyNestTile : BaseTile { [Export] public PackedScene EnemyScene; [Export] public int MaxEnemies = 5; [Export] public float SpawnDelay = 5.0f; // Time between spawn attempts [Export] public float SpawnRadius = 50.0f; // Radius around the nest where enemies can spawn [Export] public bool Active = true; private Timer _spawnTimer; private int _currentEnemyCount = 0; public override void _Ready() { base._Ready(); // Create and configure the timer _spawnTimer = new Timer { Autostart = true, WaitTime = SpawnDelay }; AddChild(_spawnTimer); _spawnTimer.Timeout += OnSpawnTimerTimeout; } private void OnSpawnTimerTimeout() { if (!Active || EnemyScene == null || _currentEnemyCount >= MaxEnemies) return; // Check if we can spawn more enemies var enemies = GetTree().GetNodesInGroup("Enemy"); _currentEnemyCount = enemies.Count; if (_currentEnemyCount >= MaxEnemies) return; // Spawn a new enemy var enemy = EnemyScene.Instantiate(); if (enemy != null) { GetParent().AddChild(enemy); // Calculate a random position within the spawn radius var randomAngle = GD.Randf() * Mathf.Pi * 2; var randomOffset = new Vector2( Mathf.Cos(randomAngle) * SpawnRadius, Mathf.Sin(randomAngle) * SpawnRadius ); enemy.GlobalPosition = GlobalPosition + randomOffset; _currentEnemyCount++; // Connect to the enemy's death signal if available enemy.TreeExiting += () => OnEnemyDied(); } } private void OnEnemyDied() { _currentEnemyCount = Mathf.Max(0, _currentEnemyCount - 1); } public void SetActive(bool active) { Active = active; _spawnTimer.Paused = !active; } }