TurnBasedStrategyCourse/Assets/Scripts/EnemyAI.cs

82 lines
2.8 KiB
C#

using System;
using System.Linq;
using Actions;
using UnityEngine;
public class EnemyAI : MonoBehaviour {
private float timer;
private State CurrentState { get; set; }
private void Awake() => 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;
}
}
private enum State {
WaitingForEnemyTurn,
TakingTurn,
Busy
}
}