/// <summary>
        /// Check if should do rappel, and do rappel and attach to wall.
        /// </summary>
        private void RappelChecks(bool airborneGraspWall)
        {
            if (airborneGraspWall)
            {
                // TODO: prevent rappelling if small falls
                if (!IsRappelling)
                {
                    // should rappelling start?
                    bool movingBackward = InputManager.Instance.HasAction(InputManager.Actions.MoveBackwards);

                    IsRappelling = (movingBackward && !acrobatMotor.Jumping);
                    if (IsRappelling)
                    {
                        DaggerfallUI.AddHUDText(UserInterfaceWindows.HardStrings.rappelMode);
                    }
                    lastPosition = controller.transform.position;
                    rappelTimer  = 0f;
                }

                if (IsRappelling)
                {
                    const float firstTimerMax = 0.7f;
                    overrideSkillCheck = true;

                    rappelTimer += Time.deltaTime;

                    if (rappelTimer <= firstTimerMax)
                    {
                        Vector3 rappelPosition = Vector3.zero;
                        // create C-shaped movement to plant self against wall beneath
                        Vector3 pos    = lastPosition;
                        float   yDist  = 1.60f;
                        float   xzDist = 0.17f;
                        rappelPosition.x = Mathf.Lerp(pos.x, pos.x - (controller.transform.forward.x * xzDist), Mathf.Sin(Mathf.PI * (rappelTimer / firstTimerMax)));
                        rappelPosition.z = Mathf.Lerp(pos.z, pos.z - (controller.transform.forward.z * xzDist), Mathf.Sin(Mathf.PI * (rappelTimer / firstTimerMax)));
                        rappelPosition.y = Mathf.Lerp(pos.y, pos.y - yDist, rappelTimer / firstTimerMax);

                        controller.transform.position = rappelPosition;
                    }
                    else
                    {
                        Vector3 rappelDirection = Vector3.zero;
                        // Auto forward to grab wall
                        float speed = speedChanger.GetBaseSpeed();
                        if (myLedgeDirection != Vector3.zero)
                        {
                            rappelDirection = myLedgeDirection;
                        }
                        else
                        {
                            rappelDirection = controller.transform.forward;
                        }
                        rappelDirection *= speed * 1.25f;
                        groundMotor.MoveWithMovingPlatform(rappelDirection);
                    }
                }
            }
        }
Esempio n. 2
0
        private void Update()
        {
            if (!playerMotor || !playerCamera || (!playerLevitating && !playerSwimming))
            {
                return;
            }

            // Cancel levitate movement if player is paralyzed
            if (GameManager.Instance.PlayerEntity.IsParalyzed)
            {
                return;
            }

            float inputX = InputManager.Instance.Horizontal;
            float inputY = InputManager.Instance.Vertical;

            if (inputX != 0.0f || inputY != 0.0f)
            {
                float inputModifyFactor = (inputX != 0.0f && inputY != 0.0f && playerMotor.limitDiagonalSpeed) ? .7071f : 1.0f;
                AddMovement(playerCamera.transform.TransformDirection(new Vector3(inputX * inputModifyFactor, 0, inputY * inputModifyFactor)));
            }

            // Up/down
            Vector3 upDownVector = new Vector3(0, 0, 0);

            bool overEncumbered = (GameManager.Instance.PlayerEntity.CarriedWeight * 4 > 250) && !playerLevitating && !GameManager.Instance.PlayerEntity.GodMode;

            if (playerSwimming && overEncumbered && !climbingMotor.IsClimbing && !GameManager.Instance.PlayerEntity.IsWaterWalking)
            {
                upDownVector += Vector3.down;
            }
            else if (InputManager.Instance.HasAction(InputManager.Actions.Jump) || InputManager.Instance.HasAction(InputManager.Actions.FloatUp))
            {
                upDownVector += Vector3.up;
            }
            else if (InputManager.Instance.HasAction(InputManager.Actions.Crouch) || InputManager.Instance.HasAction(InputManager.Actions.FloatDown))
            {
                upDownVector += Vector3.down;
            }

            AddMovement(upDownVector, true);

            // Execute movement
            if (moveDirection == Vector3.zero)
            {
                // Hack to make sure that the player can get pushed by moving objects if he's not moving
                const float pos = 0.0001f;
                groundMotor.MoveWithMovingPlatform(Vector3.up * pos);
                groundMotor.MoveWithMovingPlatform(Vector3.down * pos);
                groundMotor.MoveWithMovingPlatform(Vector3.left * pos);
                groundMotor.MoveWithMovingPlatform(Vector3.right * pos);
                groundMotor.MoveWithMovingPlatform(Vector3.forward * pos);
                groundMotor.MoveWithMovingPlatform(Vector3.back * pos);
            }

            groundMotor.MoveWithMovingPlatform(moveDirection);
            moveDirection = Vector3.zero;
        }
