From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Mon, 15 May 2023 06:18:18 +0000 (+1000) Subject: Tie NPC services to plans (#16451) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=66ae137b7056fe26dff809a16facc70e2ef74262;p=space-station-14.git Tie NPC services to plans (#16451) --- diff --git a/Content.Server/NPC/HTN/HTNComponent.cs b/Content.Server/NPC/HTN/HTNComponent.cs index aabfe99ad2..de56627cb1 100644 --- a/Content.Server/NPC/HTN/HTNComponent.cs +++ b/Content.Server/NPC/HTN/HTNComponent.cs @@ -15,17 +15,16 @@ public sealed class HTNComponent : NPCComponent public string RootTask = default!; /// - /// 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. /// - [ViewVariables] - public HTNPlan? Plan; + [DataField("checkServices")] + public bool CheckServices = true; - // TODO: Need dictionary timeoffsetserializer. /// - /// Last time we tried a particular . + /// The NPC's current plan. /// - [DataField("serviceCooldowns")] - public Dictionary ServiceCooldowns = new(); + [ViewVariables] + public HTNPlan? Plan; /// /// How long to wait after having planned to try planning again. diff --git a/Content.Server/NPC/HTN/HTNSystem.cs b/Content.Server/NPC/HTN/HTNSystem.cs index 3ef87a9e68..5d280099ad 100644 --- a/Content.Server/NPC/HTN/HTNSystem.cs +++ b/Content.Server/NPC/HTN/HTNSystem.cs @@ -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(OnHTNShutdown); - SubscribeLocalEvent(OnHTNUnpaused); SubscribeNetworkEvent(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; }