diff --git a/Content.Server/Doors/Systems/DoorSystem.cs b/Content.Server/Doors/Systems/DoorSystem.cs index 2c7dd7b715..083524132d 100644 --- a/Content.Server/Doors/Systems/DoorSystem.cs +++ b/Content.Server/Doors/Systems/DoorSystem.cs @@ -18,8 +18,12 @@ using Robust.Shared.Containers; using Robust.Shared.Physics.Dynamics; using Robust.Shared.Player; using System.Linq; +using System.Threading; using Content.Server.Tools.Systems; +using Content.Shared.Database; +using Content.Shared.Sound; using Content.Shared.Tools.Components; +using Content.Shared.Verbs; namespace Content.Server.Doors.Systems; @@ -37,6 +41,9 @@ public sealed class DoorSystem : SharedDoorSystem SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnInteractUsing, after: new[] { typeof(ConstructionSystem) }); + // Mob prying doors + SubscribeLocalEvent>(OnDoorAltVerb); + SubscribeLocalEvent(OnPryFinished); SubscribeLocalEvent(OnPryCancelled); SubscribeLocalEvent(OnWeldAttempt); @@ -152,25 +159,43 @@ public sealed class DoorSystem : SharedDoorSystem SetState(uid, DoorState.Closed, component); } + private void OnDoorAltVerb(EntityUid uid, DoorComponent component, GetVerbsEvent args) + { + if (!args.CanInteract || !TryComp(args.User, out var tool) || !tool.Qualities.Contains(component.PryingQuality)) return; + + args.Verbs.Add(new AlternativeVerb() + { + Text = "Pry door", + Impact = LogImpact.Low, + Act = () => TryPryDoor(uid, args.User, args.User, component, true), + }); + } + /// /// Pry open a door. This does not check if the user is holding the required tool. /// - private bool TryPryDoor(EntityUid target, EntityUid tool, EntityUid user, DoorComponent door) + private bool TryPryDoor(EntityUid target, EntityUid tool, EntityUid user, DoorComponent door, bool force = false) { + if (door.BeingPried) return false; + if (door.State == DoorState.Welded) return false; - var canEv = new BeforeDoorPryEvent(user); - RaiseLocalEvent(target, canEv, false); + if (!force) + { + var canEv = new BeforeDoorPryEvent(user); + RaiseLocalEvent(target, canEv, false); - if (canEv.Cancelled) - // mark handled, as airlock component will cancel after generating a pop-up & you don't want to pry a tile - // under a windoor. - return true; + if (canEv.Cancelled) + // mark handled, as airlock component will cancel after generating a pop-up & you don't want to pry a tile + // under a windoor. + return true; + } var modEv = new DoorGetPryTimeModifierEvent(); RaiseLocalEvent(target, modEv, false); + door.BeingPried = true; _toolSystem.UseTool(tool, user, target, 0f, modEv.PryTimeModifier * door.PryTime, door.PryingQuality, new PryFinishedEvent(), new PryCancelledEvent(), target); diff --git a/Content.Server/Tools/ToolSystem.TilePrying.cs b/Content.Server/Tools/ToolSystem.TilePrying.cs index ed84b0a48d..d6a79e3707 100644 --- a/Content.Server/Tools/ToolSystem.TilePrying.cs +++ b/Content.Server/Tools/ToolSystem.TilePrying.cs @@ -4,7 +4,9 @@ using Content.Server.Tools.Components; using Content.Shared.Interaction; using Content.Shared.Maps; using Content.Shared.Tools.Components; +using Robust.Shared.Audio; using Robust.Shared.Map; +using Robust.Shared.Player; using Robust.Shared.Utility; namespace Content.Server.Tools; diff --git a/Content.Shared/Doors/Components/DoorComponent.cs b/Content.Shared/Doors/Components/DoorComponent.cs index 30eb7a7382..6fc3e7fb11 100644 --- a/Content.Shared/Doors/Components/DoorComponent.cs +++ b/Content.Shared/Doors/Components/DoorComponent.cs @@ -1,6 +1,8 @@ +using System.Threading; using Content.Shared.Damage; using Content.Shared.Sound; using Content.Shared.Tools; +using Robust.Shared.Audio; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; diff --git a/Content.Shared/Doors/Systems/SharedDoorSystem.cs b/Content.Shared/Doors/Systems/SharedDoorSystem.cs index 06baab6635..3b2d3e99fa 100644 --- a/Content.Shared/Doors/Systems/SharedDoorSystem.cs +++ b/Content.Shared/Doors/Systems/SharedDoorSystem.cs @@ -11,6 +11,8 @@ using Robust.Shared.Physics.Dynamics; using Robust.Shared.Timing; using System.Linq; using Content.Shared.Tag; +using Content.Shared.Tools.Components; +using Content.Shared.Verbs; namespace Content.Shared.Doors.Systems; diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml index 10e7c8fd96..9e768d4c85 100644 --- a/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml +++ b/Resources/Prototypes/Entities/Mobs/NPCs/xeno.yml @@ -13,6 +13,12 @@ behaviorSets: - Idle - UnarmedAttackHostiles + - type: Tool + speed: 0.3 + qualities: + - Prying + useSound: + path: /Audio/Items/crowbar.ogg - type: Reactive groups: Flammable: [Touch]