using System.Collections; using System.Collections.Generic; using UnityEngine; using Random = System.Random; namespace Creatures.Player.Movement { 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(); } 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(); _lastDamageMultiplier = new Dictionary(); } 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; Dictionary _lastDamageMultiplier = new Dictionary(); Dictionary _currentDamageMultiplier = new Dictionary(); IEnumerator DealDamage() { List damagedColliders = new List(); _currentDamageMultiplier = new Dictionary(); _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()); enemy.gameObject.GetComponent().Health = -CalculateDamage(enemy); damagedColliders.Add(enemy); } } yield return null; } _lastDamageMultiplier = _currentDamageMultiplier; } float CalculateDamage(Collider enemy) { print(_lastDamageMultiplier.ContainsKey(enemy.GetInstanceID())); // If enemy is hit for the first time during "Combo" he gets added to the dictionary to get its own combo mult if (!_lastDamageMultiplier.ContainsKey(enemy.GetInstanceID())) { _currentDamageMultiplier.Add(enemy.GetInstanceID(), 0f); } // If enemy gets hit again its Combo mult is incremented else if(_lastDamageMultiplier.ContainsKey(enemy.GetInstanceID())) { _currentDamageMultiplier.Add(enemy.GetInstanceID(), _lastDamageMultiplier[enemy.GetInstanceID()]); Random rnd = new Random(); _currentDamageMultiplier[enemy.GetInstanceID()] += _comboStep * (rnd.Next(1, 10) / 10f); } return _baseDamage * _comboCurve.Evaluate(_currentDamageMultiplier[enemy.GetInstanceID()]); } } }