ReisenYoumuOuting/Assets/Scripts/Entities/Enemy.cs

141 lines
3.5 KiB
C#

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;
private float currentState = 1;
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<Ability> 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 && currentState >= 1f)
{
currentState = 0f;
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()
{
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;
}
}
}