using System; using Game; using JetBrains.Annotations; using Meta; using Stages; using UnityEngine; using UnityEngine.AI; using Utils; namespace Ai { public class Body : MonoBehaviour { [SerializeField] private Animator _animator; [SerializeField] private float _hitPoints; [SerializeField] private HealthBar _bar; [SerializeField] private bool _boss; [SerializeField] private float _bossResist = 0.6f; [SerializeField] private NavMeshAgent _agent; [SerializeField] private bool _isImmortal; [SerializeField] private bool _isTargetable; [SerializeField] private GameObject _headshotFx; [SerializeField] private GameObject _deathObject; private float _currentHitPoints; private static readonly int Hp = Animator.StringToHash("hp"); private static readonly int Hit = Animator.StringToHash("hit"); private static readonly int Rnd = Animator.StringToHash("rnd"); private static readonly int Speed = Animator.StringToHash("speed"); private static readonly int Distance = Animator.StringToHash("Distance"); public bool IsTargetable { get { return _isTargetable; } } public event Action DeathEvent; private void OnEnable() { _currentHitPoints = _hitPoints * PlayerResources.Instance.NPCHitPoints + (_hitPoints * 0.2f * StageProcessor.Instance.World - 1); UpdateAnimatorParams(); if (_animator == null) _animator = GetComponent(); } public void SetDamage(float damage, bool showText = true) { if (_isImmortal) return; _currentHitPoints -= damage * (_boss ? _bossResist : 1); if (showText) FlyingText.Init(-(int)damage, FlyingText.State.Normal, transform.position); SoundsManager.Instance.PlaySound("damage"); UpdateAnimatorParams(); if (_bar != null) { _bar.SetPercent(_currentHitPoints / (_hitPoints * PlayerResources.Instance.NPCHitPoints + (_hitPoints * 0.2f * StageProcessor.Instance.World - 1))); } if (_currentHitPoints <= 0) { if (DeathEvent != null) DeathEvent(); if (_deathObject != null) { var deathObj = Instantiate(_deathObject); deathObj.transform.position = transform.position; } var position = gameObject.transform.position; Destroy(gameObject); AiController.Instance.EnemyDied(position); } } private void UpdateAnimatorParams() { if (_animator != null) { _animator.SetFloat(Hp, _currentHitPoints/ (_hitPoints * PlayerResources.Instance.NPCHitPoints)); _animator.SetTrigger(Hit); _animator.SetFloat(Distance, Vector3.Distance(AiController.Instance.PlayerPosition, transform.position)); } } void FixedUpdate() { if (_animator != null) { _animator.ResetTrigger(Hit); _animator.SetFloat(Rnd, UnityEngine.Random.Range(0.0f,1.0f)); if (_agent != null) { var speed = _agent.velocity.magnitude / _agent.speed; _animator.SetFloat(Speed, speed); } _animator.SetFloat(Distance, Vector3.Distance(AiController.Instance.PlayerPosition, transform.position)); } } [UsedImplicitly] public void SetImmortal(int i) { _isImmortal = i > 0; } [UsedImplicitly] public void SetTargetable(int i) { _isTargetable = i > 0; } public void InstantDestroy(float damage) { if (_headshotFx != null) { var fx = Instantiate(_headshotFx); fx.transform.position = transform.position; } if (!_boss) { FlyingText.Init(-(int) _currentHitPoints, FlyingText.State.Danger, transform.position); SetDamage(_currentHitPoints, false); } } } }