diff --git a/Content.Server/Plants/Components/PottedPlantHideComponent.cs b/Content.Server/Plants/Components/PottedPlantHideComponent.cs index eae2ee3ac3..1254cf94f1 100644 --- a/Content.Server/Plants/Components/PottedPlantHideComponent.cs +++ b/Content.Server/Plants/Components/PottedPlantHideComponent.cs @@ -1,54 +1,23 @@ -using System.Threading.Tasks; +using Content.Server.Plants.Systems; using Content.Server.Storage.Components; -using Content.Shared.Audio; -using Content.Shared.Interaction; -using Content.Shared.Popups; using Content.Shared.Sound; -using Robust.Shared.Audio; +using Robust.Shared.Analyzers; using Robust.Shared.GameObjects; -using Robust.Shared.Localization; -using Robust.Shared.Player; using Robust.Shared.Serialization.Manager.Attributes; -using Robust.Shared.ViewVariables; namespace Content.Server.Plants.Components { + /// + /// Interaction wrapper for . + /// Gently rustle after each interaction with plant. + /// [RegisterComponent] - public class PottedPlantHideComponent : Component, IInteractUsing, IInteractHand + [Friend(typeof(PottedPlantHideSystem))] + public class PottedPlantHideComponent : Component { public override string Name => "PottedPlantHide"; - [ViewVariables] private SecretStashComponent _secretStash = default!; - [DataField("rustleSound")] private SoundSpecifier _rustleSound = new SoundPathSpecifier("/Audio/Effects/plant_rustle.ogg"); - - protected override void Initialize() - { - base.Initialize(); - _secretStash = Owner.EnsureComponent(); - } - - async Task IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs) - { - Rustle(); - return _secretStash.TryHideItem(eventArgs.User, eventArgs.Using); - } - - bool IInteractHand.InteractHand(InteractHandEventArgs eventArgs) - { - Rustle(); - - var gotItem = _secretStash.TryGetItem(eventArgs.User); - if (!gotItem) - { - Owner.PopupMessage(eventArgs.User, Loc.GetString("potted-plant-hide-component-interact-hand-got-no-item-message")); - } - - return gotItem; - } - - private void Rustle() - { - SoundSystem.Play(Filter.Pvs(Owner), _rustleSound.GetSound(), Owner, AudioHelpers.WithVariation(0.25f)); - } + [DataField("rustleSound")] + public SoundSpecifier RustleSound = new SoundPathSpecifier("/Audio/Effects/plant_rustle.ogg"); } } diff --git a/Content.Server/Plants/Systems/PottedPlantHideSystem.cs b/Content.Server/Plants/Systems/PottedPlantHideSystem.cs new file mode 100644 index 0000000000..f0dfe1aae8 --- /dev/null +++ b/Content.Server/Plants/Systems/PottedPlantHideSystem.cs @@ -0,0 +1,75 @@ +using Content.Server.Plants.Components; +using Content.Server.Popups; +using Content.Server.Storage.Components; +using Content.Server.Storage.EntitySystems; +using Content.Shared.ActionBlocker; +using Content.Shared.Audio; +using Content.Shared.Interaction; +using Robust.Shared.Audio; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Localization; +using Robust.Shared.Player; + +namespace Content.Server.Plants.Systems +{ + public class PottedPlantHideSystem : EntitySystem + { + [Dependency] private readonly SecretStashSystem _stashSystem = default!; + [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly ActionBlockerSystem _blocker = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnInteractUsing); + SubscribeLocalEvent(OnInteractHand); + } + + private void OnInit(EntityUid uid, PottedPlantHideComponent component, ComponentInit args) + { + EntityManager.EnsureComponent(uid); + } + + private void OnInteractUsing(EntityUid uid, PottedPlantHideComponent component, InteractUsingEvent args) + { + if (args.Handled) + return; + + // standard interaction checks + if (!_blocker.CanInteract(args.User)) return; + + Rustle(uid, component); + args.Handled = _stashSystem.TryHideItem(uid, args.User, args.Used); + } + + private void OnInteractHand(EntityUid uid, PottedPlantHideComponent component, InteractHandEvent args) + { + if (args.Handled) + return; + + // standard interaction checks + if (!_blocker.CanInteract(args.User)) return; + + Rustle(uid, component); + + var gotItem = _stashSystem.TryGetItem(uid, args.User); + if (!gotItem) + { + var msg = Loc.GetString("potted-plant-hide-component-interact-hand-got-no-item-message"); + _popupSystem.PopupEntity(msg, uid, Filter.Entities(args.User)); + } + + args.Handled = gotItem; + } + + private void Rustle(EntityUid uid, PottedPlantHideComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + SoundSystem.Play(Filter.Pvs(uid), component.RustleSound.GetSound(), uid, AudioHelpers.WithVariation(0.25f)); + } + } +} diff --git a/Content.Server/Storage/Components/SecretStashComponent.cs b/Content.Server/Storage/Components/SecretStashComponent.cs index 30e8992a59..3e4564a1c7 100644 --- a/Content.Server/Storage/Components/SecretStashComponent.cs +++ b/Content.Server/Storage/Components/SecretStashComponent.cs @@ -1,120 +1,44 @@ -using Content.Server.Hands.Components; -using Content.Server.Items; -using Content.Shared.Acts; +using Content.Server.Storage.EntitySystems; +using Content.Server.Toilet; +using Content.Shared.Containers.ItemSlots; using Content.Shared.Item; -using Content.Shared.Popups; +using Robust.Shared.Analyzers; using Robust.Shared.Containers; using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Localization; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; namespace Content.Server.Storage.Components { /// - /// Logic for secret single slot stash, like plant pot or toilet cistern + /// Logic for a secret slot stash, like plant pot or toilet cistern. + /// Unlike it doesn't have interaction logic or verbs. + /// Other classes like should implement it. /// [RegisterComponent] - public class SecretStashComponent : Component, IDestroyAct + [Friend(typeof(SecretStashSystem))] + public class SecretStashComponent : Component { - [Dependency] private readonly IEntityManager _entMan = default!; - public override string Name => "SecretStash"; + /// + /// Max item size that can be fitted into secret stash. + /// [ViewVariables] [DataField("maxItemSize")] - private int _maxItemSize = (int) ReferenceSizes.Pocket; + public int MaxItemSize = (int) ReferenceSizes.Pocket; + /// + /// IC secret stash name. For example "the toilet cistern". + /// If empty string, will replace it with entity name in init. + /// [ViewVariables] [DataField("secretPartName")] - private readonly string? _secretPartNameOverride = null; - - [ViewVariables] private ContainerSlot _itemContainer = default!; - - public string SecretPartName => _secretPartNameOverride ?? Loc.GetString("comp-secret-stash-secret-part-name", ("name", _entMan.GetComponent(Owner).EntityName)); - - protected override void Initialize() - { - base.Initialize(); - _itemContainer = ContainerHelpers.EnsureContainer(Owner, "stash", out _); - } + public string SecretPartName = ""; /// - /// Tries to hide item inside secret stash from hands of user + /// Container used to keep secret stash item. /// - /// - /// - /// True if item was hidden inside stash - public bool TryHideItem(EntityUid user, EntityUid itemToHide) - { - if (_itemContainer.ContainedEntity != null) - { - Owner.PopupMessage(user, Loc.GetString("comp-secret-stash-action-hide-container-not-empty")); - return false; - } + [ViewVariables] + public ContainerSlot ItemContainer = default!; - if (!_entMan.TryGetComponent(itemToHide, out ItemComponent? item)) - return false; - - if (item.Size > _maxItemSize) - { - Owner.PopupMessage(user, - Loc.GetString("comp-secret-stash-action-hide-item-too-big",("item", itemToHide),("stash", SecretPartName))); - return false; - } - - if (!_entMan.TryGetComponent(user, out HandsComponent? hands)) - return false; - - if (!hands.Drop(itemToHide, _itemContainer)) - return false; - - Owner.PopupMessage(user, Loc.GetString("comp-secret-stash-action-hide-success", ("item", itemToHide), ("this", SecretPartName))); - return true; - } - - /// - /// Try get item and place it in users hand - /// If user can't take it by hands, will drop item from container - /// - /// - /// True if user recieved item - public bool TryGetItem(EntityUid user) - { - if (_itemContainer.ContainedEntity is not {Valid: true} contained) - return false; - - Owner.PopupMessage(user, Loc.GetString("comp-secret-stash-action-get-item-found-something", ("stash", SecretPartName))); - - if (_entMan.TryGetComponent(user, out HandsComponent? hands)) - { - if (!_entMan.TryGetComponent(contained, out ItemComponent? item)) - return false; - hands.PutInHandOrDrop(item); - } - else if (_itemContainer.Remove(contained)) - { - _entMan.GetComponent(contained).Coordinates = _entMan.GetComponent(Owner).Coordinates; - } - - return true; - } - - /// - /// Is there something inside secret stash item container? - /// - /// - public bool HasItemInside() - { - return _itemContainer.ContainedEntity != null; - } - - public void OnDestroy(DestructionEventArgs eventArgs) - { - // drop item inside - if (_itemContainer.ContainedEntity is {Valid: true} contained) - { - _entMan.GetComponent(contained).Coordinates = _entMan.GetComponent(Owner).Coordinates; - } - } } } diff --git a/Content.Server/Storage/EntitySystems/SecretStashSystem.cs b/Content.Server/Storage/EntitySystems/SecretStashSystem.cs new file mode 100644 index 0000000000..fa19fce286 --- /dev/null +++ b/Content.Server/Storage/EntitySystems/SecretStashSystem.cs @@ -0,0 +1,136 @@ +using Content.Server.Items; +using Content.Server.Popups; +using Content.Server.Storage.Components; +using Content.Shared.Acts; +using Content.Shared.Hands.Components; +using Robust.Shared.Containers; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Localization; +using Robust.Shared.Player; + +namespace Content.Server.Storage.EntitySystems +{ + public class SecretStashSystem : EntitySystem + { + [Dependency] private readonly PopupSystem _popupSystem = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnDestroyed); + } + + private void OnInit(EntityUid uid, SecretStashComponent component, ComponentInit args) + { + // set default secret part name + if (component.SecretPartName == "") + { + var meta = EntityManager.GetComponent(uid); + var entityName = Loc.GetString("comp-secret-stash-secret-part-name", ("name", meta.EntityName)); + component.SecretPartName = entityName; + } + + component.ItemContainer = ContainerHelpers.EnsureContainer(uid, "stash", out _); + } + + private void OnDestroyed(EntityUid uid, SecretStashComponent component, DestructionEventArgs args) + { + component.ItemContainer.EmptyContainer(); + } + + /// + /// Is there something inside secret stash item container? + /// + public bool HasItemInside(EntityUid uid, SecretStashComponent? component = null) + { + if (!Resolve(uid, ref component)) + return false; + return component.ItemContainer.ContainedEntity != null; + } + + /// + /// Tries to hide item inside secret stash from hands of user. + /// + /// True if item was hidden inside stash + public bool TryHideItem(EntityUid uid, EntityUid userUid, EntityUid itemToHideUid, + SecretStashComponent? component = null, ItemComponent? item = null, + MetaDataComponent? itemMeta = null, SharedHandsComponent? hands = null) + { + if (!Resolve(uid, ref component)) + return false; + if (!Resolve(itemToHideUid, ref item, ref itemMeta)) + return false; + if (!Resolve(userUid, ref hands)) + return false; + + // check if secret stash is already occupied + var container = component.ItemContainer; + if (container.ContainedEntity != null) + { + var msg = Loc.GetString("comp-secret-stash-action-hide-container-not-empty"); + _popupSystem.PopupEntity(msg, uid, Filter.Entities(userUid)); + return false; + } + + // check if item is too big to fit into secret stash + var itemName = itemMeta.EntityName; + if (item.Size > component.MaxItemSize) + { + var msg = Loc.GetString("comp-secret-stash-action-hide-item-too-big", + ("item", itemName), ("stash", component.SecretPartName)); + _popupSystem.PopupEntity(msg, uid, Filter.Entities(userUid)); + return false; + } + + // try to move item from hands to stash container + if (!hands.Drop(itemToHideUid, container)) + { + return false; + } + + // all done, show success message + var successMsg = Loc.GetString("comp-secret-stash-action-hide-success", + ("item", itemName), ("this", component.SecretPartName)); + _popupSystem.PopupEntity(successMsg, uid, Filter.Entities(userUid)); + return true; + } + + /// + /// Try get item and place it in users hand. + /// If user can't take it by hands, will drop item from container. + /// + /// True if user received item + public bool TryGetItem(EntityUid uid, EntityUid userUid, SecretStashComponent? component = null, + SharedHandsComponent? hands = null) + { + if (!Resolve(uid, ref component)) + return false; + if (!Resolve(userUid, ref hands)) + return false; + + // check if secret stash has something inside + var container = component.ItemContainer; + if (container.ContainedEntity == null) + { + return false; + } + + // get item inside container + var itemUid = container.ContainedEntity; + if (!EntityManager.TryGetComponent(itemUid, out ItemComponent? item)) + { + return false; + } + hands.PutInHandOrDrop(item); + + // show success message + var successMsg = Loc.GetString("comp-secret-stash-action-get-item-found-something", + ("stash", component.SecretPartName)); + _popupSystem.PopupEntity(successMsg, uid, Filter.Entities(userUid)); + + return true; + } + } +} diff --git a/Content.Server/Toilet/ToiletComponent.cs b/Content.Server/Toilet/ToiletComponent.cs index b44f600799..5d66ccacbe 100644 --- a/Content.Server/Toilet/ToiletComponent.cs +++ b/Content.Server/Toilet/ToiletComponent.cs @@ -1,180 +1,34 @@ -using System.Threading.Tasks; using Content.Server.Act; -using Content.Server.Buckle.Components; using Content.Server.Chat.Managers; -using Content.Server.Popups; -using Content.Server.Storage.Components; -using Content.Server.Tools; -using Content.Server.Tools.Components; -using Content.Shared.Audio; -using Content.Shared.Body.Components; -using Content.Shared.Body.Part; -using Content.Shared.Examine; -using Content.Shared.Interaction; -using Content.Shared.Popups; using Content.Shared.Sound; -using Content.Shared.Toilet; using Content.Shared.Tools; -using Robust.Shared.Audio; using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Localization; -using Robust.Shared.Player; -using Robust.Shared.Random; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; -using Robust.Shared.Utility; -using Robust.Shared.ViewVariables; namespace Content.Server.Toilet { [RegisterComponent] -#pragma warning disable 618 - public class ToiletComponent : Component, IInteractUsing, - IInteractHand, IMapInit, IExamine, ISuicideAct -#pragma warning restore 618 + [ComponentProtoName("Toilet")] + public sealed class ToiletComponent : Component, ISuicideAct { - [Dependency] private readonly IEntityManager _entMan = default!; - - public sealed override string Name => "Toilet"; - - private const float PryLidTime = 1f; - - private bool _isPrying = false; + [DataField("pryLidTime")] + public float PryLidTime = 1f; [DataField("pryingQuality", customTypeSerializer:typeof(PrototypeIdSerializer))] - private string _pryingQuality = "Prying"; + public string PryingQuality = "Prying"; - [ViewVariables] public bool LidOpen { get; private set; } - [ViewVariables] public bool IsSeatUp { get; private set; } + [DataField("toggleSound")] + public SoundSpecifier ToggleSound = new SoundPathSpecifier("/Audio/Effects/toilet_seat_down.ogg"); - [ViewVariables] private SecretStashComponent _secretStash = default!; - - [DataField("toggleSound")] SoundSpecifier _toggleSound = new SoundPathSpecifier("/Audio/Effects/toilet_seat_down.ogg"); - - protected override void Initialize() - { - base.Initialize(); - _secretStash = Owner.EnsureComponent(); - } - - public void MapInit() - { - // roll is toilet seat will be up or down - var random = IoCManager.Resolve(); - IsSeatUp = random.Prob(0.5f); - UpdateSprite(); - } - - async Task IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs) - { - // are player trying place or lift of cistern lid? - if (_entMan.TryGetComponent(eventArgs.Using, out ToolComponent? tool) - && tool.Qualities.Contains(_pryingQuality)) - { - // check if someone is already prying this toilet - if (_isPrying) - return false; - _isPrying = true; - - if (!await EntitySystem.Get().UseTool(eventArgs.Using, eventArgs.User, Owner, 0f, PryLidTime, _pryingQuality)) - { - _isPrying = false; - return false; - } - - _isPrying = false; - - // all cool - toggle lid - LidOpen = !LidOpen; - UpdateSprite(); - - return true; - } - // maybe player trying to hide something inside cistern? - else if (LidOpen) - { - return _secretStash.TryHideItem(eventArgs.User, eventArgs.Using); - } - - return false; - } - - bool IInteractHand.InteractHand(InteractHandEventArgs eventArgs) - { - // trying get something from stash? - if (LidOpen) - { - var gotItem = _secretStash.TryGetItem(eventArgs.User); - - if (gotItem) - return true; - } - - // just want to up/down seat? - // check that nobody seats on seat right now - if (_entMan.TryGetComponent(Owner, out StrapComponent? strap)) - { - if (strap.BuckledEntities.Count != 0) - return false; - } - - ToggleToiletSeat(); - return true; - } - - public void Examine(FormattedMessage message, bool inDetailsRange) - { - if (inDetailsRange && LidOpen) - { - if (_secretStash.HasItemInside()) - { - message.AddMarkup(Loc.GetString("toilet-component-on-examine-found-hidden-item")); - } - } - } - - public void ToggleToiletSeat() - { - IsSeatUp = !IsSeatUp; - SoundSystem.Play(Filter.Pvs(Owner), _toggleSound.GetSound(), Owner, AudioHelpers.WithVariation(0.05f)); - - UpdateSprite(); - } - - private void UpdateSprite() - { - if (_entMan.TryGetComponent(Owner, out AppearanceComponent? appearance)) - { - appearance.SetData(ToiletVisuals.LidOpen, LidOpen); - appearance.SetData(ToiletVisuals.SeatUp, IsSeatUp); - } - } + public bool LidOpen = false; + public bool IsSeatUp = false; + public bool IsPrying = false; + // todo: move me to ECS SuicideKind ISuicideAct.Suicide(EntityUid victim, IChatManager chat) { - // check that victim even have head - if (_entMan.TryGetComponent(victim, out var body) && - body.HasPartOfType(BodyPartType.Head)) - { - var othersMessage = Loc.GetString("toilet-component-suicide-head-message-others", ("victim",Name: _entMan.GetComponent(victim).EntityName),("owner", Name: _entMan.GetComponent(Owner).EntityName)); - victim.PopupMessageOtherClients(othersMessage); - - var selfMessage = Loc.GetString("toilet-component-suicide-head-message", ("owner", Name: _entMan.GetComponent(Owner).EntityName)); - victim.PopupMessage(selfMessage); - - return SuicideKind.Asphyxiation; - } - else - { - var othersMessage = Loc.GetString("toilet-component-suicide-message-others",("victim", Name: _entMan.GetComponent(victim).EntityName),("owner", Name: _entMan.GetComponent(Owner).EntityName)); - victim.PopupMessageOtherClients(othersMessage); - - var selfMessage = Loc.GetString("toilet-component-suicide-message", ("owner",Name: _entMan.GetComponent(Owner).EntityName)); - victim.PopupMessage(selfMessage); - - return SuicideKind.Blunt; - } + return EntitySystem.Get().Suicide(Owner, victim, this); } } diff --git a/Content.Server/Toilet/ToiletSystem.cs b/Content.Server/Toilet/ToiletSystem.cs new file mode 100644 index 0000000000..2113bd5291 --- /dev/null +++ b/Content.Server/Toilet/ToiletSystem.cs @@ -0,0 +1,225 @@ +using Content.Server.Act; +using Content.Server.Buckle.Components; +using Content.Server.Popups; +using Content.Server.Storage.Components; +using Content.Server.Storage.EntitySystems; +using Content.Server.Tools; +using Content.Server.Tools.Components; +using Content.Shared.Audio; +using Content.Shared.Body.Components; +using Content.Shared.Body.Part; +using Content.Shared.Examine; +using Content.Shared.Interaction; +using Content.Shared.Toilet; +using Robust.Shared.Audio; +using Robust.Shared.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Localization; +using Robust.Shared.Player; +using Robust.Shared.Random; + +namespace Content.Server.Toilet +{ + public class ToiletSystem : EntitySystem + { + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly SecretStashSystem _secretStash = default!; + [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly ToolSystem _toolSystem = default!; + + public override void Initialize() + { + base.Initialize(); + SubscribeLocalEvent(OnInit); + SubscribeLocalEvent(OnMapInit); + SubscribeLocalEvent(OnInteractUsing); + SubscribeLocalEvent(OnInteractHand); + SubscribeLocalEvent(OnExamine); + SubscribeLocalEvent(OnToiletPried); + SubscribeLocalEvent(OnToiletInterrupt); + } + + private void OnInit(EntityUid uid, ToiletComponent component, ComponentInit args) + { + EntityManager.EnsureComponent(uid); + } + + private void OnMapInit(EntityUid uid, ToiletComponent component, MapInitEvent args) + { + // roll is toilet seat will be up or down + component.IsSeatUp = _random.Prob(0.5f); + UpdateSprite(uid, component); + } + + private void OnInteractUsing(EntityUid uid, ToiletComponent component, InteractUsingEvent args) + { + if (args.Handled) + return; + + // are player trying place or lift of cistern lid? + if (EntityManager.TryGetComponent(args.Used, out ToolComponent? tool) + && tool.Qualities.Contains(component.PryingQuality)) + { + // check if someone is already prying this toilet + if (component.IsPrying) + return; + component.IsPrying = true; + + // try to pry toilet cistern + if (!_toolSystem.UseTool(args.Used, args.User, uid, 0f, + component.PryLidTime, component.PryingQuality, + new ToiletPryFinished(uid), new ToiletPryInterrupted(uid))) + { + component.IsPrying = false; + return; + } + + args.Handled = true; + } + // maybe player trying to hide something inside cistern? + else if (component.LidOpen) + { + args.Handled = _secretStash.TryHideItem(uid, args.User, args.Used); + } + } + + private void OnInteractHand(EntityUid uid, ToiletComponent component, InteractHandEvent args) + { + if (args.Handled) + return; + + // trying get something from stash? + if (component.LidOpen) + { + var gotItem = _secretStash.TryGetItem(uid, args.User); + if (gotItem) + { + args.Handled = true; + return; + } + } + + // just want to up/down seat? + // check that nobody seats on seat right now + if (EntityManager.TryGetComponent(uid, out StrapComponent? strap)) + { + if (strap.BuckledEntities.Count != 0) + return; + } + + ToggleToiletSeat(uid, component); + args.Handled = true; + } + + private void OnExamine(EntityUid uid, ToiletComponent component, ExaminedEvent args) + { + if (args.IsInDetailsRange && component.LidOpen) + { + if (_secretStash.HasItemInside(uid)) + { + var msg = Loc.GetString("toilet-component-on-examine-found-hidden-item"); + args.PushMarkup(msg); + } + } + } + + public SuicideKind Suicide(EntityUid uid, EntityUid victimUid, ToiletComponent? component = null, + MetaDataComponent? meta = null, MetaDataComponent? victimMeta = null) + { + if (!Resolve(uid, ref component, ref meta)) + return SuicideKind.Special; + + if (!Resolve(uid, ref victimMeta)) + return SuicideKind.Special; + + // check that victim even have head + if (EntityManager.TryGetComponent(victimUid, out var body) && + body.HasPartOfType(BodyPartType.Head)) + { + var othersMessage = Loc.GetString("toilet-component-suicide-head-message-others", + ("victim",victimMeta.Name),("owner", meta.Name)); + _popupSystem.PopupEntity(othersMessage, uid, Filter.Pvs(victimUid)); + + var selfMessage = Loc.GetString("toilet-component-suicide-head-message", + ("owner", meta.Name)); + _popupSystem.PopupEntity(selfMessage, uid, Filter.Entities(victimUid)); + + return SuicideKind.Asphyxiation; + } + else + { + var othersMessage = Loc.GetString("toilet-component-suicide-message-others", + ("victim", victimMeta.Name),("owner", meta.Name)); + _popupSystem.PopupEntity(othersMessage, uid, Filter.Pvs(uid)); + + var selfMessage = Loc.GetString("toilet-component-suicide-message", + ("owner",meta.Name)); + _popupSystem.PopupEntity(selfMessage, uid, Filter.Entities(victimUid)); + + return SuicideKind.Blunt; + } + } + + private void OnToiletInterrupt(ToiletPryInterrupted ev) + { + if (!EntityManager.TryGetComponent(ev.Uid, out ToiletComponent? toilet)) + return; + + toilet.IsPrying = false; + } + + private void OnToiletPried(ToiletPryFinished ev) + { + if (!EntityManager.TryGetComponent(ev.Uid, out ToiletComponent? toilet)) + return; + + toilet.IsPrying = false; + toilet.LidOpen = !toilet.LidOpen; + UpdateSprite(ev.Uid, toilet); + } + + public void ToggleToiletSeat(EntityUid uid, ToiletComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + component.IsSeatUp = !component.IsSeatUp; + SoundSystem.Play(Filter.Pvs(uid), component.ToggleSound.GetSound(), uid, + AudioHelpers.WithVariation(0.05f)); + + UpdateSprite(uid, component); + } + + private void UpdateSprite(EntityUid uid, ToiletComponent? component = null) + { + if (!Resolve(uid, ref component)) + return; + + if (!EntityManager.TryGetComponent(uid,out AppearanceComponent? appearance)) + return; + + appearance.SetData(ToiletVisuals.LidOpen, component.LidOpen); + appearance.SetData(ToiletVisuals.SeatUp, component.IsSeatUp); + } + } + + public class ToiletPryFinished : EntityEventArgs + { + public EntityUid Uid; + + public ToiletPryFinished(EntityUid uid) + { + Uid = uid; + } + } + + public class ToiletPryInterrupted : EntityEventArgs + { + public EntityUid Uid; + + public ToiletPryInterrupted(EntityUid uid) + { + Uid = uid; + } + } +} diff --git a/Resources/Locale/en-US/storage/components/secret-stash-component.ftl b/Resources/Locale/en-US/storage/components/secret-stash-component.ftl index 57b79b748d..6695088251 100644 --- a/Resources/Locale/en-US/storage/components/secret-stash-component.ftl +++ b/Resources/Locale/en-US/storage/components/secret-stash-component.ftl @@ -1,7 +1,7 @@ ### Secret stash component. Stuff like potted plants, comfy chair cushions, etc... comp-secret-stash-secret-part-name = {$name} -comp-secret-stash-action-hide-success = You hide { THE($item) } in { $this } +comp-secret-stash-action-hide-success = You hide {$item} in { $this } comp-secret-stash-action-hide-container-not-empty = There's already something in here?! comp-secret-stash-action-hide-item-too-big = {$item} is too big to fit in {$stash}! -comp-secret-stash-action-get-item-found-something = There was something inside {$stash}! \ No newline at end of file +comp-secret-stash-action-get-item-found-something = There was something inside {$stash}!