public IReGoapGoal Plan(IReGoapAgent agent, IReGoapGoal blacklistGoal = null, Queue <ReGoapActionState> currentPlan = null, Action <IReGoapGoal> callback = null) { ReGoapLogger.Log("[ReGoalPlanner] Starting planning calculation for agent: " + agent); goapAgent = agent; Calculated = false; currentGoal = null; var possibleGoals = new List <IReGoapGoal>(); foreach (var goal in goapAgent.GetGoalsSet()) { if (goal == blacklistGoal) { continue; } goal.Precalculations(this); if (goal.IsGoalPossible()) //goal.GetPriority() > bestPriority && { possibleGoals.Add(goal); } } possibleGoals.Sort((x, y) => x.GetPriority().CompareTo(y.GetPriority())); while (possibleGoals.Count > 0) { currentGoal = possibleGoals[possibleGoals.Count - 1]; possibleGoals.RemoveAt(possibleGoals.Count - 1); var goalState = currentGoal.GetGoalState(); var leaf = (BGoapNode)astar.Run( new BGoapNode(this, goalState, null, null), goapAgent.GetMemory().GetWorldState(), settings.MaxIterations, settings.PlanningEarlyExit); if (leaf == null) { currentGoal = null; continue; } var path = leaf.CalculatePath(); if (currentPlan != null && currentPlan == path) { currentGoal = null; break; } currentGoal.SetPlan(path); break; } Calculated = true; if (callback != null) { callback(currentGoal); } if (currentGoal != null) { ReGoapLogger.Log(string.Format("[ReGoapPlanner] Calculated plan for goal '{0}', plan length: {1}", currentGoal, currentGoal.GetPlan().Count)); } else { ReGoapLogger.LogWarning("[ReGoapPlanner] Error while calculating plan."); } return(currentGoal); }
public override bool IsGoalPossible() { var state = agent.GetMemory().GetWorldState(); if (state.HasKey($"Has Role {type}")) { return((bool)state.Get($"Has Role {type}")); } return(false); }
protected override IEnumerable <BGoapState> GetPossibleGenericVariableCombinations(IReGoapAgent goapAgent) { foreach (SmartObject so in (goapAgent.GetMemory() as GoapMemory).GetAvailableSoList()) { if (so is RPGSOTable) { BGoapState resultState = new BGoapState(); resultState.Set(table, so); yield return(resultState); } } }
protected override IEnumerable <BGoapState> GetPossibleVariableCombinations(BGoapState lockInValues, IReGoapAgent goapAgent, BGoapState genericAssignments) { if (lockInValues.HasKey(itemVariable) && lockInValues.Get(itemVariable) == null) //this should be handled by place/drop item { yield break; } if (lockInValues.HasKey(itemVariable) && lockInValues.HasKey(itemTypeVariable)) //both item type and specific item are locked in { if (lockInValues.Get(itemVariable).sourceItem == lockInValues.Get(itemTypeVariable)) //check that this combination is valid { BGoapState assignment = new BGoapState(); assignment.Set(locationVariable, lockInValues.Get(itemVariable).positionCache); yield return(assignment); } } else if (lockInValues.HasKey(itemVariable) && lockInValues.Get(itemVariable) != null) //specific item locked in, fill in it's values { BGoapState assignment = new BGoapState(); assignment.Set(itemTypeVariable, lockInValues.Get(itemVariable).sourceItem); assignment.Set(locationVariable, lockInValues.Get(itemVariable).positionCache); yield return(assignment); } else if (lockInValues.HasKey(itemTypeVariable)) //item type locked in, fill in all possible items { DBItem requiredItemType = lockInValues.Get(itemTypeVariable); foreach (InGameItem item in (goapAgent.GetMemory() as GoapMemory).GetAvailableItemList()) { if (item.sourceItem == requiredItemType) { BGoapState assignment = new BGoapState(); assignment.Set(itemVariable, item); assignment.Set(locationVariable, item.positionCache); yield return(assignment); } } } yield break; }
private void UpdateGoapNodes <T, W>(IReGoapAgent <T, W> agent) { if (nodes == null) { nodes = new List <ReGoapNodeEditor>(); } if (agentHelper == null || agent == null || !agent.IsActive() || agent.GetMemory() == null) { return; } nodes.Clear(); var width = 300f; var height = 70f; var nodePosition = new Vector2(0f, 60f); var nodeMiddleY = new Vector2(0f, height * 0.5f); ReGoapNodeEditor?previousNode = null; foreach (var goal in agent.GetGoalsSet()) { if (goal.GetGoalState() == null) { continue; } var text = string.Format("<b>GOAL</b> <i>{0}</i>\n", goal); foreach (var keyValue in goal.GetGoalState().GetValues()) { text += string.Format("<b>'{0}'</b> = <i>'{1}'</i>", keyValue.Key, keyValue.Value); } var style = nodeStyle; if (agent.IsActive() && agent.GetCurrentGoal() == goal) { style = activeStyle; } var newNode = DrawGenericNode(text, width, height, style, ref nodePosition); if (previousNode.HasValue) { var startPosition = previousNode.Value.Rect.max - nodeMiddleY - new Vector2(10f, 0f); var endPosition = newNode.Rect.min + nodeMiddleY + new Vector2(10f, 0f); Handles.DrawLine(startPosition, endPosition); } previousNode = newNode; } previousNode = null; nodePosition = new Vector2(0f, nodePosition.y + height + 10); height = 66; var maxHeight = height; var emptyGoal = agent.InstantiateNewState(); GoapActionStackData <T, W> stackData; stackData.agent = agent; stackData.currentState = agent.GetMemory().GetWorldState(); stackData.goalState = emptyGoal; stackData.next = null; stackData.settings = null; foreach (var action in agent.GetActionsSet()) { var curHeight = height; var text = string.Format("<b>POSS.ACTION</b> <i>{0}</i>\n", action.GetName()); text += "-<b>preconditions</b>-\n"; var preconditionsDifferences = agent.InstantiateNewState(); var preconditions = action.GetPreconditions(stackData); if (preconditions == null) { continue; } preconditions.MissingDifference(stackData.currentState, ref preconditionsDifferences); foreach (var preconditionPair in preconditions.GetValues()) { curHeight += 13; var color = "#004d00"; if (preconditionsDifferences.GetValues().ContainsKey(preconditionPair.Key)) { color = "#800000"; } text += string.Format("<color={2}>'<b>{0}</b>' = '<i>{1}</i>'</color>\n", preconditionPair.Key, preconditionPair.Value, color); } preconditionsDifferences.Recycle(); text += "-<b>effects</b>-\n"; foreach (var effectPair in action.GetEffects(stackData).GetValues()) { curHeight += 13; text += string.Format("'<b>{0}</b>' = '<i>{1}</i>'\n", effectPair.Key, effectPair.Value); } curHeight += 13; var proceduralCheck = action.CheckProceduralCondition(stackData); text += string.Format("<color={0}>-<b>proceduralCondition</b>: {1}</color>\n", proceduralCheck ? "#004d00" : "#800000", proceduralCheck); maxHeight = Mathf.Max(maxHeight, curHeight); nodeMiddleY = new Vector2(0f, curHeight * 0.5f); var newNode = DrawGenericNode(text, width, curHeight, possibleActionStyle, ref nodePosition); if (previousNode.HasValue) { var startPosition = previousNode.Value.Rect.max - nodeMiddleY - new Vector2(10f, 0f); var endPosition = newNode.Rect.min + nodeMiddleY + new Vector2(10f, 0f); Handles.DrawLine(startPosition, endPosition); } previousNode = newNode; } previousNode = null; nodePosition.x = 0; nodePosition.y += maxHeight + 10; height = 40; nodeMiddleY = new Vector2(0f, height * 0.5f); if (agent.GetCurrentGoal() != null) { foreach (var action in agent.GetStartingPlan().ToArray()) { var style = actionNodeStyle; if (action.Action.IsActive()) { style = activeActionNodeStyle; } var text = string.Format("<b>ACTION</b> <i>{0}</i>\n", action.Action.GetName()); var newNode = DrawGenericNode(text, width, height, style, ref nodePosition); if (previousNode.HasValue) { var startPosition = previousNode.Value.Rect.max - nodeMiddleY - new Vector2(10f, 0f); var endPosition = newNode.Rect.min + nodeMiddleY + new Vector2(10f, 0f); Handles.DrawLine(startPosition, endPosition); } previousNode = newNode; } } if (agent.GetMemory() != null) { nodePosition = new Vector2(0, nodePosition.y + height + 10); width = 500; height = 40; nodeMiddleY = new Vector2(0f, height * 0.5f); var nodeText = "<b>WORLD STATE</b>\n"; foreach (var pair in agent.GetMemory().GetWorldState().GetValues()) { nodeText += string.Format("'<b>{0}</b>' = '<i>{1}</i>'\n", pair.Key, pair.Value); height += 13; } DrawGenericNode(nodeText, width, height, worldStateStyle, ref nodePosition); } }
public IReGoapGoal <T, W> Plan(IReGoapAgent <T, W> agent, IReGoapGoal <T, W> blacklistGoal = null, Queue <ReGoapActionState <T, W> > currentPlan = null, Action <IReGoapGoal <T, W> > callback = null) { if (ReGoapLogger.Level == ReGoapLogger.DebugLevel.Full) { ReGoapLogger.Log("[ReGoalPlanner] Starting planning calculation for agent: " + agent); } goapAgent = agent; Calculated = false; currentGoal = null; var possibleGoals = new List <IReGoapGoal <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 = ReGoapState <T, W> .Instantiate(); previous.MissingDifference(action.GetEffects(stackData), ref wantedGoalCheck); } // finally push the current world state var current = wantedGoalCheck; wantedGoalCheck = ReGoapState <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 = (ReGoapNode <T, W>)astar.Run( ReGoapNode <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; if (callback != null) { callback(currentGoal); } if (currentGoal != null) { ReGoapLogger.Log(string.Format("[ReGoapPlanner] Calculated plan for goal '{0}', plan length: {1}", currentGoal, currentGoal.GetPlan().Count)); if (ReGoapLogger.Level == ReGoapLogger.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; ReGoapLogger.Log(string.Format("[ReGoapPlanner] {0}) {1}", i++, action.Action.ToString(stackData))); } } } else { ReGoapLogger.LogWarning("[ReGoapPlanner] Error while calculating plan."); } return(currentGoal); }
private void UpdateGoapNodes(GameObject gameObj) { if (agent == null || !agent.IsActive() || agent.GetMemory() == null) { return; } if (nodes == null) { nodes = new List <ReGoapNodeEditor>(); } nodes.Clear(); var width = 250f; var height = 70f; var nodePosition = Vector2.zero; foreach (var goal in gameObj.GetComponents <IReGoapGoal>()) { if (goal.GetGoalState() == null) { continue; } var text = string.Format("<b>GOAL</b> <i>{0}</i>\n", goal); foreach (var keyValue in goal.GetGoalState().GetValues()) { text += string.Format("<b>'{0}'</b> = <i>'{1}'</i>", keyValue.Key, keyValue.Value); } var style = nodeStyle; if (agent.IsActive() && agent.GetCurrentGoal() == goal) { style = activeStyle; } DrawGenericNode(text, width, height, style, ref nodePosition); } nodePosition = new Vector2(0f, nodePosition.y + height + 10); height = 66; var maxHeight = height; var worldState = agent.GetMemory().GetWorldState(); foreach (var action in agent.GetActionsSet()) { var curHeight = height; var text = string.Format("<b>POSS.ACTION</b> <i>{0}</i>\n", action.GetName()); text += "-<b>preconditions</b>-\n"; ReGoapState preconditionsDifferences = new ReGoapState(); var preconditions = action.GetPreconditions(null); if (preconditions == null) { continue; } preconditions.MissingDifference(worldState, ref preconditionsDifferences); foreach (var preconditionPair in preconditions.GetValues()) { curHeight += 13; var color = "#004d00"; if (preconditionsDifferences.GetValues().ContainsKey(preconditionPair.Key)) { color = "#800000"; } text += string.Format("<color={2}>'<b>{0}</b>' = '<i>{1}</i>'</color>\n", preconditionPair.Key, preconditionPair.Value, color); } text += "-<b>effects</b>-\n"; foreach (var effectPair in action.GetEffects(null).GetValues()) { curHeight += 13; text += string.Format("'<b>{0}</b>' = '<i>{1}</i>'\n", effectPair.Key, effectPair.Value); } curHeight += 13; var proceduralCheck = action.CheckProceduralCondition(agent, null); text += string.Format("<color={0}>-<b>proceduralCondition</b>: {1}</color>\n", proceduralCheck ? "#004d00" : "#800000", proceduralCheck); maxHeight = Mathf.Max(maxHeight, curHeight); DrawGenericNode(text, width, curHeight, possibleActionStyle, ref nodePosition); } nodePosition.x = 0; nodePosition.y += maxHeight + 10; height = 40; if (agent.GetCurrentGoal() != null) { foreach (var action in agent.GetStartingPlan().ToArray()) { var style = actionNodeStyle; if (action.Action.IsActive()) { style = activeActionNodeStyle; } var text = string.Format("<b>ACTION</b> <i>{0}</i>\n", action.Action.GetName()); DrawGenericNode(text, width, height, style, ref nodePosition); } } if (agent.GetMemory() != null) { nodePosition = new Vector2(0, nodePosition.y + height + 10); width = 500; height = 40; var nodeText = "<b>WORLD STATE</b>\n"; foreach (var pair in agent.GetMemory().GetWorldState().GetValues()) { nodeText += string.Format("'<b>{0}</b>' = '<i>{1}</i>'\n", pair.Key, pair.Value); height += 13; } DrawGenericNode(nodeText, width, height, worldStateStyle, ref nodePosition); } }