using UnityEngine; using MalbersAnimations.Weapons; using MalbersAnimations.Events; using MalbersAnimations.Scriptables; using System; using MalbersAnimations.Utilities; using System.Collections; using System.Collections.Generic; namespace MalbersAnimations.HAP { /// Variables and Properties public partial class MWeaponManager { private const string FreeBothHands = "FreeBothHands"; private const string FreeRightHand = "FreeRightHand"; private const string FreeLeftHand = "FreeLeftHand"; #region Riding Only public bool UseWeaponsOnlyWhileRiding = true; public Transform IgnoreTransform { get; set; } public IRider Rider { get; private set; } #endregion /// Sets a Bool Parameter on the Animator using the parameter Hash public Action SetBoolParameter { get; set; } /// Sets a float Parameter on the Animator using the parameter Hash public Action SetFloatParameter { get; set; } /// Sets a Integer Parameter on the Animator using the parameter Hash public Action SetIntParameter { get; set; } /// Sets a Trigger Parameter on the Animator using the parameter Hash public Action SetTriggerParameter { get; set; } #region Public Entries public bool UseInventory = true; //Use this if the weapons are on an Inventory public bool AlreadyInstantiated = true; //If the weapons comes from an inventory check if they are already intantiate public bool UseHolsters = false; //Use this if the weapons are on the Holsters public HolsterID DefaultHolster; public List holsters = new List(); public float HolsterTime = 0.3f; /// Used to change to the Next/Previus Holster public int ActiveHolsterIndex { get; set; } /// ID Value of the Active Holster public Holster ActiveHolster { get; set; } public bool UseDefaultIK = true; //Exit the Combat Mode on Dismount [Tooltip("Disable the Aim Component when is not Needed")] public bool DisableAim = false; //Exit the Combat Mode on Dismount public Transform LeftHandEquipPoint, RightHandEquipPoint; //Equip Point for the Right Hand /// Path of the Combat Layer on the Resource Folder public string CombatLayerPath = "Layers/Combat"; /// Name of the Combat Layer public string CombatLayerName = "Rider Combat"; public bool debug; #endregion /// Reference for the Animator component public Animator Anim { get; set; } /// Reference for the Animator Update Mode public AnimatorUpdateMode DefaultAnimUpdateMode { get; set; } private int weaponAction = 0; //Which type of action is making the active weapon [Tooltip("If the weapon is on the Idle Action it will be stored after X seconds. If Zero, this feature will be ignored.")] public FloatReference StoreAfter = new FloatReference(0); #region Animator Hashs public string m_WeaponAim = "WeaponAim"; public string m_WeaponType = "WeaponType"; public string m_WeaponAction = "WeaponAction"; public string m_WeaponCharge = "WeaponPower"; public string m_WeaponHand = "WeaponHand"; internal int Hash_WAim; internal int Hash_WType; internal int Hash_WAction; internal int Hash_WCharge; internal int Hash_WHand; #endregion #region Events public BoolEvent OnCombatMode = new BoolEvent(); public GameObjectEvent OnEquipWeapon = new GameObjectEvent(); public GameObjectEvent OnUnequipWeapon = new GameObjectEvent(); public IntEvent OnWeaponAction = new IntEvent(); public GameObjectEvent OnMainAttackStart = new GameObjectEvent(); #endregion #region Properties /// Is the weapon Manager Enabled If is false everything will be ignored public bool Active { get => enabled; set { if (!value) { if (CombatMode) //Means it has a weapon equipped!! { Store_Weapon(); } else ResetCombat(); //If the Rider Combat was deactivated } enabled = value; } } /// Same As Active public void SetActive(bool value) => Active = value; /// is there an Ability Active and the Active Weapon is Active too public bool WeaponIsActive => (Weapon && Weapon.Active) && Active && !Paused && CheckRidingOnly; public bool CheckRidingOnly => !UseWeaponsOnlyWhileRiding || (Rider != null && Rider.IsRiding); public bool Paused => Time.timeScale == 0; //public MRider Rider { get; set; } public IAim Aimer { get; set; } /// Store the Default aiming Side public AimSide defaultAimSide { get; set; } //public Aim m_Aim { get; set; } public float DeltaTime { get; set; } private bool combatMode; /// Enable or Disable the Combat Mode (True When the rider has equipped a weapon) public bool CombatMode { get => combatMode; set { combatMode = value; OnCombatMode.Invoke(value); } } /// Which Action is currently using the RiderCombat. See WeaponActions Enum for more detail public int WeaponAction { get => weaponAction; set { weaponAction = value; Debugging($"[Weapon Action] -> [<{WA.WValue(value)}><{value}>]","green"); SetIntParameter?.Invoke(Hash_WAction, (int)weaponAction); //Set the WeaponAction in the Animator OnWeaponAction.Invoke(weaponAction); if (StoreAfter.Value > 0) { if (IStoreAfter != null) StopCoroutine(IStoreAfter); if (weaponAction == WA.Idle) IStoreAfter = StartCoroutine(C_StoreAfter()); } if (weaponAction == WA.None) SendMessage(FreeBothHands); } } protected IEnumerator C_StoreAfter() { yield return StoreAfterTime; Store_Weapon(); } private WaitForSeconds StoreAfterTime; Coroutine IStoreAfter; /// Weights for the IK Two Handed Weapon public float WeaponIKW { get; set; } public GameObject Owner => gameObject; private MWeapon m_weapon; /// Returns the IMWeapon Interface of the Active Weapon GameObject public MWeapon Weapon { get => m_weapon; set { if (value == null) //No Weapon { if (m_weapon != null) //If there was a weapon before then remove the Weapon SetWeapon(false); m_weapon = value; } else //NEW WEAPON { if (m_weapon != null) SetWeapon(false); m_weapon = value; SetWeapon(true); SetWeaponHand(); } } } /// Prepare a new and Old Weapon private void SetWeapon(bool new_Weapon) { if (new_Weapon) { m_weapon.WeaponAction += Action; m_weapon.OnCharged.AddListener(SetWeaponCharge); } else { m_weapon.WeaponAction -= Action; m_weapon.OnCharged.RemoveListener(SetWeaponCharge); m_weapon.IgnoreTransform = null; } } /// This will recieve the messages Animator Behaviors the moment the rider make an action on the weapon public virtual void Action(int value) { WeaponAction = value; if (Weapon && !Weapon.Active) Aim = (false); //Reset Aiming if the weapon is Disable IMPORTANT } /// This will recieve the messages Animator Behaviors the moment the rider make an action on the weapon public virtual void CheckAim() { WeaponAction = Aim ? WA.Aim : CombatMode ? WA.Idle : WA.None; } public bool AimingSide => Aimer.AimingSide; private bool aim; /// Is the Rider Aiming? public bool Aim { private set { if (!WeaponIsActive) return; //Do nothing if the weapon is not active if (aim != value) { aim = value; if (Rider!= null) Rider.IsAiming = value; //Let know the Rider is Aiming. So if is using Straigth Spine, it stops. Debugging($"Aim → [{aim}]", "gray"); if (aim) { Aimer.AimSide = Weapon.AimSide; //Send to the Aimer the Corret Side. Aimer.Active = true; //Activate the Aimer Just In Case!! if (Weapon is MShootable && !(Weapon as MShootable).HasAmmo) //If I have no Ammo Do not Aim { return; } if (!MTools.CompareOR(Mathf.Abs(WeaponAction), WA.Preparing, WA.Reload)) WeaponAction = WA.Aim; //If the weapon is Right Handed set the action to AimRight else AimLeft } else { ExitAim(); if (!MTools.CompareOR(Mathf.Abs(WeaponAction), WA.Fire_Projectile, WA.Reload)) WeaponAction = CombatMode ? WA.Idle : WA.None; } WeaponIKW = value ? 1 : 0; Weapon.IsAiming = value; //Send to the active weapon that the Rider is/isn't aiming } } get => aim; } public virtual void Aim_Set(bool value) => Aim = value; /// Returns the Normalized Angle Around the Y Axis (from -1 to 1) regarding the Target position public float HorizontalAngle { get; private set; } #region Bones References public Transform RightShoulder { get; set; } public Transform LeftShoulder { get; set; } public Transform RightHand { get; set; } public Transform LeftHand { get; set; } public Transform Head { get; set; } public Transform Chest { get; set; } #endregion /// Direction the Rider is Aiming public Vector3 AimDirection => Aimer.AimDirection; public LayerMask Layer { get => Aimer.Layer; set => Aimer.Layer = value; } public QueryTriggerInteraction TriggerInteraction { get => Aimer.TriggerInteraction; set => Aimer.TriggerInteraction = value; } public bool Weapon_is_RightHand => Weapon.IsRightHanded; public bool Weapon_is_LeftHand => !Weapon.IsRightHanded; private int weaponType; //Which Type of weapon is in the active weapon /// Which Type of Weapon is in the Active Weapon, this value is sent to the animator public int WeaponType { get => weaponType; set { weaponType = value; SetIntParameter?.Invoke(Hash_WType, weaponType); //Set the WeaponType in the Animator } } #endregion [HideInInspector] public int Editor_Tabs1; [HideInInspector] public int Editor_Tabs2; } }