using System.Collections.Generic; using Godot; using GodotHostTest.Helpers; using GodotHostTest.Interfaces; using R3; namespace GodotHostTest.Game; public partial class TargetSpawner : Node2D, ITargetCollector, ITargetSpawner { [Export] public double TimeBetweenSpawns; [Export] public required Timer Timer; private readonly List _availableTargets = []; public override void _Ready() { Spawn(); Timer.Start(TimeBetweenSpawns); } private void MakeTargetAvailable(ITarget target) { _availableTargets.Add(target); } private void OnTimer() { Spawn(); } private void Spawn() { // pick a random target var randomIndex = GD.RandRange(0, _availableTargets.Count - 1); var target = _availableTargets[randomIndex]; _availableTargets.RemoveAt(randomIndex); // enable it target.Enable(); // notify that a target has been spawned _targetSpawned.OnNext(target); } public void NewTarget(ITarget target) { _availableTargets.Add(target); target.Hit.Merge(target.TimedOut).Select(_ => target).Subscribe(MakeTargetAvailable).AddTo(this); } protected override void Dispose(bool disposing) { base.Dispose(disposing); _targetSpawned.Dispose(); } private readonly Subject _targetSpawned = new(); public Observable TargetSpawned => _targetSpawned.AsObservable(); }