Ejemplo n.º 1
0
        private Rope AttachRopeAttachedEntityToEntity(Entity entity)
        {
            var length = Math.Min(Vector3.Distance(entity.Position, _ropeAttachedEntity.Position) / 2, 7.5f);
            var rope   = Rope.AddRope(entity.Position, length, GTARopeType.ThickRope, length, 0.1f, true, false);

            rope.AttachEntities(entity, Vector3.Zero, _ropeAttachedEntity, Vector3.Zero, length);
            rope.ActivatePhysics();
            Profile.LocalUser.PlayAimAnim(entity);
            return(rope);
        }
Ejemplo n.º 2
0
        private void OnShotWeb(Entity webShooterHelper, Entity entityHit)
        {
            // The length of the rope.
            _initialWebLength = Vector3.Distance(webShooterHelper.Position, entityHit.Position);

            // Create the rope between the entity hit,
            // and the web shooter helper.
            _webShooterRope = Rope.AddRope(webShooterHelper.Position, _initialWebLength, GTARopeType.ThickRope,
                                           _initialWebLength, 0.1f, true, false);

            // Attach the entities together.
            _webShooterRope.AttachEntities(webShooterHelper, Vector3.Zero, entityHit, Vector3.Zero, _initialWebLength);
        }
Ejemplo n.º 3
0
        public void Explode()
        {
            if (Exploded)
            {
                return;
            }
            Exploded = true;
            var entities = World.GetNearbyEntities(Prop.Position, 20f);

            Prop.Position       = new Vector3(Prop.Position.X, Prop.Position.Y, World.GetGroundHeight(Prop.Position));
            Prop.FreezePosition = true;
            foreach (var ent in entities)
            {
                if (ent.GetEntityType() == EntityType.Object)
                {
                    continue;
                }
                if (ent.Handle == Game.Player.Character.Handle)
                {
                    continue;
                }
                if (ent.IsDead)
                {
                    continue;
                }
                //Utilities.CreateParticleChain(Prop.Position, ent.Position, Vector3.Zero, 0.1f, particleScale: 0.2f);
                if (ent is Ped ped)
                {
                    if (ped.IsInVehicle())
                    {
                        continue;
                    }
                    Utilities.ShockPed(ped, 100);
                }
                var length = Vector3.Distance(ent.Position, Prop.Position);
                var rope   = Rope.AddRope(Prop.Position, length, GTARopeType.ThickRope, length / 2, 0.1f, true, false);
                rope.AttachEntities(Prop, Vector3.Zero, ent, Vector3.Zero, length / 2);
                rope.ActivatePhysics();
                _attachments.Add(new AttachmentInfo(ent, Prop, rope));
                WebAttachments.AddAttachment(ent, Prop, rope, true);
            }
            GTAGraphics.StartParticle("core", "ent_ray_prologue_elec_crackle_sp", Prop.Position, Vector3.Zero, 5.0f);
            World.DrawLightWithRange(Prop.Position, Color.White, 25f, 100f);
            World.AddOwnedExplosion(Game.Player.Character, Prop.Position, ExplosionType.Grenade, 0f, 0.1f, true, false);
        }
