mirror of
https://github.com/celisej567/gm_construct_port.git
synced 2026-01-02 13:50:32 +03:00
147 lines
4.1 KiB
C#
147 lines
4.1 KiB
C#
using Sandbox;
|
|
using System;
|
|
|
|
[Library( "ent_drone", Title = "Drone", Spawnable = true )]
|
|
public partial class DroneEntity : Prop
|
|
{
|
|
public virtual float altitudeAcceleration => 2000;
|
|
public virtual float movementAcceleration => 5000;
|
|
public virtual float yawSpeed => 150;
|
|
public virtual float uprightSpeed => 5000;
|
|
public virtual float uprightDot => 0.5f;
|
|
public virtual float leanWeight => 0.5f;
|
|
public virtual float leanMaxVelocity => 1000;
|
|
|
|
private struct DroneInputState
|
|
{
|
|
public Vector3 movement;
|
|
public float throttle;
|
|
public float pitch;
|
|
public float yaw;
|
|
|
|
public void Reset()
|
|
{
|
|
movement = Vector3.Zero;
|
|
pitch = 0;
|
|
yaw = 0;
|
|
}
|
|
}
|
|
|
|
private DroneInputState currentInput;
|
|
|
|
public override void Spawn()
|
|
{
|
|
base.Spawn();
|
|
|
|
SetModel( "entities/drone/drone.vmdl" );
|
|
SetupPhysicsFromModel( PhysicsMotionType.Dynamic, false );
|
|
}
|
|
|
|
[Event.Physics.PostStep]
|
|
public void OnPostPhysicsStep()
|
|
{
|
|
if ( !PhysicsBody.IsValid() )
|
|
{
|
|
return;
|
|
}
|
|
|
|
var body = PhysicsBody;
|
|
var transform = Transform;
|
|
|
|
body.LinearDrag = 1.0f;
|
|
body.AngularDrag = 1.0f;
|
|
body.LinearDamping = 4.0f;
|
|
body.AngularDamping = 4.0f;
|
|
|
|
var yawRot = Rotation.From( new Angles( 0, Rotation.Angles().yaw, 0 ) );
|
|
var worldMovement = yawRot * currentInput.movement;
|
|
var velocityDirection = body.Velocity.WithZ( 0 );
|
|
var velocityMagnitude = velocityDirection.Length;
|
|
velocityDirection = velocityDirection.Normal;
|
|
|
|
var velocityScale = (velocityMagnitude / leanMaxVelocity).Clamp( 0, 1 );
|
|
var leanDirection = worldMovement.LengthSquared == 0.0f
|
|
? -velocityScale * velocityDirection
|
|
: worldMovement;
|
|
|
|
var targetUp = (Vector3.Up + leanDirection * leanWeight * velocityScale).Normal;
|
|
var currentUp = transform.NormalToWorld( Vector3.Up );
|
|
var alignment = Math.Max( Vector3.Dot( targetUp, currentUp ), 0 );
|
|
|
|
bool hasCollision = false;
|
|
bool isGrounded = false;
|
|
|
|
if ( !hasCollision || isGrounded )
|
|
{
|
|
var hoverForce = isGrounded && currentInput.throttle <= 0 ? Vector3.Zero : -1 * transform.NormalToWorld( Vector3.Up ) * -800.0f;
|
|
var movementForce = isGrounded ? Vector3.Zero : worldMovement * movementAcceleration;
|
|
var altitudeForce = transform.NormalToWorld( Vector3.Up ) * currentInput.throttle * altitudeAcceleration;
|
|
var totalForce = hoverForce + movementForce + altitudeForce;
|
|
body.ApplyForce( (totalForce * alignment) * body.Mass );
|
|
}
|
|
|
|
if ( !hasCollision && !isGrounded )
|
|
{
|
|
var spinTorque = Transform.NormalToWorld( new Vector3( 0, 0, currentInput.yaw * yawSpeed ) );
|
|
var uprightTorque = Vector3.Cross( currentUp, targetUp ) * uprightSpeed;
|
|
var uprightAlignment = alignment < uprightDot ? 0 : alignment;
|
|
var totalTorque = spinTorque * alignment + uprightTorque * uprightAlignment;
|
|
body.ApplyTorque( (totalTorque * alignment) * body.Mass );
|
|
}
|
|
}
|
|
|
|
public override void Simulate( Client owner )
|
|
{
|
|
if ( owner == null ) return;
|
|
if ( !IsServer ) return;
|
|
|
|
using ( Prediction.Off() )
|
|
{
|
|
currentInput.Reset();
|
|
var x = (Input.Down( InputButton.Forward ) ? -1 : 0) + (Input.Down( InputButton.Back ) ? 1 : 0);
|
|
var y = (Input.Down( InputButton.Right ) ? 1 : 0) + (Input.Down( InputButton.Left ) ? -1 : 0);
|
|
currentInput.movement = new Vector3( x, y, 0 ).Normal;
|
|
currentInput.throttle = (Input.Down( InputButton.Run ) ? 1 : 0) + (Input.Down( InputButton.Duck ) ? -1 : 0);
|
|
currentInput.yaw = -Input.MouseDelta.x;
|
|
}
|
|
}
|
|
|
|
public void ResetInput()
|
|
{
|
|
currentInput.Reset();
|
|
}
|
|
|
|
private readonly Vector3[] turbinePositions = new Vector3[]
|
|
{
|
|
new Vector3( -35.37f, 35.37f, 10.0f ),
|
|
new Vector3( 35.37f, 35.37f, 10.0f ),
|
|
new Vector3( 35.37f, -35.37f, 10.0f ),
|
|
new Vector3( -35.37f, -35.37f, 10.0f )
|
|
};
|
|
|
|
public override void OnNewModel( Model model )
|
|
{
|
|
base.OnNewModel( model );
|
|
|
|
if ( IsClient )
|
|
{
|
|
}
|
|
}
|
|
|
|
private float spinAngle;
|
|
|
|
[Event.Frame]
|
|
public void OnFrame()
|
|
{
|
|
spinAngle += 10000.0f * Time.Delta;
|
|
spinAngle %= 360.0f;
|
|
|
|
for ( int i = 0; i < turbinePositions.Length; ++i )
|
|
{
|
|
var transform = Transform.ToWorld( new Transform( turbinePositions[i] * Scale, Rotation.From( new Angles( 0, spinAngle, 0 ) ) ) );
|
|
transform.Scale = Scale;
|
|
SetBoneTransform( i, transform );
|
|
}
|
|
}
|
|
}
|