diff --git a/Content.Client/GameObjects/Components/ExtinguisherCabinetVisualizer.cs b/Content.Client/GameObjects/Components/ExtinguisherCabinetVisualizer.cs new file mode 100644 index 0000000000..931a26229e --- /dev/null +++ b/Content.Client/GameObjects/Components/ExtinguisherCabinetVisualizer.cs @@ -0,0 +1,41 @@ +using Content.Shared.GameObjects.Components; +using Robust.Client.GameObjects; +using Robust.Client.Interfaces.GameObjects.Components; + +namespace Content.Client.GameObjects.Components +{ + public class ExtinguisherCabinetVisualizer : AppearanceVisualizer + { + private string _prefix; + + public override void OnChangeData(AppearanceComponent component) + { + base.OnChangeData(component); + + var sprite = component.Owner.GetComponent(); + + if (component.TryGetData(ExtinguisherCabinetVisuals.IsOpen, out bool isOpen)) + { + if (isOpen) + { + if (component.TryGetData(ExtinguisherCabinetVisuals.ContainsExtinguisher, out bool contains)) + { + if (contains) + { + sprite.LayerSetState(0, "extinguisher_full"); + } + else + { + sprite.LayerSetState(0, "extinguisher_empty"); + } + + } + } + else + { + sprite.LayerSetState(0, "extinguisher_closed"); + } + } + } + } +} diff --git a/Content.Server/GameObjects/Components/ExtinguisherCabinetComponent.cs b/Content.Server/GameObjects/Components/ExtinguisherCabinetComponent.cs new file mode 100644 index 0000000000..38640b766c --- /dev/null +++ b/Content.Server/GameObjects/Components/ExtinguisherCabinetComponent.cs @@ -0,0 +1,128 @@ +using System.Threading.Tasks; +using Content.Server.GameObjects.Components.GUI; +using Content.Server.GameObjects.Components.Items; +using Content.Server.GameObjects.Components.Items.Storage; +using Content.Server.Interfaces.GameObjects.Components.Items; +using Content.Shared.Audio; +using Content.Shared.GameObjects.Components; +using Content.Shared.Interfaces; +using Content.Shared.Interfaces.GameObjects.Components; +using Robust.Server.GameObjects; +using Robust.Server.GameObjects.Components.Container; +using Robust.Server.GameObjects.EntitySystems; +using Robust.Shared.GameObjects; +using Robust.Shared.GameObjects.Systems; +using Robust.Shared.Localization; +using Robust.Shared.Serialization; +using Robust.Shared.ViewVariables; + +namespace Content.Server.GameObjects.Components +{ + + [RegisterComponent] + [ComponentReference(typeof(IActivate))] + public class ExtinguisherCabinetComponent : Component, IInteractUsing, IInteractHand, IActivate + { + public override string Name => "ExtinguisherCabinet"; + + private bool _opened = false; + private string _doorSound; + + [ViewVariables] protected ContainerSlot ItemContainer; + [ViewVariables] public string DoorSound => _doorSound; + + public override void Initialize() + { + base.Initialize(); + + ItemContainer = + ContainerManagerComponent.Ensure("extinguisher_cabinet", Owner, out _); + } + + public override void ExposeData(ObjectSerializer serializer) + { + base.ExposeData(serializer); + + serializer.DataField(ref _doorSound, "doorSound", "/Audio/Machines/machine_switch.ogg"); + } + + async Task IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs) + { + if (!_opened) + { + _opened = true; + ClickLatchSound(); + } + else + { + if (ItemContainer.ContainedEntity != null || !eventArgs.Using.HasComponent()) + { + return false; + } + var handsComponent = eventArgs.User.GetComponent(); + + if (!handsComponent.Drop(eventArgs.Using, ItemContainer)) + { + return false; + } + } + + UpdateVisuals(); + + return true; + } + + bool IInteractHand.InteractHand(InteractHandEventArgs eventArgs) + { + if (_opened) + { + if (ItemContainer.ContainedEntity == null) + { + _opened = false; + ClickLatchSound(); + } + else if (eventArgs.User.TryGetComponent(out HandsComponent hands)) + { + Owner.PopupMessage(eventArgs.User, + Loc.GetString("You take {0:extinguisherName} from the {1:cabinetName}", ItemContainer.ContainedEntity.Name, Owner.Name)); + hands.PutInHandOrDrop(ItemContainer.ContainedEntity.GetComponent()); + } + else if (ItemContainer.Remove(ItemContainer.ContainedEntity)) + { + ItemContainer.ContainedEntity.Transform.GridPosition = Owner.Transform.GridPosition; + } + } + else + { + _opened = true; + ClickLatchSound(); + } + + UpdateVisuals(); + + return true; + } + + void IActivate.Activate(ActivateEventArgs eventArgs) + { + _opened = !_opened; + ClickLatchSound(); + UpdateVisuals(); + } + + private void UpdateVisuals() + { + if (Owner.TryGetComponent(out AppearanceComponent appearance)) + { + appearance.SetData(ExtinguisherCabinetVisuals.IsOpen, _opened); + appearance.SetData(ExtinguisherCabinetVisuals.ContainsExtinguisher, ItemContainer.ContainedEntity != null); + } + } + + private void ClickLatchSound() + { + EntitySystem.Get() // Don't have original click, this sounds close + .PlayFromEntity(DoorSound, Owner, AudioHelpers.WithVariation(0.15f)); + } + } +} diff --git a/Content.Server/GameObjects/Components/ExtinguisherCabinetFilledComponent.cs b/Content.Server/GameObjects/Components/ExtinguisherCabinetFilledComponent.cs new file mode 100644 index 0000000000..f9a861e238 --- /dev/null +++ b/Content.Server/GameObjects/Components/ExtinguisherCabinetFilledComponent.cs @@ -0,0 +1,19 @@ +using Content.Shared.Interfaces.GameObjects.Components; +using Robust.Shared.GameObjects; +using Robust.Shared.ViewVariables; + +namespace Content.Server.GameObjects.Components +{ + [RegisterComponent] + public class ExtinguisherCabinetFilledComponent : ExtinguisherCabinetComponent + { + public override string Name => "ExtinguisherCabinetFilled"; + + public override void Initialize() + { + base.Initialize(); + + ItemContainer.Insert(Owner.EntityManager.SpawnEntity("FireExtinguisher", Owner.Transform.GridPosition)); + } + } +} diff --git a/Content.Server/GameObjects/Components/Items/FireExtinguisherComponent.cs b/Content.Server/GameObjects/Components/Items/FireExtinguisherComponent.cs new file mode 100644 index 0000000000..540a922a26 --- /dev/null +++ b/Content.Server/GameObjects/Components/Items/FireExtinguisherComponent.cs @@ -0,0 +1,14 @@ +using Content.Shared.GameObjects.EntitySystems; +using Content.Shared.Interfaces.GameObjects.Components; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.Random; +using Robust.Shared.Prototypes; + +namespace Content.Server.GameObjects.Components.Items +{ + [RegisterComponent] + public class FireExtinguisherComponent : Component + { + public override string Name => "FireExtinguisher"; + } +} diff --git a/Content.Shared/GameObjects/Components/ExtinguisherCabinet.cs b/Content.Shared/GameObjects/Components/ExtinguisherCabinet.cs new file mode 100644 index 0000000000..c42e355f1e --- /dev/null +++ b/Content.Shared/GameObjects/Components/ExtinguisherCabinet.cs @@ -0,0 +1,12 @@ +using System; +using Robust.Shared.Serialization; + +namespace Content.Shared.GameObjects.Components +{ + [Serializable, NetSerializable] + public enum ExtinguisherCabinetVisuals + { + IsOpen, + ContainsExtinguisher + } +} diff --git a/Resources/Prototypes/Entities/Constructible/Walls/extinguisher_cabinet.yml b/Resources/Prototypes/Entities/Constructible/Walls/extinguisher_cabinet.yml new file mode 100644 index 0000000000..243d5eb565 --- /dev/null +++ b/Resources/Prototypes/Entities/Constructible/Walls/extinguisher_cabinet.yml @@ -0,0 +1,26 @@ +- type: entity + id: ExtinguisherCabinet + name: extinguisher cabinet + abstract: true + description: A small wall mounted cabinet designed to hold a fire extinguisher. + components: + - type: Clickable + - type: InteractionOutline + - type: Sprite + sprite: Constructible/Misc/extinguisher_cabinet.rsi + state: extinguisher_closed + - type: Icon + sprite: Constructible/Misc/extinguisher_cabinet.rsi + state: extinguisher_closed + - type: ExtinguisherCabinet + - type: Appearance + visuals: + - type: ExtinguisherCabinetVisualizer + placement: + mode: SnapgridCenter + +- type: entity + id: ExtinguisherCabinetFilled + parent: ExtinguisherCabinet + components: + - type: ExtinguisherCabinetFilled diff --git a/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml b/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml index c341ef56d0..f1c5501fe1 100644 --- a/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml +++ b/Resources/Prototypes/Entities/Objects/Misc/fire_extinguisher.yml @@ -27,3 +27,4 @@ fuelType: chem.H2O fuelName: water fuelCost: 50 + - type: FireExtinguisher diff --git a/Resources/Prototypes/Recipes/Construction/misc.yml b/Resources/Prototypes/Recipes/Construction/misc.yml index d8e96ea00a..96fe94099f 100644 --- a/Resources/Prototypes/Recipes/Construction/misc.yml +++ b/Resources/Prototypes/Recipes/Construction/misc.yml @@ -10,3 +10,20 @@ steps: - material: Metal amount: 1 + +- type: construction + id: ExtinguisherCabinet + name: extinguisher cabinet + category: Items/Misc + keywords: [misc] + placementMode: SnapgridCenter + canBuildInImpassable: true + description: A small wall mounted cabinet designed to hold a fire extinguisher. + icon: Constructible/Misc/extinguisher_cabinet.rsi/extinguisher_closed.png + result: ExtinguisherCabinet + steps: + - material: Metal + amount: 2 + icon: + sprite: Constructible/Misc/extinguisher_cabinet.rsi + state: extinguisher_closed diff --git a/Resources/Textures/Constructible/Misc/extinguisher_cabinet.rsi/extinguisher_closed.png b/Resources/Textures/Constructible/Misc/extinguisher_cabinet.rsi/extinguisher_closed.png new file mode 100644 index 0000000000..f0a2177fec Binary files /dev/null and b/Resources/Textures/Constructible/Misc/extinguisher_cabinet.rsi/extinguisher_closed.png differ diff --git a/Resources/Textures/Constructible/Misc/extinguisher_cabinet.rsi/extinguisher_empty.png b/Resources/Textures/Constructible/Misc/extinguisher_cabinet.rsi/extinguisher_empty.png new file mode 100644 index 0000000000..5653c6026a Binary files /dev/null and b/Resources/Textures/Constructible/Misc/extinguisher_cabinet.rsi/extinguisher_empty.png differ diff --git a/Resources/Textures/Constructible/Misc/extinguisher_cabinet.rsi/extinguisher_full.png b/Resources/Textures/Constructible/Misc/extinguisher_cabinet.rsi/extinguisher_full.png new file mode 100644 index 0000000000..740b7d3729 Binary files /dev/null and b/Resources/Textures/Constructible/Misc/extinguisher_cabinet.rsi/extinguisher_full.png differ diff --git a/Resources/Textures/Constructible/Misc/extinguisher_cabinet.rsi/extinguisher_mini.png b/Resources/Textures/Constructible/Misc/extinguisher_cabinet.rsi/extinguisher_mini.png new file mode 100644 index 0000000000..4e97717d6d Binary files /dev/null and b/Resources/Textures/Constructible/Misc/extinguisher_cabinet.rsi/extinguisher_mini.png differ diff --git a/Resources/Textures/Constructible/Misc/extinguisher_cabinet.rsi/meta.json b/Resources/Textures/Constructible/Misc/extinguisher_cabinet.rsi/meta.json new file mode 100644 index 0000000000..f27ae0220e --- /dev/null +++ b/Resources/Textures/Constructible/Misc/extinguisher_cabinet.rsi/meta.json @@ -0,0 +1,47 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from https://github.com/tgstation/tgstation at commit d0d81185f09ca30d3b0856d476544240dba0de53", + "states": [ + { + "name": "extinguisher_closed", + "directions": 1, + "delays": [ + [ + 1.0 + ] + ] + }, + { + "name": "extinguisher_empty", + "directions": 1, + "delays": [ + [ + 1.0 + ] + ] + }, + { + "name": "extinguisher_full", + "directions": 1, + "delays": [ + [ + 1.0 + ] + ] + }, + { + "name": "extinguisher_mini", + "directions": 1, + "delays": [ + [ + 1.0 + ] + ] + } + ] +}