Bandaid medibots (#11718)

This commit is contained in:
metalgearsloth
2022-10-13 21:36:29 +11:00
committed by GitHub
parent 8e1d599656
commit fa59983bd9
11 changed files with 67 additions and 14 deletions

View File

@@ -42,7 +42,7 @@ public sealed class MoveToOperator : HTNOperator
/// Where the pathfinding result will be stored (if applicable). This gets removed after execution.
/// </summary>
[ViewVariables, DataField("pathfindKey")]
public string PathfindKey = "MovementPathfind";
public string PathfindKey = NPCBlackboard.PathfindKey;
/// <summary>
/// How close we need to get before considering movement finished.

View File

@@ -30,7 +30,7 @@ public sealed class PickAccessibleComponentOperator : HTNOperator
/// Where the pathfinding result will be stored (if applicable). This gets removed after execution.
/// </summary>
[ViewVariables, DataField("pathfindKey")]
public string PathfindKey = "MovementPathfind";
public string PathfindKey = NPCBlackboard.PathfindKey;
public override void Initialize(IEntitySystemManager sysManager)
{

View File

@@ -23,7 +23,7 @@ public sealed class PickAccessibleOperator : HTNOperator
/// Where the pathfinding result will be stored (if applicable). This gets removed after execution.
/// </summary>
[ViewVariables, DataField("pathfindKey")]
public string PathfindKey = "MovementPathfind";
public string PathfindKey = NPCBlackboard.PathfindKey;
public override void Initialize(IEntitySystemManager sysManager)
{

View File

@@ -50,6 +50,9 @@ public sealed class MedibotInjectOperator : HTNOperator
if (!_entManager.TryGetComponent<MedibotComponent>(owner, out var botComp))
return HTNOperatorStatus.Failed;
// To avoid spam, the rest of this needs fixing.
_entManager.EnsureComponent<NPCRecentlyInjectedComponent>(target);
if (!_entManager.TryGetComponent<DamageableComponent>(target, out var damage))
return HTNOperatorStatus.Failed;
@@ -62,20 +65,18 @@ public sealed class MedibotInjectOperator : HTNOperator
if (damage.TotalDamage == 0)
return HTNOperatorStatus.Failed;
if (damage.TotalDamage <= MedibotComponent.StandardMedDamageThreshold)
if (damage.TotalDamage >= MedibotComponent.EmergencyMedDamageThreshold)
{
_solutionSystem.TryAddReagent(target, injectable, botComp.StandardMed, botComp.StandardMedInjectAmount, out var accepted);
_entManager.EnsureComponent<NPCRecentlyInjectedComponent>(target);
_solutionSystem.TryAddReagent(target, injectable, botComp.EmergencyMed, botComp.EmergencyMedInjectAmount, out var accepted);
_popupSystem.PopupEntity(Loc.GetString("hypospray-component-feel-prick-message"), target, Filter.Entities(target));
SoundSystem.Play("/Audio/Items/hypospray.ogg", Filter.Pvs(target), target);
_chat.TrySendInGameICMessage(owner, Loc.GetString("medibot-finish-inject"), InGameICChatType.Speak, false);
return HTNOperatorStatus.Finished;
}
if (damage.TotalDamage >= MedibotComponent.EmergencyMedDamageThreshold)
if (damage.TotalDamage >= MedibotComponent.StandardMedDamageThreshold)
{
_solutionSystem.TryAddReagent(target, injectable, botComp.EmergencyMed, botComp.EmergencyMedInjectAmount, out var accepted);
_entManager.EnsureComponent<NPCRecentlyInjectedComponent>(target);
_solutionSystem.TryAddReagent(target, injectable, botComp.StandardMed, botComp.StandardMedInjectAmount, out var accepted);
_popupSystem.PopupEntity(Loc.GetString("hypospray-component-feel-prick-message"), target, Filter.Entities(target));
SoundSystem.Play("/Audio/Items/hypospray.ogg", Filter.Pvs(target), target);
_chat.TrySendInGameICMessage(owner, Loc.GetString("medibot-finish-inject"), InGameICChatType.Speak, false);

View File

@@ -2,7 +2,9 @@ using System.Threading;
using System.Threading.Tasks;
using Content.Server.Chemistry.Components.SolutionManager;
using Content.Server.NPC.Components;
using Content.Server.NPC.Pathfinding;
using Content.Shared.Damage;
using Content.Shared.Interaction;
using Content.Shared.MobState.Components;
namespace Content.Server.NPC.HTN.PrimitiveTasks.Operators.Specific;
@@ -11,6 +13,7 @@ public sealed class PickNearbyInjectableOperator : HTNOperator
{
[Dependency] private readonly IEntityManager _entManager = default!;
private EntityLookupSystem _lookup = default!;
private PathfindingSystem _pathfinding = default!;
[ViewVariables, DataField("rangeKey")] public string RangeKey = NPCBlackboard.MedibotInjectRange;
@@ -30,6 +33,7 @@ public sealed class PickNearbyInjectableOperator : HTNOperator
{
base.Initialize(sysManager);
_lookup = sysManager.GetEntitySystem<EntityLookupSystem>();
_pathfinding = sysManager.GetEntitySystem<PathfindingSystem>();
}
public override async Task<(bool Valid, Dictionary<string, object>? Effects)> Plan(NPCBlackboard blackboard,
@@ -53,10 +57,16 @@ public sealed class PickNearbyInjectableOperator : HTNOperator
damage.TotalDamage > 0 &&
!recentlyInjected.HasComponent(entity))
{
var path = await _pathfinding.GetPath(owner, entity, SharedInteractionSystem.InteractionRange, cancelToken);
if (path.Result == PathResult.NoPath)
continue;
return (true, new Dictionary<string, object>()
{
{TargetKey, entity},
{TargetMoveKey, _entManager.GetComponent<TransformComponent>(entity).Coordinates}
{TargetMoveKey, _entManager.GetComponent<TransformComponent>(entity).Coordinates},
{NPCBlackboard.PathfindKey, path},
});
}
}

View File

@@ -196,6 +196,11 @@ public sealed class NPCBlackboard : IEnumerable<KeyValuePair<string, object>>
public const string OwnerCoordinates = "OwnerCoordinates";
public const string MovementTarget = "MovementTarget";
/// <summary>
/// Can the NPC click open entities such as doors.
/// </summary>
public const string NavInteract = "NavInteract";
/// <summary>
/// Can the NPC pry open doors for steering.
/// </summary>
@@ -205,6 +210,12 @@ public sealed class NPCBlackboard : IEnumerable<KeyValuePair<string, object>>
/// Can the NPC smash obstacles for steering.
/// </summary>
public const string NavSmash = "NavSmash";
/// <summary>
/// Default key storage for a movement pathfind.
/// </summary>
public const string PathfindKey = "MovementPathfind";
public const string RotateSpeed = "RotateSpeed";
public const string VisionRadius = "VisionRadius";
public const float MeleeRange = 1f;

View File

@@ -19,4 +19,9 @@ public enum PathFlags : byte
/// Can stuff like walls be broken.
/// </summary>
Smashing = 1 << 2,
/// <summary>
/// Can we open stuff that requires interaction (e.g. click-open doors).
/// </summary>
Interact = 1 << 3,
}

View File

@@ -58,7 +58,7 @@ public sealed partial class PathfindingSystem
// TODO: Handling power + door prying
// Door we should be able to open
if (isDoor && !isAccess)
if (isDoor && !isAccess && (request.Flags & PathFlags.Interact) != 0x0)
{
modifier += 0.5f;
}

View File

@@ -280,6 +280,21 @@ namespace Content.Server.NPC.Pathfinding
return distance;
}
public async Task<PathResultEvent> GetPath(
EntityUid entity,
EntityUid target,
float range,
CancellationToken cancelToken,
PathFlags flags = PathFlags.None)
{
if (!TryComp<TransformComponent>(entity, out var xform) ||
!TryComp<TransformComponent>(target, out var targetXform))
return new PathResultEvent(PathResult.NoPath, new Queue<PathPoly>());
var request = GetRequest(entity, xform.Coordinates, targetXform.Coordinates, range, cancelToken, flags);
return await GetPath(request);
}
public async Task<PathResultEvent> GetPath(
EntityUid entity,
EntityCoordinates start,
@@ -385,16 +400,21 @@ namespace Content.Server.NPC.Pathfinding
{
var flags = PathFlags.None;
if (blackboard.TryGetValue<bool>(NPCBlackboard.NavPry, out var pry))
if (blackboard.TryGetValue<bool>(NPCBlackboard.NavPry, out var pry) && pry)
{
flags |= PathFlags.Prying;
}
if (blackboard.TryGetValue<bool>(NPCBlackboard.NavSmash, out var smash))
if (blackboard.TryGetValue<bool>(NPCBlackboard.NavSmash, out var smash) && smash)
{
flags |= PathFlags.Smashing;
}
if (blackboard.TryGetValue<bool>(NPCBlackboard.NavInteract, out var interact) && interact)
{
flags |= PathFlags.Interact;
}
return flags;
}

View File

@@ -63,7 +63,7 @@ public sealed partial class NPCSteeringSystem
if (!doorQuery.TryGetComponent(ent, out var door))
continue;
if (!door.BumpOpen)
if (!door.BumpOpen && (component.Flags & PathFlags.Interact) != 0x0)
{
if (door.State != DoorState.Opening)
{
@@ -71,6 +71,10 @@ public sealed partial class NPCSteeringSystem
return SteeringObstacleStatus.Continuing;
}
}
else
{
return SteeringObstacleStatus.Failed;
}
}
return SteeringObstacleStatus.Completed;

View File

@@ -15,6 +15,8 @@
- type: HTN
rootTask: XenoCompound
blackboard:
NavInteract: !type:Bool
true
NavPry: !type:Bool
true
NavSmash: !type:Bool