Esempio n. 3
0
        private void HangMoveDirection()
        {
            RaycastHit hit;

            if (Physics.SphereCast(controller.transform.position, scanner.HeadHitRadius, controller.transform.up, out hit, 2f))
            {
                float   playerspeed = speedChanger.GetClimbingSpeed(playerMotor.Speed);
                Vector3 moveVector  = Vector3.zero;
                if (InputManager.Instance.HasAction(InputManager.Actions.MoveForwards))
                {
                    moveVector += controller.transform.forward;
                }
                else if (InputManager.Instance.HasAction(InputManager.Actions.MoveBackwards))
                {
                    moveVector -= controller.transform.forward;
                }

                if (InputManager.Instance.HasAction(InputManager.Actions.MoveRight))
                {
                    moveVector += controller.transform.right;
                }
                else if (InputManager.Instance.HasAction(InputManager.Actions.MoveLeft))
                {
                    moveVector -= controller.transform.right;
                }

                if (moveVector != Vector3.zero)
                {
                    moveVector = (Vector3.ProjectOnPlane(moveVector, hit.normal).normalized *playerspeed) + (-hit.normal * 0.2f * playerspeed);

                    moveVector.y = Mathf.Max(moveVector.y, 0.2f);
                }
                else
                {
                    moveVector = (Vector3.up * 0.001f);
                }
                Debug.DrawRay(controller.transform.position, hit.normal, Color.yellow);
                groundMotor.MoveWithMovingPlatform(moveVector);
                Debug.DrawRay(controller.transform.position, moveVector, Color.blue);
            }
        }
Esempio n. 4
0
        void FixedUpdate()
        {
            // Check if on a solid surface
            grounded = (collisionFlags & CollisionFlags.Below) != 0;

            // Clear movement
            if (cancelMovement)
            {
                moveDirection  = Vector3.zero;
                cancelMovement = false;
                groundMotor.ClearActivePlatform();
                acrobatMotor.ClearFallingDamage();
                return;
            }

            // Handle freeze movement
            if (freezeMotor > 0)
            {
                freezeMotor -= Time.deltaTime;
                if (freezeMotor <= 0)
                {
                    freezeMotor    = 0;
                    CancelMovement = true;
                }
                return;
            }

            playerScanner.FindHeadHit(new Ray(controller.transform.position, Vector3.up));
            playerScanner.SetHitSomethingInFront();
            // Check if should hang
            hangingMotor.HangingChecks();
            // Handle Rappeling
            rappelMotor.RappelChecks();
            // Handle climbing
            climbingMotor.ClimbingCheck();

            // Do nothing if player levitating/swimming or climbing - replacement motor will take over movement for levitating/swimming
            if (levitateMotor && (levitateMotor.IsLevitating || levitateMotor.IsSwimming) || climbingMotor.IsClimbing || hangingMotor.IsHanging)
            {
                moveDirection = Vector3.zero;
                return;
            }


            if (climbingMotor.WallEject)
            {   // True in terms of the player having their feet on solid surface.
                grounded = true;
            }

            if (grounded)
            {
                acrobatMotor.Jumping = false;

                acrobatMotor.CheckFallingDamage();

                // checks if sliding and applies movement to moveDirection if true
                frictionMotor.GroundedMovement(ref moveDirection);

                acrobatMotor.HandleJumpInput(ref moveDirection);
            }
            else
            {
                acrobatMotor.CheckInitFall(ref moveDirection);

                acrobatMotor.CheckAirControl(ref moveDirection, speed);
            }

            playerScanner.FindStep(moveDirection);

            acrobatMotor.ApplyGravity(ref moveDirection);

            acrobatMotor.HitHead(ref moveDirection);

            groundMotor.MoveWithMovingPlatform(moveDirection);
        }
