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; }
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 PlanWork(IReGoapAgent agent, IReGoapGoal blacklistGoal, Queue <ReGoapActionState> actions, Action <IReGoapGoal> callback) : this() { Agent = agent; BlacklistGoal = blacklistGoal; Actions = actions; Callback = callback; }
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(); }
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(); }
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); }
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(); }
protected virtual void OnDisable() { if (currentActionState != null) { currentActionState.Action.Exit(null); currentActionState = null; currentGoal = null; } }
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); }
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); }
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); }
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); }
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(); } }
// 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 } }
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); }
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); }
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); }
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)); } } }