147 lines
3.7 KiB
C#
147 lines
3.7 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;
|
|
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")]
|
|
public bool isBossEnemy;
|
|
[SerializeField] private bool hasStartedDialogue;
|
|
[Header("Attack")]
|
|
[SerializeField] private float attackCooldown;
|
|
private float currentAttackCooldown;
|
|
[SerializeField] private DialogueScript thisBossDialogue;
|
|
[Header("Animation")]
|
|
public Animator animator;
|
|
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)
|
|
{
|
|
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)
|
|
{
|
|
DialogueManager.instance.battleUIAnimator.SetTrigger(DialogueManager.instance.nobossTrigger);
|
|
WaveManager.instance.musicSource.clip = WaveManager.instance.musicLoop;
|
|
WaveManager.instance.musicSource.Play();
|
|
}
|
|
}
|
|
|
|
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;
|
|
if (thisBossDialogue && !GameManager.instance.isEndless)
|
|
{
|
|
DialogueManager.instance.StartDialogue(thisBossDialogue); //the worst code ever
|
|
}
|
|
isStalled = true;
|
|
}
|
|
}
|
|
transform.position = Vector3.Lerp(origin, moveDirection, currentMovement);
|
|
yield return null;
|
|
}
|
|
}
|
|
}
|