Esempio n. 5
0
        private void Update()
        {
            if (!playerMotor || !playerCamera || (!playerLevitating && !playerSwimming))
            {
                return;
            }

            // Cancel levitate movement if player is paralyzed
            if (GameManager.Instance.PlayerEntity.IsParalyzed)
            {
                return;
            }

            // Forward/backwards
            if (InputManager.Instance.HasAction(InputManager.Actions.MoveForwards))
            {
                AddMovement(playerCamera.transform.forward);
            }
            else if (InputManager.Instance.HasAction(InputManager.Actions.MoveBackwards))
            {
                AddMovement(-playerCamera.transform.forward);
            }

            // Right/left
            if (InputManager.Instance.HasAction(InputManager.Actions.MoveRight))
            {
                AddMovement(playerCamera.transform.right);
            }
            else if (InputManager.Instance.HasAction(InputManager.Actions.MoveLeft))
            {
                AddMovement(-playerCamera.transform.right);
            }

            // Up/down
            Vector3 upDownVector = new Vector3(0, 0, 0);

            bool overEncumbered = (GameManager.Instance.PlayerEntity.CarriedWeight * 4 > 250) && !playerLevitating && !GameManager.Instance.PlayerEntity.GodMode;

            if (playerSwimming && overEncumbered && !climbingMotor.IsClimbing && !GameManager.Instance.PlayerEntity.IsWaterWalking)
            {
                upDownVector += Vector3.down;
            }
            else if (InputManager.Instance.HasAction(InputManager.Actions.Jump) || InputManager.Instance.HasAction(InputManager.Actions.FloatUp))
            {
                upDownVector += Vector3.up;
            }
            else if (InputManager.Instance.HasAction(InputManager.Actions.Crouch) || InputManager.Instance.HasAction(InputManager.Actions.FloatDown))
            {
                upDownVector += Vector3.down;
            }

            AddMovement(upDownVector, true);

            // Execute movement
            if (moveDirection == Vector3.zero)
            {
                // Hack to make sure that the player can get pushed by moving objects if he's not moving
                const float pos = 0.0001f;
                groundMotor.MoveWithMovingPlatform(Vector3.up * pos);
                groundMotor.MoveWithMovingPlatform(Vector3.down * pos);
                groundMotor.MoveWithMovingPlatform(Vector3.left * pos);
                groundMotor.MoveWithMovingPlatform(Vector3.right * pos);
                groundMotor.MoveWithMovingPlatform(Vector3.forward * pos);
                groundMotor.MoveWithMovingPlatform(Vector3.back * pos);
            }

            groundMotor.MoveWithMovingPlatform(moveDirection);
            moveDirection = Vector3.zero;
        }
