From 879438169755aa7cd6645e6c3c82446a9c2eb826 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Mon, 25 May 2020 13:58:56 +0200 Subject: [PATCH] Secure lockers & locker welding. --- .../Components/Storage/StorageVisualizer2D.cs | 23 ++- .../Items/Storage/EntityStorageComponent.cs | 118 +++++++++++-- .../Storage/SecureEntityStorageComponent.cs | 157 ++++++++++++++++++ .../Storage/SharedStorageComponent.cs | 5 +- Resources/Audio/machines/door_lock_off.ogg | Bin 0 -> 10588 bytes Resources/Audio/machines/door_lock_on.ogg | Bin 0 -> 10847 bytes .../Storage/Closets/closet_secure.yml | 17 +- .../Entities/Buildings/Storage/closet.yml | 3 + .../Entities/Buildings/Storage/crate_base.yml | 1 + 9 files changed, 305 insertions(+), 19 deletions(-) create mode 100644 Content.Server/GameObjects/Components/Items/Storage/SecureEntityStorageComponent.cs create mode 100644 Resources/Audio/machines/door_lock_off.ogg create mode 100644 Resources/Audio/machines/door_lock_on.ogg diff --git a/Content.Client/GameObjects/Components/Storage/StorageVisualizer2D.cs b/Content.Client/GameObjects/Components/Storage/StorageVisualizer2D.cs index b64b5b974e..e9cfe3e356 100644 --- a/Content.Client/GameObjects/Components/Storage/StorageVisualizer2D.cs +++ b/Content.Client/GameObjects/Components/Storage/StorageVisualizer2D.cs @@ -59,11 +59,32 @@ namespace Content.Client.GameObjects.Components.Storage sprite.LayerSetState(StorageVisualLayers.Door, open ? _stateOpen ?? $"{_stateBase}_open" : _stateClosed ?? $"{_stateBase}_door"); + + if (component.TryGetData(StorageVisuals.CanLock, out bool canLock) && canLock) + { + if (!component.TryGetData(StorageVisuals.Locked, out bool locked)) + { + locked = true; + } + + sprite.LayerSetVisible(StorageVisualLayers.Lock, !open); + if (!open) + { + sprite.LayerSetState(StorageVisualLayers.Lock, locked ? "locked" : "unlocked"); + } + } + + if (component.TryGetData(StorageVisuals.Welded, out bool weldedVal)) + { + sprite.LayerSetVisible(StorageVisualLayers.Welded, weldedVal); + } } } public enum StorageVisualLayers { - Door + Door, + Welded, + Lock } } diff --git a/Content.Server/GameObjects/Components/Items/Storage/EntityStorageComponent.cs b/Content.Server/GameObjects/Components/Items/Storage/EntityStorageComponent.cs index 355be0b0fb..647380b819 100644 --- a/Content.Server/GameObjects/Components/Items/Storage/EntityStorageComponent.cs +++ b/Content.Server/GameObjects/Components/Items/Storage/EntityStorageComponent.cs @@ -1,18 +1,22 @@ using System; using System.Linq; +using Content.Server.GameObjects.Components.Interactable; using Content.Server.GameObjects.Components.Items.Storage; using Content.Server.GameObjects.Components.Sound; using Content.Server.GameObjects.EntitySystems; -using Content.Server.Utility; using Content.Shared.GameObjects; +using Content.Shared.GameObjects.Components.Interactable; using Content.Shared.GameObjects.Components.Storage; +using Content.Shared.Interfaces; using Robust.Server.GameObjects; using Robust.Server.GameObjects.Components.Container; using Robust.Server.Interfaces.GameObjects; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Components; using Robust.Shared.Interfaces.GameObjects; -using Robust.Shared.Interfaces.Network; +using Robust.Shared.Interfaces.Timing; +using Robust.Shared.IoC; +using Robust.Shared.Localization; using Robust.Shared.Maths; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -22,18 +26,26 @@ namespace Content.Server.GameObjects.Components [RegisterComponent] [ComponentReference(typeof(IActivate))] [ComponentReference(typeof(IStorageComponent))] - public class EntityStorageComponent : Component, IActivate, IStorageComponent + public class EntityStorageComponent : Component, IActivate, IStorageComponent, IInteractUsing { public override string Name => "EntityStorage"; private const float MaxSize = 1.0f; // maximum width or height of an entity allowed inside the storage. + private static readonly TimeSpan InternalOpenAttemptDelay = TimeSpan.FromSeconds(0.5); + private TimeSpan _lastInternalOpenAttempt; + + [ViewVariables] private int StorageCapacityMax; + [ViewVariables] private bool IsCollidableWhenOpen; + [ViewVariables] private Container Contents; + [ViewVariables] private IEntityQuery entityQuery; private bool _showContents; private bool _open; + private bool _isWeldedShut; /// /// Determines if the container contents should be drawn when the container is closed. @@ -49,6 +61,31 @@ namespace Content.Server.GameObjects.Components } } + [ViewVariables(VVAccess.ReadWrite)] + public bool Open + { + get => _open; + private set => _open = value; + } + + [ViewVariables(VVAccess.ReadWrite)] + public bool IsWeldedShut + { + get => _isWeldedShut; + set + { + _isWeldedShut = value; + + if (Owner.TryGetComponent(out AppearanceComponent appearance)) + { + appearance.SetData(StorageVisuals.Welded, value); + } + } + } + + [ViewVariables(VVAccess.ReadWrite)] + public bool CanWeldShut { get; set; } + /// public override void Initialize() { @@ -73,29 +110,30 @@ namespace Content.Server.GameObjects.Components serializer.DataField(ref IsCollidableWhenOpen, "IsCollidableWhenOpen", false); serializer.DataField(ref _showContents, "showContents", false); serializer.DataField(ref _open, "open", false); - } - - [ViewVariables(VVAccess.ReadWrite)] - public bool Open - { - get => _open; - private set => _open = value; + serializer.DataField(this, a => a.IsWeldedShut, "IsWeldedShut", false); + serializer.DataField(this, a => a.CanWeldShut, "CanWeldShut", true); } public virtual void Activate(ActivateEventArgs eventArgs) { - ToggleOpen(); + ToggleOpen(eventArgs.User); } - private void ToggleOpen() + protected virtual void ToggleOpen(IEntity user) { + if (IsWeldedShut) + { + Owner.PopupMessage(user, Loc.GetString("It's welded completely shut!")); + return; + } + if (Open) { CloseStorage(); } else { - OpenStorage(); + TryOpenStorage(user); } } @@ -130,6 +168,7 @@ namespace Content.Server.GameObjects.Components { soundComponent.Play("/Audio/machines/closetclose.ogg"); } + _lastInternalOpenAttempt = default; } private void OpenStorage() @@ -238,12 +277,30 @@ namespace Content.Server.GameObjects.Components case RelayMovementEntityMessage msg: if (msg.Entity.HasComponent()) { - OpenStorage(); + var timing = IoCManager.Resolve(); + if (timing.CurTime < + _lastInternalOpenAttempt + InternalOpenAttemptDelay) + { + break; + } + + _lastInternalOpenAttempt = timing.CurTime; + TryOpenStorage(msg.Entity); } break; } } + protected virtual void TryOpenStorage(IEntity user) + { + if (IsWeldedShut) + { + Owner.PopupMessage(user, Loc.GetString("It's welded completely shut!")); + return; + } + OpenStorage(); + } + /// public bool Remove(IEntity entity) { @@ -284,14 +341,43 @@ namespace Content.Server.GameObjects.Components { protected override void GetData(IEntity user, EntityStorageComponent component, VerbData data) { - data.Text = component.Open ? "Close" : "Open"; + component.OpenVerbGetData(user, component, data); + } /// protected override void Activate(IEntity user, EntityStorageComponent component) { - component.ToggleOpen(); + component.ToggleOpen(user); } } + + protected virtual void OpenVerbGetData(IEntity user, EntityStorageComponent component, VerbData data) + { + if (IsWeldedShut) + { + data.Visibility = VerbVisibility.Disabled; + var verb = Loc.GetString(component.Open ? "Close" : "Open"); + data.Text = Loc.GetString("{0} (welded shut)", verb); + return; + } + + data.Text = component.Open ? "Close" : "Open"; + } + + public bool InteractUsing(InteractUsingEventArgs eventArgs) + { + if (!CanWeldShut) + return false; + + if (!eventArgs.Using.TryGetComponent(out WelderComponent tool)) + return false; + + if (!tool.UseTool(eventArgs.User, Owner, ToolQuality.Welding, 1f)) + return false; + + IsWeldedShut ^= true; + return true; + } } } diff --git a/Content.Server/GameObjects/Components/Items/Storage/SecureEntityStorageComponent.cs b/Content.Server/GameObjects/Components/Items/Storage/SecureEntityStorageComponent.cs new file mode 100644 index 0000000000..374b85050c --- /dev/null +++ b/Content.Server/GameObjects/Components/Items/Storage/SecureEntityStorageComponent.cs @@ -0,0 +1,157 @@ +using Content.Server.GameObjects.Components.Access; +using Content.Server.GameObjects.EntitySystems; +using Content.Server.Interfaces; +using Content.Shared.GameObjects; +using Content.Shared.GameObjects.Components.Storage; +using Content.Shared.Interfaces; +using Robust.Server.GameObjects; +using Robust.Server.GameObjects.EntitySystems; +using Robust.Shared.Audio; +using Robust.Shared.GameObjects; +using Robust.Shared.GameObjects.Systems; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Localization; +using Robust.Shared.Serialization; +using Robust.Shared.ViewVariables; + +namespace Content.Server.GameObjects.Components.Items.Storage +{ + [RegisterComponent] + [ComponentReference(typeof(EntityStorageComponent))] + [ComponentReference(typeof(IActivate))] + [ComponentReference(typeof(IStorageComponent))] + public class SecureEntityStorageComponent : EntityStorageComponent + { + public override string Name => "SecureEntityStorage"; + private bool _locked; + + [ViewVariables(VVAccess.ReadWrite)] + public bool Locked + { + get => _locked; + set + { + _locked = value; + + if (Owner.TryGetComponent(out AppearanceComponent appearance)) + { + appearance.SetData(StorageVisuals.Locked, _locked); + } + } + } + + public override void ExposeData(ObjectSerializer serializer) + { + base.ExposeData(serializer); + + serializer.DataField(ref _locked, "locked", true); + } + + protected override void Startup() + { + base.Startup(); + + if (Owner.TryGetComponent(out AppearanceComponent appearance)) + { + appearance.SetData(StorageVisuals.CanLock, true); + } + } + + public override void Activate(ActivateEventArgs eventArgs) + { + if (Locked) + { + DoToggleLock(eventArgs.User); + return; + } + + base.Activate(eventArgs); + } + + protected override void TryOpenStorage(IEntity user) + { + if (Locked) + { + Owner.PopupMessage(user, "It's locked!"); + return; + } + + base.TryOpenStorage(user); + } + + protected override void OpenVerbGetData(IEntity user, EntityStorageComponent component, VerbData data) + { + if (Locked) + { + data.Visibility = VerbVisibility.Invisible; + return; + } + + base.OpenVerbGetData(user, component, data); + } + + private void DoToggleLock(IEntity user) + { + if (Locked) + { + DoUnlock(user); + } + else + { + DoLock(user); + } + } + + private void DoUnlock(IEntity user) + { + if (CheckAccess(user)) return; + + Locked = false; + EntitySystem.Get().Play("/Audio/machines/door_lock_off.ogg", Owner, AudioParams.Default.WithVolume(-5)); + } + + private void DoLock(IEntity user) + { + if (CheckAccess(user)) return; + + Locked = true; + EntitySystem.Get().Play("/Audio/machines/door_lock_on.ogg", Owner, AudioParams.Default.WithVolume(-5)); + } + + private bool CheckAccess(IEntity user) + { + if (Owner.TryGetComponent(out AccessReader reader)) + { + if (!reader.IsAllowed(user)) + { + IoCManager.Resolve() + .PopupMessage(Owner, user, Loc.GetString("Access denied")); + return true; + } + } + + return false; + } + + [Verb] + private sealed class ToggleLockVerb : Verb + { + protected override void GetData(IEntity user, SecureEntityStorageComponent component, VerbData data) + { + if (component.Open) + { + data.Visibility = VerbVisibility.Invisible; + return; + } + + data.Text = component.Locked ? Loc.GetString("Unlock") : Loc.GetString("Lock"); + } + + protected override void Activate(IEntity user, SecureEntityStorageComponent component) + { + component.DoToggleLock(user); + } + } + } +} diff --git a/Content.Shared/GameObjects/Components/Storage/SharedStorageComponent.cs b/Content.Shared/GameObjects/Components/Storage/SharedStorageComponent.cs index b992670ab2..6e6b051a86 100644 --- a/Content.Shared/GameObjects/Components/Storage/SharedStorageComponent.cs +++ b/Content.Shared/GameObjects/Components/Storage/SharedStorageComponent.cs @@ -86,6 +86,9 @@ namespace Content.Shared.GameObjects.Components.Storage [Serializable] public enum StorageVisuals { - Open + Open, + CanLock, + Welded, + Locked } } diff --git a/Resources/Audio/machines/door_lock_off.ogg b/Resources/Audio/machines/door_lock_off.ogg new file mode 100644 index 0000000000000000000000000000000000000000..1dbd10d19714aeaee64eabcf7e315cb04126b523 GIT binary patch literal 10588 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 literal 0 HcmV?d00001 diff --git a/Resources/Audio/machines/door_lock_on.ogg b/Resources/Audio/machines/door_lock_on.ogg new file mode 100644 index 0000000000000000000000000000000000000000..8102fbfe4b17c01461ad165a416460e0d299f8e9 GIT binary patch literal 10847 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 E05C0c1^@s6 literal 0 HcmV?d00001 diff --git a/Resources/Prototypes/Entities/Buildings/Storage/Closets/closet_secure.yml b/Resources/Prototypes/Entities/Buildings/Storage/Closets/closet_secure.yml index 26606721c5..84980e5f0d 100644 --- a/Resources/Prototypes/Entities/Buildings/Storage/Closets/closet_secure.yml +++ b/Resources/Prototypes/Entities/Buildings/Storage/Closets/closet_secure.yml @@ -2,4 +2,19 @@ id: LockerSecureBase parent: LockerGeneric abstract: true - # TODO: Access components and such. + components: + - type: AccessReader + - type: SecureEntityStorage + - type: Sprite + netsync: false + sprite: Buildings/closet.rsi + layers: + - state: generic + - state: generic_door + map: ["enum.StorageVisualLayers.Door"] + - state: locked + map: ["enum.StorageVisualLayers.Lock"] + shader: unshaded + - state: welded + visible: false + map: ["enum.StorageVisualLayers.Welded"] diff --git a/Resources/Prototypes/Entities/Buildings/Storage/closet.yml b/Resources/Prototypes/Entities/Buildings/Storage/closet.yml index 58449ceb75..b802ea327f 100644 --- a/Resources/Prototypes/Entities/Buildings/Storage/closet.yml +++ b/Resources/Prototypes/Entities/Buildings/Storage/closet.yml @@ -10,6 +10,9 @@ - state: generic - state: generic_door map: ["enum.StorageVisualLayers.Door"] + - state: welded + visible: false + map: ["enum.StorageVisualLayers.Welded"] - type: Icon sprite: Buildings/closet.rsi state: generic_door diff --git a/Resources/Prototypes/Entities/Buildings/Storage/crate_base.yml b/Resources/Prototypes/Entities/Buildings/Storage/crate_base.yml index bdf48c1229..3707dd2f69 100644 --- a/Resources/Prototypes/Entities/Buildings/Storage/crate_base.yml +++ b/Resources/Prototypes/Entities/Buildings/Storage/crate_base.yml @@ -27,6 +27,7 @@ Anchored: false - type: EntityStorage Capacity: 60 + CanWeldShut: false - type: PlaceableSurface - type: Damageable - type: Destructible