Skip to content
Snippets Groups Projects
Fighter.cs 2.61 KiB
Newer Older
  • Learn to ignore specific revisions
  • using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public interface IFighterCallback
    {
        void OnDeath();
    }
    
    // Generic subclass for any Fighter on the field, whether it's an Enemy or the AntiPlayer.
    // Contains stats management such as health, attacks, damage, death, etc.
    public abstract class Fighter : MonoBehaviour
    {
    
        [SerializeField] int baseHealth = 100;
    
        [SerializeField, Tooltip("Attack every x seconds")] float baseAttackSpeed = 1f;
    
        [SerializeField] int baseAttackDamage = 10;
        [SerializeField] int baseArmor = 1;
    
        public List<IFighterCallback> callbacks = new List<IFighterCallback>();
    
    
        [SerializeField] protected int currentHealth = 100;
    
        protected Animator animator;
        protected bool alive { get => currentHealth > 0; }
    
        protected FighterTypes fighterType;
    
        protected abstract void Attack();
    
        float timeSinceLastAttack = 0f;
    
        protected virtual void Awake()
        {
            animator = GetComponent<Animator>();
    
            fighterType = FighterTypes.ENEMY;
        }
    
        protected virtual void Start()
        {
            currentHealth = Mathf.RoundToInt(baseHealth * GetStats().healthMultiplier);
    
        }
    
        protected virtual void Update()
        {
            if (alive)
            {
                timeSinceLastAttack += Time.deltaTime;
                var timeUntilNextAttack = baseAttackSpeed - timeSinceLastAttack;
    
                if (timeUntilNextAttack <= 0) // TODO only attack when near opposing faction
    
                {
                    Attack();
                    timeSinceLastAttack = -timeUntilNextAttack; // To account for overshoot
                }
            }
        }
    
        public void DealDamage(int dmg)
        {
    
            var actualDamage = Mathf.Max(0, Mathf.RoundToInt(dmg - baseArmor * GetStats().armorMultiplier));
    
            currentHealth = Mathf.Max(currentHealth - actualDamage, 0);
            if (currentHealth == 0)
            {
                animator.SetTrigger("Death");
                callbacks.ForEach(c => c.OnDeath());
                // TODO (Depending on the death animation) only destroy on round end so that corpses stay on the ground
                // Destroy(gameObject);
            }
            else
            {
                animator.SetTrigger("Hurt");
            }
        }
    
    
        protected FighterStats GetStats()
        {
            return StatsManager.instance.fighterStats[fighterType];
        }
    
    
        void OnTriggerEnter2D(Collider2D other)
        {
            if (other.CompareTag("AntiPlayer"))
            {
    
                var damageToDeal = Mathf.RoundToInt(baseAttackDamage * GetStats().damageMultiplier);
    
                other.GetComponent<Fighter>().DealDamage(damageToDeal);
            }
        }
    
    }