public static void BuildGraph(this AIContext context)
    {
        var goapAction = context.GetGroup(AIMatcher.AllOf(AIMatcher.GoapCondition, AIMatcher.GoapEffect, AIMatcher.GoapAction));
        var entities   = goapAction.GetEntities();

        foreach (var e in entities)
        {
            context.BuildGraphBranch(null, entities, e.goapEffect.value);
        }
    }
    public IEnumerator <int> Plan(AIContext context, IGoapState <string, object> goalState)
    {
        var goapAction = context.GetGroup(AIMatcher.AllOf(AIMatcher.GoapNodeChildren, AIMatcher.GoapEffect, AIMatcher.GoapAction));

        var IDList = Search(context, goapAction.GetEntities(), goalState);

        if (IDList == null || IDList.Count == 0)
        {
            return(null);
        }

        var RIDList = IDList.Reverse().ToList();

        return(RIDList.GetEnumerator());
    }
    public GoapPlannerSystems(Contexts contexts) : base(contexts)
    {
        var AIContext = contexts.aI;

        /* INITIALIZE GRAPH. */
        AddInitialize(() =>
        {
            AIContext.BuildGraph();
        });

        /* CREATE PLAN. */
        AddReactEach(AIMatcher.GoapPlanRequest, (e) => e.isGoapAgent && e.hasGoapPlanner && e.hasGoapWorldState && e.hasGoapGoalState && !e.hasGoapPlan, (e) =>
        {
            e.isGoapPlanRequest = false;
            var enumerator      = e.goapPlanner.value.Plan(AIContext, e.goapGoalState.value);
            if (enumerator != null)
            {
#if DEBUG
                var list = (e.hasGoapPlanDebug) ? e.goapPlanDebug.value : new List <int> ();
                list.Clear();
                while (enumerator.MoveNext())
                {
                    list.Add(enumerator.Current);
                }
                enumerator.Reset();
                e.ReplaceGoapPlanDebug(list);
#endif

                enumerator.MoveNext();
                e.AddGoapPlan(enumerator);
            }
        });

        var goapAgentWithPlan = contexts.aI.GetGroup(AIMatcher.AllOf(AIMatcher.GoapAgent, AIMatcher.GoapPlan));

        /* RUN PLAN. */
        AddExecute(() =>
        {
            foreach (var e in goapAgentWithPlan.GetEntities())
            {
                var ID          = e.goapPlan.value.Current;
                var AIEntity    = AIContext.GetEntityWithID(ID);
                var actionState = AIEntity.goapAction.value();
                if (actionState == GoapActionStatus.Active)
                {
                    continue;
                }
                else if (actionState == GoapActionStatus.Fail)
                {
                    e.RemoveGoapPlan();
                    e.isGoapPlanRequest = true;
                    continue;
                }

                if (!e.goapPlan.value.MoveNext())
                {
                    e.RemoveGoapPlan();
                    e.isGoapPlanRequest = true;
                    continue;
                }
            }
        });
    }