using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(Animator))]
[RequireComponent(typeof(AudioSource))]
public class WeaponHitscan : MonoBehaviour
{
[Header("Stats")]
public float damage = 3f;
public float fireRate = 1f;
public int pelletCount = 1;
public int ammoConsumption = 1;
public float spread = 0f;
public float impactForce = 1f;
[Header("Reloading")]
public int clipSize;
private int currentAmmo;
public float reloadDelay;
public float reloadTime;
public int reloadAmount;
public bool magReload = false;
[HideInInspector] public bool isReloading = false;
[HideInInspector] public Animator anim;
[HideInInspector] public AudioSource sound;
[Header("FX")]
public ParticleSystem muzzleFlash;
public GameObject bulletHole;
public AudioClip shootSound;
public AudioClip reloadSound;
public Vector2 recoil;
[Header("Casing")]
public Transform casingSpawnPosition;
public GameObject casing;
public float casingDelay;
public float casingFlyForce;
protected float nextTimeToFire = 1f;
protected GameObject cam; protected PlayerStats ps;
private CameraRecoil recoilFunc;
void Start()
{
ps = GameObject.Find("Player").GetComponent<PlayerStats>();
cam = GameObject.Find("Main Camera");
recoilFunc = cam.transform.parent.GetComponent<CameraRecoil>();
anim = GetComponent<Animator>();
sound = GetComponent<AudioSource>();
currentAmmo = clipSize;
}
void Update()
{
if(ps.textClip) ps.textClip.text = currentAmmo.ToString();
if (!GetComponentInParent<WeaponSwitch>().isHolstering)
{
if (isReloading) return;
if (currentAmmo <= 0 && ps.globalAmmo > 0 || Input.GetKey(KeyCode.R) && currentAmmo < clipSize)
{
StartCoroutine(Reload());
return;
}
if (Input.GetMouseButton(0) && Time.time >= nextTimeToFire)
{
if (currentAmmo > 0)
{
nextTimeToFire = Time.time + 1f / fireRate;
StartCoroutine(ShootChecker());
}
}
}
}
void Shoot()
{
for (int i = 0; i < pelletCount; i++)
{
Quaternion hSpreadAngle = Quaternion.AngleAxis(Random.Range(-spread, spread), new Vector3(0, 1, 1));
Quaternion vSpreadAngle = Quaternion.AngleAxis(Random.Range(-spread, spread), new Vector3(1, 0, 2));
Vector3 newVector = hSpreadAngle * vSpreadAngle * cam.transform.forward;
RaycastHit hit;
if (Physics.Raycast(cam.transform.position, newVector, out hit))
{
GameObject target = null;//hit.transform.GetComponent<Enemy>();
if (target != null)
{
//target.TakeDamage(Random.Range(damage * 1, damage * 3));
//GameObject blood = Instantiate(bloodEffect, hit.point, Quaternion.LookRotation(hit.normal));
//Destroy(blood, 3f);
}
else
{
ParticlesContainer parList = GameObject.Find("GameManager").GetComponent<ParticlesContainer>();
if (hit.collider.GetComponent<Terrain>()) return;
if (hit.collider.GetComponent<MeshRenderer>() != null && hit.collider.GetComponent<MeshRenderer>().material.name.Contains("glass")
|| hit.collider.GetComponentInChildren<MeshRenderer>().material.name.Contains("glass"))
{
GameObject newGlasshole = Instantiate(parList.glassHole, hit.point, Quaternion.LookRotation(hit.normal) * parList.glassHole.transform.rotation);
newGlasshole.transform.SetParent(hit.collider.transform); Destroy(newGlasshole, 60f);
var savedVolume = newGlasshole.GetComponent<AudioSource>().volume;
newGlasshole.GetComponent<AudioSource>().volume = savedVolume / pelletCount;
newGlasshole.transform.parent = hit.transform;
}
else
{
if (!hit.collider.gameObject.name.Contains("pickup"))
{
GameObject impact = Instantiate(bulletHole, hit.point, Quaternion.LookRotation(hit.normal));
impact.transform.parent = hit.collider.transform; Destroy(impact, 60f);
}
if (hit.collider.GetComponent<MeshRenderer>() != null)
{
if (hit.collider.GetComponent<MeshRenderer>().material.name.Contains("concrete") || hit.transform.GetComponentInChildren<MeshRenderer>().material.name.Contains("concrete"))
{
GameObject crumble = Instantiate(parList.concreteCrumble, hit.point, Quaternion.LookRotation(hit.normal) * Quaternion.Euler(-30, 0, 0));
var savedVolume = crumble.GetComponent<AudioSource>().volume;
crumble.GetComponent<AudioSource>().volume = savedVolume / pelletCount;
}
if (hit.collider.GetComponent<MeshRenderer>().material.name.Contains("wood") || hit.transform.GetComponentInChildren<MeshRenderer>().material.name.Contains("wood"))
{
GameObject crumble = Instantiate(parList.woodCrumble, hit.point, Quaternion.LookRotation(hit.normal) * Quaternion.Euler(-30, 0, 0));
var savedVolume = crumble.GetComponent<AudioSource>().volume;
crumble.GetComponent<AudioSource>().volume = savedVolume / pelletCount;
}
if (hit.collider.GetComponent<MeshRenderer>().material.name.Contains("metal") || hit.transform.GetComponentInChildren<MeshRenderer>().material.name.Contains("metal"))
{
GameObject crumble = Instantiate(parList.metalCrumble, hit.point, Quaternion.LookRotation(hit.normal) * Quaternion.Euler(-30, 0, 0));
var savedVolume = crumble.GetComponent<AudioSource>().volume;
crumble.GetComponent<AudioSource>().volume = savedVolume / pelletCount;
}
}
Rigidbody rb = hit.transform.GetComponent<Rigidbody>();
if (rb != null) rb.AddForce(newVector * impactForce);
}
LightDestroy ld = hit.transform.GetComponent<LightDestroy>();
if (ld != null) ld.ChangeMat();
Destructible dest = hit.collider.transform.GetComponent<Destructible>();
if (dest != null) dest.TakeDamage(damage);
}
}
}
currentAmmo -= ammoConsumption;
}
IEnumerator ShootChecker()
{
anim.Play("fire");
Shoot();
int newRecoil = Random.Range(((int)recoil.x), (int)recoil.y);
recoilFunc.Recoil(newRecoil);
if (sound != null) { sound.clip = shootSound; sound.Play(); }
if(muzzleFlash != null) muzzleFlash.Play();
if(casing != null)
{
yield return new WaitForSeconds(casingDelay);
GameObject shell = Instantiate(casing, casingSpawnPosition.position, casingSpawnPosition.rotation);
shell.GetComponent<Rigidbody>().AddForce((casingSpawnPosition.transform.up * casingFlyForce + -transform.forward) * 2f, ForceMode.Impulse);
Destroy(shell, 20f);
}
}
IEnumerator Reload()
{
isReloading = true;
//yield return new WaitForSeconds(reloadDelay /2);
anim.Play("reload");
yield return new WaitForSeconds(reloadDelay);
if (magReload)
{
if (sound != null)
{ sound.Stop(); sound.clip = reloadSound; sound.Play(); }
yield return new WaitForSeconds(reloadTime);
int reloadAmount2 = clipSize - currentAmmo;
reloadAmount2 = (ps.globalAmmo - reloadAmount2) >= 0 ? reloadAmount2 : ps.globalAmmo;
currentAmmo += reloadAmount2;
ps.globalAmmo -= reloadAmount2;
isReloading = false;
}
else
{
StartCoroutine(ReloadUnmag());
}
}
IEnumerator ReloadUnmag()
{
if (currentAmmo < clipSize)
{
anim.Play("");
anim.Play("reload_put");
if (sound != null)
{ sound.Stop(); sound.clip = reloadSound; sound.Play(); }
yield return new WaitForSeconds(reloadTime / 2);
currentAmmo += reloadAmount;
ps.globalAmmo -= reloadAmount;
StartCoroutine(ReloadUnmag());
}
if (currentAmmo == clipSize || ps.globalAmmo == 0)
{
anim.Play("reload_finish");
yield return new WaitForSeconds(reloadTime / 2);
isReloading = false;
yield break;
}
}
}