protected void RunNextAction()
        {
            if (m_currentGoal == null || m_currentAction != null)
            {
                return;
            }
            var goalActions = m_currentGoal.GetPlan();

            if (goalActions.Count > 0)
            {
                IGoapAction nextAction = goalActions.Dequeue();
                m_currentAction = nextAction;
                m_currentAction.OnBegin(m_currentGoal.GetGoalState(this));
            }
            else
            {
                CompleteCurrentGoal();
                CalculateGoal();
            }
        }
Esempio n. 2
0
        public IGoapGoal Plan(IGoapAgent agent)
        {
            m_agent       = agent;
            m_currentGoal = null;

            List <IGoapGoal> possibleGoals = GetPossibleGoals(agent);

            if (possibleGoals.Count == 0)
            {
                GoapLogger.LogWarning("[ReGoapPlanner] Agent does not have any Goals to perform. " + m_agent.GetName());
            }

            while (possibleGoals.Count > 0)
            {
                m_currentGoal = possibleGoals[possibleGoals.Count - 1];
                possibleGoals.RemoveAt(possibleGoals.Count - 1);

                if (CanFullfillWithActions(m_agent, m_currentGoal) == false)
                {
                    //No actions can't handle this goal
                    GoapLogger.LogWarning("GoalPlanner :: No Actions to handle Goal (" + m_currentGoal.GetName() + ")");
                    m_currentGoal = null;
                    continue;
                }


                GoapState targetState = m_currentGoal.GetGoalState(agent);

                GoapNode <GoapState> leaf = (GoapNode <GoapState>)m_aStar.Run(GoapNode <GoapState> .Instantiate(this, targetState, null, null), targetState);

                if (leaf == null)
                {
                    GoapLogger.LogWarning("GoapPlanner :: Pathfinding failed!");
                    m_currentGoal = null;
                    continue;
                }

                Queue <IGoapAction> actions = leaf.CalculatePath();
                if (actions.Count == 0)
                {
                    GoapLogger.LogWarning("GoapPlanner :: Calculating Path failed!");
                    m_currentGoal = null;
                    continue;
                }

                m_currentGoal.SetPlan(actions);
                break;
            }

            if (m_currentGoal != null)
            {
                GoapLogger.Log(string.Format("[ReGoapPlanner] Calculated plan for goal '{0}', plan length: {1}", m_currentGoal, m_currentGoal.GetPlan().Count));
            }
            else
            {
                GoapLogger.LogWarning("[ReGoapPlanner] Error while calculating plan.");
            }

            return(m_currentGoal);
        }
Esempio n. 3
0
        public IGoapGoal <T, W> Plan(IGoapAgent <T, W> agent, IGoapGoal <T, W> blacklistGoal = null, Queue <GoapActionState <T, W> > currentPlan = null, Action <IGoapGoal <T, W> > callback = null)
        {
            if (GoapLogger.Level == GoapLogger.DebugLevel.Full)
            {
                GoapLogger.Log("[ReGoalPlanner] Starting planning calculation for agent: " + agent);
            }
            goapAgent   = agent;
            Calculated  = false;
            currentGoal = null;
            var possibleGoals = new List <IGoapGoal <T, W> >();

            foreach (var goal in goapAgent.GetGoalsSet())
            {
                if (goal == blacklistGoal)
                {
                    continue;
                }
                goal.Precalculations(this);
                if (goal.IsGoalPossible())
                {
                    possibleGoals.Add(goal);
                }
            }
            possibleGoals.Sort((x, y) => x.GetPriority().CompareTo(y.GetPriority()));

            var currentState = agent.GetMemory().GetWorldState();

            while (possibleGoals.Count > 0)
            {
                currentGoal = possibleGoals[possibleGoals.Count - 1];
                possibleGoals.RemoveAt(possibleGoals.Count - 1);
                var goalState = currentGoal.GetGoalState();

                // can't work with dynamic actions, of course
                if (!settings.UsingDynamicActions)
                {
                    var wantedGoalCheck = currentGoal.GetGoalState();
                    GoapActionStackData <T, W> stackData;
                    stackData.agent        = goapAgent;
                    stackData.currentState = currentState;
                    stackData.goalState    = goalState;
                    stackData.next         = null;
                    stackData.settings     = null;
                    // we check if the goal can be archived through actions first, so we don't brute force it with A* if we can't
                    foreach (var action in goapAgent.GetActionsSet())
                    {
                        action.Precalculations(stackData);
                        if (!action.CheckProceduralCondition(stackData))
                        {
                            continue;
                        }
                        // check if the effects of all actions can archieve currentGoal
                        var previous = wantedGoalCheck;
                        wantedGoalCheck = GoapState <T, W> .Instantiate();

                        previous.MissingDifference(action.GetEffects(stackData), ref wantedGoalCheck);
                    }
                    // finally push the current world state
                    var current = wantedGoalCheck;
                    wantedGoalCheck = GoapState <T, W> .Instantiate();

                    current.MissingDifference(GetCurrentAgent().GetMemory().GetWorldState(), ref wantedGoalCheck);
                    // can't validate goal
                    if (wantedGoalCheck.Count > 0)
                    {
                        currentGoal = null;
                        continue;
                    }
                }

                goalState = goalState.Clone();
                var leaf = (GoapNode <T, W>)astar.Run(
                    GoapNode <T, W> .Instantiate(this, goalState, null, null, null), goalState, settings.MaxIterations, settings.PlanningEarlyExit, debugPlan: settings.DebugPlan);
                if (leaf == null)
                {
                    currentGoal = null;
                    continue;
                }

                var result = leaf.CalculatePath();
                if (currentPlan != null && currentPlan == result)
                {
                    currentGoal = null;
                    break;
                }
                if (result.Count == 0)
                {
                    currentGoal = null;
                    continue;
                }
                currentGoal.SetPlan(result);
                break;
            }
            Calculated = true;

            callback?.Invoke(currentGoal);

            if (currentGoal != null)
            {
                GoapLogger.Log(string.Format("[ReGoapPlanner] Calculated plan for goal '{0}', plan length: {1}", currentGoal, currentGoal.GetPlan().Count));
                if (GoapLogger.Level == GoapLogger.DebugLevel.Full)
                {
                    int i = 0;
                    GoapActionStackData <T, W> stackData;
                    stackData.agent        = agent;
                    stackData.currentState = currentState;
                    stackData.goalState    = currentGoal.GetGoalState();
                    stackData.next         = null;
                    foreach (var action in currentGoal.GetPlan())
                    {
                        stackData.settings = action.Settings;
                        GoapLogger.Log(string.Format("[ReGoapPlanner] {0}) {1}", i++, action.Action.ToString(stackData)));
                    }
                }
            }
            else
            {
                GoapLogger.LogWarning("[ReGoapPlanner] Error while calculating plan.");
            }
            return(currentGoal);
        }