From f308a1b31e2f178badbb74d218d1bf83a830e5a0 Mon Sep 17 00:00:00 2001
From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Date: Mon, 29 May 2023 16:53:28 +1000
Subject: [PATCH] Fix cleanbots (#16922)
---
.../Operators/Fluid/PickPuddleOperator.cs | 106 ------------------
Content.Server/NPC/NPCBlackboard.cs | 4 +
.../Queries/Queries/NearbyComponentsQuery.cs | 9 --
.../NPC/Queries/Queries/PuddleFilter.cs | 6 +
.../NPC/Systems/NPCUtilitySystem.cs | 35 +++++-
Resources/Prototypes/NPCs/cleanbot.yml | 24 +++-
Resources/Prototypes/NPCs/utility_queries.yml | 16 +++
7 files changed, 75 insertions(+), 125 deletions(-)
delete mode 100644 Content.Server/NPC/HTN/PrimitiveTasks/Operators/Fluid/PickPuddleOperator.cs
delete mode 100644 Content.Server/NPC/Queries/Queries/NearbyComponentsQuery.cs
create mode 100644 Content.Server/NPC/Queries/Queries/PuddleFilter.cs
diff --git a/Content.Server/NPC/HTN/PrimitiveTasks/Operators/Fluid/PickPuddleOperator.cs b/Content.Server/NPC/HTN/PrimitiveTasks/Operators/Fluid/PickPuddleOperator.cs
deleted file mode 100644
index ecce69ce38..0000000000
--- a/Content.Server/NPC/HTN/PrimitiveTasks/Operators/Fluid/PickPuddleOperator.cs
+++ /dev/null
@@ -1,106 +0,0 @@
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-using Content.Server.Chemistry.EntitySystems;
-using Content.Server.Fluids.EntitySystems;
-using Content.Server.NPC.Pathfinding;
-using Content.Shared.Fluids.Components;
-using Robust.Shared.Map;
-
-namespace Content.Server.NPC.HTN.PrimitiveTasks.Operators.Fluid;
-
-///
-/// Picks a nearby evaporatable puddle.
-///
-public sealed class PickPuddleOperator : HTNOperator
-{
- // This is similar to PickAccessibleComponent however I have an idea on generic utility queries
- // that can also be re-used for melee that needs further fleshing out.
-
- [Dependency] private readonly IComponentFactory _factory = default!;
- [Dependency] private readonly IEntityManager _entManager = default!;
- private PathfindingSystem _pathfinding = default!;
- private EntityLookupSystem _lookup = default!;
-
- [DataField("rangeKey", required: true)]
- public string RangeKey = string.Empty;
-
- [DataField("target")] public string Target = "Target";
-
- [DataField("targetKey", required: true)]
- public string TargetKey = string.Empty;
-
- ///
- /// Where the pathfinding result will be stored (if applicable). This gets removed after execution.
- ///
- [DataField("pathfindKey")]
- public string PathfindKey = NPCBlackboard.PathfindKey;
-
- public override void Initialize(IEntitySystemManager sysManager)
- {
- base.Initialize(sysManager);
- _lookup = sysManager.GetEntitySystem();
- _pathfinding = sysManager.GetEntitySystem();
- }
-
- ///
- [Obsolete("Obsolete")]
- public override async Task<(bool Valid, Dictionary? Effects)> Plan(NPCBlackboard blackboard,
- CancellationToken cancelToken)
- {
- var range = blackboard.GetValueOrDefault(RangeKey, _entManager);
- var owner = blackboard.GetValue(NPCBlackboard.Owner);
-
- if (!blackboard.TryGetValue(NPCBlackboard.OwnerCoordinates, out var coordinates, _entManager))
- {
- return (false, null);
- }
-
- var targets = new List();
- var puddleSystem = _entManager.System();
- var solSystem = _entManager.System();
-
- foreach (var comp in _lookup.GetComponentsInRange(coordinates, range))
- {
- if (comp.Owner == owner ||
- !solSystem.TryGetSolution(comp.Owner, comp.SolutionName, out var puddleSolution) ||
- puddleSystem.CanFullyEvaporate(puddleSolution))
- {
- continue;
- }
-
- targets.Add((comp.Owner));
- }
-
- if (targets.Count == 0)
- {
- return (false, null);
- }
-
- foreach (var target in targets)
- {
- var path = await _pathfinding.GetPath(
- owner,
- target,
- 1f,
- cancelToken,
- flags: _pathfinding.GetFlags(blackboard));
-
- if (path.Result != PathResult.Path)
- {
- return (false, null);
- }
-
- var xform = _entManager.GetComponent(target);
-
- return (true, new Dictionary()
- {
- { Target, target },
- { TargetKey, xform.Coordinates },
- { PathfindKey, path}
- });
- }
-
- return (false, null);
- }
-}
diff --git a/Content.Server/NPC/NPCBlackboard.cs b/Content.Server/NPC/NPCBlackboard.cs
index 4e8581efb2..f386fba21e 100644
--- a/Content.Server/NPC/NPCBlackboard.cs
+++ b/Content.Server/NPC/NPCBlackboard.cs
@@ -4,6 +4,7 @@ using Content.Server.Interaction;
using Content.Shared.Access.Systems;
using Content.Shared.ActionBlocker;
using Content.Shared.Interaction;
+using JetBrains.Annotations;
using Robust.Shared.Utility;
namespace Content.Server.NPC;
@@ -60,6 +61,7 @@ public sealed class NPCBlackboard : IEnumerable>
return dict;
}
+ [Pure]
public bool ContainsKey(string key)
{
return _blackboard.ContainsKey(key);
@@ -68,6 +70,7 @@ public sealed class NPCBlackboard : IEnumerable>
///
/// Get the blackboard data for a particular key.
///
+ [Pure]
public T GetValue(string key)
{
return (T) _blackboard[key];
@@ -76,6 +79,7 @@ public sealed class NPCBlackboard : IEnumerable>
///
/// Tries to get the blackboard data for a particular key. Returns default if not found
///
+ [Pure]
public T? GetValueOrDefault(string key, IEntityManager entManager)
{
if (_blackboard.TryGetValue(key, out var value))
diff --git a/Content.Server/NPC/Queries/Queries/NearbyComponentsQuery.cs b/Content.Server/NPC/Queries/Queries/NearbyComponentsQuery.cs
deleted file mode 100644
index c465f11fd2..0000000000
--- a/Content.Server/NPC/Queries/Queries/NearbyComponentsQuery.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using Robust.Shared.Prototypes;
-
-namespace Content.Server.NPC.Queries.Queries;
-
-public sealed class NearbyComponentsQuery : UtilityQuery
-{
- [DataField("components")]
- public ComponentRegistry Component = default!;
-}
diff --git a/Content.Server/NPC/Queries/Queries/PuddleFilter.cs b/Content.Server/NPC/Queries/Queries/PuddleFilter.cs
new file mode 100644
index 0000000000..65ebfda395
--- /dev/null
+++ b/Content.Server/NPC/Queries/Queries/PuddleFilter.cs
@@ -0,0 +1,6 @@
+namespace Content.Server.NPC.Queries.Queries;
+
+public sealed class PuddleFilter : UtilityQueryFilter
+{
+
+}
diff --git a/Content.Server/NPC/Systems/NPCUtilitySystem.cs b/Content.Server/NPC/Systems/NPCUtilitySystem.cs
index 0b00ab8c83..a9e93062e8 100644
--- a/Content.Server/NPC/Systems/NPCUtilitySystem.cs
+++ b/Content.Server/NPC/Systems/NPCUtilitySystem.cs
@@ -1,5 +1,7 @@
using System.Linq;
+using Content.Server.Chemistry.EntitySystems;
using Content.Server.Examine;
+using Content.Server.Fluids.EntitySystems;
using Content.Server.NPC.Queries;
using Content.Server.NPC.Queries.Considerations;
using Content.Server.NPC.Queries.Curves;
@@ -8,8 +10,10 @@ using Content.Server.Nutrition.Components;
using Content.Server.Nutrition.EntitySystems;
using Content.Server.Storage.Components;
using Content.Shared.Examine;
+using Content.Shared.Fluids.Components;
using Content.Shared.Mobs.Systems;
using Robust.Server.Containers;
+using Robust.Shared.Collections;
using Robust.Shared.Prototypes;
namespace Content.Server.NPC.Systems;
@@ -23,9 +27,11 @@ public sealed class NPCUtilitySystem : EntitySystem
[Dependency] private readonly ContainerSystem _container = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly FactionSystem _faction = default!;
- [Dependency] private readonly MobStateSystem _mobState = default!;
- [Dependency] private readonly SharedTransformSystem _transform = default!;
[Dependency] private readonly FoodSystem _food = default!;
+ [Dependency] private readonly MobStateSystem _mobState = default!;
+ [Dependency] private readonly PuddleSystem _puddle = default!;
+ [Dependency] private readonly SharedTransformSystem _transform = default!;
+ [Dependency] private readonly SolutionContainerSystem _solutions = default!;
///
/// Runs the UtilityQueryPrototype and returns the best-matching entities.
@@ -269,10 +275,31 @@ public sealed class NPCUtilitySystem : EntitySystem
private void Filter(NPCBlackboard blackboard, HashSet entities, UtilityQueryFilter filter)
{
- var owner = blackboard.GetValue(NPCBlackboard.Owner);
-
switch (filter)
{
+ case PuddleFilter:
+ {
+ var puddleQuery = GetEntityQuery();
+
+ var toRemove = new ValueList();
+
+ foreach (var ent in entities)
+ {
+ if (!puddleQuery.TryGetComponent(ent, out var puddleComp) ||
+ !_solutions.TryGetSolution(ent, puddleComp.SolutionName, out var sol) ||
+ _puddle.CanFullyEvaporate(sol))
+ {
+ toRemove.Add(ent);
+ }
+ }
+
+ foreach (var ent in toRemove)
+ {
+ entities.Remove(ent);
+ }
+
+ break;
+ }
default:
throw new NotImplementedException();
}
diff --git a/Resources/Prototypes/NPCs/cleanbot.yml b/Resources/Prototypes/NPCs/cleanbot.yml
index ca3835338a..60e8bdb8b6 100644
--- a/Resources/Prototypes/NPCs/cleanbot.yml
+++ b/Resources/Prototypes/NPCs/cleanbot.yml
@@ -12,18 +12,30 @@
branches:
- tasks:
- id: PickPuddlePrimitive
- - id: MoveToAccessiblePrimitive
- - id: InteractWithPrimitive
+ - id: MoveToCombatTargetPrimitive
+ - id: MopPrimitive
- type: htnPrimitive
id: PickPuddlePrimitive
- operator: !type:PickPuddleOperator
- rangeKey: BufferRange
- targetKey: MovementTarget
- component: Puddle
+ operator: !type:UtilityOperator
+ proto: NearbyPuddles
- type: htnPrimitive
id: SetIdleTimePrimitive
operator: !type:SetFloatOperator
targetKey: IdleTime
amount: 3
+
+- type: htnPrimitive
+ id: MopPrimitive
+ preconditions:
+ - !type:TargetInRangePrecondition
+ targetKey: CombatTarget
+ rangeKey: InteractRange
+ operator: !type:InteractWithOperator
+ targetKey: CombatTarget
+ services:
+ - !type:UtilityService
+ id: PuddleService
+ proto: NearbyPuddles
+ key: CombatTarget
diff --git a/Resources/Prototypes/NPCs/utility_queries.yml b/Resources/Prototypes/NPCs/utility_queries.yml
index 87eda1f9eb..7b804f6f37 100644
--- a/Resources/Prototypes/NPCs/utility_queries.yml
+++ b/Resources/Prototypes/NPCs/utility_queries.yml
@@ -35,6 +35,22 @@
- !type:TargetInLOSOrCurrentCon
curve: !type:BoolCurve
+- type: utilityQuery
+ id: NearbyPuddles
+ query:
+ - !type:ComponentQuery
+ components:
+ - type: Puddle
+ - !type:PuddleFilter
+ considerations:
+ - !type:TargetDistanceCon
+ curve: !type:PresetCurve
+ preset: TargetDistance
+ - !type:TargetAccessibleCon
+ curve: !type:BoolCurve
+ - !type:TargetInLOSOrCurrentCon
+ curve: !type:BoolCurve
+
- type: utilityQuery
id: NearbyRangedTargets
query: