public ReGoapPlanWork(IReGoapAgent <T, W> agent, IReGoapGoal <T, W> blacklistGoal, Queue <ReGoapActionState <T, W> > actions, Action <IReGoapGoal <T, W> > callback) : this()
 {
     Agent         = agent;
     BlacklistGoal = blacklistGoal;
     Actions       = actions;
     Callback      = callback;
 }
예제 #2
0
    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);
    }
예제 #3
0
 public PlanWork(IReGoapAgent agent, IReGoapGoal blacklistGoal, Queue <ReGoapActionState> actions, Action <IReGoapGoal> callback) : this()
 {
     Agent         = agent;
     BlacklistGoal = blacklistGoal;
     Actions       = actions;
     Callback      = callback;
 }
예제 #4
0
    protected virtual void OnDonePlanning(IReGoapGoal newGoal)
    {
        currentPlanWorker = null;
        if (newGoal == null)
        {
            if (currentGoal == null)
            {
                ReGoapLogger.LogWarning("GoapAgent " + this + " could not find a plan.");
            }
            return;
        }

        if (currentActionState != null)
        {
            currentActionState.Action.Exit(null);
        }
        currentActionState = null;
        currentGoal        = newGoal;
        var plan = currentGoal.GetPlan();

        startingPlan = plan.ToList();
        ClearPlanValues();
        foreach (var actionState in startingPlan)
        {
            actionState.Action.PostPlanCalculations(this);
        }
        currentGoal.Run(WarnGoalEnd);
        PushAction();
    }
예제 #5
0
        protected virtual void OnDonePlanning(IReGoapGoal <T, W> newGoal)
        {
            startedPlanning         = false;
            currentReGoapPlanWorker = default(ReGoapPlanWork <T, W>);
            if (newGoal == null)
            {
                if (currentGoal == null)
                {
                    ReGoapLogger.LogWarning("GoapAgent " + this + " could not find a plan.");
                }
                return;
            }

            if (currentActionState != null)
            {
                currentActionState.Action.Exit(null);
            }
            currentActionState = null;
            currentGoal        = newGoal;
            if (startingPlan != null)
            {
                for (int i = 0; i < startingPlan.Count; i++)
                {
                    startingPlan[i].Action.PlanExit(i > 0 ? startingPlan[i - 1].Action : null, i + 1 < startingPlan.Count ? startingPlan[i + 1].Action : null, startingPlan[i].Settings, currentGoal.GetGoalState());
                }
            }
            startingPlan = currentGoal.GetPlan().ToList();
            ClearPlanValues();
            for (int i = 0; i < startingPlan.Count; i++)
            {
                startingPlan[i].Action.PlanEnter(i > 0 ? startingPlan[i - 1].Action : null, i + 1 < startingPlan.Count ? startingPlan[i + 1].Action : null, startingPlan[i].Settings, currentGoal.GetGoalState());
            }
            currentGoal.Run(WarnGoalEnd);
            PushAction();
        }
예제 #6
0
        public static void ApplyAndValidatePlan(IReGoapGoal <string, object> plan, ReGoapTestMemory memory)
        {
            foreach (var action in plan.GetPlan())
            {
                Assert.That(action.Action.GetPreconditions(plan.GetGoalState()).MissingDifference(memory.GetWorldState(), 1) == 0);
                foreach (var effectsPair in action.Action.GetEffects(plan.GetGoalState()).GetValues())
                {   // in a real game this should be done by memory itself
                    //  e.x. isNearTarget = (transform.position - target.position).magnitude < minRangeForCC
                    string      key = effectsPair.Key;
                    StructValue curValue;
                    StructValue endValue;

                    if (memory.GetWorldState().GetValues().TryGetValue(key, out curValue))
                    {
                        endValue = curValue.MergeWith(effectsPair.Value);
                    }
                    else
                    {
                        endValue = effectsPair.Value;
                    }
                    memory.SetStructValue(effectsPair.Key, endValue);
                }
            }
            Assert.That(plan.GetGoalState().MissingDifference(memory.GetWorldState(), 1) == 0);
        }
