using Godot; using GodotHostTest.Interfaces; using OwofGames.AetherBind; using R3; namespace GodotHostTest.Game.Target; public partial class Target : Node2D, ITarget { private readonly Subject _hit = new(); private readonly Subject _timedOut = new(); [Export] public required Area2D CollisionArea; [Export] public required Sprite2D Image; [Export] public required Timer TimeOutTimer; [Export] private PackedScene _explosionPackedScene = null!; [Inject] private ILevel _level = null!; [Inject] private ITargetCollector _targetCollector = null!; public Observable TimedOut => _timedOut.AsObservable(); public Observable Hit => _hit.AsObservable(); public void Enable() { Image.Visible = true; CollisionArea.Monitoring = true; CollisionArea.Monitorable = true; TimeOutTimer.Start(_level.SpawnDuration.TotalSeconds); } public override void _Ready() { _targetCollector.NewTarget(this); } public override void _ExitTree() { _timedOut.Dispose(); _hit.Dispose(); } private void OnAreaEntered(Area2D _) { OnHit(); } private void OnHit() { Disable(); TimeOutTimer.Stop(); _hit.OnNext(Unit.Default); var explosion = (GpuParticles2D)_explosionPackedScene.Instantiate(); explosion.GlobalPosition = GlobalPosition; explosion.Emitting = true; GetTree().CurrentScene.AddChild(explosion); } private void Disable() { Image.Visible = false; // can't se monitoring/monitorable when inside the collision code, like during OnHit CollisionArea.SetDeferred(Area2D.PropertyName.Monitoring, false); CollisionArea.SetDeferred(Area2D.PropertyName.Monitorable, false); } private void OnTimeout() { Disable(); _timedOut.OnNext(Unit.Default); } }