dedicated

This commit is contained in:
Valera 2025-12-03 15:17:36 +07:00
parent 66fcc6a2bb
commit e22e463f11
13 changed files with 105 additions and 80 deletions

View File

@ -0,0 +1,8 @@
{
"loop": false,
"start": 0,
"end": 0,
"rate": 44100,
"compress": false,
"bitrate": 256
}

View File

@ -15,7 +15,7 @@ public class Transmission : PowertrainComponent
/// <summary> /// <summary>
/// A class representing a single ground surface type. /// A class representing a single ground surface type.
/// </summary> /// </summary>
public partial class TransmissionGearingProfile public class TransmissionGearingProfile
{ {
/// <summary> /// <summary>
/// List of forward gear ratios starting from 1st forward gear. /// List of forward gear ratios starting from 1st forward gear.

View File

@ -4,8 +4,10 @@ namespace VeloX;
public abstract partial class VeloXBase public abstract partial class VeloXBase
{ {
internal InputResolver Input { get; set; } = new(); internal readonly InputResolver Input = new();
public Connection Driver { get => Input.Driver; set => Input.Driver = value; }
public Guid DriverId { get; set; }
public Connection Driver => Connection.Find( DriverId );
public bool IsDriver => Connection.Local == Driver; public bool IsDriver => Connection.Local == Driver;
private bool IsDriverActive => Driver is not null; private bool IsDriverActive => Driver is not null;
@ -109,6 +111,8 @@ public abstract partial class VeloXBase
protected void UpdateInput() protected void UpdateInput()
{ {
//VerticalInput = Input.AnalogMove.x; //VerticalInput = Input.AnalogMove.x;
if ( IsDriverActive )
{
Brakes = Input.Brake; Brakes = Input.Brake;
Throttle = Input.Throttle; Throttle = Input.Throttle;
@ -121,6 +125,11 @@ public abstract partial class VeloXBase
IsShiftingUp = Input.Pressed( "Shift Up" ); IsShiftingUp = Input.Pressed( "Shift Up" );
IsShiftingDown = Input.Pressed( "Shift Down" ); IsShiftingDown = Input.Pressed( "Shift Down" );
}
else
{
ResetInput();
}
if ( TotalSpeed < 150 && Driver is null ) if ( TotalSpeed < 150 && Driver is null )
Handbrake = 1; Handbrake = 1;

View File

@ -5,7 +5,6 @@ namespace VeloX;
public abstract partial class VeloXBase public abstract partial class VeloXBase
{ {
private Vector3 linForce;
private Vector3 angForce; private Vector3 angForce;
protected const float BrakeForce = 4500f; protected const float BrakeForce = 4500f;
protected const float HandbrakeForce = 35000f; protected const float HandbrakeForce = 35000f;
@ -13,18 +12,16 @@ public abstract partial class VeloXBase
{ {
if ( Body.Sleeping && Input.AnalogMove.x == 0 ) if ( Body.Sleeping && Input.AnalogMove.x == 0 )
return; return;
//Body.PhysicsBody.SetInertiaTensor( new Vector3( 800000, 3000000, 6000000 ), Rotation.Identity );
var drag = AngularDrag; var drag = AngularDrag;
var mass = Body.Mass; var mass = Body.Mass;
var angVel = Body.AngularVelocity; var angVel = Body.AngularVelocity;
linForce.x = 0;
linForce.y = 0;
linForce.z = 0;
angForce = angForce.WithX( angVel.x * drag.x * mass * 1000 ); angForce = angForce.WithX( angVel.x * drag.x * mass * 1000 );
angForce = angForce.WithY( angVel.y * drag.y * mass * 1000 ); angForce = angForce.WithY( angVel.y * drag.y * mass * 1000 );
angForce = angForce.WithZ( angVel.z * drag.z * mass * 1000 ); angForce = angForce.WithZ( angVel.z * drag.z * mass * 1000 );
if ( Wheels.Count > 0 ) if ( Wheels.Count > 0 )
{ {
Vector3 vehVel = Body.Velocity; Vector3 vehVel = Body.Velocity;
@ -58,8 +55,8 @@ public abstract partial class VeloXBase
Body.AngularVelocity = vehAngVel; Body.AngularVelocity = vehAngVel;
} }
Body.ApplyForce( linForce ); //Body.ApplyForce( linForce );
Body.ApplyTorque( angForce ); //Body.ApplyTorque( angForce );
} }

View File

@ -56,10 +56,4 @@ public abstract partial class VeloXBase : Component, IGameObjectNetworkEvents
PhysicsSimulate(); PhysicsSimulate();
} }
//void IGameObjectNetworkEvents.NetworkOwnerChanged( Connection newOwner, Connection previousOwner )
//{
// Driver = newOwner;
// EngineIgnition = Driver is not null;
//}
} }

View File

@ -8,6 +8,9 @@ internal sealed class WheelManager : GameObjectSystem
public WheelManager( Scene scene ) : base( scene ) public WheelManager( Scene scene ) : base( scene )
{ {
if ( Application.IsDedicatedServer )
return;
Listen( Stage.StartFixedUpdate, -99, UpdateWheels, "UpdateWheels" ); Listen( Stage.StartFixedUpdate, -99, UpdateWheels, "UpdateWheels" );
Listen( Stage.StartFixedUpdate, -100, UpdateEngine, "UpdateEngine" ); Listen( Stage.StartFixedUpdate, -100, UpdateEngine, "UpdateEngine" );
} }

View File

@ -15,7 +15,7 @@ public partial class VeloXCar
if ( !UseABS ) if ( !UseABS )
return; return;
if ( TotalSpeed < 100 || Steering.AlmostEqual( 0, 1 ) ) if ( TotalSpeed < 100 || SteeringAngle.AlmostEqual( 0, 1 ) )
return; return;

View File

@ -1,6 +1,7 @@
 
using Sandbox; using Sandbox;
using Sandbox.Audio;
using System; using System;
namespace VeloX; namespace VeloX;
@ -48,23 +49,27 @@ public partial class VeloXCar
protected virtual void UpdateDrift( float dt ) protected virtual void UpdateDrift( float dt )
{ {
float driftAngle = GetDriftAngle();
float mul = (driftAngle - MIN_DRIFT_ANGLE) / (90 - MIN_DRIFT_ANGLE); var avgslip = 0f;
foreach ( var item in Wheels )
avgslip += item.NormalizedLongitudinalSlip + item.NormalizedLateralSlip;
if ( !_skidHandle.IsValid() ) float mul = Math.Clamp( avgslip, 0, 2 );
_skidHandle = Sound.PlayFile( SkidSound );
if ( !_skidHandle.IsValid() )
return;
targetVolume = mul; targetVolume = mul;
targetPitch = 0.75f + 0.25f * mul; targetPitch = 0.75f + 0.25f * mul;
if ( mul > 0.1f && !_skidHandle.IsValid() )
{
_skidHandle = Sound.PlayFile( SkidSound );
_skidHandle.TargetMixer = Mixer.Default;
}
if ( !_skidHandle.IsValid() )
return;
_skidHandle.Pitch += (targetPitch - _skidHandle.Pitch) * dt * 5f; _skidHandle.Pitch += (targetPitch - _skidHandle.Pitch) * dt * 5f;
_skidHandle.Volume += (targetVolume - _skidHandle.Volume) * dt * 10f; _skidHandle.Volume += (targetVolume - _skidHandle.Volume) * dt * 10f;
_skidHandle.Position = WorldPosition; _skidHandle.Position = WorldPosition;
} }
} }

View File

@ -24,15 +24,6 @@ public partial class VeloXCar
angle -= SteerAngle.yaw * 0.5f; angle -= SteerAngle.yaw * 0.5f;
float absAngle = angle < 0 ? -angle : angle; float absAngle = angle < 0 ? -angle : angle;
//foreach ( var wheel in Wheels )
//{
// if ( !wheel.IsOnGround )
// continue;
// Log.Info( wheel.LongitudinalSlip < 0.1f );
// if ( wheel.LongitudinalSlip < 0.1f )
// wheel.BrakeTorque += Math.Abs( wheel.LongitudinalSlip ) * 10000;
//}
if ( Engine.RevLimiterActive || absAngle < 2f ) if ( Engine.RevLimiterActive || absAngle < 2f )
return; return;

View File

@ -21,16 +21,11 @@ public partial class VeloXCar
public int CarDirection { get { return ForwardSpeed < 1 ? 0 : (VelocityAngle < 90 && VelocityAngle > -90 ? 1 : -1); } } public int CarDirection { get { return ForwardSpeed < 1 ? 0 : (VelocityAngle < 90 && VelocityAngle > -90 ? 1 : -1); } }
public float VelocityAngle { get; private set; } public float VelocityAngle { get; private set; }
[Sync] public float Steering { get; private set; }
private float currentSteerAngle; private float currentSteerAngle;
private float inputSteer;
private void UpdateSteering( float dt ) private void UpdateSteering( float dt )
{ {
inputSteer = Input.AnalogMove.y; float targetSteerAngle = SteeringAngle * MaxSteerAngle;
float targetSteerAngle = inputSteer * MaxSteerAngle;
if ( !Input.Down( "Jump" ) ) if ( !Input.Down( "Jump" ) )
targetSteerAngle *= Math.Clamp( 1 - Math.Clamp( TotalSpeed / 3000, 0f, 0.85f ), -1, 1 ); targetSteerAngle *= Math.Clamp( 1 - Math.Clamp( TotalSpeed / 3000, 0f, 0.85f ), -1, 1 );
@ -42,10 +37,9 @@ public partial class VeloXCar
if ( TotalSpeed > 150 && CarDirection > 0 && IsOnGround ) if ( TotalSpeed > 150 && CarDirection > 0 && IsOnGround )
targetAngle = VelocityAngle * MaxSteerAngleMultiplier; targetAngle = VelocityAngle * MaxSteerAngleMultiplier;
float lerpSpeed = Math.Abs( inputSteer ) < 0.1f ? SteerReturnSpeed : SteerInputResponse; float lerpSpeed = Math.Abs( SteeringAngle ) < 0.1f ? SteerReturnSpeed : SteerInputResponse;
currentSteerAngle = ExpDecay( currentSteerAngle, targetSteerAngle, lerpSpeed, Time.Delta ); currentSteerAngle = ExpDecay( currentSteerAngle, targetSteerAngle, lerpSpeed, Time.Delta );
Steering = currentSteerAngle + targetAngle; SteerAngle = new( 0, Math.Clamp( currentSteerAngle + targetAngle, -MaxSteerAngle, MaxSteerAngle ), 0 );
SteerAngle = new( 0, Math.Clamp( Steering, -MaxSteerAngle, MaxSteerAngle ), 0 );
} }
} }

