/// <summary>
        /// Decides which ability to use based on the input context and activates it
        /// </summary>
        /// <param name="context">The input callback context</param>
        /// <param name="args">Any additional arguments to give to the ability.
        /// Index 0 is always the power scale.
        /// index 1 is always the direction of input.</param>
        public void BufferNormalAbility(InputAction.CallbackContext context, params object[] args)
        {
            //Ignore player input if they are in knockback
            if (_playerState != "Idle" && _playerState != "Attacking")
            {
                return;
            }

            AbilityType abilityType = AbilityType.NONE;

            _attackDirection.x *= Mathf.Round(transform.forward.x);

            //Decide which ability type to use based on the input
            if (_attackDirection.y != 0)
            {
                abilityType = AbilityType.WEAKSIDE;
            }
            else if (_attackDirection.x < 0)
            {
                abilityType = AbilityType.WEAKBACKWARD;
            }
            else if (_attackDirection.x > 0)
            {
                abilityType = AbilityType.WEAKFORWARD;
            }
            else
            {
                abilityType = AbilityType.WEAKNEUTRAL;
            }

            //Assign the arguments for the ability
            args[1] = _attackDirection;
            //Find the power scale based on the time the button was held to use a charge ability
            float timeHeld = Mathf.Clamp((float)context.duration, 0, _maxChargeTime);

            if (timeHeld > _minChargeLimit && (int)abilityType < 4)
            {
                abilityType += 4;
                float powerScale = 0;
                powerScale       = timeHeld * 0.1f + 1;
                args[0]          = powerScale;
                _bufferedAction  = new BufferedInput(action => UseAbility(abilityType, args), condition => { _abilityBuffered = false; return(_moveset.GetCanUseAbility() && !_gridMovement.IsMoving); }, 0.2f);
                _abilityBuffered = true;
                return;
            }

            //Use a normal ability if it was not held long enough
            _bufferedAction  = new BufferedInput(action => UseAbility(abilityType, args), condition => { _abilityBuffered = false; return(_moveset.GetCanUseAbility() && !_gridMovement.IsMoving); }, 0.2f);
            _abilityBuffered = true;
        }
 /// <summary>
 /// Buffers a parry only if the attack button is not being pressed
 /// </summary>
 /// <param name="context"></param>
 public void BufferParry(InputAction.CallbackContext context)
 {
     if (_attackButtonDown)
     {
         return;
     }
     else if (_bufferedAction == null && (_playerState == "Tumbling" || _playerState == "FreeFall" || _playerState == "Idle"))
     {
         _bufferedAction = new BufferedInput(action => UseDefensiveAction(), condition => !_gridMovement.IsMoving, 0.2f);
     }
     else if (!_bufferedAction.HasAction() && (_playerState == "Tumbling" ||
                                               _playerState == "FreeFall" || _playerState == "Idle"))
     {
         _bufferedAction = new BufferedInput(action => UseDefensiveAction(), condition => !_gridMovement.IsMoving, 0.2f);
     }
 }
        /// <summary>
        /// Decides which ability to use based on the input context and activates it
        /// </summary>
        /// <param name="context">The input callback context</param>
        /// <param name="args">Any additional arguments to give to the ability.
        public void BufferSpecialAbility(InputAction.CallbackContext context, params object[] args)
        {
            //Ignore player input if they aren't in a state that can attack
            if (_playerState != "Idle" && _playerState != "Attacking")
            {
                return;
            }

            AbilityType abilityType = AbilityType.SPECIAL;

            _attackDirection.x *= Mathf.Round(transform.forward.x);

            //Assign the arguments for the ability
            args[1] = _attackDirection;

            //Use a normal ability if it was not held long enough
            _bufferedAction  = new BufferedInput(action => UseAbility(abilityType, args), condition => { _abilityBuffered = false; return(_moveset.GetCanUseAbility() && !_gridMovement.IsMoving); }, 0.2f);
            _abilityBuffered = true;
        }