EasyPry airlocks for arrivals. Now also prying refactor I guess (#19394)

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
nikthechampiongr
2023-09-28 11:34:21 +00:00
committed by GitHub
parent cbeba20ebb
commit 5ff79120e6
24 changed files with 463 additions and 170 deletions

View File

@@ -1,7 +1,6 @@
using Content.Server.DeviceLinking.Events;
using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Shared.Tools.Components;
using Content.Server.Wires;
using Content.Shared.Doors;
using Content.Shared.Doors.Components;
@@ -9,6 +8,7 @@ using Content.Shared.Doors.Systems;
using Content.Shared.Interaction;
using Robust.Server.GameObjects;
using Content.Shared.Wires;
using Content.Shared.Prying.Components;
using Robust.Shared.Prototypes;
namespace Content.Server.Doors.Systems;
@@ -31,9 +31,9 @@ public sealed class AirlockSystem : SharedAirlockSystem
SubscribeLocalEvent<AirlockComponent, DoorStateChangedEvent>(OnStateChanged);
SubscribeLocalEvent<AirlockComponent, BeforeDoorOpenedEvent>(OnBeforeDoorOpened);
SubscribeLocalEvent<AirlockComponent, BeforeDoorDeniedEvent>(OnBeforeDoorDenied);
SubscribeLocalEvent<AirlockComponent, ActivateInWorldEvent>(OnActivate, before: new [] {typeof(DoorSystem)});
SubscribeLocalEvent<AirlockComponent, DoorGetPryTimeModifierEvent>(OnGetPryMod);
SubscribeLocalEvent<AirlockComponent, BeforeDoorPryEvent>(OnDoorPry);
SubscribeLocalEvent<AirlockComponent, ActivateInWorldEvent>(OnActivate, before: new[] { typeof(DoorSystem) });
SubscribeLocalEvent<AirlockComponent, GetPryTimeModifierEvent>(OnGetPryMod);
SubscribeLocalEvent<AirlockComponent, BeforePryEvent>(OnBeforePry);
}
@@ -169,20 +169,18 @@ public sealed class AirlockSystem : SharedAirlockSystem
}
}
private void OnGetPryMod(EntityUid uid, AirlockComponent component, DoorGetPryTimeModifierEvent args)
private void OnGetPryMod(EntityUid uid, AirlockComponent component, ref GetPryTimeModifierEvent args)
{
if (_power.IsPowered(uid))
args.PryTimeModifier *= component.PoweredPryModifier;
}
private void OnDoorPry(EntityUid uid, AirlockComponent component, BeforeDoorPryEvent args)
private void OnBeforePry(EntityUid uid, AirlockComponent component, ref BeforePryEvent args)
{
if (this.IsPowered(uid, EntityManager))
if (this.IsPowered(uid, EntityManager) && !args.PryPowered)
{
if (HasComp<ToolForcePoweredComponent>(args.Tool))
return;
Popup.PopupEntity(Loc.GetString("airlock-component-cannot-pry-is-powered-message"), uid, args.User);
args.Cancel();
Popup.PopupClient(Loc.GetString("airlock-component-cannot-pry-is-powered-message"), uid, args.User);
args.Cancelled = true;
}
}

View File

