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(); } } }
private void EndAttachment() { // Delete the web helpers. _webShooterRope?.Delete(); _webShooterHelper?.Delete(); Profile.LocalUser.Task.ClearAnimation("amb@code_human_wander_texting@male@base", "static"); Profile.LocalUser.Task.ClearAnimation("move_crouch_proto", "idle_intro"); GameWaiter.Wait(200); }
/// <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); } }
/// <summary> /// Catch our landing so we don't die from high falls. /// </summary> private bool CheckFallAndCatchLanding(Rope rope = null) { // If the player is falling then... if (Profile.LocalUser.IsFalling) { // Check the falling flag. if (!_falling) { _fallHeight = Profile.LocalUser.HeightAboveGround; } // Set the flag regardless. We're just // using it as a trigger of sorts. _falling = true; } else { // Like before, set it regardless. _falling = false; // Set the input vector before we start falling. } // Catch our landing at high falls. bool didCollide; if (!(didCollide = Profile.LocalUser.GetConfigFlag(60)) && !(Profile.LocalUser.HeightAboveGround < 2f)) { return(false); } // Check the fall height, catch the landing, // and reset the fall height. const float maxFallHeight = 5f; if (_fallHeight > maxFallHeight) { if (!didCollide) { var vel = Profile.LocalUser.Velocity; Profile.LocalUser.SetCoordsSafely(Profile.LocalUser.Position - Vector3.WorldUp * Profile.LocalUser.HeightAboveGround); Profile.LocalUser.Velocity = vel; } // Try to catch our landing. rope?.Delete(); CatchLanding(); CaughtLanding?.Invoke(this, new EventArgs(), _fallHeight); _fallHeight = 0f; } else { // If we should splat then let us, so that // the falling anim isn't constantly playing. Profile.LocalUser.Task.ClearAnimation("move_fall", "fall_high"); } // This will return true since we landed. return(true); // Nothing happened so we return false. }