using System.Collections.Generic; using UnityEngine; public class vp_FPWeaponMeleeAttack : vp_Component { public string WeaponStatePull = "Pull"; public string WeaponStateSwing = "Swing"; public float SwingDelay = 0.5f; public float SwingDuration = 0.5f; public float SwingRate = 1f; protected float m_NextAllowedSwingTime; public int SwingSoftForceFrames = 50; public Vector3 SwingPositionSoftForce = new Vector3(-0.5f, -0.1f, 0.3f); public Vector3 SwingRotationSoftForce = new Vector3(50f, -25f, 0f); public float ImpactTime = 0.11f; public Vector3 ImpactPositionSpringRecoil = new Vector3(0.01f, 0.03f, -0.05f); public Vector3 ImpactPositionSpring2Recoil = Vector3.zero; public Vector3 ImpactRotationSpringRecoil = Vector3.zero; public Vector3 ImpactRotationSpring2Recoil = new Vector3(0f, 0f, 10f); public bool AttackPickRandomState = true; protected int m_AttackCurrent; public List SoundSwing = new List(); public Vector2 SoundSwingPitch = new Vector2(0.5f, 1.5f); private vp_Timer.Handle SwingDelayTimer = new vp_Timer.Handle(); private vp_Timer.Handle ImpactTimer = new vp_Timer.Handle(); private vp_Timer.Handle SwingDurationTimer = new vp_Timer.Handle(); private vp_Timer.Handle ResetTimer = new vp_Timer.Handle(); private vp_FPPlayerEventHandler m_Player; private vp_FPWeapon m_FPWeapon; private vp_WeaponShooter m_WeaponShooter; protected vp_FPCamera m_FPCamera; protected vp_Controller m_FPController; protected vp_HitscanBullet m_HitscanBullet; private vp_FPPlayerEventHandler Player { get { if (m_Player == null && base.EventHandler != null) { m_Player = (vp_FPPlayerEventHandler)base.EventHandler; } return m_Player; } } private vp_FPWeapon FPWeapon { get { if (m_FPWeapon == null) { m_FPWeapon = base.Transform.GetComponent(); } return m_FPWeapon; } } private vp_WeaponShooter WeaponShooter { get { if (m_WeaponShooter == null) { m_WeaponShooter = base.Transform.GetComponent(); if (m_WeaponShooter == null) { Debug.LogWarning(string.Concat("Warning (", this, ") This component requires a vp_WeaponShooter (adding vp_WeaponShooter automatically).")); m_WeaponShooter = base.gameObject.AddComponent(); } else if (m_WeaponShooter is vp_FPWeaponShooter) { m_WeaponShooter.enabled = false; Debug.LogWarning(string.Concat("Warning (", this, ") This component requires a vp_WeaponShooter. It does _not_ work with a vp_FPWeaponShooter! (removing vp_FPWeaponShooter and adding vp_WeaponShooter automatically).")); m_WeaponShooter = base.gameObject.AddComponent(); } } return m_WeaponShooter; } } public vp_FPCamera FPCamera { get { if (m_FPCamera == null) { m_FPCamera = base.Root.GetComponentInChildren(); } return m_FPCamera; } } public vp_Controller FPController { get { if (m_FPController == null) { m_FPController = base.Root.GetComponentInChildren(); } return m_FPController; } } public vp_HitscanBullet HitscanBullet { get { if (m_HitscanBullet == null && WeaponShooter != null && WeaponShooter.ProjectilePrefab != null) { m_HitscanBullet = WeaponShooter.ProjectilePrefab.GetComponent(); if (m_HitscanBullet == null) { Debug.LogWarning(string.Concat("Warning (", this, ") ProjectilePrefab of the WeaponShooter has no 'vp_Hitscanbullet' (this melee weapon won't be able to do damage).")); } } return m_HitscanBullet; } } protected override void Awake() { base.Awake(); if (WeaponShooter != null) { WeaponShooter.ProjectileFiringRate = SwingRate; WeaponShooter.ProjectileTapFiringRate = SwingRate; WeaponShooter.ProjectileSpawnDelay = SwingDelay; WeaponShooter.ProjectileScale = 1f; WeaponShooter.ProjectileCount = 1; WeaponShooter.ProjectileSpread = 0f; if (WeaponShooter.ProjectilePrefab == null) { Debug.LogWarning(string.Concat("Warning (", this, ") WeaponShooter for this melee weapon has no 'ProjectilePrefab' (it won't be able to do damage).")); } } } protected override void OnEnable() { RefreshFirePoint(); base.OnEnable(); } protected override void Update() { base.Update(); UpdateAttack(); } protected void UpdateAttack() { if (!Player.Attack.Active || Player.SetWeapon.Active || FPWeapon == null || !FPWeapon.Wielded || Time.time < m_NextAllowedSwingTime) { return; } m_NextAllowedSwingTime = Time.time + SwingRate; if (AttackPickRandomState) { PickAttack(); } FPWeapon.SetState(WeaponStatePull); FPWeapon.Refresh(); vp_Timer.In(SwingDelay, delegate { if (SoundSwing.Count > 0) { base.Audio.pitch = Random.Range(SoundSwingPitch.x, SoundSwingPitch.y) * Time.timeScale; base.Audio.clip = (AudioClip)SoundSwing[Random.Range(0, SoundSwing.Count)]; if (vp_Utility.IsActive(base.gameObject)) { base.Audio.Play(); } } FPWeapon.SetState(WeaponStatePull, false); FPWeapon.SetState(WeaponStateSwing); FPWeapon.Refresh(); FPWeapon.AddSoftForce(SwingPositionSoftForce, SwingRotationSoftForce, SwingSoftForceFrames); vp_Timer.In(ImpactTime, delegate { Ray ray = new Ray(new Vector3(FPController.Transform.position.x, FPCamera.Transform.position.y, FPController.Transform.position.z), FPCamera.Transform.forward); RaycastHit hitInfo; Physics.Raycast(ray, out hitInfo, (!(HitscanBullet != null)) ? 2f : HitscanBullet.Range, vp_Layer.Mask.BulletBlockers); if (hitInfo.collider != null) { if (WeaponShooter != null) { WeaponShooter.FirePosition = Camera.main.transform.position; WeaponShooter.TryFire(); } ApplyRecoil(); } else { vp_Timer.In(SwingDuration - ImpactTime, delegate { FPWeapon.StopSprings(); Reset(); }, SwingDurationTimer); } }, ImpactTimer); }, SwingDelayTimer); } private void PickAttack() { int num = States.Count - 1; do { num = Random.Range(0, States.Count - 1); } while (States.Count > 1 && num == m_AttackCurrent && Random.value < 0.5f); m_AttackCurrent = num; SetState(States[m_AttackCurrent].Name); } private void ApplyRecoil() { FPWeapon.StopSprings(); FPWeapon.AddForce(ImpactPositionSpringRecoil, ImpactRotationSpringRecoil); FPWeapon.AddForce2(ImpactPositionSpring2Recoil, ImpactRotationSpring2Recoil); Reset(); } private void Reset() { vp_Timer.In(0.05f, delegate { if (FPWeapon != null) { FPWeapon.SetState(WeaponStatePull, false); FPWeapon.SetState(WeaponStateSwing, false); FPWeapon.Refresh(); if (AttackPickRandomState) { ResetState(); } } }, ResetTimer); } protected virtual void OnMessage_CameraToggle3rdPerson() { RefreshFirePoint(); } private void RefreshFirePoint() { if (!(WeaponShooter == null) && Player.IsFirstPerson != null) { if (Player.IsFirstPerson.Get()) { WeaponShooter.m_ProjectileSpawnPoint = FPCamera.gameObject; } else { WeaponShooter.m_ProjectileSpawnPoint = FPController.gameObject; } if (Player.CurrentWeaponName.Get() != base.name) { WeaponShooter.m_ProjectileSpawnPoint = FPCamera.gameObject; } } } }