@@ -1,15 +1,12 @@
using Content.Server.Access;
using Content.Server.Atmos.Components;
using Content.Server.Atmos.EntitySystems;
using Content.Server.Construction;
using Content.Shared.Database;
using Content.Shared.Doors;
using Content.Shared.Doors.Components;
using Content.Shared.Doors.Systems;
using Content.Shared.Emag.Systems;
using Content.Shared.Interaction;
using Content.Shared.Tools.Components;
using Content.Shared.Verbs;
using Robust.Shared.Audio;
using Content.Server.Administration.Logs;
using Content.Server.Power.EntitySystems;
@@ -17,6 +14,8 @@ using Content.Shared.Tools;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Events;
using Content.Shared.DoAfter;
using Content.Shared.Prying.Systems;
using Content.Shared.Prying.Components;
using Content.Shared.Tools.Systems;
namespace Content.Server.Doors.Systems;
@@ -27,20 +26,19 @@ public sealed class DoorSystem : SharedDoorSystem
[Dependency] private readonly DoorBoltSystem _bolts = default!;
[Dependency] private readonly AirtightSystem _airtightSystem = default!;
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
[Dependency] private readonly PryingSystem _pryingSystem = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<DoorComponent, InteractUsingEvent>(OnInteractUsing, after: new[] { typeof(ConstructionSystem) });
// Mob prying doors
SubscribeLocalEvent<DoorComponent, GetVerbsEvent<AlternativeVerb>>(OnDoorAltVerb);
SubscribeLocalEvent<DoorComponent, DoorPryDoAfterEvent>(OnPryFinished);
SubscribeLocalEvent<DoorComponent, BeforePryEvent>(OnBeforeDoorPry);
SubscribeLocalEvent<DoorComponent, WeldableAttemptEvent>(OnWeldAttempt);
SubscribeLocalEvent<DoorComponent, WeldableChangedEvent>(OnWeldChanged);
SubscribeLocalEvent<DoorComponent, GotEmaggedEvent>(OnEmagged);
SubscribeLocalEvent<DoorComponent, PriedEvent>(OnAfterPry);
}
protected override void OnActivate(EntityUid uid, DoorComponent door, ActivateInWorldEvent args)
@@ -49,7 +47,9 @@ public sealed class DoorSystem : SharedDoorSystem
if (args.Handled || !door.ClickOpen)
return;
TryToggleDoor(uid, door, args.User);
if (!TryToggleDoor(uid, door, args.User))
_pryingSystem.TryPry(uid, args.User, out _);
args.Handled = true;
}
@@ -108,24 +108,7 @@ public sealed class DoorSystem : SharedDoorSystem
Audio.PlayPvs(soundSpecifier, uid, audioParams);
}
#region DoAfters
/// <summary>
/// Weld or pry open a door.
/// </summary>
private void OnInteractUsing(EntityUid uid, DoorComponent door, InteractUsingEvent args)
{
if (args.Handled)
return;
if (!TryComp(args.Used, out ToolComponent? tool))
return;
if (tool.Qualities.Contains(door.PryingQuality))
{
args.Handled = TryPryDoor(uid, args.Used, args.User, door, out _);
}
}
#region DoAfters
private void OnWeldAttempt(EntityUid uid, DoorComponent component, WeldableAttemptEvent args)
{
if (component.CurrentlyCrushing.Count > 0)
@@ -147,69 +130,12 @@ public sealed class DoorSystem : SharedDoorSystem
SetState(uid, DoorState.Closed, component);
}
private void OnDoorAltVerb(EntityUid uid, DoorComponent component, GetVerbsEvent<AlternativeVerb> args)
private void OnBeforeDoorPry(EntityUid id, DoorComponent door, ref BeforePryEvent args)
{
if (!args.CanInteract || !args.CanAccess)
return;
if (!TryComp<ToolComponent>(args.User, out var tool) || !tool.Qualities.Contains(component.PryingQuality))
return;
args.Verbs.Add(new AlternativeVerb()
{
Text = Loc.GetString("door-pry"),
Impact = LogImpact.Low,
Act = () => TryPryDoor(uid, args.User, args.User, component, out _, force: true),
});
if (door.State == DoorState.Welded || !door.CanPry)
args.Cancelled = true;
}
/// <summary>
/// Pry open a door. This does not check if the user is holding the required tool.
/// </summary>
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;
if (!force)
{
var canEv = new BeforeDoorPryEvent(user, tool);
RaiseLocalEvent(target, canEv, false);
if (!door.CanPry || 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(user);
RaiseLocalEvent(target, modEv, false);
_adminLog.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(user)} is using {ToPrettyString(tool)} to pry {ToPrettyString(target)} while it is {door.State}"); // TODO move to generic tool use logging in a way that includes door state
_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
}
private void OnPryFinished(EntityUid uid, DoorComponent door, DoAfterEvent args)
{
if (args.Cancelled)
return;
if (door.State == DoorState.Closed)
{
_adminLog.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(args.User)} pried {ToPrettyString(uid)} open"); // TODO move to generic tool use logging in a way that includes door state
StartOpening(uid, door);
}
else if (door.State == DoorState.Open)
{
_adminLog.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(args.User)} pried {ToPrettyString(uid)} closed"); // TODO move to generic tool use logging in a way that includes door state
StartClosing(uid, door);
}
}
#endregion
#endregion
/// <summary>
@@ -233,7 +159,7 @@ public sealed class DoorSystem : SharedDoorSystem
}
private void OnEmagged(EntityUid uid, DoorComponent door, ref GotEmaggedEvent args)
{
if(TryComp<AirlockComponent>(uid, out var airlockComponent))
if (TryComp<AirlockComponent>(uid, out var airlockComponent))
{
if (_bolts.IsBolted(uid) || !this.IsPowered(uid, EntityManager))
return;
@@ -259,10 +185,27 @@ public sealed class DoorSystem : SharedDoorSystem
if (door.OpenSound != null)
PlaySound(uid, door.OpenSound, AudioParams.Default.WithVolume(-5), user, predicted);
if(lastState == DoorState.Emagging && TryComp<DoorBoltComponent>(uid, out var doorBoltComponent))
if (lastState == DoorState.Emagging && TryComp<DoorBoltComponent>(uid, out var doorBoltComponent))
_bolts.SetBoltsWithAudio(uid, doorBoltComponent, !doorBoltComponent.BoltsDown);
}
/// <summary>
/// Open or close a door after it has been successfuly pried.
/// </summary>
private void OnAfterPry(EntityUid uid, DoorComponent door, ref PriedEvent args)
{
if (door.State == DoorState.Closed)
{
_adminLog.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(args.User)} pried {ToPrettyString(uid)} open");
StartOpening(uid, door, args.User);
}
else if (door.State == DoorState.Open)
{
_adminLog.Add(LogType.Action, LogImpact.Medium, $"{ToPrettyString(args.User)} pried {ToPrettyString(uid)} closed");
StartClosing(uid, door, args.User);
}
}
protected override void CheckDoorBump(DoorComponent component, PhysicsComponent body)
{
var uid = body.Owner;

View File

@@ -18,6 +18,7 @@ using Microsoft.Extensions.Options;
using Robust.Server.GameObjects;
using Robust.Shared.Map.Components;
using Robust.Shared.Player;
using Content.Shared.Prying.Components;
namespace Content.Server.Doors.Systems
{
@@ -38,7 +39,7 @@ namespace Content.Server.Doors.Systems
base.Initialize();
SubscribeLocalEvent<FirelockComponent, BeforeDoorOpenedEvent>(OnBeforeDoorOpened);
SubscribeLocalEvent<FirelockComponent, DoorGetPryTimeModifierEvent>(OnDoorGetPryTimeModifier);
SubscribeLocalEvent<FirelockComponent, GetPryTimeModifierEvent>(OnDoorGetPryTimeModifier);
SubscribeLocalEvent<FirelockComponent, DoorStateChangedEvent>(OnUpdateState);
SubscribeLocalEvent<FirelockComponent, BeforeDoorAutoCloseEvent>(OnBeforeDoorAutoclose);
@@ -144,7 +145,7 @@ namespace Content.Server.Doors.Systems
args.Cancel();
}
private void OnDoorGetPryTimeModifier(EntityUid uid, FirelockComponent component, DoorGetPryTimeModifierEvent args)
private void OnDoorGetPryTimeModifier(EntityUid uid, FirelockComponent component, ref GetPryTimeModifierEvent args)
{
var state = CheckPressureAndFire(uid, component);
@@ -261,7 +262,7 @@ namespace Content.Server.Doors.Systems
List<AtmosDirection> directions = new(4);
for (var i = 0; i < Atmospherics.Directions; i++)
{
var dir = (AtmosDirection) (1 << i);
var dir = (AtmosDirection)(1 << i);
if (airtight.AirBlockedDirection.HasFlag(dir))
{
directions.Add(dir);