39
Code/Car/VeloXCar.TCS.cs Normal file
View File

@ -0,0 +1,39 @@
using Sandbox;
using System;
namespace VeloX;
public partial class VeloXCar
{
public bool TCSActive { get; private set; } = true;
public static bool UseTCS = true;
private void UpdateTCS()
{
TCSActive = false;
if ( !UseTCS )
return;
if ( TotalSpeed < 50 || CarDirection != 1 )
return;
float vehicleSpeed = TotalSpeed.InchToMeter();
foreach ( var wheel in Wheels )
{
if ( !wheel.IsOnGround )
continue;
float wheelLinearSpeed = wheel.AngularVelocity * wheel.Radius;
float wheelSlip = wheelLinearSpeed - vehicleSpeed;
if ( wheelSlip > 2.0f )
{
TCSActive = true;
wheel.BrakeTorque = wheelSlip * 1000;
}
}
}
}

View File

@ -15,6 +15,7 @@ public partial class VeloXCar : VeloXBase
return; return;
UpdateABS(); UpdateABS();
UpdateESC(); UpdateESC();
UpdateTCS();
var dt = Time.Delta; var dt = Time.Delta;
//EngineThink( dt ); //EngineThink( dt );
SimulateAerodinamics( dt ); SimulateAerodinamics( dt );
@ -26,7 +27,7 @@ public partial class VeloXCar : VeloXBase
private void UpdateUnflip( float dt ) private void UpdateUnflip( float dt )
{ {
if ( Math.Abs( inputSteer ) < 0.1f ) if ( Math.Abs( SteeringAngle ) < 0.1f )
return; return;
if ( IsOnGround || Math.Abs( WorldRotation.Roll() ) < 60 ) if ( IsOnGround || Math.Abs( WorldRotation.Roll() ) < 60 )
@ -42,7 +43,7 @@ public partial class VeloXCar : VeloXBase
if ( velocityFactor <= 0.01f ) if ( velocityFactor <= 0.01f )
return; return;
var force = inputSteer * velocityFactor * 150; var force = SteeringAngle * velocityFactor * 150;
Body.AngularVelocity -= Body.WorldRotation.Forward * force * dt; Body.AngularVelocity -= Body.WorldRotation.Forward * force * dt;
} }

