twinStick/twinStickCrawler/Assets/Scripts/Creatures/Player/PlayerAttack.cs
2024-12-24 14:34:15 +01:00

145 lines
4.3 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Mathematics;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Events;
using Random = System.Random;
public class PlayerAttack : MonoBehaviour
{
private InputManager _inputManager;
private LayerMask _enemyLayermask;
private Animate _animate;
private Collider _hurtbox;
private string[] _availableAttacks;
private float _baseDamage;
private float _comboStep;
private AnimationCurve _comboCurve;
public void initialize(InputManager inputManager, LayerMask enemyLayermask, Animate animate, Collider hurtbox, string[] availableAttacks, float baseDamage, float comboStep, AnimationCurve comboCurve)
{
_inputManager = inputManager;
_enemyLayermask = enemyLayermask;
_hurtbox = hurtbox;
_animate = animate;
_availableAttacks = availableAttacks;
_baseDamage = baseDamage;
_comboStep = comboStep;
_comboCurve = comboCurve;
OnEnable();
}
#region Event Setup
private void OnEnable()
{
if (_animate != null)
{
_animate.OnReset += _onResetHandler;
_animate.OnStartDamage += _onStartDamageHandler;
_animate.OnEndDamage += _onEndDamageHandler;
_animate.OnAnimationEnd += _onAnimationEndHandler;
}
_canAttack = true;
_attacking = false;
_damageEnded = true;
_currentDamageMultiplier = new Dictionary<int, float>();
}
private void OnDisable()
{
_animate.OnReset -= _onResetHandler;
_animate.OnStartDamage -= _onStartDamageHandler;
_animate.OnEndDamage -= _onEndDamageHandler;
_animate.OnAnimationEnd -= _onAnimationEndHandler;
}
private void _onResetHandler()
{
_canAttack = true;
}
private void _onAnimationEndHandler()
{
_attacking = false;
_currentDamageMultiplier = new Dictionary<int, float>();
}
private void _onStartDamageHandler()
{
StartCoroutine(DealDamage());
}
private void _onEndDamageHandler()
{
_damageEnded = true;
}
#endregion
private bool _attacking=false;
private bool _canAttack = true;
private int _attack = 0;
public bool Attack()
{
if (_canAttack && _inputManager.attackPerformed)
{
if (_attack >= 2 || _animate.IsCurrentAnimation("Blend Tree"))
{
_attack = 0;
}
_animate.TriggerAnimation(_availableAttacks[_attack]);
_canAttack = false;
_attack++;
_attacking = true;
}
return _attacking;
}
private bool _damageEnded = true;
IEnumerator DealDamage()
{
List<Collider> damagedColliders = new List<Collider>();
_damageEnded = false;
while (!_damageEnded)
{
Collider[] hitColliders = Physics.OverlapBox(_hurtbox.bounds.center, _hurtbox.bounds.extents, Quaternion.identity, _enemyLayermask);
foreach (Collider enemy in hitColliders)
{
if (!damagedColliders.Contains(enemy))
{
print(enemy.gameObject.GetComponent<Vitals>().Health);
enemy.gameObject.GetComponent<Vitals>().Health -= CalculateDamage(enemy);
damagedColliders.Add(enemy);
}
}
yield return null;
}
}
Dictionary<int, float> _currentDamageMultiplier = new Dictionary<int, float>();
float CalculateDamage(Collider enemy)
{
// If enemy is hit for the first time during "Combo" he gets added to the dictionary to get its own combo mult
if (!_currentDamageMultiplier.ContainsKey(enemy.GetInstanceID()))
{
_currentDamageMultiplier.Add(enemy.GetInstanceID(), 0f);
}
// If enemy gets hit again its Combo mult is incremented
else
{
Random rnd = new Random();
_currentDamageMultiplier[enemy.GetInstanceID()] += _comboStep * (rnd.Next(1, 10) / 10f);
}
return _baseDamage * _comboCurve.Evaluate(_currentDamageMultiplier[enemy.GetInstanceID()]);
}
}