2022-04-03 17:00:42 -04:00

179 lines
5.5 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using JetBrains.Annotations;
using NaughtyAttributes;
using UnityEngine;
[RequireComponent(typeof(Rigidbody2D))]
public class Entity : MonoBehaviour {
[Flags]
public enum EntityFlag {
Vampire = 0,
Monster = 1,
Gladiator = 2,
}
public Arena arena = null!;
[SerializeField]
[Required]
public GameFlowManager gameFlowManager = null!;
[field: SerializeField] public float Health { get; private set; }
[Min(10f)]
protected float initialHealth;
[SerializeField] [Required] protected HealthBar healthBar;
bool isAlive = true;
public int bloodTokens = 1;
[field: SerializeField] public float movementSpeed { get; private set; }
[field: SerializeField] public float rotSpeed { get; private set; }
[SerializeField] private float fov;
[field: SerializeField] public float attackRange { get; private set; }
[field: SerializeField] public float attackDmg { get; private set; }
[SerializeField] protected float attackCooldown;
protected float attackTimer;
public Transform target;
public EntityFlag entityType { get; protected set; }
public Vector3 direction { get; set; }
public Rigidbody2D rb { get; private set; }
public Collider2D collider { get; private set; }
[field: SerializeField]public SpriteRenderer renderer { get; private set; }
[SerializeField] GameObject halo;
[SerializeField] protected Color deadColor = Color.red;
[SerializeField] protected Color emptyColor = Color.grey;
[HideInInspector] public Animator animator;
bool beingSucked;
[HideInInspector] public SoundManager soundManager;
[SerializeField] protected AudioSource hurtSource;
[SerializeField] protected AudioSource deathSource;
[SerializeField] protected AudioSource attackSource;
[SerializeField] protected AudioClip[] hurtSounds;
[SerializeField] protected AudioClip[] deathSounds;
[SerializeField] protected AudioClip[] attackSounds;
virtual protected void Awake(){
rb = GetComponent<Rigidbody2D>();
collider = GetComponent<Collider2D>();
animator = GetComponentInChildren<Animator>();
soundManager = FindObjectOfType<SoundManager>();
}
protected virtual void Start() {
if (direction == Vector3.zero && !(this is VampireEntity))
Debug.LogWarning("Entity had null direction.");
gameFlowManager.stateChanged += OnGameFlowStateChanged;
attackTimer = attackCooldown;
initialHealth = Health;
if (halo != null) {
halo.SetActive(false);
}
}
protected virtual void Update() { }
protected virtual void FixedUpdate() {}
protected void OnDestroy() => gameFlowManager.stateChanged -= OnGameFlowStateChanged;
protected virtual void Attack() {
}
protected virtual void SpecialAttack() {
}
protected virtual void MoveToTarget() {
//Would be nice if we could force this to be in FixedUpdate
direction = Vector3.RotateTowards(direction, (target.position - transform.position), rotSpeed * Time.fixedDeltaTime, 0.0f);
if (!IsInAttackRange()) {
rb.MovePosition(transform.position + direction * movementSpeed * Time.fixedDeltaTime);
}
}
//Apply damage to the entity, returns true if it is still alive
public virtual bool TakeDamage(float amount, Entity other) {
Health -= amount;
healthBar.SetHealthFraction(Health / initialHealth);
if (Health <= 0) {
OnDied();
return false;
}
soundManager.PlaySound(hurtSource, hurtSounds, randomPitch:true, createTempSourceIfBusy:true);
return true;
}
public virtual void HealDamage(float amount) {
Health += amount;
healthBar.SetHealthFraction(Health / initialHealth);
if(Health > initialHealth) {
Health = initialHealth;
}
}
protected bool IsInAttackRange() {
float distance = Vector2.Distance(transform.position, target.position);
return distance <= attackRange;
}
protected bool IsLookingAtTarget() {
float angle = Vector2.SignedAngle(direction, (target.position - transform.position));
return angle >= -fov && angle <= fov;
}
public bool IsAlive() {
return isAlive;
}
protected virtual void OnDied() {
soundManager.PlaySound(deathSource, deathSounds, randomPitch: true, createTempSourceIfBusy: true);
isAlive = false;
if(!(collider is null)){
collider.isTrigger = true;
}
if(!(rb is null)){
rb.isKinematic = true;
rb.velocity = Vector2.zero;
}
healthBar.gameObject.SetActive(false);
if(bloodTokens > 0){
renderer.color = deadColor;
renderer.sortingOrder = -1;
}else{
renderer.color = emptyColor;
renderer.sortingOrder = -2;
}
}
protected virtual void OnEmpty(){
renderer.color = emptyColor;
renderer.sortingOrder = -2;
}
public void OnSuck(bool val){
beingSucked = val;
}
public bool IsBeingSucked(){
return beingSucked;
}
public void EnableHalo() {
halo.SetActive(true);
}
public void DisableHalo() {
halo.SetActive(false);
}
void OnGameFlowStateChanged(BaseState newState) {
if (gameFlowManager.pauseLevel >= GameFlowManager.PauseLevel.NothingMoves)
rb.velocity = Vector2.zero;
}
}