velox/Code/Base/VeloXBase.Input.cs
2025-11-18 21:53:51 +07:00

162 lines
3.6 KiB
C#

using Sandbox;
using System;
namespace VeloX;
public abstract partial class VeloXBase
{
[Feature( "Input" )] internal InputResolver Input { get; set; } = new();
[Feature( "Input" )] public Connection Driver { get => Input.Driver; set => Input.Driver = value; }
private bool IsDriverActive => Driver is not null;
public Vector2 MouseDelta => IsDriverActive ? Input.MouseDelta : default;
public Vector2 MouseWheel => IsDriverActive ? Input.MouseWheel : default;
public Angles AnalogLook => IsDriverActive ? Input.AnalogLook : default;
public Vector3 AnalogMove => IsDriverActive ? Input.AnalogMove : default;
private float throttle;
private float brakes;
private float steerAngle;
private float handbrake;
public bool CanInputSwapping { get; set; } = true;
public bool IsInputSwapped => CanInputSwapping && Transmission.Gear < 0;
public bool IsShiftingDown { get; private set; }
public bool IsShiftingUp { get; private set; }
public float IsClutching { get; private set; }
public float SwappedThrottle => IsInputSwapped ? Brakes : Throttle;
public float SwappedBrakes => IsInputSwapped ? Throttle : Brakes;
[Sync]
public float VerticalInput
{
get => throttle - brakes;
set
{
float clampedValue = Math.Clamp( value, -1, 1 );
if ( value > 0 )
{
throttle = clampedValue;
brakes = 0;
}
else
{
throttle = 0;
brakes = -clampedValue;
}
}
}
/// <summary>
/// Throttle axis.
/// For combined throttle/brake input use 'VerticalInput' instead.
/// </summary>
[Sync( SyncFlags.Interpolate ), Range( 0, 1 ), Property, ReadOnly]
public float Throttle
{
get => throttle;
set => throttle = Math.Clamp( value, 0, 1 );
}
/// <summary>
/// Brake axis.
/// For combined throttle/brake input use 'VerticalInput' instead.
/// </summary>
[Range( 0, 1 ), Property, ReadOnly]
public float Brakes
{
get => brakes;
set => brakes = Math.Clamp( value, 0, 1 );
}
[Sync( SyncFlags.Interpolate ), Range( 0, 1 ), Property, ReadOnly]
public float SteeringAngle
{
get => steerAngle;
set => steerAngle = Math.Clamp( value, -1, 1 );
}
[Sync]
public float Handbrake
{
get => handbrake;
set => handbrake = Math.Clamp( value, 0, 1 );
}
public void ResetInput()
{
VerticalInput = 0;
Handbrake = 0;
SteeringAngle = 0;
IsClutching = 0;
IsShiftingUp = false;
IsShiftingDown = false;
}
protected void UpdateInput()
{
VerticalInput = Input.AnalogMove.x;
Handbrake = Input.Down( "Handbrake" ) ? 1 : 0;
SteeringAngle = Input.AnalogMove.y;
IsClutching = Input.Down( "Clutch" ) ? 1 : 0;
IsShiftingUp = Input.Pressed( "Shift Up" );
IsShiftingDown = Input.Pressed( "Shift Down" );
if ( TotalSpeed < 150 && Driver is null )
Handbrake = 1;
}
public bool Down( string action )
{
return IsDriverActive && Input.Down( action );
}
public bool Pressed( string action )
{
return IsDriverActive && Input.Pressed( action );
}
public bool Released( string action )
{
return IsDriverActive && Input.Released( action );
}
public void TriggerHaptics( float leftMotor, float rightMotor, float leftTrigger = 0f, float rightTrigger = 0f, int duration = 500 )
{
if ( IsDriverActive )
{
Input.TriggerHaptics( leftMotor, rightMotor, leftTrigger, rightTrigger, duration );
}
}
public void TriggerHaptics( HapticEffect effect, float lengthScale = 1, float frequencyScale = 1, float amplitudeScale = 1 )
{
if ( IsDriverActive )
{
Input.TriggerHaptics( effect, lengthScale, frequencyScale, amplitudeScale );
}
}
public void StopAllHaptics()
{
if ( IsDriverActive )
Input.StopAllHaptics();
}
}