mirror of
https://github.com/celisej567/gm_construct_port.git
synced 2026-01-01 09:48:13 +03:00
123 lines
2.5 KiB
C#
123 lines
2.5 KiB
C#
namespace Sandbox.Tools
|
|
{
|
|
[Library( "tool_rope", Title = "Rope", Description = "Join two things together with a rope", Group = "construction" )]
|
|
public partial class RopeTool : BaseTool
|
|
{
|
|
private PhysicsBody targetBody;
|
|
private int targetBone;
|
|
private Vector3 localOrigin1;
|
|
private Vector3 globalOrigin1;
|
|
|
|
public override void Simulate()
|
|
{
|
|
if ( !Host.IsServer )
|
|
return;
|
|
|
|
using ( Prediction.Off() )
|
|
{
|
|
if ( !Input.Pressed( InputButton.Attack1 ) )
|
|
return;
|
|
|
|
var startPos = Owner.EyePos;
|
|
var dir = Owner.EyeRot.Forward;
|
|
|
|
var tr = Trace.Ray( startPos, startPos + dir * MaxTraceDistance )
|
|
.Ignore( Owner )
|
|
.Run();
|
|
|
|
if ( !tr.Hit )
|
|
return;
|
|
|
|
if ( !tr.Body.IsValid() )
|
|
return;
|
|
|
|
if ( !tr.Entity.IsValid() )
|
|
return;
|
|
|
|
if ( tr.Entity is not ModelEntity )
|
|
return;
|
|
|
|
if ( !targetBody.IsValid() )
|
|
{
|
|
targetBody = tr.Body;
|
|
targetBone = tr.Bone;
|
|
globalOrigin1 = tr.EndPos;
|
|
localOrigin1 = tr.Body.Transform.PointToLocal( globalOrigin1 );
|
|
|
|
CreateHitEffects( tr.EndPos );
|
|
|
|
return;
|
|
}
|
|
|
|
if ( targetBody == tr.Body )
|
|
return;
|
|
|
|
var rope = Particles.Create( "particles/rope.vpcf" );
|
|
|
|
if ( targetBody.Entity.IsWorld )
|
|
{
|
|
rope.SetPosition( 0, localOrigin1 );
|
|
}
|
|
else
|
|
{
|
|
rope.SetEntityBone( 0, targetBody.Entity, targetBone, new Transform( localOrigin1 * (1.0f / targetBody.Entity.Scale) ) );
|
|
}
|
|
|
|
var localOrigin2 = tr.Body.Transform.PointToLocal( tr.EndPos );
|
|
|
|
if ( tr.Entity.IsWorld )
|
|
{
|
|
rope.SetPosition( 1, localOrigin2 );
|
|
}
|
|
else
|
|
{
|
|
rope.SetEntityBone( 1, tr.Entity, tr.Bone, new Transform( localOrigin2 * (1.0f / tr.Entity.Scale) ) );
|
|
}
|
|
|
|
var spring = PhysicsJoint.Spring
|
|
.From( targetBody, localOrigin1 )
|
|
.To( tr.Body, localOrigin2 )
|
|
.WithFrequency( 5.0f )
|
|
.WithDampingRatio( 0.7f )
|
|
.WithReferenceMass( targetBody.Mass )
|
|
.WithMinRestLength( 0 )
|
|
.WithMaxRestLength( tr.EndPos.Distance( globalOrigin1 ) )
|
|
.WithCollisionsEnabled()
|
|
.Create();
|
|
|
|
spring.EnableAngularConstraint = false;
|
|
spring.OnBreak( () =>
|
|
{
|
|
rope?.Destroy( true );
|
|
spring.Remove();
|
|
} );
|
|
|
|
CreateHitEffects( tr.EndPos );
|
|
|
|
Reset();
|
|
}
|
|
}
|
|
|
|
private void Reset()
|
|
{
|
|
targetBody = null;
|
|
targetBone = -1;
|
|
localOrigin1 = default;
|
|
}
|
|
|
|
public override void Activate()
|
|
{
|
|
base.Activate();
|
|
|
|
Reset();
|
|
}
|
|
|
|
public override void Deactivate()
|
|
{
|
|
base.Deactivate();
|
|
|
|
Reset();
|
|
}
|
|
}
|
|
}
|