using Invector; using Invector.vCharacterController; using Invector.vEventSystems; using Invector.vMelee; using UnityEngine; namespace Beyond { // here you can modify the Melee Combat inputs // if you want to modify the Basic Locomotion inputs, go to the vThirdPersonInput [vClassHeader("MELEE INPUT MANAGER", iconName = "inputIcon")] public class bMeleeCombatInput : bThirdPersonInput, vIMeleeFighter { #region Variables [vEditorToolbar("Inputs")] [Header("Melee Inputs")] public GenericInput weakAttackInput = new GenericInput("Mouse0", "RB", "RB"); public GenericInput strongAttackInput = new GenericInput("Alpha1", false, "RT", true, "RT", false); public GenericInput blockInput = new GenericInput("Mouse1", "LB", "LB"); internal vMeleeManager meleeManager; protected bool _isAttacking; public bool isAttacking { get => _isAttacking || cc.IsAnimatorTag("Attack"); protected set { _isAttacking = value; } } public bool isBlocking { get; protected set; } public bool isArmed { get { return meleeManager != null && (meleeManager.rightWeapon != null || (meleeManager.leftWeapon != null && meleeManager.leftWeapon.meleeType != vMeleeType.OnlyDefense)); } } public bool isEquipping { get; protected set; } [HideInInspector] public bool lockMeleeInput; public void SetLockMeleeInput(bool value) { lockMeleeInput = value; if (value) { isAttacking = false; isBlocking = false; } } public override void SetLockAllInput(bool value) { base.SetLockAllInput(value); SetLockMeleeInput(value); } private MagicAttacks magicAttacks; #endregion Variables public virtual bool lockInventory { get { return isAttacking || cc.isDead || (cc.customAction || cc.IsAnimatorTag("special")) || cc.isRolling; } } protected override void Start() { base.Start(); magicAttacks = GetComponent(); } protected override void LateUpdate() { UpdateMeleeAnimations(); base.LateUpdate(); } protected override void FixedUpdate() { base.FixedUpdate(); //force showing cursor ShowCursor(showCursorOnStart); isBlocking = Input.GetKeyDown(KeyCode.D); } protected override void InputHandle() { if (cc == null || cc.isDead) { return; } base.InputHandle(); if (MeleeAttackConditions() && !lockMeleeInput) { MeleeWeakAttackInput(); MeleeStrongAttackInput(); BlockingInput(); } else { ResetAttackTriggers(); isBlocking = false; } } #region MeleeCombat Input Methods /// /// WEAK ATK INPUT /// public virtual void MeleeWeakAttackInput() { if (cc.animator == null) { return; } if (weakAttackInput.GetButtonDown() && MeleeAttackStaminaConditions()) { TriggerWeakAttack(); } } public virtual void TriggerWeakAttack() { cc.animator.SetInteger(vAnimatorParameters.AttackID, AttackID); cc.animator.SetTrigger(vAnimatorParameters.WeakAttack); } /// /// STRONG ATK INPUT /// public virtual void MeleeStrongAttackInput() { if (cc.animator == null) { return; } if (strongAttackInput.GetButtonDown() && (!meleeManager.CurrentActiveAttackWeapon || meleeManager.CurrentActiveAttackWeapon.useStrongAttack) && MeleeAttackStaminaConditions()) { TriggerStrongAttack(); } } public virtual void TriggerStrongAttack() { cc.animator.SetInteger(vAnimatorParameters.AttackID, AttackID); cc.animator.SetTrigger(vAnimatorParameters.StrongAttack); } /// /// BLOCK INPUT /// public virtual void BlockingInput() { if (cc.animator == null) { return; } isBlocking = blockInput.GetButton() && cc.currentStamina > 0 && !cc.customAction && !cc.IsAnimatorTag("special") && !isAttacking; } public override void ControlRotation() { if (cameraMain && !lockUpdateMoveDirection) { if (!cc.keepDirection) { cc.UpdateMoveDirection(cameraMain.transform); } } //here if (tpCamera != null && tpCamera.lockTarget && cc.isStrafing && !cc.isRolling) { cc.RotateToPosition(tpCamera.lockTarget.position); // rotate the character to a specific target } else { cc.ControlRotationType(); // handle the controller rotation type (strafe or free) } } /// /// Override the Sprint method to cancel Sprinting when Attacking /// protected override void SprintInput() { if (sprintInput.useInput) { bool canSprint = cc.useContinuousSprint ? sprintInput.GetButtonDown() : sprintInput.GetButton(); cc.Sprint(canSprint && !isAttacking); } } #endregion MeleeCombat Input Methods #region Conditions protected virtual bool MeleeAttackStaminaConditions() { var result = cc.currentStamina - meleeManager.GetAttackStaminaCost(); return result >= 0; } public virtual bool MeleeAttackConditions() { if (meleeManager == null) { meleeManager = GetComponent(); } return meleeManager != null && cc.isGrounded && !cc.customAction && !cc.IsAnimatorTag("special") && !cc.isJumping && !cc.isCrouching && !cc.isRolling && !isEquipping && !cc.animator.IsInTransition(cc.baseLayer); } protected override bool JumpConditions() { return !isAttacking && base.JumpConditions(); } protected override bool RollConditions() { return base.RollConditions() && !isAttacking && !cc.animator.IsInTransition(cc.upperBodyLayer) && !cc.animator.IsInTransition(cc.fullbodyLayer); } #endregion Conditions #region Update Animations protected virtual void UpdateMeleeAnimations() { if (cc.animator == null || meleeManager == null) { return; } cc.animator.SetInteger(vAnimatorParameters.AttackID, AttackID); cc.animator.SetInteger(vAnimatorParameters.DefenseID, DefenseID); cc.animator.SetBool(vAnimatorParameters.IsBlocking, isBlocking); cc.animator.SetFloat(vAnimatorParameters.MoveSet_ID, meleeMoveSetID, .2f, vTime.deltaTime); isEquipping = cc.IsAnimatorTag("IsEquipping"); } /// /// Default moveset id used when is without weapon /// public virtual int defaultMoveSetID { get; set; } /// /// Used to ignore the Weapon moveset id and use the /// public virtual bool overrideWeaponMoveSetID { get; set; } /// /// Current moveset id based if is using weapon or not /// public virtual int meleeMoveSetID { get { int id = meleeManager.GetMoveSetID(); if (id == 0 || overrideWeaponMoveSetID) { id = defaultMoveSetID; } return id; } } public virtual void ResetMeleeAnimations() { if (meleeManager == null || !animator) { return; } cc.animator.SetBool(vAnimatorParameters.IsBlocking, false); } public virtual int AttackID { get { return meleeManager ? meleeManager.GetAttackID() : 0; } } public virtual int DefenseID { get { return meleeManager ? meleeManager.GetDefenseID() : 0; } } #endregion Update Animations #region Melee Methods public virtual void OnEnableAttack() { if (meleeManager == null) { meleeManager = GetComponent(); } if (meleeManager == null) { return; } cc.currentStaminaRecoveryDelay = meleeManager.GetAttackStaminaRecoveryDelay(); cc.currentStamina -= meleeManager.GetAttackStaminaCost(); isAttacking = true; cc.isSprinting = false; } public virtual void OnDisableAttack() { isAttacking = false; } public virtual void ResetAttackTriggers() { cc.animator.ResetTrigger(vAnimatorParameters.WeakAttack); cc.animator.ResetTrigger(vAnimatorParameters.StrongAttack); } public virtual void BreakAttack(int breakAtkID) { ResetAttackTriggers(); OnRecoil(breakAtkID); } public virtual void OnRecoil(int recoilID) { cc.animator.SetInteger(vAnimatorParameters.RecoilID, recoilID); cc.animator.SetTrigger(vAnimatorParameters.TriggerRecoil); cc.animator.SetTrigger(vAnimatorParameters.ResetState); cc.animator.ResetTrigger(vAnimatorParameters.WeakAttack); cc.animator.ResetTrigger(vAnimatorParameters.StrongAttack); } protected override void RollInput() { if (rollInput.GetButtonDown()) { if (horizontalInput.GetAxis() != 0f || verticallInput.GetAxis() != 0f) { if (RollConditions()) { cc.Roll(); } } else { bThirdPersonController beyondController = (bThirdPersonController)cc; beyondController.Dash(); } } } public virtual void OnReceiveAttack(vDamage damage, vIMeleeFighter attacker) { if (magicAttacks.shieldEffectIsActive) { return; } // character is blocking if (!damage.ignoreDefense && isBlocking && meleeManager != null && meleeManager.CanBlockAttack(damage.sender.position)) { var damageReduction = meleeManager.GetDefenseRate(); if (damageReduction > 0) { damage.ReduceDamage(damageReduction); } if (attacker != null && meleeManager != null && meleeManager.CanBreakAttack()) { attacker.BreakAttack(meleeManager.GetDefenseRecoilID()); } meleeManager.OnDefense(); cc.currentStaminaRecoveryDelay = damage.staminaRecoveryDelay; cc.currentStamina -= damage.staminaBlockCost; } // apply damage damage.hitReaction = !isBlocking || damage.ignoreDefense; cc.TakeDamage(damage); } public virtual vICharacter character { get { return cc; } } #endregion Melee Methods } }