Code/Examples/FlyCamera.cs
// =============================================================
// EXAMPLE FILE — reference implementation for integrators.
//
// This file is NOT used by the library at runtime.
// Copy it into your own RP project and adapt to your needs.
// =============================================================

using Sandbox;
using Casino.RpSlot;

namespace Casino.RpSlot.Examples;

public sealed class FlyCamera : Component
{
    [Property] public float MoveSpeed { get; set; } = 300f;
    [Property] public float MouseSensitivity { get; set; } = 0.1f;
    [Property] public bool MovementLocked { get; set; }

    public Transform? LockTarget { get; set; }
    public float LockLerpSpeed { get; set; } = 8f;

    private Angles _angles;
    private Transform? _savedTransform;
    private float _releaseTimer;

    protected override void OnStart()
    {
        base.OnStart();
        _angles = WorldRotation.Angles();
        SlotMachineUI.OnPlayerEngaged += HandleEngaged;
        SlotMachineUI.OnPlayerDisengaged += HandleDisengaged;
    }

    protected override void OnDestroy()
    {
        SlotMachineUI.OnPlayerEngaged -= HandleEngaged;
        SlotMachineUI.OnPlayerDisengaged -= HandleDisengaged;
        base.OnDestroy();
    }

    private void HandleEngaged( Transform target )
    {
        _savedTransform = new Transform( WorldPosition, WorldRotation );
        MovementLocked = true;
        LockTarget = target;
        _releaseTimer = 0f;
    }

    private void HandleDisengaged()
    {
        MovementLocked = false;

        if ( _savedTransform.HasValue )
        {
            LockTarget = _savedTransform.Value;
            _savedTransform = null;
            _releaseTimer = 0.6f;
        }
        else
        {
            LockTarget = null;
        }
    }

    protected override void OnUpdate()
    {
        if ( _releaseTimer > 0f )
        {
            _releaseTimer -= Time.Delta;
            if ( _releaseTimer <= 0f )
                LockTarget = null;
        }

        if ( LockTarget.HasValue )
        {
            var target = LockTarget.Value;
            WorldPosition = Vector3.Lerp( WorldPosition, target.Position, Time.Delta * LockLerpSpeed );
            WorldRotation = Rotation.Slerp( WorldRotation, target.Rotation, Time.Delta * LockLerpSpeed );
            return;
        }

        if ( !Mouse.Visible )
        {
            _angles.pitch += Input.MouseDelta.y * MouseSensitivity;
            _angles.yaw   += -Input.MouseDelta.x * MouseSensitivity;
            _angles.pitch = _angles.pitch.Clamp( -89f, 89f );
            WorldRotation = _angles.ToRotation();
        }

        if ( !MovementLocked )
        {
            var velocity = Vector3.Zero;
            if ( Input.Down( "Forward" ) )  velocity += WorldRotation.Forward;
            if ( Input.Down( "Backward" ) ) velocity -= WorldRotation.Forward;
            if ( Input.Down( "Left" ) )     velocity -= WorldRotation.Right;
            if ( Input.Down( "Right" ) )    velocity += WorldRotation.Right;
            if ( Input.Down( "Jump" ) )     velocity += Vector3.Up;
            if ( Input.Down( "Duck" ) )     velocity -= Vector3.Up;

            if ( velocity.Length > 0 )
                WorldPosition += velocity.Normal * MoveSpeed * Time.Delta;
        }
    }
}