using System; using System.Linq; using Actions; using Grid; using UnityEngine; using UnityEngine.Serialization; public class EnemyAI : MonoBehaviour { public enum State { WaitingForEnemyTurn, TakingTurn, Busy } public static EnemyAI Instance { get; private set; } public State CurrentState { get; private set; } private float timer; private void Awake() { if (Instance is not null) { Debug.LogError($"There is more than one TurnSystem! {transform} - {Instance}"); Destroy(gameObject); return; } Instance = this; CurrentState = State.WaitingForEnemyTurn; } private void Start() => TurnSystem.Instance.OnTurnChanged += TurnSystem_OnTurnChanged; private void Update() { if (TurnSystem.Instance.IsPlayerTurn) return; switch (CurrentState) { case State.WaitingForEnemyTurn: break; case State.TakingTurn: timer -= Time.deltaTime; if (timer <= 0f) { if (TryTakeEnemyAIAction(SetStateTakingTurn)) { CurrentState = State.Busy; } else { TurnSystem.Instance.NextTurn(); // No more enemies have actions they can take, end enemy turn } } break; case State.Busy: break; } } private void SetStateTakingTurn() { timer = .5f; CurrentState = State.TakingTurn; } private void TurnSystem_OnTurnChanged(object sender, EventArgs e) { if (TurnSystem.Instance.IsPlayerTurn) return; CurrentState = State.TakingTurn; timer = 2f; } private static bool TryTakeEnemyAIAction(Action onEnemyAIActionComplete) => UnitManager.Instance.EnemyUnitList.Any(enemyUnit => TryTakeEnemyAIAction(enemyUnit, onEnemyAIActionComplete)); private static bool TryTakeEnemyAIAction(Unit enemyUnit, Action onEnemyAIActionComplete) { EnemyAIAction bestEnemyAIAction = null; BaseAction bestBaseAction = null; foreach (BaseAction baseAction in enemyUnit.BaseActionArray) { if (enemyUnit.ActionPoints < baseAction.ActionPointsCost) continue; //Enemy cannot afford this action if (bestEnemyAIAction == null) { bestEnemyAIAction = baseAction.GetBestEnemyAIAction(); bestBaseAction = baseAction; } else { EnemyAIAction testEnemyAIAction = baseAction.GetBestEnemyAIAction(); if (testEnemyAIAction == null || testEnemyAIAction.ActionValue <= bestEnemyAIAction.ActionValue) continue; bestEnemyAIAction = testEnemyAIAction; bestBaseAction = baseAction; } } if (bestEnemyAIAction != null && enemyUnit.TrySpendActionPointsToTakeAction(bestBaseAction)) { bestBaseAction.TakeAction(bestEnemyAIAction.GridPosition, onEnemyAIActionComplete); return true; } else { return false; } } }