mirror of
https://github.com/celisej567/gm_construct_port.git
synced 2026-09-19 20:11:46 +03:00
Add files via upload
This commit is contained in:
122
code/tools/Rope.cs
Normal file
122
code/tools/Rope.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user