/// <summary> /// Gets the possible action branches that arrive at the goals required state. /// </summary> /// <param name="goal"></param> /// <returns></returns> List <GoapNode> GetGoalTree(GoapGoal goal) { List <GoapNode> EndNodes = new List <GoapNode>(); GoapNode RootNode = new GoapNode(null, 0, goal.RequiredWorldState, null); // check if the world state already matches this goal. if (TestGoalStateAgainstWorldState(goal)) { return(new List <GoapNode>()); } List <GoapAction> ImmedeateActions = GetGoalActions(goal); foreach (GoapAction action in ImmedeateActions) { // test each immediate action's pre-requisite states against the world states. if (TestActionAgainstWorldState(action)) { EndNodes.Add(new GoapNode(RootNode, RootNode.CumulativeCost + action.Cost, action.SatisfiesStates, action)); } else { // recurse through this action's state requirements until it either matches the world state or has no prerequisites. EndNodes.AddRange(GetActionTree(action, new GoapNode(RootNode, RootNode.CumulativeCost + action.Cost, action.SatisfiesStates, action))); } } return(EndNodes); }
// Returns a list of actions (from the available actions) that satisfy one or all of our goals required states. List <GoapAction> GetGoalActions(GoapGoal goal) { List <GoapAction> ReturnActions = new List <GoapAction>(); foreach (GoapState state in goal.RequiredWorldState) { foreach (GoapAction action in AvailableActions) { if (action.CanActionRun()) { for (int i = 0; i < action.SatisfiesStates.Count; ++i) { if (GoapState.Compare(state, action.SatisfiesStates[i])) { ReturnActions.Add(action); } } } } } return(ReturnActions); }
// test to see if our current world state matches that of our goals required states. bool TestGoalStateAgainstWorldState(GoapGoal goal) { bool GoalStatesMatch = true; foreach (GoapState goalState in goal.RequiredWorldState) { bool currentStateCheck = false; foreach (GoapState worldState in CurrentWorldState) { if (GoapState.Compare(worldState, goalState)) { currentStateCheck = true; } } if (!currentStateCheck) { GoalStatesMatch = false; break; } } return(GoalStatesMatch); }