public List <PlannerNode <TKey, TValue> > GetNeighbours(PlannerNode <TKey, TValue> _baseNode) { m_NeighbourNodes.Clear(); WorldStateModifier <TKey, TValue> basePreconditions = _baseNode.Action?.GetPreconditions(); WorldState <TKey, TValue> worldStateAtBaseNode = _baseNode.GetWorldStateAtNode(); Goal <TKey, TValue> goalWorldStateAtBaseNode = _baseNode.GetGoalWorldStateAtNode(); WorldState <TKey, TValue> remainingGoals = goalWorldStateAtBaseNode - worldStateAtBaseNode; // We implement regressive A* for GOAP by chaining action preconditions to action effects until all preconditions are fulfilled. // For this planner, neighbours are nodes that fulfil any of the remaining goals of the base node without conflicting with any of its preconditions. foreach (IAction <TKey, TValue> possibleAction in m_CurrentAgent.GetActionSet()) { var effects = possibleAction.GetEffects(); if (!effects.ContainsAny(remainingGoals)) { continue; } if (effects.ConflictsAny(basePreconditions)) { continue; } PlannerNode <TKey, TValue> plannerNode = GetAvailablePlannerNode(); plannerNode.Init(possibleAction); plannerNode.CalculateWorldStateAtNode(worldStateAtBaseNode); plannerNode.CalculateGoalWorldStateAtNode(goalWorldStateAtBaseNode); bool foundInUsed = false; foreach (PlannerNode <TKey, TValue> usedNode in m_UsedNodes) { if (usedNode.Equals(plannerNode)) { plannerNode = usedNode; foundInUsed = true; break; } } m_NeighbourNodes.Add(plannerNode); if (!foundInUsed) { m_UsedNodes.Add(plannerNode); } } return(m_NeighbourNodes); }
public static void CreateNodePairForLastOpenNode <TKey, TValue>(ref PlannerNode <TKey, TValue> _lastPlannerNode, ref List <PlannerHierarchyNodePair <TKey, TValue> > _nodePairs) { var lastHierarchyNode = new HierarchyNode <TKey, TValue>( _isPartOfFoundPath: true, _executableAction: _lastPlannerNode.Action as ExecutableAction <TKey, TValue>, _goalWorldStateAtNode: _lastPlannerNode.GetGoalWorldStateAtNode(), _worldStateAtNode: _lastPlannerNode.GetWorldStateAtNode(), _isFinalNode: true, _isClosed: false); _nodePairs.Add(new PlannerHierarchyNodePair <TKey, TValue>() { PlannerNodeInstance = _lastPlannerNode, HierarchyNodeInstance = lastHierarchyNode }); }