using System; using System.Linq; using System.Threading; using System.Threading.Tasks; using Cirno._3D.TrenchBroom.EntityScripts.Triggers; using Cirno.Scripts.Components.FSM; using Cirno.Scripts.Components.FSM._3DPlayer; using Godot; using Godot.Collections; using GTweensGodot.Extensions; namespace Cirno.Scripts.Activables._3D; [Tool] public partial class Teleporter3D : StaticBody3D, IActivable, ITargetable { [Export] public bool IsEnabled { get; set; } [Export] public bool Invisible { get; set; } = false; public bool IsPrimed { get; private set; } [Export] public Teleporter3D Target { get; set; } [Export] public string TargetGroup { get; set; } [Export] public string TargetName { get; set; } [Export] public float ParticleEmitTime { get; private set; } = 2f; [Export] public float TeleportAnimationLength { get; private set; } = 0.5f; [Export] public Vector3 TeleportOffset { get; private set; } = new Vector3(0, 4f, 0); [ExportCategory("Animations")] [Export] public StringName ActiveAnimationName { get; private set; } = "Active"; [Export] public StringName DefaultAnimationName { get; private set; } = "Default"; public virtual void _func_godot_apply_properties(Dictionary props) { TargetGroup = props["target"].AsString(); TargetName = props["targetname"].AsString(); IsEnabled = props["enabled"].AsBool(); } private void PlayAnimation(StringName name) { } private void StopParticles() { // _particles.Emitting = false; // _particleTimer = 0; } private void EmitParticles() { } public override void _Ready() { PlayAnimation(IsEnabled ? ActiveAnimationName : DefaultAnimationName); if (Engine.IsEditorHint()) return; if (!string.IsNullOrEmpty(TargetName)) { this.AddToGroup(TargetName); } IsPrimed = true; StopParticles(); this.Visible = !Invisible; // _teleportStartSound = GetNodeOrNull("TeleportStart"); // _teleportEndSound = GetNodeOrNull("TeleportEnd"); } public override void _Process(double delta) { if (Engine.IsEditorHint()) return; // if (!_particles.Emitting) return; // // _particleTimer += delta; // // if (_particleTimer >= ParticleEmitTime) // { // _particleTimer = 0; // _particles.Emitting = false; // } } public bool Activate(ActivationType activationType = ActivationType.Toggle) { switch (activationType) { case ActivationType.Toggle: // Enables/Disables teleporter break; case ActivationType.Enable: // Enables Teleporter IsEnabled = true; PlayAnimation(ActiveAnimationName); break; case ActivationType.Disable: IsEnabled = false; PlayAnimation(DefaultAnimationName); // Disables Teleporter break; case ActivationType.Use: // Teleports break; case ActivationType.Destroy: // Destroys break; } return true; } public void PrepareForReceiving() { IsPrimed = false; EmitParticles(); } public void FireParticles() { EmitParticles(); } private void _on_body_entered(Node3D body) { GD.Print("Something entered the teleporter"); if (!IsEnabled) return; if (body is not IsoPlayerFSMProxy player) return; GD.Print("Player entered the teleporter"); if (!IsPrimed) { IsPrimed = true; //_particles.Emitting = false; return; } // Teleport player to target if active if (!IsEnabled) return; GD.Print("Teleporting..."); // Call Teleport here _ = Teleport(player.PlayerFSM); } protected virtual async Task Teleport(IsoPlayerStateMachine player) { if (Target is null) { if (string.IsNullOrWhiteSpace(TargetGroup)) { return; } var foundTarget = GetTree().GetNodesInGroup(TargetGroup).FirstOrDefault(); if (foundTarget is not Teleporter3D teleporterTarget) { GD.Print($"No target for teleportation found with group {TargetGroup}"); return; } Target = teleporterTarget; }; //player.RequestMovementDisable(true); player.SetState(PlayerState.Cutscene); await TweenPlayer(player.MainObject); PlayTeleportStartSound(); //_particles.Emitting = true; FireParticles(); //await player.Teleport(); player.SetState(PlayerState.Teleporting); await Task.Delay((int)(0.6f * 1000)); await Task.Delay((int)(TeleportAnimationLength * 1000)); Target.PrepareForReceiving(); player.MainObject.GlobalPosition = Target.GlobalPosition + TeleportOffset; Target.PlayTeleportEndSound(); //await player.UnTeleport(); player.SetState(PlayerState.UnTeleporting); await Task.Delay((int)(0.6f * 1000)); //player.RequestMovementDisable(false); player.SetState(PlayerState.Active); } public void PlayTeleportStartSound() { } public void PlayTeleportEndSound() { } protected async Task TweenPlayer(CharacterBody3D player) { await player.TweenGlobalPosition(GlobalPosition + TeleportOffset, TeleportAnimationLength) .PlayAsync(CancellationToken.None); // 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"); } public void Toggle() { } }