From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Date: Fri, 21 Apr 2023 05:05:29 +0000 (+1000)
Subject: Fix NPC door prying (#15605)
X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=e780c6a98a1a8991ef30d7e621713d15e58210dd;p=space-station-14.git
Fix NPC door prying (#15605)
---
diff --git a/Content.Server/Doors/Systems/DoorSystem.cs b/Content.Server/Doors/Systems/DoorSystem.cs
index d6ecd5d65b..e35ef5c9da 100644
--- a/Content.Server/Doors/Systems/DoorSystem.cs
+++ b/Content.Server/Doors/Systems/DoorSystem.cs
@@ -1,3 +1,4 @@
+using System.Diagnostics.CodeAnalysis;
using Content.Server.Access;
using Content.Server.Atmos.Components;
using Content.Server.Atmos.EntitySystems;
@@ -127,7 +128,7 @@ public sealed class DoorSystem : SharedDoorSystem
if (tool.Qualities.Contains(door.PryingQuality))
{
- args.Handled = TryPryDoor(uid, args.Used, args.User, door);
+ args.Handled = TryPryDoor(uid, args.Used, args.User, door, out _);
}
}
@@ -164,7 +165,7 @@ public sealed class DoorSystem : SharedDoorSystem
{
Text = Loc.GetString("door-pry"),
Impact = LogImpact.Low,
- Act = () => TryPryDoor(uid, args.User, args.User, component, true),
+ Act = () => TryPryDoor(uid, args.User, args.User, component, out _, force: true),
});
}
@@ -172,8 +173,10 @@ public sealed class DoorSystem : SharedDoorSystem
///
/// Pry open a door. This does not check if the user is holding the required tool.
///
- public bool TryPryDoor(EntityUid target, EntityUid tool, EntityUid user, DoorComponent door, bool force = false)
+ public bool TryPryDoor(EntityUid target, EntityUid tool, EntityUid user, DoorComponent door, out DoAfterId? id, bool force = false)
{
+ id = null;
+
if (door.State == DoorState.Welded)
return false;
@@ -191,7 +194,7 @@ public sealed class DoorSystem : SharedDoorSystem
var modEv = new DoorGetPryTimeModifierEvent(user);
RaiseLocalEvent(target, modEv, false);
- _toolSystem.UseTool(tool, user, target, modEv.PryTimeModifier * door.PryTime, door.PryingQuality, new DoorPryDoAfterEvent());
+ _toolSystem.UseTool(tool, user, target, TimeSpan.FromSeconds(modEv.PryTimeModifier * door.PryTime), new[] {door.PryingQuality}, new DoorPryDoAfterEvent(), out id);
return true; // we might not actually succeeded, but a do-after has started
}
diff --git a/Content.Server/NPC/Components/NPCSteeringComponent.cs b/Content.Server/NPC/Components/NPCSteeringComponent.cs
index 3e87ac9f20..18a5a56527 100644
--- a/Content.Server/NPC/Components/NPCSteeringComponent.cs
+++ b/Content.Server/NPC/Components/NPCSteeringComponent.cs
@@ -1,5 +1,6 @@
using System.Threading;
using Content.Server.NPC.Pathfinding;
+using Content.Shared.DoAfter;
using Content.Shared.NPC;
using Robust.Shared.Map;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
@@ -96,6 +97,12 @@ public sealed class NPCSteeringComponent : Component
[ViewVariables] public SteeringStatus Status = SteeringStatus.Moving;
[ViewVariables(VVAccess.ReadWrite)] public PathFlags Flags = PathFlags.None;
+
+ ///
+ /// If the NPC is using a do_after to clear an obstacle.
+ ///
+ [DataField("doAfterId")]
+ public DoAfterId? DoAfterId = null;
}
public enum SteeringStatus : byte
diff --git a/Content.Server/NPC/Systems/NPCSteeringSystem.Context.cs b/Content.Server/NPC/Systems/NPCSteeringSystem.Context.cs
index df7e13e65d..e8ef3c0cb3 100644
--- a/Content.Server/NPC/Systems/NPCSteeringSystem.Context.cs
+++ b/Content.Server/NPC/Systems/NPCSteeringSystem.Context.cs
@@ -133,8 +133,10 @@ public sealed partial class NPCSteeringSystem
switch (status)
{
case SteeringObstacleStatus.Completed:
+ steering.DoAfterId = null;
break;
case SteeringObstacleStatus.Failed:
+ steering.DoAfterId = null;
// TODO: Blacklist the poly for next query
steering.Status = SteeringStatus.NoPath;
return false;
diff --git a/Content.Server/NPC/Systems/NPCSteeringSystem.Obstacles.cs b/Content.Server/NPC/Systems/NPCSteeringSystem.Obstacles.cs
index 8fd83e5162..0a49846bce 100644
--- a/Content.Server/NPC/Systems/NPCSteeringSystem.Obstacles.cs
+++ b/Content.Server/NPC/Systems/NPCSteeringSystem.Obstacles.cs
@@ -2,6 +2,7 @@ using Content.Server.Destructible;
using Content.Server.NPC.Components;
using Content.Server.NPC.Pathfinding;
using Content.Shared.CombatMode;
+using Content.Shared.DoAfter;
using Content.Shared.Doors.Components;
using Content.Shared.NPC;
using Robust.Shared.Physics;
@@ -55,14 +56,27 @@ public sealed partial class NPCSteeringSystem
if ((poly.Data.CollisionLayer & mask) != 0x0 ||
(poly.Data.CollisionMask & layer) != 0x0)
{
+ var id = component.DoAfterId;
+
+ // Still doing what we were doing before.
+ var doAfterStatus = _doAfter.GetStatus(id);
+
+ switch (doAfterStatus)
+ {
+ case DoAfterStatus.Running:
+ return SteeringObstacleStatus.Continuing;
+ case DoAfterStatus.Cancelled:
+ return SteeringObstacleStatus.Failed;
+ }
+
var obstacleEnts = new List();
GetObstacleEntities(poly, mask, layer, bodyQuery, obstacleEnts);
var isDoor = (poly.Data.Flags & PathfindingBreadcrumbFlag.Door) != 0x0;
- var isAccess = (poly.Data.Flags & PathfindingBreadcrumbFlag.Access) != 0x0;
+ var isAccessRequired = (poly.Data.Flags & PathfindingBreadcrumbFlag.Access) != 0x0;
// Just walk into it stupid
- if (isDoor && !isAccess)
+ if (isDoor && !isAccessRequired)
{
var doorQuery = GetEntityQuery();
@@ -80,16 +94,12 @@ public sealed partial class NPCSteeringSystem
return SteeringObstacleStatus.Continuing;
}
}
- else
- {
- return SteeringObstacleStatus.Failed;
- }
}
- return SteeringObstacleStatus.Completed;
+ // If we get to here then didn't succeed for reasons.
}
- if ((component.Flags & PathFlags.Prying) != 0x0 && isAccess && isDoor)
+ if ((component.Flags & PathFlags.Prying) != 0x0 && isDoor)
{
var doorQuery = GetEntityQuery();
@@ -101,8 +111,9 @@ public sealed partial class NPCSteeringSystem
// TODO: Use the verb.
if (door.State != DoorState.Opening)
- _doors.TryPryDoor(ent, uid, uid, door, true);
+ _doors.TryPryDoor(ent, uid, uid, door, out id, force: true);
+ component.DoAfterId = id;
return SteeringObstacleStatus.Continuing;
}
}
diff --git a/Content.Server/NPC/Systems/NPCSteeringSystem.cs b/Content.Server/NPC/Systems/NPCSteeringSystem.cs
index 8df27d48e8..7ab9231648 100644
--- a/Content.Server/NPC/Systems/NPCSteeringSystem.cs
+++ b/Content.Server/NPC/Systems/NPCSteeringSystem.cs
@@ -2,6 +2,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Content.Server.Administration.Managers;
+using Content.Server.DoAfter;
using Content.Server.Doors.Systems;
using Content.Server.NPC.Components;
using Content.Server.NPC.Events;
@@ -47,6 +48,7 @@ namespace Content.Server.NPC.Systems
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IParallelManager _parallel = default!;
[Dependency] private readonly IRobustRandom _random = default!;
+ [Dependency] private readonly DoAfterSystem _doAfter = default!;
[Dependency] private readonly DoorSystem _doors = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly FactionSystem _faction = default!;
diff --git a/Content.Shared/DoAfter/SharedDoAfterSystem.cs b/Content.Shared/DoAfter/SharedDoAfterSystem.cs
index 5ac861ab9a..27011816cd 100644
--- a/Content.Shared/DoAfter/SharedDoAfterSystem.cs
+++ b/Content.Shared/DoAfter/SharedDoAfterSystem.cs
@@ -356,7 +356,7 @@ public abstract partial class SharedDoAfterSystem : EntitySystem
if (doAfter.Cancelled)
return DoAfterStatus.Cancelled;
- if (GameTiming.CurTime - doAfter.StartTime < doAfter.Args.Delay)
+ if (!doAfter.Completed)
return DoAfterStatus.Running;
// Theres the chance here that the DoAfter hasn't actually finished yet if the system's update hasn't run yet.
diff --git a/Content.Shared/Tools/Systems/SharedToolSystem.cs b/Content.Shared/Tools/Systems/SharedToolSystem.cs
index b480e98df4..8cd99f14aa 100644
--- a/Content.Shared/Tools/Systems/SharedToolSystem.cs
+++ b/Content.Shared/Tools/Systems/SharedToolSystem.cs
@@ -119,7 +119,7 @@ public abstract partial class SharedToolSystem : EntitySystem
BreakOnDamage = true,
BreakOnTargetMove = true,
BreakOnUserMove = true,
- NeedHand = true,
+ NeedHand = tool != user,
AttemptFrequency = fuel <= 0 ? AttemptFrequency.Never : AttemptFrequency.EveryTick
};