using System; using System.Collections; using System.Threading.Tasks; using Godot; namespace Cirno.Scripts.Activables; public partial class Teleporter : Activable { [Export] public bool IsEnabled { get; set; } public bool IsPrimed { get; private set; } [Export] public Teleporter Target { get; set; } [Export] public float ParticleEmitTime { get; private set; } = 2f; [Export] public float TeleportAnimationLength { get; private set; } = 0.5f; [Export] public Vector2 TeleportOffset { get; private set; } = new Vector2(0,-4f); private double _particleTimer; private AnimatedSprite2D _animatedSprite; // [Export] // public GpuParticles2D Particles { get; set; } private GpuParticles2D _particles; public override void _Ready() { _particles = GetNode("./Particles"); _animatedSprite = GetNode("AnimatedSprite2D"); IsPrimed = true; _particles.Emitting = false; _particleTimer = 0; if (IsEnabled) { _animatedSprite.Play("Active"); } else { _animatedSprite.Play("Default"); } } public override void _Process(double delta) { if (!_particles.Emitting) return; _particleTimer += delta; if (_particleTimer >= ParticleEmitTime) { _particleTimer = 0; _particles.Emitting = false; } } public override void Activate(ActivationType activationType = ActivationType.Toggle) { switch (activationType) { case ActivationType.Toggle: // Enables/Disables teleporter break; case ActivationType.Enable: // Enables Teleporter IsEnabled = true; _animatedSprite.Play("Active"); break; case ActivationType.Disable: IsEnabled = false; _animatedSprite.Play("Default"); // Disables Teleporter break; case ActivationType.Use: // Teleports break; case ActivationType.Destroy: // Destroys break; } } public void PrepareForReceiving() { IsPrimed = false; _particles.Emitting = true; } public void FireParticles() { _particles.Emitting = true; _particleTimer = 0; } private void _on_body_entered(CharacterBody2D area) { if (area is not PlayerMovement player) return; if (!IsPrimed) { IsPrimed = true; //_particles.Emitting = false; return; } // Teleport player to target if active if (!IsEnabled) return; if (Target is null) return; // Call Teleport here _ = Teleport(player); } private async Task Teleport(PlayerMovement player) { player.RequestMovementDisable(true); await TweenPlayer(player); Target.PrepareForReceiving(); _particles.Emitting = true; await Task.Delay((int)(TeleportAnimationLength * 1000)); player.GlobalPosition = Target.GlobalPosition + TeleportOffset; player.RequestMovementDisable(false); } private async Task TweenPlayer(PlayerMovement player) { // Create a Tween for the teleport animation Tween tween = GetTree().CreateTween(); tween.SetEase(Tween.EaseType.InOut); tween.SetTrans(Tween.TransitionType.Sine); tween.TweenProperty(player, "global_position", GlobalPosition + new Vector2(0,-4f), TeleportAnimationLength); // Wait for the tween to finish await ToSignal(tween, "finished"); } }