using Sandbox; using System; using System.Collections.Generic; using VeloX.Powertrain; namespace VeloX; public partial class VeloXCar { [Property, Feature( "Engine" )] Engine Engine { get; set; } private void EngineThink( float dt ) { Engine.Throttle = Input.Down( "Forward" ) ? 1 : 0; Engine.ForwardStep( 0, 0 ); } //[Property, Feature( "Engine" ), Sync] public EngineState EngineState { get; set; } //[Property, Feature( "Engine" )] public EngineStream Stream { get; set; } //public EngineStreamPlayer StreamPlayer { get; set; } //[Property, Feature( "Engine" )] public float MinRPM { get; set; } = 800; //[Property, Feature( "Engine" )] public float MaxRPM { get; set; } = 7000; //[Property, Feature( "Engine" ), Range( -1, 1 )] //public float PowerDistribution //{ // get => powerDistribution; set // { // powerDistribution = value; // UpdatePowerDistribution(); // } //} //[Property, Feature( "Engine" )] public float FlyWheelMass { get; set; } = 80f; //[Property, Feature( "Engine" )] public float FlyWheelRadius { get; set; } = 0.5f; //[Property, Feature( "Engine" )] public float FlywheelFriction { get; set; } = -6000; //[Property, Feature( "Engine" )] public float FlywheelTorque { get; set; } = 20000; //[Property, Feature( "Engine" )] public float EngineBrakeTorque { get; set; } = 2000; //[Property, Feature( "Engine" )] //public Dictionary Gears { get; set; } = new() //{ // [-1] = 2.5f, // [0] = 0f, // [1] = 2.8f, // [2] = 1.7f, // [3] = 1.2f, // [4] = 0.9f, // [5] = 0.75f, // [6] = 0.7f //}; //[Property, Feature( "Engine" )] public float DifferentialRatio { get; set; } = 1f; //[Property, Feature( "Engine" ), Range( 0, 1 )] public float TransmissionEfficiency { get; set; } = 0.8f; //[Property, Feature( "Engine" )] private float MinRPMTorque { get; set; } = 5000f; //[Property, Feature( "Engine" )] private float MaxRPMTorque { get; set; } = 8000f; //[Sync] public int Gear { get; set; } = 0; //[Sync] public float Clutch { get; set; } = 1; //[Sync( SyncFlags.Interpolate )] public float EngineRPM { get; set; } //public float RPMPercent => (EngineRPM - MinRPM) / MaxRPM; //private const float TAU = MathF.Tau; //private int MinGear { get; set; } //private int MaxGear { get; set; } //[Sync] public bool IsRedlining { get; private set; } //private float flywheelVelocity; //private TimeUntil switchCD = 0; //private float groundedCount; //private float burnout; //private float frontBrake; //private float rearBrake; //private float availableFrontTorque; //private float availableRearTorque; //private float avgSideSlip; //private float avgPoweredRPM; //private float avgForwardSlip; //private float inputThrottle, inputBrake; //private bool inputHandbrake; //private float transmissionRPM; //private float powerDistribution; //public float FlywheelRPM //{ // get => flywheelVelocity * 60 / TAU; // set // { // flywheelVelocity = value * TAU / 60; EngineRPM = value; // } //} //private void UpdateGearList() //{ // int minGear = 0; // int maxGear = 0; // foreach ( var (gear, ratio) in Gears ) // { // if ( gear < minGear ) // minGear = gear; // if ( gear > maxGear ) // maxGear = gear; // if ( minGear != 0 || maxGear != 0 ) // { // SwitchGear( 0, false ); // } // } // MinGear = minGear; // MaxGear = maxGear; //} //public void SwitchGear( int index, bool cooldown = true ) //{ // if ( Gear == index ) return; // index = Math.Clamp( index, MinGear, MaxGear ); // if ( index == 0 || !cooldown ) // switchCD = 0; // else // switchCD = 0.3f; // Clutch = 1; // Gear = index; //} //public float TransmissionToEngineRPM( int gear ) => avgPoweredRPM * Gears[gear] * DifferentialRatio * 60 / TAU; //public float GetTransmissionMaxRPM( int gear ) => FlywheelRPM / Gears[gear] / DifferentialRatio; //private void UpdatePowerDistribution() //{ // if ( Wheels is null ) return; // int frontCount = 0, rearCount = 0; // foreach ( var wheel in Wheels ) // { // if ( wheel.IsFront ) // frontCount++; // else // rearCount++; // } // float frontDistribution = 0.5f + PowerDistribution * 0.5f; // float rearDistribution = 1 - frontDistribution; // frontDistribution /= frontCount; // rearDistribution /= rearCount; // foreach ( var wheel in Wheels ) // if ( wheel.IsFront ) // wheel.DistributionFactor = frontDistribution; // else // wheel.DistributionFactor = rearDistribution; //} //private void EngineAccelerate( float torque, float dt ) //{ // var inertia = 0.5f * FlyWheelMass * FlyWheelRadius * FlyWheelRadius; // var angularAcceleration = torque / inertia; // flywheelVelocity += angularAcceleration * dt; //} //private float GetTransmissionTorque( int gear, float minTorque, float maxTorque ) //{ // var torque = FlywheelRPM.Remap( MinRPM, MaxRPM, minTorque, maxTorque, true ); // torque *= (1 - Clutch); // torque = torque * Gears[gear] * DifferentialRatio * TransmissionEfficiency; // return gear == -1 ? -torque : torque; //} //private void AutoGearSwitch() //{ // if ( ForwardSpeed < 100 && Input.Down( "Backward" ) ) // { // SwitchGear( -1, false ); // return; // } // var currentGear = Gear; // if ( currentGear < 0 && ForwardSpeed < -100 ) // return; // if ( Math.Abs( avgForwardSlip ) > 10 ) // return; // var gear = Math.Clamp( currentGear, 1, MaxGear ); // float minRPM = MinRPM, maxRPM = MaxRPM; // maxRPM *= 0.98f; // float gearRPM; // for ( int i = 1; i <= MaxGear; i++ ) // { // gearRPM = TransmissionToEngineRPM( i ); // if ( (i == 1 && gearRPM < minRPM) || (gearRPM > minRPM && gearRPM < maxRPM) ) // { // gear = i; // break; // } // } // var threshold = minRPM + (maxRPM - minRPM) * (0.5 - Throttle * 0.3); // if ( gear < currentGear && gear > currentGear - 2 && EngineRPM > threshold ) // return; // SwitchGear( gear ); //} //private float EngineClutch( float dt ) //{ // if ( !switchCD ) // { // inputThrottle = 0; // return 0; // } // if ( inputHandbrake ) // return 1; // var absForwardSpeed = Math.Abs( ForwardSpeed ); // if ( groundedCount < 1 && absForwardSpeed > 30 ) // return 1; // if ( ForwardSpeed < -50 && inputBrake > 0 && Gear < 0 ) // return 1; // if ( absForwardSpeed > 200 ) // return 0; // return inputThrottle > 0.1f ? 0 : 1; //} //private void EngineThink( float dt ) //{ // inputThrottle = Input.Down( "Forward" ) ? 1 : 0; // inputBrake = Input.Down( "Backward" ) ? 1 : 0; // inputHandbrake = Input.Down( "Jump" ); // if ( burnout > 0 ) // { // SwitchGear( 1, false ); // if ( inputThrottle < 0.1f || inputBrake < 0.1f ) // burnout = 0; // } // else // AutoGearSwitch(); // if ( Gear < 0 ) // (inputBrake, inputThrottle) = (inputThrottle, inputBrake); // var rpm = FlywheelRPM; // var clutch = EngineClutch( dt ); // if ( inputThrottle > 0.1 && inputBrake > 0.1 && Math.Abs( ForwardSpeed ) < 50 ) // { // burnout = MathX.Approach( burnout, 1, dt * 2 ); // Clutch = 0; // } // else if ( inputHandbrake ) // { // frontBrake = 0f; // rearBrake = 0.5f; // Clutch = 1; // clutch = 1; // } // else // { // if ( (Gear == -1 || Gear == 1) && inputThrottle < 0.05f && inputBrake < 0.1f && groundedCount > 1 && rpm < MinRPM * 1.2f ) // inputBrake = 0.2f; // frontBrake = inputBrake * 0.5f; // rearBrake = inputBrake * 0.5f; // } // clutch = MathX.Approach( Clutch, clutch, dt * ((Gear < 2 && inputThrottle > 0.1f) ? 6 : 2) ); // Clutch = clutch; // var isRedlining = false; // transmissionRPM = 0; // if ( Gear != 0 ) // { // transmissionRPM = TransmissionToEngineRPM( Gear ); // transmissionRPM = Gear < 0 ? -transmissionRPM : transmissionRPM; // rpm = (rpm * clutch) + (MathF.Max( 0, transmissionRPM ) * (1 - clutch)); // } // var throttle = Throttle; // var gearTorque = GetTransmissionTorque( Gear, MinRPMTorque, MaxRPMTorque ); // var availableTorque = gearTorque * throttle; // if ( transmissionRPM < 0 ) // { // availableTorque += gearTorque * 2; // } // else // { // var engineBrakeTorque = GetTransmissionTorque( Gear, EngineBrakeTorque, EngineBrakeTorque ); // availableTorque -= engineBrakeTorque * (1 - throttle) * 0.5f; // } // var maxRPM = MaxRPM; // if ( rpm < MinRPM ) // { // rpm = MinRPM; // } // else if ( rpm > maxRPM ) // { // if ( rpm > maxRPM * 1.2f ) // availableTorque = 0; // rpm = maxRPM; // if ( Gear != MaxGear || groundedCount < Wheels.Count ) // isRedlining = true; // } // FlywheelRPM = Math.Clamp( rpm, 0, maxRPM ); // if ( burnout > 0 ) // availableTorque += availableTorque * burnout * 0.1f; // var front = 0.5f + PowerDistribution * 0.5f; // var rear = 1 - front; // availableFrontTorque = availableTorque * front; // availableRearTorque = availableTorque * rear; // throttle = MathX.Approach( throttle, inputThrottle, dt * 4 ); // EngineAccelerate( FlywheelFriction + FlywheelTorque * throttle, dt ); // Throttle = throttle; // IsRedlining = (isRedlining && inputThrottle > 0); //} }