| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- using Content.Server.Hands.Systems;
- using Content.Server.Storage.EntitySystems;
- using Content.Shared.Administration.Logs;
- using Content.Shared.Database;
- using Content.Shared.Hands.Components;
- using Content.Shared.Inventory;
- using Content.Shared.Popups;
- using Content.Shared.Storage;
- using Robust.Server.Containers;
- namespace Content.Server.VoiceTrigger;
- /// <summary>
- /// Allows storages to be manipulated using voice commands.
- /// </summary>
- public sealed class StorageVoiceControlSystem : EntitySystem
- {
- [Dependency] private readonly ContainerSystem _container = default!;
- [Dependency] private readonly HandsSystem _hands = default!;
- [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
- [Dependency] private readonly InventorySystem _inventory = default!;
- [Dependency] private readonly SharedPopupSystem _popup = default!;
- [Dependency] private readonly StorageSystem _storage = default!;
- public override void Initialize()
- {
- base.Initialize();
- SubscribeLocalEvent<StorageVoiceControlComponent, VoiceTriggeredEvent>(VoiceTriggered);
- }
- private void VoiceTriggered(Entity<StorageVoiceControlComponent> ent, ref VoiceTriggeredEvent args)
- {
- // Check if the component has any slot restrictions via AllowedSlots
- // If it has slot restrictions, check if the item is in a slot that is allowed
- if (ent.Comp.AllowedSlots != null && _inventory.TryGetContainingSlot(ent.Owner, out var itemSlot) &&
- (itemSlot.SlotFlags & ent.Comp.AllowedSlots) == 0)
- return;
- // Don't do anything if there is no message
- if (args.Message == null)
- return;
- // Get the storage component
- if (!TryComp<StorageComponent>(ent, out var storage))
- return;
- // Get the hands component
- if (!TryComp<HandsComponent>(args.Source, out var hands))
- return;
- // If the player has something in their hands, try to insert it into the storage
- if (hands.ActiveHand != null && hands.ActiveHand.HeldEntity.HasValue)
- {
- // Disallow insertion and provide a reason why if the person decides to insert the item into itself
- if (ent.Owner.Equals(hands.ActiveHand.HeldEntity.Value))
- {
- _popup.PopupEntity(Loc.GetString("comp-storagevoicecontrol-self-insert", ("entity", hands.ActiveHand.HeldEntity.Value)), ent, args.Source);
- return;
- }
- if (_storage.CanInsert(ent, hands.ActiveHand.HeldEntity.Value, out var failedReason))
- {
- // We adminlog before insertion, otherwise the logger will attempt to pull info on an entity that no longer is present and throw an exception
- _adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(args.Source)} inserted {ToPrettyString(hands.ActiveHand.HeldEntity.Value)} into {ToPrettyString(ent)} via voice control");
- _storage.Insert(ent, hands.ActiveHand.HeldEntity.Value, out _);
- return;
- }
- {
- // Tell the player the reason why the item couldn't be inserted
- if (failedReason == null)
- return;
- _popup.PopupEntity(Loc.GetString(failedReason), ent, args.Source);
- _adminLogger.Add(LogType.Action,
- LogImpact.Low,
- $"{ToPrettyString(args.Source)} failed to insert {ToPrettyString(hands.ActiveHand.HeldEntity.Value)} into {ToPrettyString(ent)} via voice control");
- }
- return;
- }
- // If otherwise, we're retrieving an item, so check all the items currently in the attached storage
- foreach (var item in storage.Container.ContainedEntities)
- {
- // Get the item's name
- var itemName = MetaData(item).EntityName;
- // The message doesn't match the item name the requestor requested, skip and move on to the next item
- if (!args.Message.Contains(itemName, StringComparison.InvariantCultureIgnoreCase))
- continue;
- // We found the item we want, so draw it from storage and place it into the player's hands
- if (storage.Container.ContainedEntities.Count != 0)
- {
- _container.RemoveEntity(ent, item);
- _adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(args.Source)} retrieved {ToPrettyString(item)} from {ToPrettyString(ent)} via voice control");
- _hands.TryPickup(args.Source, item, handsComp: hands);
- break;
- }
- }
- }
- }
|