using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class vp_WeaponHandler : MonoBehaviour { protected class WeaponComparer : IComparer { int IComparer.Compare(object x, object y) { return new CaseInsensitiveComparer().Compare(((vp_Weapon)x).gameObject.name, ((vp_Weapon)y).gameObject.name); } } public int StartWeapon; public float AttackStateDisableDelay = 0.5f; public float SetWeaponRefreshStatesDelay = 0.5f; public float SetWeaponDuration = 0.1f; public float SetWeaponReloadSleepDuration = 0.3f; public float SetWeaponZoomSleepDuration = 0.3f; public float SetWeaponAttackSleepDuration = 0.3f; public float ReloadAttackSleepDuration = 0.3f; public bool ReloadAutomatically = true; protected vp_PlayerEventHandler m_Player; protected List m_Weapons; protected List> m_WeaponLists = new List>(); protected int m_CurrentWeaponIndex = -1; protected vp_Weapon m_CurrentWeapon; protected vp_Timer.Handle m_SetWeaponTimer = new vp_Timer.Handle(); protected vp_Timer.Handle m_SetWeaponRefreshTimer = new vp_Timer.Handle(); protected vp_Timer.Handle m_DisableAttackStateTimer = new vp_Timer.Handle(); protected vp_Timer.Handle m_DisableReloadStateTimer = new vp_Timer.Handle(); public List Weapons { get { if (m_Weapons == null) { InitWeaponLists(); } return m_Weapons; } set { m_Weapons = value; } } public vp_Weapon CurrentWeapon { get { return m_CurrentWeapon; } } [Obsolete("Please use the 'CurrentWeaponIndex' parameter instead.")] public int CurrentWeaponID { get { return m_CurrentWeaponIndex; } } public int CurrentWeaponIndex { get { return m_CurrentWeaponIndex; } } public vp_Weapon WeaponBeingSet { get { if (!m_Player.SetWeapon.Active) { return null; } if (m_Player.SetWeapon.Argument == null) { return null; } return Weapons[Mathf.Max(0, (int)m_Player.SetWeapon.Argument - 1)]; } } protected virtual bool OnValue_CurrentWeaponWielded { get { if (m_CurrentWeapon == null) { return false; } return m_CurrentWeapon.Wielded; } } protected virtual string OnValue_CurrentWeaponName { get { if (m_CurrentWeapon == null || Weapons == null) { return string.Empty; } return m_CurrentWeapon.name; } } protected virtual int OnValue_CurrentWeaponID { get { return m_CurrentWeaponIndex; } } protected virtual int OnValue_CurrentWeaponIndex { get { return m_CurrentWeaponIndex; } } public virtual int OnValue_CurrentWeaponType { get { return (!(CurrentWeapon == null)) ? CurrentWeapon.AnimationType : 0; } } public virtual int OnValue_CurrentWeaponGrip { get { return (!(CurrentWeapon == null)) ? CurrentWeapon.AnimationGrip : 0; } } protected virtual void Awake() { m_Player = (vp_PlayerEventHandler)base.transform.root.GetComponentInChildren(typeof(vp_PlayerEventHandler)); if (Weapons != null) { StartWeapon = Mathf.Clamp(StartWeapon, 0, Weapons.Count); } } protected void InitWeaponLists() { List list = null; vp_FPCamera componentInChildren = base.transform.GetComponentInChildren(); if (componentInChildren != null) { list = GetWeaponList(Camera.main.transform); if (list != null && list.Count > 0) { m_WeaponLists.Add(list); } } List list2 = new List(base.transform.GetComponentsInChildren()); if (list != null && list.Count == list2.Count) { Weapons = m_WeaponLists[0]; return; } List list3 = new List(); foreach (vp_Weapon item in list2) { if ((!(componentInChildren != null) || !list.Contains(item)) && !list3.Contains(item.Parent)) { list3.Add(item.Parent); } } foreach (Transform item2 in list3) { List weaponList = GetWeaponList(item2); DeactivateAll(weaponList); m_WeaponLists.Add(weaponList); } if (m_WeaponLists.Count < 1) { Debug.LogError(string.Concat("Error (", this, ") WeaponHandler found no weapons in its hierarchy. Disabling self.")); base.enabled = false; } else { Weapons = m_WeaponLists[0]; } } public void EnableWeaponList(int index) { if (m_WeaponLists != null && m_WeaponLists.Count >= 1 && index >= 0 && index <= m_WeaponLists.Count - 1) { Weapons = m_WeaponLists[index]; } } protected List GetWeaponList(Transform target) { List list = new List(); if ((bool)target.GetComponent()) { Debug.LogError(string.Concat("Error: (", this, ") Hierarchy error. This component should sit above any vp_Weapons in the gameobject hierarchy.")); return list; } vp_Weapon[] componentsInChildren = target.GetComponentsInChildren(true); foreach (vp_Weapon item in componentsInChildren) { list.Insert(list.Count, item); } if (list.Count == 0) { Debug.LogError(string.Concat("Error: (", this, ") Hierarchy error. This component must be added to a gameobject with vp_Weapon components in child gameobjects.")); return list; } IComparer comparer = new WeaponComparer(); list.Sort(comparer.Compare); return list; } protected virtual void OnEnable() { if (m_Player != null) { m_Player.Register(this); } } protected virtual void OnDisable() { if (m_Player != null) { m_Player.Unregister(this); } } protected virtual void Update() { InitWeapon(); UpdateFiring(); } protected virtual void UpdateFiring() { if ((m_Player.IsLocal.Get() || m_Player.IsAI.Get()) && m_Player.Attack.Active && !m_Player.SetWeapon.Active && (!(m_CurrentWeapon != null) || m_CurrentWeapon.Wielded)) { m_Player.Fire.Try(); } } public virtual void SetWeapon(int weaponIndex) { if (Weapons == null || Weapons.Count < 1) { Debug.LogError(string.Concat("Error: (", this, ") Tried to set weapon with an empty weapon list.")); } else if (weaponIndex < 0 || weaponIndex > Weapons.Count) { Debug.LogError(string.Concat("Error: (", this, ") Weapon list does not have a weapon with index: ", weaponIndex)); } else { if (m_CurrentWeapon != null) { m_CurrentWeapon.ResetState(); } DeactivateAll(Weapons); ActivateWeapon(weaponIndex); } } public void DeactivateAll(List weaponList) { } public void ActivateWeapon(int index) { m_CurrentWeaponIndex = index; m_CurrentWeapon = null; if (m_CurrentWeaponIndex > 0) { m_CurrentWeapon = Weapons[m_CurrentWeaponIndex - 1]; if (m_CurrentWeapon != null) { m_CurrentWeapon.ActivateGameObject(); } } } public virtual void CancelTimers() { vp_Timer.CancelAll("EjectShell"); m_DisableAttackStateTimer.Cancel(); m_SetWeaponTimer.Cancel(); m_SetWeaponRefreshTimer.Cancel(); } public virtual void SetWeaponLayer(int layer) { if (m_CurrentWeaponIndex >= 1 && m_CurrentWeaponIndex <= Weapons.Count) { vp_Layer.Set(Weapons[m_CurrentWeaponIndex - 1].gameObject, layer, true); } } private void InitWeapon() { if (m_CurrentWeaponIndex != -1) { return; } SetWeapon(StartWeapon); vp_Timer.In(SetWeaponDuration + 0.1f, delegate { if (StartWeapon > 0 && StartWeapon < Weapons.Count + 1 && !m_Player.SetWeapon.TryStart(StartWeapon)) { Debug.LogWarning(string.Concat("Warning (", this, ") Requested 'StartWeapon' (", Weapons[StartWeapon - 1].name, ") was denied, likely by the inventory. Make sure it's present in the inventory from the beginning.")); } }); } public void RefreshAllWeapons() { foreach (vp_Weapon weapon in Weapons) { weapon.Refresh(); weapon.RefreshWeaponModel(); } } public int GetWeaponIndex(vp_Weapon weapon) { return Weapons.IndexOf(weapon) + 1; } protected virtual void OnStart_Reload() { m_Player.Attack.Stop(m_Player.CurrentWeaponReloadDuration.Get() + ReloadAttackSleepDuration); } protected virtual void OnStart_SetWeapon() { CancelTimers(); if (WeaponBeingSet == null || WeaponBeingSet.AnimationType != 2) { m_Player.Reload.Stop(SetWeaponDuration + SetWeaponReloadSleepDuration); m_Player.Zoom.Stop(SetWeaponDuration + SetWeaponZoomSleepDuration); m_Player.Attack.Stop(SetWeaponDuration + SetWeaponAttackSleepDuration); } if (m_CurrentWeapon != null) { m_CurrentWeapon.Wield(false); } m_Player.SetWeapon.AutoDuration = SetWeaponDuration; } protected virtual void OnStop_SetWeapon() { int weapon = 0; if (m_Player.SetWeapon.Argument != null) { weapon = (int)m_Player.SetWeapon.Argument; } SetWeapon(weapon); if (m_CurrentWeapon != null) { m_CurrentWeapon.Wield(); } vp_Timer.In(SetWeaponRefreshStatesDelay, delegate { m_Player.RefreshActivityStates(); if (m_CurrentWeapon != null && m_Player.CurrentWeaponAmmoCount.Get() == 0) { m_Player.AutoReload.Try(); } }, m_SetWeaponRefreshTimer); } protected virtual bool CanStart_SetWeapon() { return false; } protected virtual bool CanStart_Attack() { if (m_CurrentWeapon == null) { return false; } if (m_Player.Attack.Active) { return false; } if (m_Player.SetWeapon.Active) { return false; } if (m_Player.Reload.Active) { return false; } return true; } protected virtual void OnStop_Attack() { vp_Timer.In(AttackStateDisableDelay, delegate { if (!m_Player.Attack.Active && m_CurrentWeapon != null) { m_CurrentWeapon.SetState("Attack", false); } }, m_DisableAttackStateTimer); } protected virtual bool OnAttempt_SetPrevWeapon() { int num = m_CurrentWeaponIndex - 1; if (num < 1) { num = Weapons.Count; } int num2 = 0; while (!m_Player.SetWeapon.TryStart(num)) { num--; if (num < 1) { num = Weapons.Count; } num2++; if (num2 > Weapons.Count) { return false; } } return true; } protected virtual bool OnAttempt_SetNextWeapon() { int num = m_CurrentWeaponIndex + 1; int num2 = 0; while (!m_Player.SetWeapon.TryStart(num)) { if (num > Weapons.Count + 1) { num = 0; } num++; num2++; if (num2 > Weapons.Count) { return false; } } return true; } protected virtual bool OnAttempt_SetWeaponByName(string name) { for (int i = 0; i < Weapons.Count; i++) { if (Weapons[i].name == name) { return m_Player.SetWeapon.TryStart(i + 1); } } return false; } }