NPC utility queries (#15843)
This commit is contained in:
@@ -13,17 +13,22 @@ using JetBrains.Annotations;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.Players;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
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!;
|
||||
|
||||
private ISawmill _sawmill = default!;
|
||||
private readonly JobQueue _planQueue = new();
|
||||
private readonly JobQueue _planQueue = new(0.004);
|
||||
|
||||
private readonly HashSet<ICommonSession> _subscribers = new();
|
||||
|
||||
@@ -37,12 +42,22 @@ 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))
|
||||
@@ -251,7 +266,7 @@ public sealed class HTNSystem : EntitySystem
|
||||
// If it's the selected BTR then highlight.
|
||||
for (var i = 0; i < btr.Count; i++)
|
||||
{
|
||||
text.Append('-');
|
||||
text.Append("--");
|
||||
}
|
||||
|
||||
text.Append(' ');
|
||||
@@ -272,7 +287,7 @@ public sealed class HTNSystem : EntitySystem
|
||||
{
|
||||
var branch = branches[i];
|
||||
btr.Add(i);
|
||||
text.AppendLine($" branch {string.Join(" ", btr)}:");
|
||||
text.AppendLine($" branch {string.Join(", ", btr)}:");
|
||||
|
||||
foreach (var sub in branch)
|
||||
{
|
||||
@@ -313,7 +328,25 @@ public sealed class HTNSystem : EntitySystem
|
||||
{
|
||||
// Run the existing operator
|
||||
var currentOperator = component.Plan.CurrentOperator;
|
||||
var currentTask = component.Plan.CurrentTask;
|
||||
var blackboard = component.Blackboard;
|
||||
|
||||
foreach (var service in currentTask.Services)
|
||||
{
|
||||
// Service still on cooldown.
|
||||
if (component.ServiceCooldowns.TryGetValue(service.ID, out var lastService) &&
|
||||
_timing.CurTime < lastService)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
status = currentOperator.Update(blackboard, frameTime);
|
||||
|
||||
switch (status)
|
||||
@@ -322,6 +355,7 @@ 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.
|
||||
@@ -332,6 +366,7 @@ public sealed class HTNSystem : EntitySystem
|
||||
// Plan finished!
|
||||
if (component.Plan.Tasks.Count <= component.Plan.Index)
|
||||
{
|
||||
component.ServiceCooldowns.Clear();
|
||||
component.Plan = null;
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user