示例#1
0
    private void GrabMove(Vector3 startPos, Vector3 dir, Rotation rot)
    {
        if (!HeldBody.IsValid())
        {
            return;
        }

        holdBody.Pos = startPos + dir * HoldDistance;
        holdBody.Rot = rot * HeldRot;
    }
示例#2
0
    private void GrabMove(Vector3 startPos, Vector3 dir, Rotation rot)
    {
        if (!HeldBody.IsValid())
        {
            return;
        }

        var attachPos    = HeldBody.FindClosestPoint(startPos);
        var holdDistance = HoldDistance + attachPos.Distance(HeldBody.MassCenter);

        holdBody.Position = startPos + dir * holdDistance;
        holdBody.Rotation = rot * HeldRot;
    }
示例#3
0
    private void GrabEnd()
    {
        if (holdJoint.IsValid())
        {
            holdJoint.Remove();
        }

        if (HeldBody.IsValid())
        {
            HeldBody.EnableAutoSleeping = true;
        }

        HeldBody = null;
    }
示例#4
0
    private void GrabEnd()
    {
        holdJoint?.Remove();
        holdJoint = null;

        if (HeldBody.IsValid())
        {
            HeldBody.AutoSleep = true;
        }

        if (HeldEntity.IsValid())
        {
            Client?.Pvs.Remove(HeldEntity);
        }

        HeldBody   = null;
        HeldRot    = Rotation.Identity;
        HeldEntity = null;
    }
示例#5
0
    private void GrabEnd()
    {
        if (holdJoint.IsValid())
        {
            holdJoint.Remove();
        }

        if (HeldBody.IsValid())
        {
            HeldBody.EnableAutoSleeping = true;
        }

        if (Owner.IsValid() && HeldEntity.IsValid())
        {
            Owner.Pvs.Remove(HeldEntity);
        }

        HeldBody   = null;
        HeldRot    = Rotation.Identity;
        HeldEntity = null;
    }
示例#6
0
    public void OnPlayerControlTick(Player owner)
    {
        if (owner == null)
        {
            return;
        }

        if (!IsServer)
        {
            return;
        }

        using (Prediction.Off())
        {
            var input  = owner.Input;
            var eyePos = owner.EyePos;
            var eyeRot = owner.EyeRot;
            var eyeDir = owner.EyeRot.Forward;

            if (HeldBody.IsValid() && HeldBody.PhysicsGroup != null)
            {
                if (holdJoint.IsValid() && !holdJoint.IsActive)
                {
                    GrabEnd();
                }
                else if (input.Pressed(InputButton.Attack1))
                {
                    if (HeldBody.PhysicsGroup.BodyCount > 1)
                    {
                        // Don't throw ragdolls as hard
                        HeldBody.PhysicsGroup.ApplyImpulse(eyeDir * (ThrowForce * 0.5f), true);
                        HeldBody.PhysicsGroup.ApplyAngularImpulse(Vector3.Random * ThrowForce, true);
                    }
                    else
                    {
                        HeldBody.ApplyImpulse(eyeDir * (HeldBody.Mass * ThrowForce));
                        HeldBody.ApplyAngularImpulse(Vector3.Random * (HeldBody.Mass * ThrowForce));
                    }

                    GrabEnd();
                }
                else if (input.Pressed(InputButton.Attack2))
                {
                    timeSinceDrop = 0;

                    GrabEnd();
                }
                else
                {
                    GrabMove(eyePos, eyeDir, eyeRot);
                }

                return;
            }

            if (timeSinceDrop < DropCooldown)
            {
                return;
            }

            var tr = Trace.Ray(eyePos, eyePos + eyeDir * MaxPullDistance)
                     .UseHitboxes()
                     .Ignore(owner)
                     .Radius(2.0f)
                     .HitLayer(CollisionLayer.Debris)
                     .Run();

            if (!tr.Hit || !tr.Body.IsValid() || !tr.Entity.IsValid() || tr.Entity.IsWorld)
            {
                return;
            }

            if (tr.Entity.PhysicsGroup == null)
            {
                return;
            }

            var modelEnt = tr.Entity as ModelEntity;
            if (!modelEnt.IsValid())
            {
                return;
            }

            var body = tr.Body;

            if (input.Pressed(InputButton.Attack1))
            {
                if (tr.Distance < MaxPushDistance && !IsBodyGrabbed(body))
                {
                    var pushScale = 1.0f - Math.Clamp(tr.Distance / MaxPushDistance, 0.0f, 1.0f);
                    body.ApplyImpulseAt(tr.EndPos, eyeDir * (body.Mass * (PushForce * pushScale)));
                }
            }
            else if (input.Down(InputButton.Attack2))
            {
                var physicsGroup = tr.Entity.PhysicsGroup;

                if (physicsGroup.BodyCount > 1)
                {
                    body = modelEnt.PhysicsBody;
                    if (!body.IsValid())
                    {
                        return;
                    }
                }

                if (eyePos.Distance(body.Pos) <= AttachDistance)
                {
                    GrabStart(modelEnt, body, eyePos + eyeDir * HoldDistance, eyeRot);
                }
                else if (!IsBodyGrabbed(body))
                {
                    physicsGroup.ApplyImpulse(eyeDir * -PullForce, true);
                }
            }
        }
    }
示例#7
0
 public override bool IsUsable(Entity user)
 {
     return(Owner == null || HeldBody.IsValid());
 }