View File

@ -4,13 +4,10 @@ namespace VeloX;
public class InputResolver public class InputResolver
{ {
public Connection Driver { get; internal set; }
private bool IsDriverActive => Driver is not null; public Vector2 MouseDelta => Input.MouseDelta;
public Vector2 MouseWheel => Input.MouseWheel;
public Vector2 MouseDelta => IsDriverActive ? Input.MouseDelta : default; public Angles AnalogLook => Input.AnalogLook;
public Vector2 MouseWheel => IsDriverActive ? Input.MouseWheel : default;
public Angles AnalogLook => IsDriverActive ? Input.AnalogLook : default;
public Vector3 AnalogMove public Vector3 AnalogMove
{ {
get get
@ -22,22 +19,19 @@ public class InputResolver
input.y = -Input.GetAnalog( InputAnalog.LeftStickX ); input.y = -Input.GetAnalog( InputAnalog.LeftStickX );
return input; return input;
} }
return IsDriverActive ? Input.AnalogMove : default; return Input.AnalogMove;
} }
} }
public bool Down( string action ) public bool Down( string action )
{ {
return IsDriverActive && Input.Down( action ); return Input.Down( action );
} }
public float Brake public float Brake
{ {
get get
{ {
if ( !IsDriverActive )
return 0;
if ( Input.UsingController ) if ( Input.UsingController )
return Input.GetAnalog( InputAnalog.LeftTrigger ); return Input.GetAnalog( InputAnalog.LeftTrigger );
@ -48,9 +42,6 @@ public class InputResolver
{ {
get get
{ {
if ( !IsDriverActive )
return 0;
if ( Input.UsingController ) if ( Input.UsingController )
return Input.GetAnalog( InputAnalog.RightTrigger ); return Input.GetAnalog( InputAnalog.RightTrigger );
@ -60,37 +51,30 @@ public class InputResolver
public bool Pressed( string action ) public bool Pressed( string action )
{ {
return IsDriverActive && Input.Pressed( action ); return Input.Pressed( action );
} }
public bool Released( string action ) public bool Released( string action )
{ {
return IsDriverActive && Input.Released( action ); return Input.Released( action );
} }
public float GetAnalog( InputAnalog analog ) public float GetAnalog( InputAnalog analog )
{ {
return IsDriverActive ? Input.GetAnalog( analog ) : 0f; return Input.GetAnalog( analog );
} }
public void TriggerHaptics( float leftMotor, float rightMotor, float leftTrigger = 0f, float rightTrigger = 0f, int duration = 500 ) 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 ); Input.TriggerHaptics( leftMotor, rightMotor, leftTrigger, rightTrigger, duration );
} }
}
public void TriggerHaptics( HapticEffect effect, float lengthScale = 1, float frequencyScale = 1, float amplitudeScale = 1 ) public void TriggerHaptics( HapticEffect effect, float lengthScale = 1, float frequencyScale = 1, float amplitudeScale = 1 )
{
if ( IsDriverActive )
{ {
Input.TriggerHaptics( effect, lengthScale, frequencyScale, amplitudeScale ); Input.TriggerHaptics( effect, lengthScale, frequencyScale, amplitudeScale );
} }
}
public void StopAllHaptics() public void StopAllHaptics()
{ {
if ( IsDriverActive )
Input.StopAllHaptics(); Input.StopAllHaptics();
} }
} }