Ejemplo n.º 4
0
        private void DoSwing(Vector3 hitPoint, Entity webHitHelper, Control webControl, bool checkMinAngle = true)
        {
            // Create a helper prop for rotations.
            var rotationHelper = World.CreateVehicle("bmx", Profile.LocalUser.Position);

            rotationHelper.Alpha = 0;

            // Store the initial velocity.
            var initialVelocity = Profile.LocalUser.Velocity;

            // Clear the player tasks.
            Profile.LocalUser.Task.ClearAll();

            // Attach the player to the helper prop.
            Profile.LocalUser.AttachToEntity(rotationHelper, 0, new Vector3(0, -0.25f, -1.15f),
                                             Vector3.Zero, false, false, true, 0, true);

            var t = 0.5f;

            while (!Profile.LocalUser.IsAttached() && t > 0)
            {
                t -= Time.UnscaledDeltaTime;
                Script.Yield();
            }

            // We should play the base animation initially for good blending
            Profile.LocalUser.Task.PlayAnimation("move_fall", "fall_high",
                                                 8.0f, -4.0f, -1, AnimationFlags.StayInEndFrame, 0.0f);

            // The rappel anim!
            Profile.LocalUser.Task.PlayAnimation("missrappel", "rappel_idle", 4.0f, -4.0f, -1,
                                                 AnimationFlags.Loop | AnimationFlags.AllowRotation | AnimationFlags.UpperBodyOnly,
                                                 0.0f);

            // Create our rope.
            var initialLength = Vector3.Distance(rotationHelper.Position, hitPoint);

            if (initialLength <= 0)
            {
                initialLength = 1;
            }
            var rope = Rope.AddRope(rotationHelper.Position, initialLength,
                                    GTARopeType.ThickRope, initialLength, 0.1f, true, false);

            // Attach the two helpers.
            rope.AttachEntities(rotationHelper, Vector3.Zero, webHitHelper, Vector3.Zero, initialLength);
            rope.ActivatePhysics();

            // Init a rotation.
            var initalDirection = Vector3.ProjectOnPlane(Profile.GetCameraDirection(),
                                                         (webHitHelper.Position - rotationHelper.Position).Normalized);

            // Apply an initial force to the rotation helper.
            rotationHelper.Velocity = initalDirection * initialVelocity.Length() * 1.5f;

            // A bool to help us determine if we've played our forward swing
            // animation or not.
            var forwardSwing = false;

            // The amount of momentum we build.
            var momentumBuild = 1f;

            // Here's our loop.
            while (true)
            {
                // Disable the parachute deploy control.
                Game.DisableControlThisFrame(2, Control.ParachuteDeploy);

                // Disable the jump control.
                Game.DisableControlThisFrame(2, webControl);

                if (rotationHelper.HasCollidedWithAnything)
                {
                    var normal = rotationHelper.GetLastCollisionNormal();
                    var dir    = Vector3.Reflect(rotationHelper.Velocity, normal);
                    dir.Normalize();
                    Profile.LocalUser.Detach();
                    Profile.LocalUser.Heading  = dir.ToHeading();
                    Profile.LocalUser.Velocity = dir * rotationHelper.Velocity.Length() / 2;
                    Profile.LocalUser.Task.Skydive();
                    Profile.LocalUser.Task.PlayAnimation("swimming@swim", "recover_flip_back_to_front",
                                                         4.0f, -2.0f, 1150, (AnimationFlags)40, 0.0f);
                    Profile.LocalUser.Quaternion.Normalize();
                    Audio.ReleaseSound(Audio.PlaySoundFromEntity(Profile.LocalUser,
                                                                 "DLC_Exec_Office_Non_Player_Footstep_Mute_group_MAP"));
                    GTAGraphics.StartParticle("core", "ent_dst_dust", Profile.LocalUser.Position,
                                              Profile.LocalUser.Rotation, 1f);
                    break;
                }

                // If we're near the ground then stop.
                if (Profile.LocalUser.HeightAboveGround <= 2f)
                {
                    // The swing was canceled.
                    break;
                }

                // If we release the attach control then
                // we should start the skydive.
                if (Game.IsDisabledControlJustReleased(2, webControl))
                {
                    ReleaseWebToAir(-1, rotationHelper);
                    break;
                }

                // Set the hand ik positions.
                var ropeCoord  = rope[0];
                var boneOffset = Profile.LocalUser.RightVector * 0.05f;
                Profile.LocalUser.SetIKTarget(IKIndex.LeftArm, ropeCoord - boneOffset, -1f, 0f);
                Profile.LocalUser.SetIKTarget(IKIndex.RightArm, ropeCoord + boneOffset, -1f, 0f);

                // Swing the player's legs based on his forward direction.
                var dot = Vector3.Dot(Vector3.WorldUp, Profile.LocalUser.ForwardVector);

                // Swinging down.
                if (dot < 0)
                {
                    // Check our flag.
                    if (!forwardSwing)
                    {
                        // Play the down swinging anim.
                        Profile.LocalUser.Task.PlayAnimation("skydive@parachute@", "chute_idle_alt",
                                                             1.0f, -4.0f, -1, AnimationFlags.Loop, 0.0f);

                        // Set our flag.
                        forwardSwing = true;
                    }
                }
                // Swinging up.
                else if (dot > 0)
                {
                    // Check our flag.
                    if (forwardSwing)
                    {
                        // Play the up swinging anim.
                        Profile.LocalUser.Task.PlayAnimation("skydive@parachute@", "chute_forward",
                                                             1.0f, -4.0f, -1, AnimationFlags.Loop, 0.0f);

                        // Set our flag.
                        forwardSwing = false;
                    }
                }

                // Get the desired rotation for our
                // rotation helper.
                var directionToWebHit = webHitHelper.Position - rotationHelper.Position;
                directionToWebHit.Normalize();
                var dirVel   = Vector3.ProjectOnPlane(rotationHelper.Velocity, directionToWebHit);
                var rotation = Maths.LookRotation(dirVel, directionToWebHit);
                rotationHelper.Quaternion = rotation;

                // Get the direction of input.
                var moveDir     = Profile.GetInputDirection();
                var relativeDir = Quaternion.Euler(Profile.GetCameraRotation()) * moveDir;
                relativeDir = Vector3.ProjectOnPlane(relativeDir, directionToWebHit);

                // Apply force of input.
                if (momentumBuild < 2.5f)
                {
                    momentumBuild += Time.DeltaTime;
                }
                rotationHelper.ApplyForce(relativeDir * momentumBuild * 50f * Time.UnscaledDeltaTime);
                rotationHelper.ApplyForce(Vector3.WorldDown * 15f * Time.UnscaledDeltaTime);

                if (checkMinAngle)
                {
                    var angle = Vector3.Angle(directionToWebHit, Vector3.WorldUp);
                    if (angle > 70)
                    {
                        ReleaseWebToAir(0, rotationHelper);
                        break;
                    }
                }

                // Yield the script.
                Script.Yield();
            }

            // Reset the cooldown!
            _webSwingCooldown = 0.7f;

            Profile.LocalUser.Task.ClearAnimation("skydive@parachute@", "chute_idle_alt");
            Profile.LocalUser.Task.ClearAnimation("skydive@parachute@", "chute_forward");
            Profile.LocalUser.Task.ClearAnimation("missrappel", "rappel_idle");

            // Delete the helper props.
            rotationHelper.Delete();

            // Delete the rope.
            rope.Delete();
        }
