using Godot; using MaxEffort.Code.Core; using MaxEffort.Code.Data; namespace MaxEffort.Code.Systems; [GlobalClass] public partial class TunnelSystem : Node { [Export] private TunnelConfig _config; [Export] private ColorRect _vignetteOverlay; private float _currentFocus = 0f; private bool _isEfforting = false; public override void _Ready() { EventBus.OnLiftEffortApplied += HandleEffort; EventBus.OnFocusRelease += HandleRelease; } public override void _ExitTree() { EventBus.OnLiftEffortApplied -= HandleEffort; EventBus.OnFocusRelease -= HandleRelease; } public override void _Process(double delta) { var dt = (float)delta; if (_isEfforting) { _currentFocus += _config.VisionNarrowRate * dt; } else { _currentFocus -= _config.VisionRecoverRate * dt; } _currentFocus = Mathf.Clamp(_currentFocus, 0f, _config.MaxTunnelIntensity); var visualValue = _config.VisionCurve?.Sample(_currentFocus) ?? _currentFocus; if (_vignetteOverlay != null) { var mat = _vignetteOverlay.Material as ShaderMaterial; mat?.SetShaderParameter("vignette_intensity", visualValue); } EventBus.PublishFocusChanged(_currentFocus); _isEfforting = false; } private void HandleRelease() { _isEfforting = false; } private void HandleEffort(float effortDelta) { _isEfforting = true; } }