cirnogodot/Scripts/Activables/3D/Teleporter3D.cs
2025-09-10 16:16:05 +02:00

228 lines
No EOL
6.2 KiB
C#

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<string, Variant> 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<AudioStreamPlayer2D>("TeleportStart");
// _teleportEndSound = GetNodeOrNull<AudioStreamPlayer2D>("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()
{
}
}