Files
gm_construct_port/code/tools/Light.cs
2021-08-05 17:54:51 +03:00

117 lines
2.8 KiB
C#

namespace Sandbox.Tools
{
[Library( "tool_light", Title = "Lights", Description = "A dynamic point light", Group = "construction" )]
public partial class LightTool : BaseTool
{
PreviewEntity previewModel;
private string Model => "models/light/light_tubular.vmdl";
protected override bool IsPreviewTraceValid( TraceResult tr )
{
if ( !base.IsPreviewTraceValid( tr ) )
return false;
if ( tr.Entity is LightEntity )
return false;
return true;
}
public override void CreatePreviews()
{
if ( TryCreatePreview( ref previewModel, Model ) )
{
previewModel.RelativeToNormal = false;
previewModel.OffsetBounds = true;
previewModel.PositionOffset = -previewModel.CollisionBounds.Center;
}
}
public override void Simulate()
{
if ( !Host.IsServer )
return;
using ( Prediction.Off() )
{
bool useRope = Input.Pressed( InputButton.Attack1 );
if ( !useRope && !Input.Pressed( InputButton.Attack2 ) )
return;
var startPos = Owner.EyePos;
var dir = Owner.EyeRot.Forward;
var tr = Trace.Ray( startPos, startPos + dir * MaxTraceDistance )
.Ignore( Owner )
.Run();
if ( !tr.Hit || !tr.Entity.IsValid() )
return;
CreateHitEffects( tr.EndPos );
if ( tr.Entity is LightEntity )
{
// TODO: Set properties
return;
}
var light = new LightEntity
{
Enabled = true,
DynamicShadows = false,
Range = 128,
Falloff = 1.0f,
LinearAttenuation = 0.0f,
QuadraticAttenuation = 1.0f,
Brightness = 1,
Color = Color.Random,
};
light.UseFogNoShadows();
light.SetModel( Model );
light.SetupPhysicsFromModel( PhysicsMotionType.Dynamic, false );
light.Position = tr.EndPos + -light.CollisionBounds.Center + tr.Normal * light.CollisionBounds.Size * 0.5f;
if ( !useRope )
return;
var rope = Particles.Create( "particles/rope.vpcf" );
rope.SetEntity( 0, light, Vector3.Down * 6.5f ); // Should be an attachment point
var attachEnt = tr.Body.IsValid() ? tr.Body.Entity : tr.Entity;
var attachLocalPos = tr.Body.Transform.PointToLocal( tr.EndPos ) * (1.0f / tr.Entity.Scale);
if ( attachEnt.IsWorld )
{
rope.SetPosition( 1, attachLocalPos );
}
else
{
rope.SetEntityBone( 1, attachEnt, tr.Bone, new Transform( attachLocalPos ) );
}
var spring = PhysicsJoint.Spring
.From( light.PhysicsBody, Vector3.Down * 6.5f )
.To( tr.Body, tr.Body.Transform.PointToLocal( tr.EndPos ) )
.WithFrequency( 5.0f )
.WithDampingRatio( 0.7f )
.WithReferenceMass( light.PhysicsBody.Mass )
.WithMinRestLength( 0 )
.WithMaxRestLength( 100 )
.WithCollisionsEnabled()
.Create();
spring.EnableAngularConstraint = false;
spring.OnBreak( () =>
{
rope?.Destroy( true );
spring.Remove();
} );
}
}
}
}