Example #1
0
    public void Update()
    {
        if (current == AgentState.IDLE)
        {
            //Transizione a PLANNING: se l'agente ha un task obiettivo non completato, o non esiste una condizione obiettivo, ma il manager delle azioni è comunque in stato STOP

            if (agent.goal.methods.Count > 0 && !agent.goal.completed && (Time.frameCount % 60 == 0 || Time.frameCount == 1))
            {
                current = AgentState.PLANNING;
            }

            //Transizione a EXECUTING: se il manager delle azioni è in stato EXECUTE
            else if (agent.actionManager.state == ManagerState.EXECUTE)
            {
                current = AgentState.EXECUTING;
            }

            else if (agent.actionManager.state == ManagerState.PAUSE)
            {
                PrimitiveTask currentTask = (PrimitiveTask)agent.actionManager.currentAction;

                foreach (CuncurrentTask cuncurrent in currentTask.cuncurrentTasks)
                {
                    if (!currentTask.CheckCuncurrency(cuncurrent, agent))
                    {
                        return;
                    }
                }

                agent.actionManager.Resume();
            }
        }
        else if (current == AgentState.PLANNING)
        {
            /*In this state, agent plans to goal
             * Transition to EXECUTING : if agent has a plan towards goal (not empty actions list)
             * Transizion to IDLE: agent has no plan towards goal (empty actions list)*/


            //Generate or fix plan
            List <Task> tasks = new List <Task>();

            //If manager has stopped with INVALID state, fix plan and get a new plan
            if (agent.actionManager.state == ManagerState.INVALID)
            {
                //Climb the hierarchy and get the first valid node
                CompoundTask validNode = Planner.GetValidNode((PrimitiveTask)agent.actionManager.currentAction, agent.state);

                tasks.Add(validNode);


                //Generate first segment of fixed plan, planning from the node found

                List <PrimitiveTask> firstSegment = Planner.GeneratePlan(tasks, agent);

                if (firstSegment.Count > 0)
                {
                    //Get second segment from the current plan, deleting tasks who have node found as father or forefather
                    List <PrimitiveTask> secondSegment = new List <PrimitiveTask>();

                    foreach (PrimitiveTask task in agent.plan)
                    {
                        if (!task.IsMyForeFather(validNode) && !task.completed)
                        {
                            secondSegment.Add(task);
                        }
                    }

                    //Fix the plan concatenating first segment with second segment
                    agent.plan = firstSegment.Concat(secondSegment).ToList <PrimitiveTask>();
                }

                //No plan..
                else
                {
                    agent.plan = new List <PrimitiveTask>();

                    //If agent is a member of a group, notify it to the leader, who will stop execution of global plan
                    agent.communicationSystem.sendMessage(new Message(agent.leader, MessageContent.ORDER_FAILURE));
                }
            }

            //Otherwise generate plan
            else
            {
                tasks.Add(agent.goal);

                agent.plan = Planner.GeneratePlan(tasks, agent);
            }


            if (agent.plan != null)
            {
                foreach (IGroundAction action in agent.plan)
                {
                    agent.actionManager.ScheduleAction(action);
                }

                agent.actionManager.NextAction();

                current = AgentState.EXECUTING;

                agent.actionManager.state = ManagerState.EXECUTE;
            }
            else
            {
                agent.actionManager.state = ManagerState.STOP;

                current = AgentState.IDLE;
            }
        }
        else if (current == AgentState.EXECUTING)
        {
            //Dentro lo stato: esecuzione azione corrente del piano
            //Transizione a IDLE : se il piano è completato con successo, oppure il manager delle azioni è andato in pausa
            //Transizione a PLANNING : se il piano non è valido (precondizioni azione non valide)

            agent.actionManager.RunCurrentAction();

            if (agent.actionManager.state == ManagerState.EMPTY)
            {
                current = AgentState.IDLE;

                agent.actionManager.state = ManagerState.STOP;

                agent.goal.completed = true;
            }
            else if (agent.actionManager.state == ManagerState.INVALID)
            {
                current = AgentState.PLANNING;
            }

            else if (agent.actionManager.state == ManagerState.PAUSE)
            {
                current = AgentState.IDLE;
            }
        }
    }