예제 #7
0
 public virtual void WarnGoalEnd(IReGoapGoal <T, W> goal)
 {
     if (goal != currentGoal)
     {
         GodotBase.GD.PrintErr(string.Format("[GoapAgent] Goal {0} warned for end but is not current goal.", goal));
         return;
     }
     CalculateNewGoal();
 }
예제 #8
0
 protected virtual void OnDisable()
 {
     if (currentActionState != null)
     {
         currentActionState.Action.Exit(null);
         currentActionState = null;
         currentGoal        = null;
     }
 }
예제 #9
0
 public virtual void WarnGoalEnd(IReGoapGoal goal)
 {
     if (goal != currentGoal)
     {
         ReGoapLogger.LogWarning(string.Format("[GoapAgent] Goal {0} warned for end but is not current goal.", goal));
         return;
     }
     CalculateNewGoal();
 }
        public ReGoapPlanWork <T, W> Plan(IReGoapAgent <T, W> agent, IReGoapGoal <T, W> blacklistGoal, Queue <ReGoapActionState <T, W> > currentPlan, Action <IReGoapGoal <T, W> > callback)
        {
            var work = new ReGoapPlanWork <T, W>(agent, blacklistGoal, currentPlan, callback);

            lock (ReGoapPlannerThread <T, W> .WorksQueue)
            {
                ReGoapPlannerThread <T, W> .WorksQueue.Enqueue(work);
            }
            return(work);
        }
예제 #11
0
    public PlanWork Plan(IReGoapAgent agent, IReGoapGoal blacklistGoal, Queue <ReGoapActionState> currentPlan, Action <IReGoapGoal> callback)
    {
        var work = new PlanWork(agent, blacklistGoal, currentPlan, callback);

        lock (worksQueue)
        {
            worksQueue.Enqueue(work);
        }
        threadEvents.Set();
        return(work);
    }
예제 #12
0
 public static void ApplyAndValidatePlan(IReGoapGoal plan, ReGoapTestMemory memory)
 {
     foreach (var action in plan.GetPlan())
     {
         Assert.That(action.Action.GetPreconditions(plan.GetGoalState()).MissingDifference(memory.GetWorldState(), 1) == 0);
         foreach (var effectsPair in action.Action.GetEffects(plan.GetGoalState()).GetValues())
         {   // in a real game this should be done by memory itself
             //  e.x. isNearTarget = (transform.position - target.position).magnitude < minRangeForCC
             memory.SetValue(effectsPair.Key, effectsPair.Value);
         }
     }
     Assert.That(plan.GetGoalState().MissingDifference(memory.GetWorldState(), 1) == 0);
 }
예제 #13
0
 public virtual void WarnActionFailure(IReGoapAction <T, W> thisAction)
 {
     if (currentActionState != null && thisAction != currentActionState.Action)
     {
         GodotBase.GD.PrintErr(string.Format("[GoapAgent] Action {0} warned for failure but is not current action.", thisAction));
         return;
     }
     if (BlackListGoalOnFailure)
     {
         goalBlacklist[currentGoal] = GodotBase.OS.GetTicksMsec() + currentGoal.GetErrorDelay();
     }
     this.currentGoal = null;
     // CalculateNewGoal(true);
 }
예제 #14
0
 public virtual void WarnPossibleGoal(IReGoapGoal goal)
 {
     if ((currentGoal != null) && (goal.GetPriority() <= currentGoal.GetPriority()))
     {
         return;
     }
     if (currentActionState != null && !currentActionState.Action.IsInterruptable())
     {
         interruptOnNextTransistion = true;
         currentActionState.Action.AskForInterruption(currentActionState.Settings);
     }
     else
     {
         CalculateNewGoal();
     }
 }
예제 #15
0
    // called in another thread
    private void OnDonePlan(GoapPlannerThread plannerThread, PlanWork work, IReGoapGoal newGoal)
    {
        work.NewGoal = newGoal;
        lock (doneWorks)
        {
            doneWorks.Add(work);
#if DEBUG
            if (work.NewGoal != null)
            {
                ReGoapLogger.Log("[GoapPlannerManager] Done calculating plan, actions list:");
                var i = 0;
                foreach (var action in work.NewGoal.GetPlan())
                {
                    ReGoapLogger.Log(string.Format("{0}: {1}", i++, action.Action));
                }
            }
#endif
        }
    }
