Make ItemCabinet use ItemSlots (#4771)

* pda slot names

* cabinets use item slots

* fix yaml

* fix tests
This commit is contained in:
Leon Friedrich
2021-10-06 08:55:45 +11:00
committed by GitHub
parent d2748d1e59
commit 6f50dd2f7b
14 changed files with 164 additions and 277 deletions

View File

@@ -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<SharedItemSlotsComponent>();
sEntityManager.EntitySysManager.GetEntitySystem<SharedItemSlotsSystem>()
.TryInsertContent(itemSlots, pdaIdCard, PDAComponent.IDSlotName);
.TryInsertContent(itemSlots, pdaIdCard, pdaComponent.IdSlot);
var pdaContainedId = pdaComponent.ContainedID;
// The PDA in the hand should be found first

View File

@@ -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<ItemCabinetComponent>().Whitelist;
var whitelistSer = dummy.GetComponent<SharedItemSlotsComponent>().Slots.Values.First().Whitelist;
Assert.That(whitelistSer, Is.Not.Null);
Assert.That(whitelistSer.Components, Is.Not.Null);

View File

@@ -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
{
/// <summary>
/// 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.
/// </summary>
[RegisterComponent]
public class ItemCabinetComponent : Component
@@ -24,21 +21,10 @@ namespace Content.Server.Cabinet
public SoundSpecifier DoorSound { get; set; } = default!;
/// <summary>
/// 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.
/// </summary>
[ViewVariables]
[DataField("spawnPrototype")]
public string? SpawnPrototype { get; set; }
/// <summary>
/// A whitelist defining which entities are allowed into the cabinet.
/// </summary>
[ViewVariables]
[DataField("whitelist")]
public EntityWhitelist? Whitelist = null;
[ViewVariables]
public ContainerSlot ItemContainer = default!;
[DataField("cabinetSlot")]
public string CabinetSlot = "cabinetSlot";
/// <summary>
/// Whether the cabinet is currently open or not.

View File

@@ -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<ItemCabinetComponent, MapInitEvent>(OnMapInitialize);
SubscribeLocalEvent<ItemCabinetComponent, InteractUsingEvent>(OnInteractUsing);
SubscribeLocalEvent<ItemCabinetComponent, InteractHandEvent>(OnInteractHand);
SubscribeLocalEvent<ItemCabinetComponent, ActivateInWorldEvent>(OnActivateInWorld);
SubscribeLocalEvent<ItemCabinetComponent, TryEjectItemCabinetEvent>(OnTryEjectItemCabinet);
SubscribeLocalEvent<ItemCabinetComponent, TryInsertItemCabinetEvent>(OnTryInsertItemCabinet);
SubscribeLocalEvent<ItemCabinetComponent, ToggleItemCabinetEvent>(OnToggleItemCabinet);
SubscribeLocalEvent<ItemCabinetComponent, GetInteractionVerbsEvent>(AddEjectInsertVerbs);
SubscribeLocalEvent<ItemCabinetComponent, ComponentStartup>(InitializeAppearance);
SubscribeLocalEvent<ItemCabinetComponent, ItemSlotChangedEvent>(OnItemSlotChanged);
SubscribeLocalEvent<ItemCabinetComponent, GetActivationVerbsEvent>(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<ContainerSlot>("item_cabinet", out _);
if (comp.SpawnPrototype != null)
comp.ItemContainer.Insert(EntityManager.SpawnEntity(comp.SpawnPrototype, owner.Transform.Coordinates));
UpdateVisuals(comp);
}
/// <summary>
/// Try insert an item if the cabinet is opened. Otherwise, just try open it.
/// </summary>
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;
}
/// <summary>
/// If the cabinet is opened and has an entity, try and take it. Otherwise toggle the cabinet open/closed;
/// </summary>
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);
}
/// <summary>
/// Toggles the ItemCabinet's state.
/// </summary>
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);
}
/// <summary>
/// Tries to insert an entity into the ItemCabinet's slot from the user's hands.
/// </summary>
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<HandsComponent>(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);
}
/// <summary>
/// Tries to eject the ItemCabinet's item, either into the user's hands or onto the floor.
/// </summary>
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);
}
/// <summary>
/// Tries to eject the ItemCabinet's item, either into the user's hands. Used by both <see
/// cref="OnTryEjectItemCabinet"/> and the eject verbs.
/// </summary>
private static void TakeItem(ItemCabinetComponent comp, SharedHandsComponent hands, IEntity containedEntity, IEntity user)
{
if (containedEntity.HasComponent<ItemComponent>())
{
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
{
/// <summary>
/// The user who tried to eject the item.
/// </summary>
public IEntity User;
public TryEjectItemCabinetEvent(IEntity user)
{
User = user;
}
}
public class TryInsertItemCabinetEvent : CancellableEntityEventArgs
{
/// <summary>
/// The user who tried to eject the item.
/// </summary>
public IEntity User;
/// <summary>
/// The item to be inserted.
/// </summary>
public IEntity Item;
public TryInsertItemCabinetEvent(IEntity user, IEntity item)
{
User = user;
Item = item;
UpdateAppearance(uid, cabinet);
}
}
}

View File

@@ -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;

View File

@@ -29,7 +29,7 @@ namespace Content.Server.PDA
SubscribeLocalEvent<PDAComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<PDAComponent, ActivateInWorldEvent>(OnActivateInWorld);
SubscribeLocalEvent<PDAComponent, UseInHandEvent>(OnUse);
SubscribeLocalEvent<PDAComponent, ItemSlotChanged>(OnItemSlotChanged);
SubscribeLocalEvent<PDAComponent, ItemSlotChangedEvent>(OnItemSlotChanged);
SubscribeLocalEvent<PDAComponent, LightToggleEvent>(OnLightToggle);
SubscribeLocalEvent<PDAComponent, UplinkInitEvent>(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 _:

View File

@@ -138,7 +138,7 @@ namespace Content.Server.Sandbox
if (pda.Owner.TryGetComponent(out SharedItemSlotsComponent? itemSlots))
{
_entityManager.EntitySysManager.GetEntitySystem<SharedItemSlotsSystem>().
TryInsertContent(itemSlots, newID, PDAComponent.IDSlotName);
TryInsertContent(itemSlots, newID, pda.IdSlot);
}
}
else

View File

@@ -5,14 +5,14 @@ namespace Content.Shared.Containers.ItemSlots
/// <summary>
/// Item was placed in or removed from one of the slots in <see cref="SharedItemSlotsComponent"/>
/// </summary>
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;

View File

@@ -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;
/// <summary>
/// The name of this item slot. This will be shown to the user in the verb menu.
/// </summary>
[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<EntityPrototype>))]
[ViewVariables] public string? StartingItem;
[ViewVariables] public ContainerSlot ContainerSlot = default!;
public bool HasEntity => ContainerSlot.ContainedEntity != null;
}
}

View File

@@ -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 <full-in-game-username>'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 <full-in-game-username>'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);
}
/// <summary>
/// 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.
/// </summary>
/// <returns>False if failed to insert item</returns>
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
/// <summary>
/// Try to eject item from slot to users hands
/// </summary>
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;
}
}

View File

@@ -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) }.

View File

@@ -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:

View File

@@ -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

View File

@@ -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