213 lines
5.9 KiB
C#

using GatherAndDefend;
using System.Collections;
using System.Collections.Generic;
using UnityEditor.SceneManagement;
using UnityEngine;
public abstract class Entity : LevelObject
{
[SerializeField]
private WorldSlider _lifeBar;
//Attribut
[SerializeField]
private int _hp;
private int _maxHp;
[SerializeField]
private float _speed;
[SerializeField]
private int _attack_damage = 2;
[SerializeField]
private float _attack_interval = 2;
private float _attack_speed_wait = 0f;
private AnimationEntity _animation;
private Shader _shaderGUItext;
private Shader _shaderSpritesDefault;
private SpriteRenderer[] _spriteRenderers;
private AudioPlayerComponent _audioPlayerComponent;
private StatusHandler _statusHandler;
// status modifiers
private float _speedStatusModifier = 1f;
//Enemy Spotted
private bool _isEnemyDetected = false;
[SerializeField]
private Entity _enemy;
//Methods
public virtual void Start()
{
_maxHp = _hp;
_spriteRenderers = GetComponentsInChildren<SpriteRenderer>(true);
_audioPlayerComponent = GetComponent<AudioPlayerComponent>();
Animation = gameObject.AddComponent<AnimationEntity>();
_statusHandler = gameObject.AddComponent<StatusHandler>();
if (_audioPlayerComponent == null)
{
_audioPlayerComponent = gameObject.AddComponent<AudioPlayerComponent>();
}
}
public virtual void Update()
{
Animation.AttackSpeedMultiplier = AttackSpeedMultiplier;
Animation.SpeedMultiplier = SpeedMultiplier * SpeedStatusModifier;
_lifeBar.gameObject.SetActive(_lifeBar.value <= 0.99f);
}
//Start the animation of death and the fading of the entity
public virtual void Death()
{
_animation.PlayDieAnim();
Invoke("Dying", 0.1f);
}
//Recursive method that fade the dying entity
private void Dying()
{
foreach (SpriteRenderer renderer in _spriteRenderers)
{
Color currentColor = renderer.color;
currentColor.a = currentColor.a - 0.1f;
renderer.color = currentColor;
}
if (_spriteRenderers[0].color.a > 0f)
{
Invoke("Dying", 0.1f);
}
else
{
Destroy(gameObject);
}
}
//When hit : get damage and start a flash of light
public void Hit(int damage)
{
_hp -= damage;
_lifeBar.value = _hp / (float)_maxHp;
_shaderGUItext = Shader.Find("GUI/Text Shader");
_shaderSpritesDefault = Shader.Find("Sprites/Default");
foreach (SpriteRenderer renderer in _spriteRenderers)
{
renderer.material.shader = _shaderGUItext;
}
Invoke("ReturnNormalColor", 0.1f);
}
//End the flash of light from the method above
private void ReturnNormalColor()
{
foreach (SpriteRenderer renderer in _spriteRenderers)
{
renderer.material.shader = _shaderSpritesDefault;
}
}
public void Move()
{
if (!_animation.IsWalking)
{
_animation.PlayWalkAnim();
}
}
public void PlaySound(string soundName, float volumeMultiplier = 1f, float overrideVolume = -1f)
{
_audioPlayerComponent.PlaySound(soundName, volumeMultiplier, overrideVolume);
}
public void PlaySound(AudioTemplate sound, float volumeMultiplier = 1f, float overrideVolume = -1f)
{
_audioPlayerComponent.PlaySound(sound, volumeMultiplier, overrideVolume);
}
//GETTERS AND SETTERS
public abstract Vector2 RangeMultiplier { get; }
public abstract float HpMultiplier { get; }
public abstract float SpeedMultiplier { get; }
public abstract float DamageMultiplier { get; }
public abstract float AttackSpeedMultiplier { get; }
public int Hp => (int)(_hp * HpMultiplier);
public float Speed => _speed * SpeedMultiplier * SpeedStatusModifier;
public int AttackDamage
{
get { return (int)(_attack_damage * DamageMultiplier); }
set { _attack_damage = value; }
}
public float AttackInterval => _attack_interval / AttackSpeedMultiplier;
public float AttackSpeedWait
{
get { return _attack_speed_wait; }
set { _attack_speed_wait = value; }
}
public bool IsEnemyDetected
{
get { return _isEnemyDetected; }
set { _isEnemyDetected = value; }
}
public Entity Enemy
{
get { return _enemy; }
set { _enemy = value; }
}
public AnimationEntity Animation
{
get { return _animation; }
set { _animation = value; }
}
public SpriteRenderer[] SpriteRenderers { get { return _spriteRenderers; } }
public StatusHandler StatusHandler {
get => _statusHandler;
}
public float SpeedStatusModifier { get => _speedStatusModifier; set => _speedStatusModifier = value; }
#region [LevelManager code]
public override bool Equals(ILevelObject other)
{
return other is Entity otherEntity
&& base.Equals(otherEntity)
&& otherEntity._hp == _hp
&& otherEntity._speed == _speed
&& otherEntity._attack_interval == _attack_interval
&& otherEntity._attack_damage == _attack_damage;
}
public override Dictionary<string, object> ToDictionary()
{
var dict = base.ToDictionary();
dict[nameof(_hp)] = _hp;
dict[nameof(_speed)] = _speed;
dict[nameof(_attack_interval)] = _attack_interval;
dict[nameof(_attack_damage)] = _attack_damage;
return dict;
}
public override void LoadDictionary(Dictionary<string, object> dict)
{
base.LoadDictionary(dict);
_hp = dict[nameof(_hp)].ToInt();
_speed = dict[nameof(_speed)].ToFloat();
_attack_interval = dict[nameof(_attack_interval)].ToFloat();
_attack_damage = dict[nameof(_attack_damage)].ToInt();
}
#endregion
}