diff --git a/Content.IntegrationTests/Tests/PDA/PDAExtensionsTests.cs b/Content.IntegrationTests/Tests/PDA/PDAExtensionsTests.cs index dd7e344fb7..6a5fb61252 100644 --- a/Content.IntegrationTests/Tests/PDA/PDAExtensionsTests.cs +++ b/Content.IntegrationTests/Tests/PDA/PDAExtensionsTests.cs @@ -31,7 +31,7 @@ namespace Content.IntegrationTests.Tests.PDA components: - type: ItemSlots slots: - pda_id_slot: + pdaIdSlot: whitelist: components: - IdCard @@ -79,7 +79,7 @@ namespace Content.IntegrationTests.Tests.PDA var itemSlots = dummyPda.GetComponent(); sEntityManager.EntitySysManager.GetEntitySystem() - .TryInsertContent(itemSlots, pdaIdCard, PDAComponent.IDSlotName); + .TryInsertContent(itemSlots, pdaIdCard, pdaComponent.IdSlot); var pdaContainedId = pdaComponent.ContainedID; // The PDA in the hand should be found first diff --git a/Content.IntegrationTests/Tests/Utility/EntityWhitelistTest.cs b/Content.IntegrationTests/Tests/Utility/EntityWhitelistTest.cs index 629f726e8b..583cbdc939 100644 --- a/Content.IntegrationTests/Tests/Utility/EntityWhitelistTest.cs +++ b/Content.IntegrationTests/Tests/Utility/EntityWhitelistTest.cs @@ -1,16 +1,11 @@ -using System.IO; +using System.Linq; using System.Threading.Tasks; -using Content.Server.Cabinet; -using Content.Server.GameObjects.Components; +using Content.Shared.Containers.ItemSlots; using Content.Shared.Whitelist; using NUnit.Framework; using NUnit.Framework.Internal; using Robust.Shared.GameObjects; -using Robust.Shared.IoC; using Robust.Shared.Map; -using Robust.Shared.Maths; -using Robust.Shared.Prototypes; -using Robust.Shared.Serialization.Manager; namespace Content.IntegrationTests.Tests.Utility { @@ -30,14 +25,16 @@ namespace Content.IntegrationTests.Tests.Utility - type: entity id: WhitelistDummy components: - - type: ItemCabinet - whitelist: - prototypes: - - ValidPrototypeDummy - components: - - {ValidComponent} - tags: - - ValidTag + - type: ItemSlots + slots: + slotName: + whitelist: + prototypes: + - ValidPrototypeDummy + components: + - {ValidComponent} + tags: + - ValidTag - type: entity id: InvalidComponentDummy @@ -102,7 +99,7 @@ namespace Content.IntegrationTests.Tests.Utility // Test from serialized var dummy = entityManager.SpawnEntity("WhitelistDummy", mapCoordinates); - var whitelistSer = dummy.GetComponent().Whitelist; + var whitelistSer = dummy.GetComponent().Slots.Values.First().Whitelist; Assert.That(whitelistSer, Is.Not.Null); Assert.That(whitelistSer.Components, Is.Not.Null); diff --git a/Content.Server/Cabinet/ItemCabinetComponent.cs b/Content.Server/Cabinet/ItemCabinetComponent.cs index fca1c34c50..8b2e4d3416 100644 --- a/Content.Server/Cabinet/ItemCabinetComponent.cs +++ b/Content.Server/Cabinet/ItemCabinetComponent.cs @@ -1,6 +1,4 @@ using Content.Shared.Sound; -using Content.Shared.Whitelist; -using Robust.Shared.Containers; using Robust.Shared.GameObjects; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.ViewVariables; @@ -8,8 +6,7 @@ using Robust.Shared.ViewVariables; namespace Content.Server.Cabinet { /// - /// Used for entities that can hold one item that fits the whitelist, which can be extracted by interacting with - /// the entity, and can have an item fitting the whitelist placed back inside + /// Used for entities that can be opened, closed, and can hold one item. E.g., fire extinguisher cabinets. /// [RegisterComponent] public class ItemCabinetComponent : Component @@ -24,21 +21,10 @@ namespace Content.Server.Cabinet public SoundSpecifier DoorSound { get; set; } = default!; /// - /// The prototype that should be spawned inside the cabinet when it is map initialized. + /// The slot name, used to get the actual item slot from the ItemSlotsComponent. /// - [ViewVariables] - [DataField("spawnPrototype")] - public string? SpawnPrototype { get; set; } - - /// - /// A whitelist defining which entities are allowed into the cabinet. - /// - [ViewVariables] - [DataField("whitelist")] - public EntityWhitelist? Whitelist = null; - - [ViewVariables] - public ContainerSlot ItemContainer = default!; + [DataField("cabinetSlot")] + public string CabinetSlot = "cabinetSlot"; /// /// Whether the cabinet is currently open or not. diff --git a/Content.Server/Cabinet/ItemCabinetSystem.cs b/Content.Server/Cabinet/ItemCabinetSystem.cs index 47471633f1..2732aefac3 100644 --- a/Content.Server/Cabinet/ItemCabinetSystem.cs +++ b/Content.Server/Cabinet/ItemCabinetSystem.cs @@ -1,52 +1,68 @@ -using Content.Server.Hands.Components; -using Content.Server.Items; -using Content.Shared.ActionBlocker; using Content.Shared.Audio; using Content.Shared.Cabinet; -using Content.Shared.Hands.Components; +using Content.Shared.Containers.ItemSlots; using Content.Shared.Interaction; -using Content.Shared.Popups; using Content.Shared.Verbs; using Robust.Shared.Audio; -using Robust.Shared.Containers; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Localization; using Robust.Shared.Player; +using System; namespace Content.Server.Cabinet { public class ItemCabinetSystem : EntitySystem { - [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!; + [Dependency] private readonly SharedItemSlotsSystem _itemSlotsSystem = default!; public override void Initialize() { base.Initialize(); - SubscribeLocalEvent(OnMapInitialize); - SubscribeLocalEvent(OnInteractUsing); SubscribeLocalEvent(OnInteractHand); SubscribeLocalEvent(OnActivateInWorld); - - SubscribeLocalEvent(OnTryEjectItemCabinet); - SubscribeLocalEvent(OnTryInsertItemCabinet); - SubscribeLocalEvent(OnToggleItemCabinet); - - SubscribeLocalEvent(AddEjectInsertVerbs); + SubscribeLocalEvent(InitializeAppearance); + SubscribeLocalEvent(OnItemSlotChanged); SubscribeLocalEvent(AddToggleOpenVerb); } - private void AddToggleOpenVerb(EntityUid uid, ItemCabinetComponent component, GetActivationVerbsEvent args) + private void InitializeAppearance(EntityUid uid, ItemCabinetComponent component, ComponentStartup args) + { + UpdateAppearance(uid, component); + } + + private void UpdateAppearance(EntityUid uid, + ItemCabinetComponent? cabinet = null, + SharedItemSlotsComponent? itemSlots = null, + SharedAppearanceComponent? appearance = null) + { + if (!Resolve(uid, ref cabinet, ref itemSlots, ref appearance)) + return; + + appearance.SetData(ItemCabinetVisuals.IsOpen, cabinet.Opened); + + if (!itemSlots.Slots.TryGetValue(cabinet.CabinetSlot, out var slot)) + return; + + appearance.SetData(ItemCabinetVisuals.ContainsItem, slot.HasEntity); + } + + private void OnItemSlotChanged(EntityUid uid, ItemCabinetComponent cabinet, ItemSlotChangedEvent args) + { + UpdateAppearance(uid, cabinet, args.SlotsComponent); + } + + private void AddToggleOpenVerb(EntityUid uid, ItemCabinetComponent cabinet, GetActivationVerbsEvent args) { if (args.Hands == null || !args.CanAccess || !args.CanInteract) return; // Toggle open verb Verb toggleVerb = new(); - toggleVerb.Act = () => OnToggleItemCabinet(uid, component); - if (component.Opened) + toggleVerb.Act = () => ToggleItemCabinet(uid, cabinet); + if (cabinet.Opened) { toggleVerb.Text = Loc.GetString("verb-categories-close"); toggleVerb.IconTexture = "/Textures/Interface/VerbIcons/close.svg.192dpi.png"; @@ -59,210 +75,65 @@ namespace Content.Server.Cabinet args.Verbs.Add(toggleVerb); } - private void AddEjectInsertVerbs(EntityUid uid, ItemCabinetComponent component, GetInteractionVerbsEvent args) - { - if (args.Hands == null || !args.CanAccess || !args.CanInteract) - return; - - // "Eject" item verb - if (component.Opened && - component.ItemContainer.ContainedEntity != null && - _actionBlockerSystem.CanPickup(args.User)) - { - Verb verb = new(); - verb.Act = () => - { - TakeItem(component, args.Hands, component.ItemContainer.ContainedEntity, args.User); - UpdateVisuals(component); - }; - verb.Text = Loc.GetString("pick-up-verb-get-data-text"); - verb.IconTexture = "/Textures/Interface/VerbIcons/pickup.svg.192dpi.png"; - args.Verbs.Add(verb); - } - - // Insert item verb - if (component.Opened && - args.Using != null && - _actionBlockerSystem.CanDrop(args.User) && - (component.Whitelist?.IsValid(args.Using) ?? true) && - component.ItemContainer.CanInsert(args.Using)) - { - Verb verb = new(); - verb.Act = () => - { - args.Hands.TryPutEntityIntoContainer(args.Using, component.ItemContainer); - UpdateVisuals(component); - }; - verb.Category = VerbCategory.Insert; - verb.Text = args.Using.Name; - args.Verbs.Add(verb); - } - } - - private void OnMapInitialize(EntityUid uid, ItemCabinetComponent comp, MapInitEvent args) - { - var owner = EntityManager.GetEntity(uid); - comp.ItemContainer = - owner.EnsureContainer("item_cabinet", out _); - - if (comp.SpawnPrototype != null) - comp.ItemContainer.Insert(EntityManager.SpawnEntity(comp.SpawnPrototype, owner.Transform.Coordinates)); - - UpdateVisuals(comp); - } - + /// + /// Try insert an item if the cabinet is opened. Otherwise, just try open it. + /// private void OnInteractUsing(EntityUid uid, ItemCabinetComponent comp, InteractUsingEvent args) { - args.Handled = true; + if (args.Handled) + return; + if (!comp.Opened) - { - RaiseLocalEvent(uid, new ToggleItemCabinetEvent(), false); - } + ToggleItemCabinet(uid, comp); else - { - RaiseLocalEvent(uid, new TryInsertItemCabinetEvent(args.User, args.Used), false); - } + _itemSlotsSystem.TryInsertContent(uid, args.Used, args.User); args.Handled = true; } + /// + /// If the cabinet is opened and has an entity, try and take it. Otherwise toggle the cabinet open/closed; + /// private void OnInteractHand(EntityUid uid, ItemCabinetComponent comp, InteractHandEvent args) { - args.Handled = true; - if (comp.Opened) - { - if (comp.ItemContainer.ContainedEntity == null) - { - RaiseLocalEvent(uid, new ToggleItemCabinetEvent(), false); - return; - } - RaiseLocalEvent(uid, new TryEjectItemCabinetEvent(args.User), false); - } + if (args.Handled) + return; + + if (!EntityManager.TryGetComponent(uid, out SharedItemSlotsComponent itemSlots)) + return; + + if (!itemSlots.Slots.TryGetValue(comp.CabinetSlot, out var slot)) + return; + + if (comp.Opened && slot.HasEntity) + _itemSlotsSystem.TryEjectContent(uid, comp.CabinetSlot, args.User); else - { - RaiseLocalEvent(uid, new ToggleItemCabinetEvent(), false); - } + ToggleItemCabinet(uid, comp); + + args.Handled = true; } private void OnActivateInWorld(EntityUid uid, ItemCabinetComponent comp, ActivateInWorldEvent args) { + if (args.Handled) + return; + args.Handled = true; - RaiseLocalEvent(uid, new ToggleItemCabinetEvent(), false); + ToggleItemCabinet(uid, comp); } /// /// Toggles the ItemCabinet's state. /// - private void OnToggleItemCabinet(EntityUid uid, ItemCabinetComponent comp, ToggleItemCabinetEvent? args = null) + private void ToggleItemCabinet(EntityUid uid, ItemCabinetComponent? cabinet = null) { - comp.Opened = !comp.Opened; - ClickLatchSound(comp); - UpdateVisuals(comp); - } - - /// - /// Tries to insert an entity into the ItemCabinet's slot from the user's hands. - /// - private static void OnTryInsertItemCabinet(EntityUid uid, ItemCabinetComponent comp, TryInsertItemCabinetEvent args) - { - if (comp.ItemContainer.ContainedEntity != null || args.Cancelled || (comp.Whitelist != null && !comp.Whitelist.IsValid(args.Item))) - { + if (!Resolve(uid, ref cabinet)) return; - } - if (!args.User.TryGetComponent(out var hands) || !hands.Drop(args.Item, comp.ItemContainer)) - { - return; - } + cabinet.Opened = !cabinet.Opened; + SoundSystem.Play(Filter.Pvs(uid), cabinet.DoorSound.GetSound(), uid, AudioHelpers.WithVariation(0.15f)); - UpdateVisuals(comp); - } - - /// - /// Tries to eject the ItemCabinet's item, either into the user's hands or onto the floor. - /// - private static void OnTryEjectItemCabinet(EntityUid uid, ItemCabinetComponent comp, TryEjectItemCabinetEvent args) - { - if (comp.ItemContainer.ContainedEntity == null || args.Cancelled) - return; - if (args.User.TryGetComponent(out SharedHandsComponent? hands)) - { - // Put into hands - TakeItem(comp, hands, comp.ItemContainer.ContainedEntity, args.User); - } - else if (comp.ItemContainer.Remove(comp.ItemContainer.ContainedEntity)) - { - comp.ItemContainer.ContainedEntity.Transform.Coordinates = args.User.Transform.Coordinates; - } - UpdateVisuals(comp); - } - - /// - /// Tries to eject the ItemCabinet's item, either into the user's hands. Used by both and the eject verbs. - /// - private static void TakeItem(ItemCabinetComponent comp, SharedHandsComponent hands, IEntity containedEntity, IEntity user) - { - if (containedEntity.HasComponent()) - { - if (!hands.TryPutInActiveHandOrAny(containedEntity)) - containedEntity.Transform.Coordinates = hands.Owner.Transform.Coordinates; - - comp.Owner.PopupMessage(user, - Loc.GetString("comp-item-cabinet-successfully-taken", - ("item", containedEntity), - ("cabinet", comp.Owner))); - } - } - - private static void UpdateVisuals(ItemCabinetComponent comp) - { - if (comp.Owner.TryGetComponent(out SharedAppearanceComponent? appearance)) - { - appearance.SetData(ItemCabinetVisuals.IsOpen, comp.Opened); - appearance.SetData(ItemCabinetVisuals.ContainsItem, comp.ItemContainer.ContainedEntity != null); - } - } - - private static void ClickLatchSound(ItemCabinetComponent comp) - { - SoundSystem.Play(Filter.Pvs(comp.Owner), comp.DoorSound.GetSound(), comp.Owner, AudioHelpers.WithVariation(0.15f)); - } - } - - public class ToggleItemCabinetEvent : EntityEventArgs - { - } - - public class TryEjectItemCabinetEvent : CancellableEntityEventArgs - { - /// - /// The user who tried to eject the item. - /// - public IEntity User; - - public TryEjectItemCabinetEvent(IEntity user) - { - User = user; - } - } - - public class TryInsertItemCabinetEvent : CancellableEntityEventArgs - { - /// - /// The user who tried to eject the item. - /// - public IEntity User; - - /// - /// The item to be inserted. - /// - public IEntity Item; - - public TryInsertItemCabinetEvent(IEntity user, IEntity item) - { - User = user; - Item = item; + UpdateAppearance(uid, cabinet); } } } diff --git a/Content.Server/PDA/PDAComponent.cs b/Content.Server/PDA/PDAComponent.cs index c6f1ac78d6..88696b7713 100644 --- a/Content.Server/PDA/PDAComponent.cs +++ b/Content.Server/PDA/PDAComponent.cs @@ -13,8 +13,11 @@ namespace Content.Server.PDA { public override string Name => "PDA"; - public const string IDSlotName = "pda_id_slot"; - public const string PenSlotName = "pda_pen_slot"; + [DataField("idSlot")] + public string IdSlot = "pdaIdSlot"; + + [DataField("penSlot")] + public string PenSlot = "pdaPenSlot"; [ViewVariables] [DataField("idCard")] public string? StartingIdCard; diff --git a/Content.Server/PDA/PDASystem.cs b/Content.Server/PDA/PDASystem.cs index 9be9249c2d..499d682d6a 100644 --- a/Content.Server/PDA/PDASystem.cs +++ b/Content.Server/PDA/PDASystem.cs @@ -29,7 +29,7 @@ namespace Content.Server.PDA SubscribeLocalEvent(OnMapInit); SubscribeLocalEvent(OnActivateInWorld); SubscribeLocalEvent(OnUse); - SubscribeLocalEvent(OnItemSlotChanged); + SubscribeLocalEvent(OnItemSlotChanged); SubscribeLocalEvent(OnLightToggle); SubscribeLocalEvent(OnUplinkInit); @@ -53,7 +53,7 @@ namespace Content.Server.PDA // if pda prototype doesn't have slots, ID will drop down on ground var idCard = EntityManager.SpawnEntity(pda.StartingIdCard, pda.Owner.Transform.Coordinates); if (EntityManager.TryGetComponent(uid, out SharedItemSlotsComponent? itemSlots)) - _slotsSystem.TryInsertContent(itemSlots, idCard, PDAComponent.IDSlotName); + _slotsSystem.TryInsertContent(itemSlots, idCard, pda.IdSlot); } } @@ -71,10 +71,10 @@ namespace Content.Server.PDA args.Handled = OpenUI(pda, args.User); } - private void OnItemSlotChanged(EntityUid uid, PDAComponent pda, ItemSlotChanged args) + private void OnItemSlotChanged(EntityUid uid, PDAComponent pda, ItemSlotChangedEvent args) { // check if ID slot changed - if (args.SlotName == PDAComponent.IDSlotName) + if (args.SlotName == pda.IdSlot) { var item = args.ContainedItem; if (item == null || !EntityManager.TryGetComponent(item.Value, out IdCardComponent ? idCard)) @@ -82,7 +82,7 @@ namespace Content.Server.PDA else pda.ContainedID = idCard; } - else if (args.SlotName == PDAComponent.PenSlotName) + else if (args.SlotName == pda.PenSlot) { var item = args.ContainedItem; pda.PenInserted = item != null; @@ -162,14 +162,12 @@ namespace Content.Server.PDA case PDAEjectIDMessage _: { - if (pda.Owner.TryGetComponent(out SharedItemSlotsComponent? itemSlots)) - _slotsSystem.TryEjectContent(itemSlots, PDAComponent.IDSlotName, msg.Session.AttachedEntity); + _slotsSystem.TryEjectContent(pda.Owner.Uid, pda.IdSlot, msg.Session.AttachedEntity); break; } case PDAEjectPenMessage _: { - if (pda.Owner.TryGetComponent(out SharedItemSlotsComponent? itemSlots)) - _slotsSystem.TryEjectContent(itemSlots, PDAComponent.PenSlotName, msg.Session.AttachedEntity); + _slotsSystem.TryEjectContent(pda.Owner.Uid, pda.PenSlot, msg.Session.AttachedEntity); break; } case PDAShowUplinkMessage _: diff --git a/Content.Server/Sandbox/SandboxManager.cs b/Content.Server/Sandbox/SandboxManager.cs index 026f366981..ea109c4af6 100644 --- a/Content.Server/Sandbox/SandboxManager.cs +++ b/Content.Server/Sandbox/SandboxManager.cs @@ -138,7 +138,7 @@ namespace Content.Server.Sandbox if (pda.Owner.TryGetComponent(out SharedItemSlotsComponent? itemSlots)) { _entityManager.EntitySysManager.GetEntitySystem(). - TryInsertContent(itemSlots, newID, PDAComponent.IDSlotName); + TryInsertContent(itemSlots, newID, pda.IdSlot); } } else diff --git a/Content.Shared/Containers/ItemSlot/ItemSlotEvents.cs b/Content.Shared/Containers/ItemSlot/ItemSlotEvents.cs index 1021872d12..e2c7ffb54f 100644 --- a/Content.Shared/Containers/ItemSlot/ItemSlotEvents.cs +++ b/Content.Shared/Containers/ItemSlot/ItemSlotEvents.cs @@ -5,14 +5,14 @@ namespace Content.Shared.Containers.ItemSlots /// /// Item was placed in or removed from one of the slots in /// - public class ItemSlotChanged : EntityEventArgs + public class ItemSlotChangedEvent : EntityEventArgs { public SharedItemSlotsComponent SlotsComponent; public string SlotName; public ItemSlot Slot; public readonly EntityUid? ContainedItem; - public ItemSlotChanged(SharedItemSlotsComponent slotsComponent, string slotName, ItemSlot slot) + public ItemSlotChangedEvent(SharedItemSlotsComponent slotsComponent, string slotName, ItemSlot slot) { SlotsComponent = slotsComponent; SlotName = slotName; diff --git a/Content.Shared/Containers/ItemSlot/SharedItemSlotsComponent.cs b/Content.Shared/Containers/ItemSlot/SharedItemSlotsComponent.cs index 44f54e59ee..1a301fd672 100644 --- a/Content.Shared/Containers/ItemSlot/SharedItemSlotsComponent.cs +++ b/Content.Shared/Containers/ItemSlot/SharedItemSlotsComponent.cs @@ -2,6 +2,7 @@ using Content.Shared.Sound; using Content.Shared.Whitelist; using Robust.Shared.Containers; using Robust.Shared.GameObjects; +using Robust.Shared.Localization; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; @@ -31,9 +32,23 @@ namespace Content.Shared.Containers.ItemSlots [ViewVariables] [DataField("insertSound")] public SoundSpecifier? InsertSound; [ViewVariables] [DataField("ejectSound")] public SoundSpecifier? EjectSound; + /// + /// The name of this item slot. This will be shown to the user in the verb menu. + /// + [ViewVariables] public string Name + { + get => _name != string.Empty + ? Loc.GetString(_name) + : ContainerSlot.ContainedEntity?.Name ?? string.Empty; + set => _name = value; + } + [DataField("name")] private string _name = string.Empty; + [DataField("item", customTypeSerializer: typeof(PrototypeIdSerializer))] [ViewVariables] public string? StartingItem; [ViewVariables] public ContainerSlot ContainerSlot = default!; + + public bool HasEntity => ContainerSlot.ContainedEntity != null; } } diff --git a/Content.Shared/Containers/ItemSlot/SharedItemSlotsSystem.cs b/Content.Shared/Containers/ItemSlot/SharedItemSlotsSystem.cs index 919a620289..91f88cefd9 100644 --- a/Content.Shared/Containers/ItemSlot/SharedItemSlotsSystem.cs +++ b/Content.Shared/Containers/ItemSlot/SharedItemSlotsSystem.cs @@ -57,7 +57,7 @@ namespace Content.Shared.Containers.ItemSlots var item = EntityManager.SpawnEntity(slot.StartingItem, itemSlots.Owner.Transform.Coordinates); slot.ContainerSlot.Insert(item); - RaiseLocalEvent(uid, new ItemSlotChanged(itemSlots, slotName, slot)); + RaiseLocalEvent(uid, new ItemSlotChangedEvent(itemSlots, slotName, slot)); } } } @@ -76,11 +76,9 @@ namespace Content.Shared.Containers.ItemSlots continue; Verb verb = new(); - // TODO ITEMSLOTS give item slot names localization strings? - // Basically: its much nicer to have "insert ID" instead of the much longer "Eject 's ID card (assistant)" - verb.Text = slot.ContainerSlot.ContainedEntity.Name; + verb.Text = slot.Name; verb.Category = VerbCategory.Eject; - verb.Act = () => TryEjectContent(component, slotName, args.User); + verb.Act = () => TryEjectContent(uid, slotName, args.User, component); args.Verbs.Add(verb); } @@ -100,9 +98,7 @@ namespace Content.Shared.Containers.ItemSlots continue; Verb verb = new(); - // TODO ITEMSLOTS give item slot names localization strings? - // Basically: its much nicer to have "insert ID" instead of the much longer "Insert 's ID card (assistant)" - verb.Text = args.Using.Name; + verb.Text = slot.Name != string.Empty ? slot.Name : args.Using.Name; verb.Category = VerbCategory.Insert; verb.Act = () => InsertContent(component, slot, slotName, args.Using); args.Verbs.Add(verb); @@ -114,15 +110,18 @@ namespace Content.Shared.Containers.ItemSlots if (args.Handled) return; - args.Handled = TryInsertContent(itemSlots, args.Used, args.User); + args.Handled = TryInsertContent(uid, args.Used, args.User, itemSlots); } /// /// Tries to insert or swap an item in any fitting item slot from users hand. If a valid slot already contains an item, it will swap it out. /// /// False if failed to insert item - public bool TryInsertContent(SharedItemSlotsComponent itemSlots, IEntity item, IEntity user, SharedHandsComponent? hands = null) + public bool TryInsertContent(EntityUid uid, IEntity item, IEntity user, SharedItemSlotsComponent? itemSlots = null, SharedHandsComponent? hands = null) { + if (!Resolve(uid, ref itemSlots)) + return false; + if (!Resolve(user.Uid, ref hands)) { itemSlots.Owner.PopupMessage(user, Loc.GetString("item-slots-try-insert-no-hands")); @@ -164,7 +163,7 @@ namespace Content.Shared.Containers.ItemSlots { // insert item slot.ContainerSlot.Insert(item); - RaiseLocalEvent(itemSlots.Owner.Uid, new ItemSlotChanged(itemSlots, slotName, slot)); + RaiseLocalEvent(itemSlots.Owner.Uid, new ItemSlotChangedEvent(itemSlots, slotName, slot)); // play sound if (slot.InsertSound != null) @@ -218,8 +217,11 @@ namespace Content.Shared.Containers.ItemSlots /// /// Try to eject item from slot to users hands /// - public bool TryEjectContent(SharedItemSlotsComponent itemSlots, string slotName, IEntity? user) + public bool TryEjectContent(EntityUid uid, string slotName, IEntity? user, SharedItemSlotsComponent? itemSlots = null) { + if (!Resolve(uid, ref itemSlots)) + return false; + if (!itemSlots.Slots.TryGetValue(slotName, out var slot)) return false; @@ -246,7 +248,7 @@ namespace Content.Shared.Containers.ItemSlots if (slot.EjectSound != null) SoundSystem.Play(Filter.Pvs(itemSlots.Owner), slot.EjectSound.GetSound(), itemSlots.Owner); - RaiseLocalEvent(itemSlots.Owner.Uid, new ItemSlotChanged(itemSlots, slotName, slot)); + RaiseLocalEvent(itemSlots.Owner.Uid, new ItemSlotChangedEvent(itemSlots, slotName, slot)); return true; } } diff --git a/Resources/Locale/en-US/cabinet/item-cabinet-system.ftl b/Resources/Locale/en-US/cabinet/item-cabinet-system.ftl deleted file mode 100644 index 16d7fa5e6a..0000000000 --- a/Resources/Locale/en-US/cabinet/item-cabinet-system.ftl +++ /dev/null @@ -1,5 +0,0 @@ -### Used for item cabinet (fire extinguisher cabinets) - -## Displayed when the item is successfully taken out of the cabinet. - -comp-item-cabinet-successfully-taken = You take { THE($item) } from { THE($cabinet) }. diff --git a/Resources/Prototypes/Entities/Objects/Devices/pda.yml b/Resources/Prototypes/Entities/Objects/Devices/pda.yml index 215a291277..8ae3d6b733 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/pda.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/pda.yml @@ -35,12 +35,13 @@ type: UplinkBoundUserInterface - type: ItemSlots slots: - pda_pen_slot: + pdaPenSlot: item: "Pen" whitelist: tags: - Write - pda_id_slot: + pdaIdSlot: + name: ID Card insertSound: path: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg ejectSound: diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/extinguisher_cabinet.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/extinguisher_cabinet.yml index deafe23105..2b94a4b154 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/extinguisher_cabinet.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/extinguisher_cabinet.yml @@ -20,14 +20,17 @@ - type: ItemCabinet doorSound: path: /Audio/Machines/machine_switch.ogg - whitelist: - components: - - FireExtinguisher - type: Appearance visuals: - type: ItemCabinetVisualizer openState: open closedState: closed + - type: ItemSlots + slots: + cabinetSlot: + whitelist: + components: + - FireExtinguisher placement: mode: SnapgridCenter @@ -44,8 +47,15 @@ parent: ExtinguisherCabinet suffix: Filled components: - - type: ItemCabinet - spawnPrototype: FireExtinguisher + - type: ItemCabinet + spawnPrototype: FireExtinguisher + - type: ItemSlots + slots: + cabinetSlot: + item: FireExtinguisher + whitelist: + components: + - FireExtinguisher - type: entity id: ExtinguisherCabinetFilledOpen diff --git a/Resources/Prototypes/Entities/Structures/Wallmounts/fireaxe_cabinet.yml b/Resources/Prototypes/Entities/Structures/Wallmounts/fireaxe_cabinet.yml index ab58b7a58f..19d67e21a5 100644 --- a/Resources/Prototypes/Entities/Structures/Wallmounts/fireaxe_cabinet.yml +++ b/Resources/Prototypes/Entities/Structures/Wallmounts/fireaxe_cabinet.yml @@ -18,14 +18,17 @@ - type: ItemCabinet doorSound: path: /Audio/Machines/machine_switch.ogg - whitelist: - tags: - - FireAxe - type: Appearance visuals: - type: ItemCabinetVisualizer closedState: glass openState: glass-up + - type: ItemSlots + slots: + cabinetSlot: + whitelist: + tags: + - FireAxe placement: mode: SnapgridCenter @@ -42,8 +45,14 @@ parent: FireAxeCabinet suffix: Filled components: - - type: ItemCabinet - spawnPrototype: FireAxe + - type: ItemCabinet + - type: ItemSlots + slots: + cabinetSlot: + item: FireAxe + whitelist: + tags: + - FireAxe - type: entity id: FireAxeCabinetFilledOpen