public override void OnPlayerControlTick() { 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 || !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.WorldPos = 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); if (attachEnt.IsWorld) { rope.SetPos(1, attachLocalPos); } else { rope.SetEntityBone(1, attachEnt, tr.Bone, new Transform(attachLocalPos)); } light.AttachRope = rope; light.AttachJoint = PhysicsJoint.Spring .From(light.PhysicsBody) .To(tr.Body) .WithPivot(light.WorldPos + Vector3.Down * 6.5f) .WithFrequency(5.0f) .WithDampingRatio(0.7f) .WithReferenceMass(0) .WithMinRestLength(0) .WithMaxRestLength(100) .WithCollisionsEnabled() .Create(); } }
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.EyePosition; var dir = Owner.EyeRotation.Forward; var tr = Trace.Ray(startPos, startPos + dir * MaxTraceDistance) .Ignore(Owner) .Run(); if (!tr.Hit || !tr.Entity.IsValid()) { return; } CreateHitEffects(tr.EndPosition); 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, //LightCookie = Texture.Load( "materials/effects/lightcookie.vtex" ) }; light.UseFogNoShadows(); light.SetModel(Model); light.SetupPhysicsFromModel(PhysicsMotionType.Dynamic, false); light.Position = tr.EndPosition + -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.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(PhysicsPoint.Local(light.PhysicsBody, Vector3.Down * 6.5f), 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(); }; } }