private void UpdateInterruption()
        {
            //Check for higher priority goals becoming available
            if (m_currentAction != null)
            {
                if (m_currentAction.CanInterrupt())
                {
                    foreach (IGoapGoal goal in m_agentGoals)
                    {
                        if (goal.GetName() != m_currentGoal.GetName())
                        {
                            bool canRun = GoapPlannerManager.s_Instance.GetPlanner().CanRunGoal(this, goal);

                            if (canRun)
                            {
                                if (m_currentGoal == null || m_currentGoal.GetPriority() > goal.GetPriority())
                                {
                                    continue;
                                }


                                GoapLogger.LogWarning("BaseGoapAgent :: " + goal.GetName() + " interrupted goal " +
                                                      m_currentGoal.GetName());

                                RecalculateGoal();

                                break;
                            }
                        }
                    }
                }
            }
        }
Example #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);
        }
        private void FailCurrentGoal()
        {
            GoapLogger.LogWarning("BaseGoapAgent :: Goal Failed " + m_currentGoal.GetName());
            if (m_currentGoal != null)
            {
                m_currentGoal.OnFailed();
                m_currentGoal = null;
            }

            InterruptCurrentAction();
        }
        private void UpdateGoals(float delta)
        {
            if (m_currentGoal == null)
            {
                if (m_currentGoalReAttemptTime < m_goalReAttemptTime)
                {
                    m_currentGoalReAttemptTime += delta;
                }
                else
                {
                    CalculateGoal();
                    return;
                }
            }
            else
            {
                //TODO : GetGoalRelevance?
                // if (m_currentGoal.ValidateGoal(this) == false)
                // {
                //     GoapLogger.LogWarning("BaseGoapAgent :: Current goal validation failed! > " + m_currentGoal.GetName() + " info: " + m_currentGoal.GetValidationReason());
                //     RecalculateGoal();
                //     return;
                // }

                IGoapAction[] currentActions = m_currentGoal.GetPlan().ToArray();
                //Check if actions are still valid
                for (int i = 0; i < currentActions.Length; i++)
                {
                    if (currentActions[i].ValidateAction() == false)
                    {
                        GoapLogger.LogWarning("BaseGoapAgent :: Current action validation failed! > " +
                                              currentActions[i].GetName() + " info: " +
                                              currentActions[i].GetValidationReason());
                        FailCurrentGoal();
                        return;
                    }
                }
            }
        }
Example #5
0
        public INode <T> Run(INode <T> start, T goal, int maxIterations = 100, bool earlyExit = true, bool clearNodes = true, bool debugPlan = false)
        {
            frontier.Clear();
            stateToNode.Clear();
            explored.Clear();
            if (clearNodes)
            {
                ClearNodes();
                createdNodes.Add(start);
            }

            frontier.Enqueue(start, start.GetCost());


            var iterations = 0;

            while ((frontier.Count > 0) && (iterations < maxIterations) && (frontier.Count + 1 < frontier.MaxSize))
            {
                var node = frontier.Dequeue();
                if (node.IsGoal(goal))
                {
                    GoapLogger.Log("[Astar] Success iterations: " + iterations);
                    return(node);
                }
                explored[node.GetState()] = node;


                foreach (var child in node.Expand())
                {
                    iterations++;
                    if (clearNodes)
                    {
                        createdNodes.Add(child);
                    }
                    if (earlyExit && child.IsGoal(goal))
                    {
                        GoapLogger.Log("[Astar] (early exit) Success iterations: " + iterations);
                        return(child);
                    }
                    var childCost = child.GetCost();
                    var state     = child.GetState();
                    if (explored.ContainsKey(state))
                    {
                        continue;
                    }
                    INode <T> similiarNode;
                    stateToNode.TryGetValue(state, out similiarNode);
                    if (similiarNode != null)
                    {
                        if (similiarNode.GetCost() > childCost)
                        {
                            frontier.Remove(similiarNode);
                        }
                        else
                        {
                            break;
                        }
                    }

                    //Utilities.ReGoapLogger.Log(string.Format("    Enqueue frontier: {0}, cost: {1}", child.Name, childCost));
                    frontier.Enqueue(child, childCost);
                    stateToNode[state] = child;
                }
            }
            GoapLogger.LogWarning("[Astar] failed.");
            return(null);
        }
Example #6
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);
        }
 private void OnCalculateGoalFailed()
 {
     GoapLogger.Log("BaseGoapAgent :: No Goal found for " + GetName() + " > 'Give me something to do!'");
 }
 private void OnGoalFailed()
 {
     GoapLogger.Log("BaseGoapAgent :: Goal Failed " + m_currentAction.GetName());
 }
 private void OnActionFailed(object sender, EventArgs args)
 {
     GoapLogger.Log("BaseGoapAgent :: Action Failed (" + m_currentAction.GetName() + " )");
     InterruptCurrentAction();
     RecalculateGoal();
 }
 private void OnActionCompleted(object sender, EventArgs args)
 {
     GoapLogger.Log("BaseGoapAgent :: Action Complete (" + m_currentAction.GetName() + " )");
     FinishCurrentAction();
 }
 public virtual void OnBegin(GoapState goalState)
 {
     GoapLogger.Log("BaseGoapAction :: " + GetName() + " has begun.");
 }
 public virtual void OnInterrupted()
 {
     GoapLogger.Log("BaseGoapAction :: " + GetName() + " was interrupted");
 }
Example #13
0
        public INode <T> Run(INode <T> start, T goal, int maxIterations = 100, bool earlyExit = true, bool clearNodes = true)
        {
            m_frontier.Clear();
            m_exploredNodes.Clear();
            m_stateToNode.Clear();

            if (clearNodes)
            {
                ClearNodes();
                m_createdNodes.Add(start);
            }

            m_frontier.Enqueue(start, start.GetCost());

            var iterations = 0;

            while (m_frontier.Count > 0 && (iterations < maxIterations) && ((m_frontier.Count + 1) < m_frontier.MaxSize))
            {
                iterations++;

                if (iterations == maxIterations)
                {
                    GoapLogger.LogWarning("AStar :: Hit Max Iterations!");
                }

                var node = m_frontier.Dequeue();

                if (node.IsGoal(goal))
                {
                    if (node == start)
                    {
                        GoapLogger.Log("AStar :: Start Node was End Node!");
                    }

                    return(node);
                }

                m_exploredNodes[node.GetState()] = node;

                foreach (var child in node.GetNeighbours())
                {
                    if (clearNodes)
                    {
                        m_createdNodes.Add(child);
                    }

                    if (earlyExit && child.IsGoal(goal))
                    {
                        return(child);
                    }

                    float childCost  = child.GetCost();
                    T     childState = child.GetState();

                    if (m_exploredNodes.ContainsKey(childState))
                    {
                        continue;
                    }

                    INode <T> similarNode;
                    m_stateToNode.TryGetValue(childState, out similarNode);

                    if (similarNode != null)
                    {
                        if (similarNode.GetCost() > childCost)
                        {
                            m_frontier.Remove(similarNode);
                        }
                        else
                        {
                            break;
                        }
                    }

                    m_frontier.Enqueue(child, childCost);
                    m_stateToNode[childState] = child;
                }
            }

            return(null);
        }