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; } } } } } }
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; } } } }
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); }
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"); }
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); }