diff --git a/Assets/Scripts/NPC/NPCBrainSystem/DecisionTypes/NPCDecision.cs b/Assets/Scripts/NPC/NPCBrainSystem/DecisionTypes/NPCDecision.cs index 9ed38438..89b6c457 100644 --- a/Assets/Scripts/NPC/NPCBrainSystem/DecisionTypes/NPCDecision.cs +++ b/Assets/Scripts/NPC/NPCBrainSystem/DecisionTypes/NPCDecision.cs @@ -14,4 +14,6 @@ public abstract class NPCDecision : ScriptableObject public abstract void Interrupt(NPCBrain npc); public bool IsRunning() => executeRoutine != null; + + public abstract bool IsPossibleToExecute(NPCBrain npc); } \ No newline at end of file diff --git a/Assets/Scripts/NPC/NPCBrainSystem/DecisionTypes/NPCPatrolDecision.cs b/Assets/Scripts/NPC/NPCBrainSystem/DecisionTypes/NPCPatrolDecision.cs index aad4c0f6..938db701 100644 --- a/Assets/Scripts/NPC/NPCBrainSystem/DecisionTypes/NPCPatrolDecision.cs +++ b/Assets/Scripts/NPC/NPCBrainSystem/DecisionTypes/NPCPatrolDecision.cs @@ -66,4 +66,8 @@ public class NPCPatrolDecision : NPCDecision agent = npc.Agent; } + public override bool IsPossibleToExecute(NPCBrain npc) + { + return !npc.IsDead() && !npc.IsCasting(); + } } diff --git a/Assets/Scripts/NPC/NPCBrainSystem/NPCBrain.cs b/Assets/Scripts/NPC/NPCBrainSystem/NPCBrain.cs index b738fb0e..dea70be2 100644 --- a/Assets/Scripts/NPC/NPCBrainSystem/NPCBrain.cs +++ b/Assets/Scripts/NPC/NPCBrainSystem/NPCBrain.cs @@ -2,15 +2,30 @@ using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; +using UnityEngine.Events; public class NPCBrain : MonoBehaviour { [Header("Decision Profile")] [SerializeField] private NPCDecisionProfile decisionProfile; + NPCDecisionPriority currentlyExecutingDecision; + bool isDead; + BaseAbility currentlyQueuedAbility; + bool isCasting; + NavMeshAgent agent; public NavMeshAgent Agent => agent; + + public UnityEvent OnDecisionFinishedExecuting = new UnityEvent(); + + private void Awake() + { + isDead = false; + isCasting = false; + } + private void Start() { StartCoroutine(Decide()); @@ -18,7 +33,39 @@ public class NPCBrain : MonoBehaviour IEnumerator Decide() { - yield return null; + decisionProfile.decisions.Sort((decisionA, decisionB) => decisionB.priority.CompareTo(decisionA.priority)); + + foreach (NPCDecisionPriority decisionPriority in decisionProfile.decisions) + { + yield return null; + + if (currentlyExecutingDecision != null) + if (currentlyExecutingDecision.priority >= decisionPriority.priority) continue; + + if (!decisionPriority.decision.IsPossibleToExecute(this)) continue; + + currentlyExecutingDecision = decisionPriority; + StartCoroutine(Execute(currentlyExecutingDecision)); + } + } + + IEnumerator Execute(NPCDecisionPriority decisionPriority) + { + decisionPriority.decision.Execute(this); + + yield return new WaitUntil(() => decisionPriority.decision.IsRunning()); + + OnDecisionFinishedExecuting.Invoke(); + } + + public bool IsCasting() + { + return currentlyQueuedAbility != null ? !currentlyQueuedAbility.castableWhileMoving : isCasting; + } + + public bool IsDead() + { + return isDead; } }