diff --git a/MountainGoap/Action.cs b/MountainGoap/Action.cs
index 546c53d..3453d36 100644
--- a/MountainGoap/Action.cs
+++ b/MountainGoap/Action.cs
@@ -134,15 +134,20 @@ public float GetCost() {
/// Executes a step of work for the agent.
///
/// Agent executing the action.
- internal void Execute(Agent agent) {
+ /// The execution status of the action.
+ internal ExecutionStatus Execute(Agent agent) {
OnBeginExecuteAction(agent, this, parameters);
if (IsPossible(agent.State)) {
var newState = executor(agent, this);
if (newState == ExecutionStatus.Succeeded) ApplyEffects(agent.State);
ExecutionStatus = newState;
OnFinishExecuteAction(agent, this, ExecutionStatus, parameters);
+ return newState;
+ }
+ else {
+ OnFinishExecuteAction(agent, this, ExecutionStatus.NotPossible, parameters);
+ return ExecutionStatus.NotPossible;
}
- else OnFinishExecuteAction(agent, this, ExecutionStatus.NotPossible, parameters);
}
///
diff --git a/MountainGoap/Agent.cs b/MountainGoap/Agent.cs
index 87c4b98..2c31109 100644
--- a/MountainGoap/Agent.cs
+++ b/MountainGoap/Agent.cs
@@ -163,8 +163,8 @@ private void Execute() {
List> cullableSequences = new();
foreach (var sequence in CurrentActionSequences) {
if (sequence.Count > 0) {
- sequence[0].Execute(this);
- sequence.RemoveAt(0);
+ var executionStatus = sequence[0].Execute(this);
+ if (executionStatus != ExecutionStatus.Executing) sequence.RemoveAt(0);
}
else cullableSequences.Add(sequence);
}
diff --git a/MountainGoapTest/ActionContinuationTests.cs b/MountainGoapTest/ActionContinuationTests.cs
new file mode 100644
index 0000000..545b1b8
--- /dev/null
+++ b/MountainGoapTest/ActionContinuationTests.cs
@@ -0,0 +1,54 @@
+namespace MountainGoapTest {
+ using System.Collections.Generic;
+
+ public class ActionContinuationTests {
+ [Fact]
+ public void ItCanContinueActions() {
+ var timesExecuted = 0;
+ var agent = new Agent(
+ state: new() {
+ { "key", false },
+ { "progress", 0 }
+ },
+ goals: new List {
+ new Goal(
+ desiredState: new() {
+ { "key", true }
+ }
+ )
+ },
+ actions: new List {
+ new Action(
+ preconditions: new() {
+ { "key", false }
+ },
+ postconditions: new() {
+ { "key", true }
+ },
+ executor: (Agent agent, Action action) => {
+ timesExecuted++;
+ if (agent.State["progress"] is int progress && progress < 3) {
+ agent.State["progress"] = progress + 1;
+ return ExecutionStatus.Executing;
+ }
+ else return ExecutionStatus.Succeeded;
+ }
+ )
+ }
+ );
+ agent.Step(StepMode.OneAction);
+ if (agent.State["key"] is bool value) Assert.False(value);
+ else Assert.False(true);
+ agent.Step(StepMode.OneAction);
+ if (agent.State["key"] is bool value2) Assert.False(value2);
+ else Assert.False(true);
+ agent.Step(StepMode.OneAction);
+ if (agent.State["key"] is bool value3) Assert.False(value3);
+ else Assert.False(true);
+ agent.Step(StepMode.OneAction);
+ if (agent.State["key"] is bool value4) Assert.True(value4);
+ else Assert.False(true);
+ Assert.Equal(4, timesExecuted);
+ }
+ }
+}