using Godot; using Mr.BrickAdventures.Autoloads; using Mr.BrickAdventures.scripts.Resources; namespace Mr.BrickAdventures.scripts.UI; [GlobalClass] public partial class DeathScreen : Control { [Export] public LevelResource CurrentLevel { get; set; } [Export] public Label CurrentLevelLabel { get; set; } [Export] public Label LivesLeftLabel { get; set; } [Export] public float TimeoutTime { get; set; } = 2.0f; [Export] public Godot.Collections.Array NodesToDisable { get; set; } = new(); private Timer _timer; private bool _runOver; public override void _Ready() { EventBus.Instance.AttemptFailed += OnAttemptFailed; } public override void _ExitTree() { if (EventBus.Instance != null) EventBus.Instance.AttemptFailed -= OnAttemptFailed; } /// /// Shows the death screen. /// /// /// Driven by the settled outcome rather than by a scene connection to /// HealthComponent.Death, so the life is already spent and the count already correct. The old /// arrangement read Lives from a handler racing the one that wrote it, then read it a second /// time on timeout — two read paths for one fact, because neither was reliable alone. /// private void OnAttemptFailed(int remainingLives, bool runOver) { _runOver = runOver; LivesLeftLabel.Text = $" x {remainingLives}"; if (CurrentLevel != null) CurrentLevelLabel.Text = CurrentLevel.LevelName; ToggleNodes(); Show(); SetupTimer(); } private void SetupTimer() { _timer = new Timer { WaitTime = TimeoutTime, OneShot = true, }; _timer.Timeout += OnTimeout; AddChild(_timer); _timer.Start(); } private void ToggleNodes() { foreach (var node in NodesToDisable) { node.ProcessMode = node.ProcessMode == ProcessModeEnum.Disabled ? ProcessModeEnum.Inherit : ProcessModeEnum.Disabled; } } private void OnTimeout() { // Game over is the other screen's job; this one only retries. if (_runOver) return; GetTree().ReloadCurrentScene(); } }