From 72eb1fdc1c754ca477ff2ae696fa0158b72d7d48 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Sun, 30 Aug 2020 19:16:29 +1000 Subject: [PATCH] Add door welding (#1951) * Add door welding Surprised this wasn't in already. * smug's feedback Co-authored-by: Metal Gear Sloth --- .../Components/Doors/AirlockVisualizer.cs | 8 +++- .../Components/Doors/AirlockComponent.cs | 9 ++-- .../Components/Doors/ServerDoorComponent.cs | 48 +++++++++++++++++-- .../Components/Doors/SharedDoorComponent.cs | 1 + .../Constructible/Doors/airlock_base.yml | 2 + 5 files changed, 60 insertions(+), 8 deletions(-) diff --git a/Content.Client/GameObjects/Components/Doors/AirlockVisualizer.cs b/Content.Client/GameObjects/Components/Doors/AirlockVisualizer.cs index 622e9d0c23..2c0994a35e 100644 --- a/Content.Client/GameObjects/Components/Doors/AirlockVisualizer.cs +++ b/Content.Client/GameObjects/Components/Doors/AirlockVisualizer.cs @@ -107,6 +107,7 @@ namespace Content.Client.GameObjects.Components.Doors var unlitVisible = true; var boltedVisible = false; + var weldedVisible = false; switch (state) { case DoorVisualState.Closed: @@ -137,6 +138,9 @@ namespace Content.Client.GameObjects.Components.Doors animPlayer.Play(DenyAnimation, AnimationKey); } break; + case DoorVisualState.Welded: + weldedVisible = true; + break; default: throw new ArgumentOutOfRangeException(); } @@ -151,6 +155,7 @@ namespace Content.Client.GameObjects.Components.Doors } sprite.LayerSetVisible(DoorVisualLayers.BaseUnlit, unlitVisible); + sprite.LayerSetVisible(DoorVisualLayers.BaseWelded, weldedVisible); sprite.LayerSetVisible(DoorVisualLayers.BaseBolted, unlitVisible && boltedVisible); } } @@ -159,6 +164,7 @@ namespace Content.Client.GameObjects.Components.Doors { Base, BaseUnlit, - BaseBolted + BaseWelded, + BaseBolted, } } diff --git a/Content.Server/GameObjects/Components/Doors/AirlockComponent.cs b/Content.Server/GameObjects/Components/Doors/AirlockComponent.cs index e33ab84758..ab58e2461c 100644 --- a/Content.Server/GameObjects/Components/Doors/AirlockComponent.cs +++ b/Content.Server/GameObjects/Components/Doors/AirlockComponent.cs @@ -26,7 +26,7 @@ namespace Content.Server.GameObjects.Components.Doors [RegisterComponent] [ComponentReference(typeof(IActivate))] [ComponentReference(typeof(ServerDoorComponent))] - public class AirlockComponent : ServerDoorComponent, IWires, IInteractUsing + public class AirlockComponent : ServerDoorComponent, IWires { public override string Name => "Airlock"; @@ -383,7 +383,7 @@ namespace Content.Server.GameObjects.Components.Doors public override bool CanOpen() { - return IsPowered() && !IsBolted(); + return base.CanOpen() && IsPowered() && !IsBolted(); } public override bool CanClose() @@ -412,8 +412,11 @@ namespace Content.Server.GameObjects.Components.Doors || receiver.Powered; } - public async Task InteractUsing(InteractUsingEventArgs eventArgs) + public override async Task InteractUsing(InteractUsingEventArgs eventArgs) { + if (await base.InteractUsing(eventArgs)) + return true; + if (!eventArgs.Using.TryGetComponent(out var tool)) return false; diff --git a/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs b/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs index 064bc6fde4..5042371ea4 100644 --- a/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs +++ b/Content.Server/GameObjects/Components/Doors/ServerDoorComponent.cs @@ -2,15 +2,18 @@ using System; using System.Linq; using System.Threading; +using System.Threading.Tasks; using Content.Server.GameObjects.Components.Access; using Content.Server.GameObjects.Components.Atmos; using Content.Server.GameObjects.Components.GUI; +using Content.Server.GameObjects.Components.Interactable; using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.EntitySystems; using Content.Shared.Damage; using Content.Shared.GameObjects.Components.Body; using Content.Shared.GameObjects.Components.Damage; using Content.Shared.GameObjects.Components.Doors; +using Content.Shared.GameObjects.Components.Interactable; using Content.Shared.GameObjects.Components.Movement; using Content.Shared.Interfaces.GameObjects.Components; using Robust.Server.GameObjects; @@ -29,7 +32,7 @@ namespace Content.Server.GameObjects.Components.Doors { [RegisterComponent] [ComponentReference(typeof(IActivate))] - public class ServerDoorComponent : Component, IActivate, ICollideBehavior + public class ServerDoorComponent : Component, IActivate, ICollideBehavior, IInteractUsing { public override string Name => "Door"; @@ -45,7 +48,7 @@ namespace Content.Server.GameObjects.Components.Doors protected bool AutoClose = true; protected const float AutoCloseDelay = 5; protected float CloseSpeed = AutoCloseDelay; - + private CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); private static readonly TimeSpan CloseTimeOne = TimeSpan.FromSeconds(0.3f); @@ -60,11 +63,31 @@ namespace Content.Server.GameObjects.Components.Doors [ViewVariables] private bool _occludes; + [ViewVariables] + public bool IsWeldedShut + { + get => _isWeldedShut; + set + { + if (_isWeldedShut == value) + { + return; + } + + _isWeldedShut = value; + SetAppearance(_isWeldedShut ? DoorVisualState.Welded : DoorVisualState.Closed); + } + } + private bool _isWeldedShut; + + private bool _canWeldShut = true; + public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); serializer.DataField(ref _occludes, "occludes", true); + serializer.DataField(ref _isWeldedShut, "welded", false); } public override void OnRemove() @@ -129,7 +152,7 @@ namespace Content.Server.GameObjects.Components.Doors public virtual bool CanOpen() { - return true; + return !_isWeldedShut; } public bool CanOpen(IEntity user) @@ -192,6 +215,7 @@ namespace Content.Server.GameObjects.Components.Doors return; } + _canWeldShut = false; State = DoorState.Opening; SetAppearance(DoorVisualState.Opening); if (_occludes && Owner.TryGetComponent(out OccluderComponent? occluder)) @@ -325,6 +349,7 @@ namespace Content.Server.GameObjects.Components.Doors await Timer.Delay(CloseTimeTwo, _cancellationTokenSource.Token); + _canWeldShut = true; State = DoorState.Closed; SetAppearance(DoorVisualState.Closed); }, _cancellationTokenSource.Token); @@ -334,7 +359,7 @@ namespace Content.Server.GameObjects.Components.Doors public virtual void Deny() { - if (State == DoorState.Open) + if (State == DoorState.Open || _isWeldedShut) { return; } @@ -375,5 +400,20 @@ namespace Content.Server.GameObjects.Components.Doors Closing, Opening, } + + public virtual async Task InteractUsing(InteractUsingEventArgs eventArgs) + { + if (!_canWeldShut) + return false; + + if (!eventArgs.Using.TryGetComponent(out WelderComponent? tool)) + return false; + + if (!await tool.UseTool(eventArgs.User, Owner, 3f, ToolQuality.Welding, 3f, () => _canWeldShut)) + return false; + + IsWeldedShut ^= true; + return true; + } } } diff --git a/Content.Shared/GameObjects/Components/Doors/SharedDoorComponent.cs b/Content.Shared/GameObjects/Components/Doors/SharedDoorComponent.cs index 37f34ac70d..e9fbcb32d6 100644 --- a/Content.Shared/GameObjects/Components/Doors/SharedDoorComponent.cs +++ b/Content.Shared/GameObjects/Components/Doors/SharedDoorComponent.cs @@ -21,5 +21,6 @@ namespace Content.Shared.GameObjects.Components.Doors Open, Closing, Deny, + Welded, } } diff --git a/Resources/Prototypes/Entities/Constructible/Doors/airlock_base.yml b/Resources/Prototypes/Entities/Constructible/Doors/airlock_base.yml index 931791379e..54163a71c3 100644 --- a/Resources/Prototypes/Entities/Constructible/Doors/airlock_base.yml +++ b/Resources/Prototypes/Entities/Constructible/Doors/airlock_base.yml @@ -16,6 +16,8 @@ - state: closed_unlit shader: unshaded map: ["enum.DoorVisualLayers.BaseUnlit"] + - state: welded + map: ["enum.DoorVisualLayers.BaseWelded"] - state: bolted shader: unshaded map: ["enum.DoorVisualLayers.BaseBolted"]