]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Tie NPC services to plans (#16451)
authormetalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Mon, 15 May 2023 06:18:18 +0000 (16:18 +1000)
committerGitHub <noreply@github.com>
Mon, 15 May 2023 06:18:18 +0000 (16:18 +1000)
Content.Server/NPC/HTN/HTNComponent.cs
Content.Server/NPC/HTN/HTNSystem.cs

index aabfe99ad258e14948bc30cdf3ac2fdc9de35202..de56627cb116b0f07bf0546555a1d9d996a87e22 100644 (file)
@@ -15,17 +15,16 @@ public sealed class HTNComponent : NPCComponent
     public string RootTask = default!;
 
     /// <summary>
-    /// The NPC's current plan.
+    /// Check any active services for our current plan. This is used to find new targets for example without changing our plan.
     /// </summary>
-    [ViewVariables]
-    public HTNPlan? Plan;
+    [DataField("checkServices")]
+    public bool CheckServices = true;
 
-    // TODO: Need dictionary timeoffsetserializer.
     /// <summary>
-    /// Last time we tried a particular <see cref="UtilityService"/>.
+    /// The NPC's current plan.
     /// </summary>
-    [DataField("serviceCooldowns")]
-    public Dictionary<string, TimeSpan> ServiceCooldowns = new();
+    [ViewVariables]
+    public HTNPlan? Plan;
 
     /// <summary>
     /// How long to wait after having planned to try planning again.
index 3ef87a9e682284fedd3d322a092c4a5d68ebba80..5d280099adc536592c235404f236f68b6a0f56d9 100644 (file)
@@ -21,9 +21,7 @@ namespace Content.Server.NPC.HTN;
 public sealed class HTNSystem : EntitySystem
 {
     [Dependency] private readonly IAdminManager _admin = default!;
-    [Dependency] private readonly IGameTiming _timing = default!;
     [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
-    [Dependency] private readonly IRobustRandom _random = default!;
     [Dependency] private readonly NPCSystem _npc = default!;
     [Dependency] private readonly NPCUtilitySystem _utility = default!;
 
@@ -42,22 +40,12 @@ public sealed class HTNSystem : EntitySystem
         base.Initialize();
         _sawmill = Logger.GetSawmill("npc.htn");
         SubscribeLocalEvent<HTNComponent, ComponentShutdown>(OnHTNShutdown);
-        SubscribeLocalEvent<HTNComponent, EntityUnpausedEvent>(OnHTNUnpaused);
         SubscribeNetworkEvent<RequestHTNMessage>(OnHTNMessage);
 
         _prototypeManager.PrototypesReloaded += OnPrototypeLoad;
         OnLoad();
     }
 
-    private void OnHTNUnpaused(EntityUid uid, HTNComponent component, ref EntityUnpausedEvent args)
-    {
-        foreach (var (service, cooldown) in component.ServiceCooldowns)
-        {
-            var newCooldown = cooldown + args.PausedTime;
-            component.ServiceCooldowns[service] = newCooldown;
-        }
-    }
-
     private void OnHTNMessage(RequestHTNMessage msg, EntitySessionEventArgs args)
     {
         if (!_admin.HasAdminFlag((IPlayerSession) args.SenderSession, AdminFlags.Debug))
@@ -220,6 +208,7 @@ public sealed class HTNSystem : EntitySystem
 
                 if (comp.Plan == null || newPlanBetter)
                 {
+                    comp.CheckServices = false;
                     comp.Plan?.CurrentTask.Operator.Shutdown(comp.Blackboard, HTNOperatorStatus.BetterPlan);
                     comp.Plan = comp.PlanningJob.Result;
 
@@ -251,6 +240,11 @@ public sealed class HTNSystem : EntitySystem
                         }, session.ConnectedClient);
                     }
                 }
+                // Keeping old plan
+                else
+                {
+                    comp.CheckServices = true;
+                }
 
                 comp.PlanningJob = null;
                 comp.PlanningToken = null;
@@ -331,20 +325,16 @@ public sealed class HTNSystem : EntitySystem
             var currentTask = component.Plan.CurrentTask;
             var blackboard = component.Blackboard;
 
-            foreach (var service in currentTask.Services)
+            // Service still on cooldown.
+            if (component.CheckServices)
             {
-                // Service still on cooldown.
-                if (component.ServiceCooldowns.TryGetValue(service.ID, out var lastService) &&
-                    _timing.CurTime < lastService)
+                foreach (var service in currentTask.Services)
                 {
-                    continue;
+                    var serviceResult = _utility.GetEntities(blackboard, service.Prototype);
+                    blackboard.SetValue(service.Key, serviceResult.GetHighest());
                 }
 
-                var serviceResult = _utility.GetEntities(blackboard, service.Prototype);
-                blackboard.SetValue(service.Key, serviceResult.GetHighest());
-
-                var cooldown = TimeSpan.FromSeconds(_random.NextFloat(service.MinCooldown, service.MaxCooldown));
-                component.ServiceCooldowns[service.ID] = _timing.CurTime + cooldown;
+                component.CheckServices = false;
             }
 
             status = currentOperator.Update(blackboard, frameTime);
@@ -355,7 +345,6 @@ public sealed class HTNSystem : EntitySystem
                     break;
                 case HTNOperatorStatus.Failed:
                     currentOperator.Shutdown(blackboard, status);
-                    component.ServiceCooldowns.Clear();
                     component.Plan = null;
                     break;
                 // Operator completed so go to the next one.
@@ -366,7 +355,6 @@ public sealed class HTNSystem : EntitySystem
                     // Plan finished!
                     if (component.Plan.Tasks.Count <= component.Plan.Index)
                     {
-                        component.ServiceCooldowns.Clear();
                         component.Plan = null;
                         break;
                     }