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); }
public bool CanRunAction(IGoapAgent agent, IGoapAction action) { action.OnPrepare(agent); if (action.ValidateContextPreconditions() == false) { return(false); } return(true); }
private List <IGoapGoal> GetPossibleGoals(IGoapAgent agent) { List <IGoapGoal> possibleGoals = new List <IGoapGoal>(); foreach (IGoapGoal goal in agent.GetGoals()) { if (CanRunGoal(agent, goal)) { possibleGoals.Add(goal); } } possibleGoals.Sort((x, y) => x.GetPriority().CompareTo(y.GetPriority())); return(possibleGoals); }
private bool CanFullfillWithActions(IGoapAgent agent, IGoapGoal goal) { GoapState goalState = goal.GetGoalState(agent).Clone(); foreach (IGoapAction action in agent.GetActions()) { if (CanRunAction(agent, action) == false) { continue; } goalState.RemoveCompletedConditions(action.GetContextPostEffects(goalState));; } goalState.RemoveCompletedConditions(m_agent.GetMemory().GetWorldState()); if (goalState.Count > 0) { return(false); } return(true); }
public bool CanRunGoal(IGoapAgent agent, IGoapGoal goal) { if (agent.GetCurrentGoal() == goal) { return(false); } if (goal.CanRun(agent) == false) { return(false); } GoapState differenceState = goal.GetGoalState(agent).Clone(); differenceState.RemoveCompletedConditions(m_agent.GetMemory().GetWorldState()); if (differenceState.Count == 0) { return(false); } return(true); }
public List <INode <GoapState> > GetNeighbours() { m_expandList.Clear(); IGoapAgent agent = m_planner.GetAgent(); List <IGoapAction> actions = agent.GetActions(); for (int i = actions.Count - 1; i >= 0; i--) { IGoapAction possibleAction = actions[i]; if (possibleAction == m_action) { continue; } if (GoapPlannerManager.s_Instance.GetPlanner().CanRunAction(agent, possibleAction) == false) { continue; } GoapState preConditions = possibleAction.GetContextPreConditions(m_targetState); GoapState postEffects = possibleAction.GetContextPostEffects(m_targetState); bool isValid = (postEffects.HasAny(m_targetState)) && (!m_targetState.HasAnyConflict(preConditions)) && (!m_targetState.HasAnyConflict(postEffects)); if (isValid) { GoapState targetState = m_targetState; m_expandList.Add(Instantiate(m_planner, targetState, this, possibleAction)); } } return(m_expandList); }
public override void OnPrepare(IGoapAgent agent) { m_isInitialized = false; base.OnPrepare(agent); }
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); }
public virtual void OnPrepare(IGoapAgent agent) { m_agent = agent; }
public virtual bool CanRun(IGoapAgent agent) { return(true); }
public virtual GoapState GetGoalState(IGoapAgent agent) { return(m_goalState); }