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;
}