Ejemplo n.º 5
0
        public override void Process()
        {
            Game.DisableControlThisFrame(2, Control.ParachuteSmoke);

            var camRay = WorldProbe.StartShapeTestRay(GameplayCamera.Position, GameplayCamera.Position +
                                                      GameplayCamera.Direction * 100f,
                                                      ShapeTestFlags.IntersectPeds | ShapeTestFlags.IntersectVehicles,
                                                      PlayerCharacter).GetResult();

            if (camRay.Hit)
            {
                var bounds = camRay.EntityHit.Model.GetDimensions();
                var z      = bounds.Z / 2;

                World.DrawMarker(MarkerType.UpsideDownCone, camRay.EntityHit.Position + Vector3.WorldUp * z * 1.5f, Vector3.Zero, Vector3.Zero,
                                 new Vector3(0.3f, 0.3f, 0.3f), Color.White);

                if (Game.IsDisabledControlJustPressed(2, Control.ParachuteSmoke))
                {
                    var directionToEntity = camRay.EntityHit.Position - PlayerCharacter.Position;
                    var distance          = directionToEntity.Length();
                    directionToEntity.Normalize();


                    // Set the player's heading towards the target.
                    PlayerCharacter.Heading = directionToEntity.ToHeading();

                    // Play the web shoot animation.
                    PlayerCharacter.Task.PlayAnimation("guard_reactions", "1hand_aiming_to_idle", 8.0f, -8.0f, -1,
                                                       (AnimationFlags)40, 0.0f);

                    var playerBone = PlayerCharacter.GetBoneCoord(Bone.SKEL_R_Hand);
                    var rope       = Rope.AddRope(playerBone, distance, GTARopeType.ThickRope, 0.2f, 0.1f, true, false);
                    var timer      = 2.0f;
                    var counter    = 0;

                    while (timer > 0)
                    {
                        PlayerCharacter.SetAnimationSpeed("guard_reactions", "1hand_aiming_to_idle", 0f);
                        playerBone = PlayerCharacter.GetBoneCoord(Bone.SKEL_R_Hand);
                        rope.PinVertex(0, playerBone);
                        rope.PinVertex(rope.VertexCount - 1, camRay.EntityHit.Position);
                        timer                  -= Time.DeltaTime;
                        directionToEntity       = camRay.EntityHit.Position - PlayerCharacter.Position;
                        PlayerCharacter.Heading = directionToEntity.ToHeading();
                        if (counter % 10 == 0)
                        {
                            if (camRay.EntityType == EntityType.Ped)
                            {
                                var ped = new Ped(camRay.EntityHit.Handle);
                                Utilities.ShockPed(ped, 15);
                            }
                            Utilities.CreateParticleChain(playerBone, camRay.EntityHit.Position, Vector3.Zero,
                                                          nodeSize: 0.5f, noiseMultiplier: 0.0f);
                        }
                        counter++;
                        Script.Yield();
                    }

                    if (camRay.EntityType == EntityType.Vehicle)
                    {
                        var veh = new Vehicle(camRay.EntityHit.Handle);
                        veh.Explode();
                    }
                    PlayerCharacter.Task.ClearAll();
                    rope.Delete();
                }
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Update's a 2 handed rope.
        /// </summary>
        /// <param name="vehicle"></param>
        /// <param name="ropes"></param>
        /// <param name="ropeDeleteDelay"></param>
        /// <returns></returns>
        private float UpdateRopes2(ISpatial vehicle, IList <Rope> ropes, float ropeDeleteDelay)
        {
            // Let's update the swimming anim for this if any.
            if (Profile.LocalUser.IsPlayingAnimation("swimming@swim", "recover_flip_back_to_front"))
            {
                if (Profile.LocalUser.GetAnimationTime("swimming@swim", "recover_flip_back_to_front") > 0.25f)
                {
                    Profile.LocalUser.Task.PlayAnimation("move_fall", "fall_med",
                                                         2.0f, -4.0f, -1, AnimationFlags.StayInEndFrame, 0.0f);
                }
            }

            // Get the right hand coord.
            var rHand = Profile.LocalUser.GetBoneCoord(Bone.SKEL_R_Hand);

            // Check if the player is playing the web pull anim on
            // the upper body.
            if (!Profile.LocalUser.IsPlayingAnimation("weapons@projectile@", "throw_m_fb_stand"))
            {
                if (ropeDeleteDelay <= 0)
                {
                    // Despawn the ropes at this point.
                    DespawnRopes(ropes);
                }
                else
                {
                    // Count down the rope delete delay.
                    ropeDeleteDelay -= Time.DeltaTime;

                    // If we've spawned the ropes...
                    if (ropes.Count > 0)
                    {
                        // Pin the vertices accordingly.
                        ropes[0].UnpinVertex(0); // Unpin the one from our hand.
                        ropes[0].PinVertex(ropes[0].VertexCount - 1, vehicle.Position);
                    }
                }
            }
            // The animation's not playing so let's
            // add the ropes in.
            else
            {
                // Make sure there are no ropes.
                if (ropes.Count <= 0)
                {
                    // The distance to the target
                    // will be used as the rope length.
                    var dist = Vector3.Distance(rHand, vehicle.Position);
                    var rope = Rope.AddRope(rHand, dist, GTARopeType.ThickRope, dist / 2, 0.1f, true, false);
                    ropes.Add(rope);
                }
                // The rope is there.
                else
                {
                    // Now let's pin the vertex coords.
                    ropes[0].PinVertex(0, rHand);
                    ropes[0].PinVertex(ropes[0].VertexCount - 1, vehicle.Position);
                }
            }

            return(ropeDeleteDelay);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Updates a 1 handed rope.
        /// </summary>
        /// <param name="vehicle"></param>
        /// <param name="ropes"></param>
        /// <param name="ropeDeleteDelay"></param>
        /// <returns></returns>
        private float UpdateRopes1(ISpatial vehicle, IList <Rope> ropes, float ropeDeleteDelay)
        {
            // Stop the upper body animation after some time, and move to
            // a falling animation.
            if (Profile.LocalUser.IsPlayingAnimation("swimming@swim", "recover_back_to_idle"))
            {
                if (Profile.LocalUser.GetAnimationTime("swimming@swim", "recover_back_to_idle") > 0.2f)
                {
                    Profile.LocalUser.Task.PlayAnimation("move_fall", "fall_med",
                                                         2.0f, -4.0f, -1, AnimationFlags.StayInEndFrame, 0.0f);
                }
            }

            // Get the hand coordinates.
            var lHand = Profile.LocalUser.GetBoneCoord(Bone.SKEL_L_Hand);
            var rHand = Profile.LocalUser.GetBoneCoord(Bone.SKEL_R_Hand);

            // Check if this player is playing the web pull animation.
            if (!Profile.LocalUser.IsPlayingAnimation("amb@world_vehicle_police_carbase", "base"))
            {
                // If the ropes are ready to be deleted...
                if (ropeDeleteDelay <= 0)
                {
                    // We need to despawn the dual webs.
                    DespawnRopes(ropes);
                }
                // Otherwise...
                else
                {
                    // Make sure we decrease the rope delay.
                    ropeDeleteDelay -= Time.DeltaTime;

                    // Unpin the vertex coordinates from
                    // our hands.
                    if (ropes.Count > 0)
                    {
                        ropes[0].UnpinVertex(0);
                        ropes[1].UnpinVertex(0);

                        // Also pin the vertices to the target
                        // until we're done here.
                        ropes[0].PinVertex(ropes[0].VertexCount - 1, vehicle.Position);
                        ropes[1].PinVertex(ropes[1].VertexCount - 1, vehicle.Position);
                    }
                }
            }
            // Otherwise we need to spawn them,
            // and update them.
            else
            {
                // Spawn the ropes first.
                if (ropes.Count == 0)
                {
                    // Create the left and right hand ropes for two hand web jump.
                    var lHandDistance = Vector3.Distance(lHand, vehicle.Position);
                    var rHandDistance = Vector3.Distance(rHand, vehicle.Position);
                    var rope1         = Rope.AddRope(lHand, lHandDistance, GTARopeType.ThickRope,
                                                     lHandDistance / 2, 0.1f, true, false);
                    var rope2 = Rope.AddRope(rHand, rHandDistance, GTARopeType.ThickRope,
                                             rHandDistance / 2, 0.1f, true, false);

                    // Add the ropes to the rope collection.
                    ropes.Add(rope1);
                    ropes.Add(rope2);
                }
                // Now we need to update the vertex coordinates.
                else
                {
                    // Pin the vertices.
                    ropes[0].PinVertex(0, lHand);
                    ropes[0].PinVertex(ropes[0].VertexCount - 1, vehicle.Position);
                    ropes[1].PinVertex(0, rHand);
                    ropes[1].PinVertex(ropes[1].VertexCount - 1, vehicle.Position);
                }
            }

            return(ropeDeleteDelay);
        }
Ejemplo n.º 8
0
        /// <summary>
        ///     Grapples the player towards a point on the map.
        /// </summary>
        private void WorldGrapple(Vector3 targetPoint)
        {
            // Make sure that this point is not
            // empty just for safety.
            if (targetPoint == Vector3.Zero)
            {
                return;
            }

            // Disable the reload control for now.
            Game.DisableControlThisFrame(2, Control.Reload);

            // Now once we press the reload key, we want
            // to grapple the player (also make sure
            // he's not on the ground already).
            if (Game.IsDisabledControlJustPressed(2, Control.Reload))
            {
                // Get the direction from the player to the point.
                var directionToPoint = targetPoint - Profile.LocalUser.Position;

                // If we're on the ground then move us upwards.
                if (Profile.LocalUser.GetConfigFlag(60))
                {
                    directionToPoint += Vector3.WorldUp * 0.5f;
                }
                directionToPoint.Normalize(); // Normalize the direcion vector.

                // Set the player's heading accordingly.
                Profile.LocalUser.Heading = directionToPoint.ToHeading();

                var speed = Vector3.Distance(Profile.LocalUser.Position, targetPoint);
                speed = Maths.Clamp(speed, 65f, 150f) * Profile.WebZipForceMultiplier;

                // Play the falling animation.
                // Reset the player's velocity if anything is left over.
                Profile.LocalUser.Task.ClearAllImmediately();
                Profile.LocalUser.Velocity = Vector3.Zero;
                Profile.LocalUser.Task.Jump();

                // Initialize our rope variable.
                Rope rope = null;

                var isOnGround = Profile.LocalUser.GetConfigFlag(60);
                var timer      = 0.025f;

                if (isOnGround)
                {
                    // Wait until the player is no longer on the ground.
                    while (timer > 0f)
                    {
                        Profile.LocalUser.Velocity += Vector3.WorldUp * 500f * Time.DeltaTime;
                        timer -= Time.DeltaTime;
                        Script.Yield();
                    }
                    GameWaiter.Wait(150);
                }

                // Now we need to set player's velocity.
                Profile.LocalUser.Velocity = directionToPoint * speed;

                // Make sure we've left the ground.
                if (!Profile.LocalUser.GetConfigFlag(60))
                {
                    // Play the web grapple animation.
                    Profile.LocalUser.Task.PlayAnimation("weapons@projectile@", "throw_m_fb_stand",
                                                         8.0f, -4.0f, 250, AnimationFlags.UpperBodyOnly | AnimationFlags.AllowRotation, 0.0f);

                    timer = 0.5f;
                    while (!Profile.LocalUser.IsPlayingAnimation("weapons@projectile@", "throw_m_fb_stand") &&
                           timer > 0f)
                    {
                        timer -= Time.DeltaTime;
                        Script.Yield();
                    }
                    Profile.LocalUser.SetAnimationSpeed("weapons@projectile@", "throw_m_fb_stand", -1f);
                }

                timer = 0.7f;
                while (timer > 0f)
                {
                    if (Profile.LocalUser.HasCollidedWithAnything)
                    {
                        break;
                    }

                    if (CheckFallAndCatchLanding(rope))
                    {
                        break;
                    }

                    // Cache the players right hand coord.
                    var rHand = Profile.LocalUser.GetBoneCoord(Bone.SKEL_R_Hand);

                    // Create the rope.
                    if (rope == null)
                    {
                        // Get the inital distance to the target.
                        var initialDist = rHand.DistanceTo(targetPoint);
                        rope = Rope.AddRope(rHand, initialDist, GTARopeType.ThickRope, initialDist / 2, 0.1f, true,
                                            false);
                    }

                    // Check if the player is playing the grapple animation.
                    if (Profile.LocalUser.IsPlayingAnimation("weapons@projectile@", "throw_m_fb_stand"))
                    {
                        // Pin the rope vertices.
                        rope.PinVertex(0, rHand);
                        rope.PinVertex(rope.VertexCount - 1, targetPoint);

                        // Reverse the grapple animation.
                        Profile.LocalUser.SetAnimationSpeed("weapons@projectile@", "throw_m_fb_stand", -1f);
                    }
                    else
                    {
                        // Otherwise delete the rope.
                        rope.UnpinVertex(0);
                        rope.PinVertex(rope.VertexCount - 1, targetPoint);
                    }
                    timer -= Time.DeltaTime;
                    Script.Yield();
                }

                // Clear the throwing anim.
                Profile.LocalUser.Task.ClearAnimation("weapons@projectile@", "throw_m_fb_stand");

                // Destroy the rope here.
                if (Rope.Exists(rope))
                {
                    rope?.Delete();
                }

                //OverrideFallHeight(float.MaxValue);
            }
        }
Ejemplo n.º 9
0
        public override void Process()
        {
            if (Game.IsDisabledControlJustPressed(2, Control.Cover))
            {
                var peds = World.GetNearbyPeds(PlayerCharacter.Position, 20f);
                if (peds.Length <= 0)
                {
                    return;
                }

                var playerForward  = Vector3.ProjectOnPlane(GameplayCamera.Direction, Vector3.WorldUp);
                var playerPosition = PlayerCharacter.Position;
                var pList          = new List <Ped>();

                for (var i = 0; i < peds.Length; i++)
                {
                    var ped = peds[i];
                    if (ped.IsPlayer)
                    {
                        continue;
                    }
                    if (ped.IsInVehicle())
                    {
                        continue;
                    }
                    if (ped.IsDead)
                    {
                        continue;
                    }

                    var dir = ped.Position - playerPosition;
                    dir.Normalize();
                    var angle = Vector3.Angle(playerForward.Normalized, dir);

                    if (angle < 90f)
                    {
                        var ray = WorldProbe.StartShapeTestRay(playerPosition, ped.Position,
                                                               ShapeTestFlags.IntersectMap, PlayerCharacter);
                        var result = ray.GetResult();
                        if (result.Hit)
                        {
                            continue;
                        }
                        if (ped.Weapons.Current == null)
                        {
                            continue;
                        }
                        if (ped.Weapons.Current.Hash == WeaponHash.Unarmed)
                        {
                            continue;
                        }
                        pList.Add(ped);
                    }
                }

                if (pList.Count <= 0)
                {
                    return;
                }

                var boneCoord = PlayerCharacter.GetBoneCoord(Bone.SKEL_R_Hand);
                var helperObj = World.CreateVehicle("bmx", boneCoord);
                helperObj.Alpha = 0;
                helperObj.AttachTo(PlayerCharacter, PlayerCharacter.GetBoneIndex(Bone.SKEL_R_Hand));
                var center = Vector3.Zero;
                var rList  = new List <Rope>();
                foreach (var p in pList)
                {
                    center += p.Position;
                    var d = Vector3.Distance(helperObj.Position, p.Position);
                    var r = Rope.AddRope(helperObj.Position, d, GTARopeType.ThickRope, d, 0.1f, true, false);
                    r.AttachEntities(helperObj, Vector3.Zero, p, Vector3.Zero, d);
                    r.ActivatePhysics();
                    rList.Add(r);
                }
                center /= pList.Count;

                PlayerCharacter.PlayAimAnim(center);
                GameWaiter.Wait(300);
                PlayerCharacter.PlayGrappleAnim(-1f);
                foreach (var r in rList)
                {
                    r.Delete();
                }
                foreach (var p in pList)
                {
                    DisarmPed(p);
                }
                helperObj.Delete();
            }
        }