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

124 lines
2.6 KiB
C#

namespace Sandbox.Tools
{
[Library( "tool_balloon", Title = "Balloons", Description = "Create Balloons!", Group = "construction" )]
public partial class BalloonTool : BaseTool
{
[Net]
public Color32 Tint { get; set; }
PreviewEntity previewModel;
public override void Activate()
{
base.Activate();
if ( Host.IsServer )
{
Tint = Color.Random.ToColor32();
}
}
protected override bool IsPreviewTraceValid( TraceResult tr )
{
if ( !base.IsPreviewTraceValid( tr ) )
return false;
if ( tr.Entity is BalloonEntity )
return false;
return true;
}
public override void CreatePreviews()
{
if ( TryCreatePreview( ref previewModel, "models/citizen_props/balloonregular01.vmdl" ) )
{
previewModel.RelativeToNormal = false;
}
}
public override void Simulate()
{
if ( previewModel.IsValid() )
{
previewModel.RenderColor = Tint;
}
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 )
return;
if ( !tr.Entity.IsValid() )
return;
CreateHitEffects( tr.EndPos );
if ( tr.Entity is BalloonEntity )
return;
var ent = new BalloonEntity
{
Position = tr.EndPos,
};
ent.SetModel( "models/citizen_props/balloonregular01.vmdl" );
ent.PhysicsBody.GravityScale = -0.2f;
ent.RenderColor = Tint;
Tint = Color.Random.ToColor32();
if ( !useRope )
return;
var rope = Particles.Create( "particles/rope.vpcf" );
rope.SetEntity( 0, ent );
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( ent.PhysicsBody )
.To( tr.Body, tr.Body.Transform.PointToLocal( tr.EndPos ) )
.WithFrequency( 5.0f )
.WithDampingRatio( 0.7f )
.WithReferenceMass( ent.PhysicsBody.Mass )
.WithMinRestLength( 0 )
.WithMaxRestLength( 100 )
.WithCollisionsEnabled()
.Create();
spring.EnableAngularConstraint = false;
spring.OnBreak( () =>
{
rope?.Destroy( true );
spring.Remove();
} );
}
}
}
}