]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Fix NPC prototype reloads (#13981)
authormetalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Tue, 7 Feb 2023 21:27:34 +0000 (08:27 +1100)
committerGitHub <noreply@github.com>
Tue, 7 Feb 2023 21:27:34 +0000 (14:27 -0700)
Content.IntegrationTests/Tests/NPC/NPCTest.cs
Content.Server/NPC/HTN/HTNBranch.cs
Content.Server/NPC/HTN/HTNPlanJob.cs
Content.Server/NPC/HTN/HTNSystem.cs

index 96e7f752a45d90dcdfb386a4615e289162028ccc..08df5f98a2c6345051deaa28d0d51b4fa65a7612 100644 (file)
@@ -3,6 +3,7 @@ using System.Collections.Generic;
 using System.Threading.Tasks;
 using Content.Server.NPC.HTN;
 using NUnit.Framework;
+using Robust.Shared.GameObjects;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Utility;
 
@@ -19,6 +20,7 @@ public sealed class NPCTest
 
         await server.WaitIdleAsync();
 
+        var htnSystem = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<HTNSystem>();
         var protoManager = server.ResolveDependency<IPrototypeManager>();
 
         await server.WaitAssertion(() =>
@@ -27,7 +29,7 @@ public sealed class NPCTest
 
             foreach (var compound in protoManager.EnumeratePrototypes<HTNCompoundTask>())
             {
-                Count(compound, counts);
+                Count(compound, counts, htnSystem);
                 counts.Clear();
             }
         });
@@ -35,11 +37,13 @@ public sealed class NPCTest
         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)
                 {
@@ -48,7 +52,7 @@ public sealed class NPCTest
 
                     Assert.That(count, Is.LessThan(50));
                     counts[compound.ID] = count;
-                    Count(compoundTask, counts);
+                    Count(compoundTask, counts, htnSystem);
                 }
             }
         }
index 88a39aaabf9497e89a4a8e77be89a651f812b64e..96645b2906fd3770be73d0573f8248dd1734b4a9 100644 (file)
@@ -12,8 +12,6 @@ public sealed class HTNBranch
     [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>
index 580803cca7094984c5ab4123f93c5536e17cf973..f5ba3e8fd9133dfad04fc6ff85313f54a06a93fa 100644 (file)
@@ -11,6 +11,7 @@ namespace Content.Server.NPC.HTN;
 /// </summary>
 public sealed class HTNPlanJob : Job<HTNPlan>
 {
+    private readonly HTNSystem _htn;
     private readonly HTNCompoundTask _rootTask;
     private NPCBlackboard _blackboard;
 
@@ -21,11 +22,13 @@ public sealed class HTNPlanJob : Job<HTNPlan>
 
     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;
@@ -156,6 +159,8 @@ public sealed class HTNPlanJob : Job<HTNPlan>
     /// </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];
@@ -173,7 +178,9 @@ public sealed class HTNPlanJob : Job<HTNPlan>
             if (!isValid)
                 continue;
 
-            foreach (var task in branch.Tasks)
+            var branchTasks = compBranches[i];
+
+            foreach (var task in branchTasks)
             {
                 tasksToProcess.Enqueue(task);
             }
index b112d7696c6e220080d1e23ce66b584e035b5c24..9b84dc6515df64fafbfa7c726a9e8c35a841a2ba 100644 (file)
@@ -27,6 +27,10 @@ public sealed class HTNSystem : EntitySystem
 
     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()
     {
@@ -75,6 +79,8 @@ public sealed class HTNSystem : EntitySystem
             }
         }
 
+        _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>())
@@ -111,21 +117,25 @@ public sealed class HTNSystem : EntitySystem
 
     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
                 {
@@ -330,6 +340,7 @@ public sealed class HTNSystem : EntitySystem
 
         var job = new HTNPlanJob(
             0.02,
+            this,
             _prototypeManager.Index<HTNCompoundTask>(component.RootTask),
             component.Blackboard.ShallowClone(), branchTraversal, cancelToken.Token);
 
@@ -360,13 +371,17 @@ public sealed class HTNSystem : EntitySystem
         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);
                 }