using System.Threading; using System.Threading.Tasks; using Cirno.Scripts.Enums; using Godot; using GTweens.Builders; using GTweens.Tweens; using GTweensGodot.Extensions; namespace Cirno.Scripts.Components.FSM.Elevator; public abstract partial class ElevatorMovementState : BaseState { protected GTween Tween; protected Node2D OldPlayerParent; protected abstract Vector2 StartingPosition { get; } protected abstract Vector2 EndingPosition { get; } protected abstract ElevatorState EndState { get; } protected CharacterBody2D PlayerBody => MainObject.CachedPlayer?.StateMachine.MainObject; public override void EnterState() { Tween?.Kill(); MainObject.SetPosition(StartingPosition); Move(); } public override void ExitState() { Tween?.Kill(); RestorePlayerParent(); } private void RestorePlayerParent() { if (PlayerBody is null) return; PlayerBody.Reparent(OldPlayerParent); OldPlayerParent = null; MainObject.CachedPlayer?.StateMachine.SetState(PlayerState.Active); } private void CatchPlayer() { if (PlayerBody is null) return; OldPlayerParent = PlayerBody.GetParent(); MainObject.CachedPlayer.StateMachine.SetState(PlayerState.Cutscene); PlayerBody.Reparent(MainObject); } private void Move() { // Grab player if in range CatchPlayer(); //Ascend _ = PlayAnimation(); } private async Task PlayAnimation() { Tween = GTweenSequenceBuilder.New() .Append(MainObject.TweenPosition(EndingPosition, MainObject.MovementTime)) .Build(); await Tween.PlayAsync(CancellationToken.None); StateMachine.SetState(EndState); } }