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 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 enemiesFound = new(); foreach (Collider2D foundEntity in entitiesFound) { if (!foundEntity.CompareTag(tag) && foundEntity.TryGetComponent(out Enemy isEnemy) && !isEnemy.isBossEnemy) { enemiesFound.Add(isEnemy); } } return enemiesFound.ToArray(); } }