Esempio n. 6
0
        /// <summary>
        /// Check if should do rappel, and do rappel and attach to wall.
        /// </summary>
        public void RappelChecks()
        {
            if (rappelStage == RappelStage.Inactive)
            {
                measure = null;
            }
            else
            {
                // Player can become grounded with a partial rappel state based on object height
                // If player is grounded then reset back to inactive state
                if (GameManager.Instance.PlayerMotor.IsGrounded)
                {
                    ResetRappelState();
                    return;
                }
            }

            InitialSetRappelType();

            bool    inputBackward = InputManager.Instance.HasAction(InputManager.Actions.MoveBackwards);
            Vector3 origin        = Vector3.zero;
            Vector3 direction     = -controller.transform.forward;

            #region Scan For AdjacentSurface
            if (inputBackward)
            {
                // check from different origins to find different surfaces
                if (!climbingMotor.IsClimbing)
                {
                    origin = controller.transform.position + Vector3.down * (0.25f * controller.height) + controller.transform.forward * (0.8f * controller.radius);
                }
                else
                {
                    origin = controller.transform.position + Vector3.up * (0.25f * controller.height) + controller.transform.forward * (0.8f * controller.radius);
                }

                playerScanner.FindAdjacentSurface(origin, direction, PlayerMoveScanner.RotationDirection.YZCounterClockwise);
            }
            #endregion

            // the only time Ground closeness can cancel the start of the rappel is when we are
            // going to rappel down and behind to a wall
            if (InitialTooCloseToGround(rappelDirection))
            {
                IsRappelling = false;
                return;
            }

            if (rappelStage == RappelStage.Activated)
            {
                DaggerfallUI.AddHUDText(UserInterfaceWindows.HardStrings.rappelMode);
                rappelStage = RappelStage.Swooping;
                InitialSetGrappleDirection();

                swoopBasePosition = controller.transform.position;
                rappelTimer       = 0f;
                measure           = null;
            }

            // Rappel swooping
            if (rappelStage == RappelStage.Swooping)
            {
                player.TallySkill(DFCareer.Skills.Climbing, 1);
                Vector3 swoopDirection = grappleDirection;
                // if we are rappelling under to ceiling, grappledirection is different so use adjacentSurfaceRay
                // direction to get right direction to go under the ceiling.
                if (rappelDirection == RappelDirection.DownUnder || rappelDirection == RappelDirection.FrontUp)
                {
                    swoopDirection = playerScanner.WallDetachedVector;
                }
                rappelTimer += Time.deltaTime;

                switch (rappelDirection)
                {
                case RappelDirection.DownBehind:
                    CurlDown(swoopBasePosition, swoopDirection);
                    break;

                case RappelDirection.UpBehind:
                    CurlOver(swoopBasePosition, swoopDirection);
                    break;

                //case RappelDirection.DownUnder:
                //    CurlUnder(swoopBasePosition, swoopDirection);
                //    break;
                case RappelDirection.FrontUp:
                    if (updateSwoopBasePosition)
                    {       // enables player to bottom out on DownUnder and continue FrontUp
                        swoopBasePosition       = controller.transform.position;
                        updateSwoopBasePosition = false;
                        rappelTimer             = 0;
                    }
                    CurlUpHalf(swoopBasePosition, swoopDirection);
                    break;

                default:
                    break;
                }

                controller.transform.position = rappelPosition;
            }

            if (rappelStage == RappelStage.Grappling)
            // perform horizontal measurement-based Wall-grapple direction or vertical for ceiling
            {
                // if measurement hasn't started, start measuring grapple-to-surface movement
                if (measure == null)
                {
                    measure = new VectorMeasurement(controller.transform.position);
                }

                if (!(/*hangingMotor.IsHanging ||*/ climbingMotor.IsClimbing) &&
                    measure.Distance(controller.transform.position) < 1f)
                {
                    // Auto move toward surface to grab
                    float speed = speedChanger.GetBaseSpeed();

                    grappleDirection = grappleDirection.normalized * speed * 1.15f;
                    groundMotor.MoveWithMovingPlatform(grappleDirection);
                }
                else // if we've moved past the distance limit
                {
                    ResetRappelState();
                }
            }
        }