using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using Random = UnityEngine.Random; public class Enemy : Entity { private Ability abilitySelected; public SpriteRenderer sprite; public float colorChangeSpeed; [Header("Movement")] public float moveSpeed; public float moveSpeedDelta; [Header("wobble")] public bool preventWobble; public Vector3 originalPosition; [SerializeField] private float variance; public Coroutine currentMovementRoutine; [Header("boss stuff")] [SerializeField] private bool isBossEnemy; [SerializeField] private bool hasStartedDialogue; [Header("Attack")] [SerializeField] private float attackCooldown; private float currentAttackCooldown; [SerializeField] private DialogueScript thisBossDialogue; public event Action onTakeDamage; private void Start() { moveSpeed += Random.Range(-moveSpeedDelta, moveSpeedDelta); currentAttackCooldown = Random.Range(0, attackCooldown); } protected virtual void Update() { if (!isStalled) { if (!preventWobble && currentMovementRoutine == null) { //Debug.Log("reset movement"); //StopCoroutine(currentMovementRoutine); Vector3 newPosition = new Vector3(originalPosition.x + Random.Range(-variance, variance), originalPosition.y + Random.Range(-variance*0.5f, variance*0.5f)); currentMovementRoutine = StartCoroutine(MoveToPosition(transform.position, newPosition, moveSpeed)); } if (currentAttackCooldown <= 0) { List freeAbilities = new(); foreach (Ability ability in abilities) { if (ability.currentCooldown <= 0) { freeAbilities.Add(ability); } } if (freeAbilities.Count == 0) { return; } if (!abilitySelected) { abilitySelected = freeAbilities[Random.Range(0, freeAbilities.Count)]; } bool success = abilitySelected.TryAbility(); if (!success && abilitySelected.currentCooldown <= 0.5f) { StartCoroutine(ImminentAttackAnim()); } else { abilitySelected = null; currentAttackCooldown = attackCooldown; } } else { currentAttackCooldown -= Time.deltaTime; } } } public override void TakeDamage(int damage) { base.TakeDamage(damage); if (isBossEnemy) { WaveManager.instance.UpdateBossUI(); //this is fucking stupid but it works i guess } onTakeDamage?.Invoke(); } protected override void OnDeath() { base.OnDeath(); Destroy(gameObject); WaveManager.instance.enemiesInPlay.Remove(this); WaveManager.instance.UpdateKills(); if (isBossEnemy) { WaveManager.instance.bossUI.SetActive(false); } } private IEnumerator ImminentAttackAnim() { float currentState = 0; while (currentState < 1) { currentState += Time.deltaTime * colorChangeSpeed; sprite.color = Color.Lerp(Color.red, Color.white, currentState); yield return null; } } public IEnumerator MoveToPosition(Vector3 origin, Vector3 moveDirection, float lerpSpeed) { float currentMovement = 0; while (currentMovement < 1) { currentMovement += Time.deltaTime * lerpSpeed; if (currentMovement >= 1) { isStalled = false; invulnerable = false; currentMovementRoutine = null; if (isBossEnemy && !hasStartedDialogue) { hasStartedDialogue = true; DialogueManager.instance.StartDialogue(thisBossDialogue); //the worst code ever isStalled = true; } } transform.position = Vector3.Lerp(origin, moveDirection, currentMovement); yield return null; } } }