예제 #16
0
        public static void ApplyAndValidatePlan(IReGoapGoal <string, object> plan, ReGoapTestAgent agent, ReGoapTestMemory memory)
        {
            GoapActionStackData <string, object> stackData;

            stackData.agent        = agent;
            stackData.currentState = memory.GetWorldState();
            stackData.goalState    = plan.GetGoalState();
            stackData.next         = null;
            stackData.settings     = null;
            foreach (var action in plan.GetPlan())
            {
                stackData.settings = action.Settings;
                Assert.That(action.Action.GetPreconditions(stackData).MissingDifference(stackData.currentState, 1) == 0);
                foreach (var effectsPair in action.Action.GetEffects(stackData).GetValues())
                {   // in a real game this should be done by memory itself
                    //  e.x. isNearTarget = (transform.position - target.position).magnitude < minRangeForCC
                    memory.SetValue(effectsPair.Key, effectsPair.Value);
                }
            }
            Assert.That(plan.GetGoalState().MissingDifference(memory.GetWorldState(), 1) == 0);
        }
예제 #17
0
        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)
        {
            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);
                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);
            }
            return(currentGoal);
        }
예제 #18
0
    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();

            // can't work with dynamic actions, of course
            if (!settings.UsingDynamicActions)
            {
                var wantedGoalCheck = currentGoal.GetGoalState();
                // 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(goapAgent, goalState);
                    if (!action.CheckProceduralCondition(goapAgent, wantedGoalCheck))
                    {
                        continue;
                    }
                    // check if the effects of all actions can archieve currentGoal
                    var previous = wantedGoalCheck;
                    wantedGoalCheck = new ReGoapState();
                    previous.MissingDifference(action.GetEffects(wantedGoalCheck), ref wantedGoalCheck);
                }
                // can't validate goal
                if (wantedGoalCheck.Count > 0)
                {
                    currentGoal = null;
                    continue;
                }
            }

            var leaf = (ReGoapNode)astar.Run(
                new ReGoapNode(this, goalState, null, null), goalState, 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);
    }
예제 #19
0
        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()));

            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();
                    // 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(goapAgent, goalState);
                        if (!action.CheckProceduralCondition(goapAgent, wantedGoalCheck))
                        {
                            continue;
                        }
                        // check if the effects of all actions can archieve currentGoal
                        var previous = wantedGoalCheck;
                        wantedGoalCheck = ReGoapState <T, W> .Instantiate();

                        previous.MissingDifference(action.GetEffects(wantedGoalCheck), ref wantedGoalCheck);
                    }
                    // can't validate goal
                    if (wantedGoalCheck.Count > 0)
                    {
                        currentGoal = null;
                        continue;
                    }
                }

                //Utilities.ReGoapLogger.Log(string.Format("**** Goal: {0}, Expected State = ({1})", currentGoal.GetName(), goalState));

                goalState = goalState.Clone();
                var leaf = (ReGoapNode <T, W>)astar.Run(
                    ReGoapNode <T, W> .Instantiate(this, goalState, null, null), goalState, settings.MaxIterations, settings.PlanningEarlyExit, debugPlan: agent.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;
                    foreach (var action in currentGoal.GetPlan())
                    {
                        ReGoapLogger.Log(string.Format("[ReGoapPlanner] {0}) {1}", i++, action.Action));
                    }
                }
            }
            else
            {
                ReGoapLogger.LogWarning("[ReGoapPlanner] Error while calculating plan.");
            }
            return(currentGoal);
        }
 // called in another thread
 private void OnDonePlan(ReGoapPlannerThread <T, W> plannerThread, ReGoapPlanWork <T, W> work, IReGoapGoal <T, W> newGoal)
 {
     work.NewGoal = newGoal;
     lock (doneWorks)
     {
         doneWorks.Add(work);
     }
     if (work.NewGoal != null && ReGoapLogger.Level == ReGoapLogger.DebugLevel.Full)
     {
         ReGoapLogger.Log("[GoapPlannerManager] Done calculating plan, actions list:");
         var i = 0;
         foreach (var action in work.NewGoal.GetPlan())
         {
             ReGoapLogger.Log(string.Format("{0}: {1}", i++, action.Action));
         }
     }
 }