File size: 1,923 Bytes
00437a9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
using System;

namespace Quantum
{
	/// <summary>
	/// The sequence task is similar to an and operation. It will return failure as soon as one of its child tasks return failure.
	/// If a child task returns success then it will sequentially run the next task. If all child tasks return success then it will return success.
	/// </summary>
	[Serializable]
	public unsafe partial class BTSequence : BTComposite
	{
		protected override BTStatus OnUpdate(BTParams btParams)
		{
			BTStatus status = BTStatus.Success;

			while (GetCurrentChild(btParams.Frame, btParams.Agent) < _childInstances.Length)
			{
				var currentChildId = GetCurrentChild(btParams.Frame, btParams.Agent);
				var child = _childInstances[currentChildId];
				status = child.RunUpdate(btParams);

				if (status == BTStatus.Abort)
				{
					if (btParams.Agent->IsAborting == true)
					{
						return BTStatus.Abort;
					}
					else
					{
						return BTStatus.Failure;
					}
				}

				if (status == BTStatus.Success)
				{
					SetCurrentChild(btParams.Frame, currentChildId + 1, btParams.Agent);
				}
				else
				{
					break;
				}
			}

			return status;
		}

		internal override void ChildCompletedRunning(BTParams btParams, BTStatus childResult)
		{
			if (childResult == BTStatus.Abort)
			{
				return;
			}

			if (childResult == BTStatus.Failure)
			{
				SetCurrentChild(btParams.Frame, _childInstances.Length, btParams.Agent);

				// If the child failed, then we already know that this sequence failed, so we can force it
				SetStatus(btParams.Frame, BTStatus.Failure, btParams.Agent);

				// Trigger the debugging callbacks
				BTManager.OnNodeFailure?.Invoke(btParams.Entity, Guid.Value);
				BTManager.OnNodeExit?.Invoke(btParams.Entity, Guid.Value);
			}
			else
			{
				var currentChild = GetCurrentChild(btParams.Frame, btParams.Agent);
				SetCurrentChild(btParams.Frame, currentChild + 1, btParams.Agent);
			}
		}
	}
}