private void EndRopeAttachment() { if (!Attached) { // Delete the web shooter helper. if (Entity.Exists(_webShooterHelper)) { _webShooterHelper.Delete(); } // Delete the web shooter rope. if (Rope.Exists(_webShooterRope)) { _webShooterRope.Delete(); } } }
/// <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); } }