using System; using Actions; using Grid; using UnityEngine; public class Unit : MonoBehaviour { private const int ACTION_POINTS_MAX = 10; [SerializeField] private bool isEnemy; private int actionPoints = ACTION_POINTS_MAX; public GridPosition GridPosition { get; private set; } public BaseAction[] BaseActionArray { get; private set; } public HealthSystem HealthSystem { get; private set; } public int ActionPoints { get => actionPoints; private set { actionPoints = value; OnAnyActionPointsChanged?.Invoke(this, EventArgs.Empty); } } public bool IsEnemy => isEnemy; private void Awake() { BaseActionArray = GetComponents(); HealthSystem = GetComponent(); } private void Start() { GridPosition = LevelGrid.Instance.GetGridPosition(transform.position); LevelGrid.Instance.AddUnitAtGridPosition(GridPosition, this); TurnSystem.Instance.OnTurnChanged += TurnSystem_OnTurnChanged; HealthSystem.OnDead += HealthSystem_OnDead; OnAnyUnitSpawned?.Invoke(this, EventArgs.Empty); } private void Update() { GridPosition newGridPosition = LevelGrid.Instance.GetGridPosition(transform.position); if (newGridPosition == GridPosition) return; GridPosition oldGridPosition = GridPosition; GridPosition = newGridPosition; LevelGrid.Instance.UnitMovedGridPosition(this, oldGridPosition, GridPosition); } public static event EventHandler OnAnyUnitSpawned; public static event EventHandler OnAnyUnitDead; public T GetAction() where T : BaseAction { foreach (BaseAction baseAction in BaseActionArray) { if (baseAction is T action) return action; } return null; } private void HealthSystem_OnDead(object sender, EventArgs e) { LevelGrid.Instance.RemoveUnitAtGridPosition(GridPosition, this); Destroy(gameObject); OnAnyUnitDead?.Invoke(this, EventArgs.Empty); } public static event EventHandler OnAnyActionPointsChanged; private void TurnSystem_OnTurnChanged(object sender, EventArgs e) { if (IsEnemy ^ TurnSystem.Instance.IsPlayerTurn || TurnSystem.Instance.IsPlayerTurn ^ IsEnemy) { ActionPoints = ACTION_POINTS_MAX; } } public bool TrySpendActionPointsToTakeAction(BaseAction baseAction) { if (!CanSpendActionPointsToTakeAction(baseAction)) return false; SpendActionPoints(baseAction.ActionPointsCost); return true; } private bool CanSpendActionPointsToTakeAction(BaseAction baseAction) => ActionPoints >= baseAction.ActionPointsCost; private void SpendActionPoints(int amount) => ActionPoints -= amount; public void Damage(int damageAmount) => HealthSystem.Damage(damageAmount); public Vector3 GetWorldPosition() => transform.position; }