namespace Sandbox.Movement;
///
/// The character is sitting
///
[Icon( "airline_seat_recline_normal" ), Group( "Movement" ), Title( "MoveMode - Sit" )]
public sealed class SitMoveMode : MoveMode, PlayerController.IEvents
{
///
/// Score this move mode highly if we're parented to a chair
///
public override int Score( PlayerController controller )
{
if ( controller.GetComponentInParent() is ISitTarget chair )
{
return 10000;
}
return -1;
}
///
/// Update the animator while sitting in a chair
///
public override void UpdateAnimator( SkinnedModelRenderer renderer )
{
if ( renderer.GetComponentInParent() is not ISitTarget chair )
return;
OnUpdateAnimatorVelocity( renderer );
chair.UpdatePlayerAnimator( Controller, renderer );
}
///
/// Entering the chair, disable body and collider
///
public override void OnModeBegin()
{
base.OnModeBegin();
Controller.Body.Enabled = false;
Controller.ColliderObject.Enabled = false;
Controller.EyeAngles = default;
}
///
/// Leaving the chair, re-enable body and collider
///
public override void OnModeEnd( MoveMode next )
{
Controller.Body.Enabled = true;
Controller.ColliderObject.Enabled = true;
Controller.WorldRotation = Rotation.LookAt( Controller.EyeTransform.Forward.WithZ( 0 ), Vector3.Up );
base.OnModeEnd( next );
}
///
/// Move is always zero while sitting
///
public override Vector3 UpdateMove( Rotation eyes, Vector3 input )
{
return 0;
}
///
/// Get the eye transform from the chair we're sitting in
///
public override Transform CalculateEyeTransform()
{
if ( GetComponentInParent() is not ISitTarget chair )
{
return base.CalculateEyeTransform();
}
return chair.CalculateEyeTransform( Controller );
}
///
/// Player pressed "use" but failed to press it. So we'll interpret that as wanting to leave the chair.
///
void PlayerController.IEvents.FailPressing()
{
if ( GetComponentInParent() is not ISitTarget chair )
return;
chair.AskToLeave( Controller );
}
}
///
/// A component that can be sat in by a player. If the player is parented to an object with this component, they will be sitting in it.
///
public interface ISitTarget
{
///
/// Here you can set any animator parameters needed for sitting in this chair
///
void UpdatePlayerAnimator( PlayerController controller, SkinnedModelRenderer renderer );
///
/// Get the transform representing the eye position when seated. This is the first person
/// eye position, not the third person camera position.
///
Transform CalculateEyeTransform( PlayerController controller );
///
/// Player wants to leave the chair
///
void AskToLeave( PlayerController controller );
}