ReisenYoumuOuting/Assets/Scripts/Abilities/YoumuDeflect.cs
2026-07-14 20:23:37 -07:00

182 lines
5.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Core.Extensions;
using UnityEngine;
using Random = UnityEngine.Random;
public class YoumuDeflect : Ability
{
[SerializeField] private Camera cam;
private List<Projectile> projectilesInRange = new();
[Header("Deflection")]
[SerializeField] private float deflectionSpeed;
[SerializeField] private float deflectionSpeedVariance;
[SerializeField] private float deflectionAngleMin = -48;
[SerializeField] private float deflectionAngleMax = 90;
[SerializeField] private Projectile chargeProjectile;
[SerializeField] private float destructionChance;
[Header("Entity Detection")]
[SerializeField] private float detectionRadius;
[SerializeField] private LayerMask entityLayer;
[Header("SlashCharge")]
[SerializeField] private float mouseHoldTime;
private float currentMouseHoldTime;
private float currentChargeTime;
private bool isCharging;
[SerializeField] private float maxChargeTime;
[SerializeField] private float chargeCooldown;
private float currentChargeCooldown;
private float currentUnleashedChargeTime;
[Header("Charge Effects")]
[SerializeField] private AudioClip chargeSlashSFX;
[SerializeField] private float chargeVolume = 1f;
[SerializeField] private Transform chargeMeter;
[Header("Effects")]
[SerializeField] private ParticleSystem deflectionParticles;
[SerializeField] private GameObject chargeSweepEffect;
[SerializeField] private AudioClip noHitSlashSFX;
[SerializeField] private float noHitVolume = 1f;
protected override void AbilityEffects()
{
base.AbilityEffects();
if (currentChargeCooldown > 0)
{
RegularDeflection();
}
else
{
currentMouseHoldTime = mouseHoldTime;
}
}
private void RegularDeflection()
{
if (projectilesInRange.Count > 0)
{
DeflectProjectiles();
}
else
{
WaveManager.instance.audioSource.PlayOneShot(noHitSlashSFX, noHitVolume);
}
foreach (Enemy enemy in DetectEnemies())
{
enemy.TakeDamage(power);
}
}
private void DeflectProjectiles()
{
GameManager.instance.deflections += projectilesInRange.Count;
foreach (Projectile projectile in projectilesInRange.ToList())
{
if (!projectile)
{
projectilesInRange.Remove(projectile);
continue;
}
projectile.transform.eulerAngles = new Vector3(0, 0, Random.Range(deflectionAngleMin, deflectionAngleMax));
projectile.direction = projectile.transform.right;
projectile.tag = tag;
projectile.speed = deflectionSpeed + Random.Range(-deflectionSpeedVariance, deflectionSpeedVariance);
ParticleSystem newParticles = Instantiate(deflectionParticles, projectile.transform);
projectile.Deflected();
float destructionRoll = Random.Range(0f, 1f);
if (destructionRoll < destructionChance)
{
Destroy(projectile.gameObject);
}
projectilesInRange.Remove(projectile);
}
WaveManager.instance.audioSource.PlayOneShot(abilitySound, volume);
}
private void OnTriggerEnter2D(Collider2D other)
{
if (!other.CompareTag(tag))
{
if (other.TryGetComponent(out Projectile isProjectile) && isProjectile.deflectable)
{
projectilesInRange.Add(isProjectile);
}
}
}
private void OnTriggerExit2D(Collider2D other)
{
if (!other.CompareTag(tag) && other.TryGetComponent(out Projectile isProjectile) && projectilesInRange.Contains(isProjectile))
{
projectilesInRange.Remove(isProjectile);
}
}
private void ShootBullet(Projectile projectileToShoot, int damage)
{
Debug.Log(damage);
direction = cam.ScreenToWorldPoint(Input.mousePosition);
Projectile newProjectile = Instantiate(projectileToShoot, origin.position, Quaternion.identity);
newProjectile.transform.Lookat2D(direction);
newProjectile.damage = damage;
newProjectile.tag = tag;
newProjectile.playerBullet = true;
}
protected override void Update()
{
base.Update();
if (currentMouseHoldTime > 0)
{
currentMouseHoldTime -= Time.deltaTime;
if (currentMouseHoldTime <= 0 && Input.GetMouseButton(1) && currentChargeTime <= 0)
{
isCharging = true;
currentChargeTime += mouseHoldTime;
}
else if (Input.GetMouseButtonUp(1))
{
RegularDeflection();
currentMouseHoldTime = 0;
isCharging = false;
}
}
if (isCharging && Input.GetMouseButton(1)) //this code REEKS
{
currentChargeTime += Time.deltaTime;
chargeMeter.localScale = new Vector3(1f, Math.Clamp(currentChargeTime, 0, maxChargeTime)/maxChargeTime, 1f);
}
else if (isCharging && Input.GetMouseButtonUp(1))
{
Debug.Log("here");
ShootBullet(chargeProjectile, power * (int)Math.Clamp(currentChargeTime, 0, maxChargeTime));
currentChargeTime = 0;
WaveManager.instance.audioSource.PlayOneShot(chargeSlashSFX, chargeVolume);
currentChargeCooldown = chargeCooldown;
isCharging = false;
chargeMeter.localScale = new Vector3(0f, 1f, 1f);
}
if (currentChargeCooldown > 0)
{
currentChargeCooldown -= Time.deltaTime;
}
//Debug.Log(currentChargeTime);
}
private Enemy[] DetectEnemies()
{
Collider2D[] entitiesFound = Physics2D.OverlapCircleAll(transform.position, detectionRadius, entityLayer);
List<Enemy> enemiesFound = new();
foreach (Collider2D foundEntity in entitiesFound)
{
if (!foundEntity.CompareTag(tag) && foundEntity.TryGetComponent(out Enemy isEnemy) && !isEnemy.isBossEnemy)
{
enemiesFound.Add(isEnemy);
}
}
return enemiesFound.ToArray();
}
}