using System.Threading.Tasks;
using Content.Server.NPC.HTN;
using NUnit.Framework;
+using Robust.Shared.GameObjects;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
await server.WaitIdleAsync();
+ var htnSystem = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<HTNSystem>();
var protoManager = server.ResolveDependency<IPrototypeManager>();
await server.WaitAssertion(() =>
foreach (var compound in protoManager.EnumeratePrototypes<HTNCompoundTask>())
{
- Count(compound, counts);
+ Count(compound, counts, htnSystem);
counts.Clear();
}
});
await pool.CleanReturnAsync();
}
- private static void Count(HTNCompoundTask compound, Dictionary<string, int> counts)
+ private static void Count(HTNCompoundTask compound, Dictionary<string, int> counts, HTNSystem htnSystem)
{
- foreach (var branch in compound.Branches)
+ var compoundBranches = htnSystem.CompoundBranches[compound];
+
+ for (var i = 0; i < compound.Branches.Count; i++)
{
- foreach (var task in branch.Tasks)
+ foreach (var task in compoundBranches[i])
{
if (task is HTNCompoundTask compoundTask)
{
Assert.That(count, Is.LessThan(50));
counts[compound.ID] = count;
- Count(compoundTask, counts);
+ Count(compoundTask, counts, htnSystem);
}
}
}
[DataField("preconditions")]
public List<HTNPrecondition> Preconditions = new();
- [ViewVariables] public List<HTNTask> Tasks = new();
-
/// <summary>
/// Due to how serv3 works we need to defer getting the actual tasks until after they have all been serialized.
/// </summary>
/// </summary>
public sealed class HTNPlanJob : Job<HTNPlan>
{
+ private readonly HTNSystem _htn;
private readonly HTNCompoundTask _rootTask;
private NPCBlackboard _blackboard;
public HTNPlanJob(
double maxTime,
+ HTNSystem htn,
HTNCompoundTask rootTask,
NPCBlackboard blackboard,
List<int>? branchTraversal,
CancellationToken cancellationToken = default) : base(maxTime, cancellationToken)
{
+ _htn = htn;
_rootTask = rootTask;
_blackboard = blackboard;
_branchTraversal = branchTraversal;
/// </summary>
private bool TryFindSatisfiedMethod(HTNCompoundTask compound, Queue<HTNTask> tasksToProcess, NPCBlackboard blackboard, ref int mtrIndex)
{
+ var compBranches = _htn.CompoundBranches[compound];
+
for (var i = mtrIndex; i < compound.Branches.Count; i++)
{
var branch = compound.Branches[i];
if (!isValid)
continue;
- foreach (var task in branch.Tasks)
+ var branchTasks = compBranches[i];
+
+ foreach (var task in branchTasks)
{
tasksToProcess.Enqueue(task);
}
private readonly HashSet<ICommonSession> _subscribers = new();
+ // hngngghghgh
+ public IReadOnlyDictionary<HTNCompoundTask, List<HTNTask>[]> CompoundBranches => _compoundBranches;
+ private Dictionary<HTNCompoundTask, List<HTNTask>[]> _compoundBranches = new();
+
// Hierarchical Task Network
public override void Initialize()
{
}
}
+ _compoundBranches.Clear();
+
// Add dependencies for all operators.
// We put code on operators as I couldn't think of a clean way to put it on systems.
foreach (var compound in _prototypeManager.EnumeratePrototypes<HTNCompoundTask>())
private void UpdateCompound(HTNCompoundTask compound)
{
- foreach (var branch in compound.Branches)
+ var branchies = new List<HTNTask>[compound.Branches.Count];
+ _compoundBranches.Add(compound, branchies);
+
+ for (var i = 0; i < compound.Branches.Count; i++)
{
- branch.Tasks.Clear();
- branch.Tasks.EnsureCapacity(branch.TaskPrototypes.Count);
+ var branch = compound.Branches[i];
+ var brancho = new List<HTNTask>(branch.TaskPrototypes.Count);
+ branchies[i] = brancho;
// Didn't do this in a typeserializer because we can't recursively grab our own prototype during it, woohoo!
foreach (var proto in branch.TaskPrototypes)
{
if (_prototypeManager.TryIndex<HTNCompoundTask>(proto, out var compTask))
{
- branch.Tasks.Add(compTask);
+ brancho.Add(compTask);
}
else if (_prototypeManager.TryIndex<HTNPrimitiveTask>(proto, out var primTask))
{
- branch.Tasks.Add(primTask);
+ brancho.Add(primTask);
}
else
{
var job = new HTNPlanJob(
0.02,
+ this,
_prototypeManager.Index<HTNCompoundTask>(component.RootTask),
component.Blackboard.ShallowClone(), branchTraversal, cancelToken.Token);
else if (task is HTNCompoundTask compound)
{
builder.AppendLine(buffer + $"Compound: {task.ID}");
+ var compoundBranches = CompoundBranches[compound];
- foreach (var branch in compound.Branches)
+ for (var i = 0; i < compound.Branches.Count; i++)
{
+ var branch = compound.Branches[i];
+
builder.AppendLine(buffer + " branch:");
indent++;
+ var branchTasks = compoundBranches[i];
- foreach (var branchTask in branch.Tasks)
+ foreach (var branchTask in branchTasks)
{
AppendDomain(builder, branchTask, ref indent);
}