IEnumerator ManageGoals() { while (goalDirectory.GoalList.Count() > 0) { currentGoal = null; foreach (Goal g in goalDirectory.GoalList) { if (g.IsSatisfied()) { if (g.Type == GoalType.Pursuit) { Testing.WriteToLog(transform.name, transform.name + " achieved goal: " + g.Name); goalDirectory.RemoveGoal(g); } else if (g.Type == GoalType.Interest && !g.Dormant) { Testing.WriteToLog(transform.name, transform.name + " achieved goal: " + g.Name); g.Dormant = true; } yield return(new WaitForSeconds(manager.GetRandomInt(2, 8))); } else { currentGoal = g; if (currentGoal.Type == GoalType.Interest) { currentGoal.Dormant = false; } break; } } //if the goal isn't satisifed then check if the goal has a plan associated with it. if (currentGoal != null) { if (currentGoal.TimesFailed >= Goal.MaxFail) { currentGoal.ClearFailedActions(); } //If the goal hasn't got a plan then let's create one! if (currentGoal.Plan == null) { Testing.WriteToLog(transform.name, transform.name + " is evaluating " + Testing.GetGoalInfo(currentGoal)); //create a plan // Create a LinkedList to store the plans and populate it. PlanList planList = new PlanList(); CreatePlans(currentGoal, currentGoal.TargetCharacter, currentGoal.SuccessCondition, planList, new Plan(), currentGoal.FailedActions); // If there are no plans in the collection then the goal is already satisifed or its impossible to reach. if (planList.Count() < 1) { // Set the goal to complete and it will be removed from the collection the next time Update() is run. currentGoal.Complete = true; Testing.WriteToLog(transform.name, transform.name + " cancelled goal: " + currentGoal.Name + " because a plan is impossible to make."); currentGoal.ClearFailedActions(); Testing.WriteToLog(transform.name, "Clearing previously failed action list in attempt to satisfy goal..."); } // If we successfully constructed one or more plans then we need to pick one for the agent to use. else { Testing.WriteToLog(transform.name, transform.name + " created at least one plan for goal: " + currentGoal.Name); //pick a plan from List<LinkedList<Action>> plans and assign to g.plan currentGoal.SetPlan(planList.GetBestPlan(manager, actionQueue, GetComponent <MemoryManager>(), transform)); Testing.WriteToLog(transform.name, transform.name + " nominated a best plan for goal: " + currentGoal.Name + ":"); Testing.WriteToLog(transform.name, Testing.GetPlanInfo(currentGoal.Plan)); } } // if the goal has got a plan... else { //manage its execution Plan plan = currentGoal.Plan; Action currentAction = plan.GetCurrentAction(); if (currentAction != null) { switch (currentAction.Status) { case Status.notSent: currentAction.SetStatus(Status.Sent); Testing.WriteToLog(transform.name, transform.name + " is queueing action: " + Testing.GetActionInfo(currentAction)); actionQueue.QueueAction(currentAction); break; case Status.Resend: currentAction.SetStatus(Status.ResendSent); actionQueue.QueueAction(currentAction); break; case Status.Failed: //action repair currentGoal.TimesFailed++; Testing.WriteToLog(transform.name, transform.name + " failed action: " + Testing.GetActionInfo(currentAction)); currentAction.SetStatus(Status.notSent); currentGoal.AddFailedAction(new Action(currentAction)); currentGoal.SetPlan(null); Testing.WriteToLog(transform.name, transform.name + " is replanning: " + Testing.GetGoalInfo(currentGoal)); yield return(new WaitForSeconds(manager.GetRandomInt(1, 3))); break; case Status.Successful: Testing.WriteToLog(transform.name, transform.name + " succeeded action: " + Testing.GetActionInfo(currentAction)); currentAction.SetStatus(Status.notSent); plan.RemoveAction(currentAction); yield return(new WaitForSeconds(manager.GetRandomInt(1, 3))); break; } } else { currentGoal.SetPlan(null); } } } yield return(null); } }