public override void OnPlayerControlTick() { if (previewModel.IsValid()) { previewModel.RenderColor = color; } if (!Host.IsServer) { return; } using (Prediction.Off()) { var input = Owner.Input; 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 { WorldPos = tr.EndPos, }; ent.SetModel("models/citizen_props/balloonregular01.vmdl"); ent.PhysicsBody.GravityScale = -0.2f; ent.RenderColor = color; color = 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); if (attachEnt.IsWorld) { rope.SetPos(1, attachLocalPos); } else { rope.SetEntityBone(1, attachEnt, tr.Bone, new Transform(attachLocalPos)); } ent.AttachRope = rope; ent.AttachJoint = PhysicsJoint.Spring .From(ent.PhysicsBody) .To(tr.Body) .WithPivot(tr.EndPos) .WithFrequency(5.0f) .WithDampingRatio(0.7f) .WithReferenceMass(0) .WithMinRestLength(0) .WithMaxRestLength(100) .WithCollisionsEnabled() .Create(); } }
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.EyePosition; var dir = Owner.EyeRotation.Forward; var tr = Trace.Ray(startPos, startPos + dir * MaxTraceDistance) .Ignore(Owner) .Run(); if (!tr.Hit) { return; } if (!tr.Entity.IsValid()) { return; } CreateHitEffects(tr.EndPosition); if (tr.Entity is BalloonEntity) { return; } var ent = new BalloonEntity { Position = tr.EndPosition, }; ent.SetModel("models/citizen_props/balloonregular01.vmdl"); ent.PhysicsBody.GravityScale = -0.2f; ent.RenderColor = Tint; Tint = Color.Random; if (!useRope) { return; } var rope = Particles.Create("particles/rope.vpcf"); rope.SetEntity(0, ent); var attachEnt = tr.Body.IsValid() ? tr.Body.GetEntity() : tr.Entity; var attachLocalPos = tr.Body.Transform.PointToLocal(tr.EndPosition) * (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.CreateLength(ent.PhysicsBody, PhysicsPoint.World(tr.Body, tr.EndPosition), 100); spring.SpringLinear = new(5, 0.7f); spring.Collisions = true; spring.EnableAngularConstraint = false; spring.OnBreak += () => { rope?.Destroy(true); spring.Remove(); }; } }