using System.Threading.Tasks; using Cirno.Scripts; using Cirno.Scripts.Components; using Godot; using GTweens.Builders; using GTweens.Tweens; using GTweensGodot.Extensions; public partial class PlayerAnimationProvider : Node2D { [Export] public AnimatedSprite2D _animatedSprite {get; private set;} [Export] private PackedScene _deathParticles; [Export] private GpuParticles2D _shieldParticles; [ExportCategory("Animation Names")] [Export] public StringName WalkRightAnimationName {get; private set;} = "walk_right"; [Export] public StringName WalkLeftAnimationName {get; private set;} = "walk_left"; [Export] public StringName WalkDownAnimationName {get; private set;} = "walk_down"; [Export] public StringName WalkUpAnimationName {get; private set;} = "walk_up"; [Export] public StringName DrowningAnimationName {get; private set;} = "Drowning"; [ExportCategory("Shaders")] [Export] public ShaderMaterial BlinkMaterial {get; private set;} [Export] public StringName BlinkShaderPropertyName { get; private set; } = new("blink_intensity"); [Export] public StringName TeleportProgressPropertyName { get; private set; } = new("teleport_progress"); [Export] public StringName ScanlineDensityPropertyName { get; private set; } = new("scanline_density"); private GTween _blinkTween; [Signal] public delegate void OnAnimationEndedEventHandler(StringName animationName); public override void _Ready() { _animatedSprite.AnimationFinished += () => EmitSignal(SignalName.OnAnimationEnded, _animatedSprite.Animation); } public void ShowSprite() { _animatedSprite.Show(); } public void HideSprite() { _animatedSprite.Hide(); } public void SetAnimationSpeed(Vector2 velocity) { if (velocity.Length() == 0) { _animatedSprite.SpeedScale = 0; } else { if (velocity.Length() > 40) { _animatedSprite.SpeedScale = 1; } else { _animatedSprite.SpeedScale = 0.8f; } } } public void SweepSprite(float angle, float sweepAngle) { if (_animatedSprite == null) return; var frames = _animatedSprite.SpriteFrames.GetFrameCount("default"); // Map angle (-SweepAngle/2 to +SweepAngle/2) to frame (0 to 5) float normalizedAngle = (angle + (sweepAngle / 2)) / sweepAngle; int frame = Mathf.Clamp((int)(normalizedAngle * frames), 0, frames); _animatedSprite.Frame = frame; } public void SetAnimation(Vector2 direction) { if (direction == Vector2.Zero) return; float angle = Mathf.RadToDeg(direction.Angle()); // Normalize to 0-360 if (angle < 0) angle += 360; string animToPlay; switch (angle) { case >= 45 and < 135: _animatedSprite.Play(WalkDownAnimationName); break; case >= 135 and < 225: _animatedSprite.Play(WalkLeftAnimationName); break; case >= 225 and < 315: _animatedSprite.Play(WalkUpAnimationName); break; default: _animatedSprite.Play(WalkRightAnimationName); break; } } public void Blink() { if (BlinkMaterial == null) return; _animatedSprite.Material = BlinkMaterial; var material = ((ShaderMaterial)_animatedSprite.Material); _blinkTween?.Kill(); _blinkTween = GTweenSequenceBuilder.New() .Append(material.TweenPropertyFloat(BlinkShaderPropertyName, 1f, 0f)) .Append(material.TweenPropertyFloat(BlinkShaderPropertyName, 0f, 0.5f)) .Build(); _blinkTween.Play(); } public void PlayTeleportAnimation() { if (BlinkMaterial == null) return; _animatedSprite.Material = BlinkMaterial; var material = ((ShaderMaterial)_animatedSprite.Material); _blinkTween?.Kill(); _blinkTween = GTweenSequenceBuilder.New() .Append(material.TweenPropertyFloat(TeleportProgressPropertyName, 0f, 0f)) .Append(material.TweenPropertyFloat(ScanlineDensityPropertyName, 0f, 0f)) .Append(material.TweenPropertyFloat(ScanlineDensityPropertyName,50f,0.5f)) .Join(material.TweenPropertyFloat(TeleportProgressPropertyName, 1f,0.5f)) .Build(); _blinkTween.Play(); } public void PlayUnteleportAnimation() { if (BlinkMaterial == null) return; _animatedSprite.Material = BlinkMaterial; var material = ((ShaderMaterial)_animatedSprite.Material); _blinkTween?.Kill(); _blinkTween = GTweenSequenceBuilder.New() .Append(material.TweenPropertyFloat(TeleportProgressPropertyName, 1f, 0f)) .Append(material.TweenPropertyFloat(ScanlineDensityPropertyName, 50f, 0f)) .Append(material.TweenPropertyFloat(ScanlineDensityPropertyName,0f,0.5f)) .Join(material.TweenPropertyFloat(TeleportProgressPropertyName, 0f,0.5f)) .Build(); _blinkTween.Play(); } private void SetShaderTeleportProgress(float value) { ((ShaderMaterial)_animatedSprite.Material).SetShaderParameter("teleport_progress", value); } private void SetShaderScanlineDensity(float value) { ((ShaderMaterial)_animatedSprite.Material).SetShaderParameter("scanline_density", value); } private void SetShaderBlinkIntensity(float newValue) { ((ShaderMaterial)_animatedSprite.Material).SetShaderParameter("blink_intensity", newValue); } public void PlayDeathAnimation() { if (_deathParticles is null) return; this.CreateSibling(_deathParticles, this.GlobalPosition); _animatedSprite.Visible = false; } public void PlayDrowningAnimation() { _animatedSprite.Visible = true; _animatedSprite.Play(DrowningAnimationName); _animatedSprite.SpeedScale = 1; } public void PlayShieldAnimation() { if (_shieldParticles is null) return; _shieldParticles.Emitting = true; } }