InventorySystem.Helpers.cs 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. using System.Diagnostics.CodeAnalysis;
  2. using Content.Shared.Hands.Components;
  3. using Content.Shared.Storage.EntitySystems;
  4. using Robust.Shared.Prototypes;
  5. namespace Content.Shared.Inventory;
  6. public partial class InventorySystem
  7. {
  8. [Dependency] private readonly SharedStorageSystem _storageSystem = default!;
  9. /// <summary>
  10. /// Yields all entities in hands or inventory slots with the specific flags.
  11. /// </summary>
  12. public IEnumerable<EntityUid> GetHandOrInventoryEntities(Entity<HandsComponent?, InventoryComponent?> user, SlotFlags flags = SlotFlags.All)
  13. {
  14. if (Resolve(user.Owner, ref user.Comp1, false))
  15. {
  16. foreach (var hand in user.Comp1.Hands.Values)
  17. {
  18. if (hand.HeldEntity == null)
  19. continue;
  20. yield return hand.HeldEntity.Value;
  21. }
  22. }
  23. if (!Resolve(user.Owner, ref user.Comp2, false))
  24. yield break;
  25. var slotEnumerator = new InventorySlotEnumerator(user.Comp2, flags);
  26. while (slotEnumerator.NextItem(out var item))
  27. {
  28. yield return item;
  29. }
  30. }
  31. /// <summary>
  32. /// Returns the definition of the inventory slot that the given entity is currently in..
  33. /// </summary>
  34. public bool TryGetContainingSlot(Entity<TransformComponent?, MetaDataComponent?> entity, [NotNullWhen(true)] out SlotDefinition? slot)
  35. {
  36. if (!_containerSystem.TryGetContainingContainer(entity, out var container))
  37. {
  38. slot = null;
  39. return false;
  40. }
  41. return TryGetSlot(container.Owner, container.ID, out slot);
  42. }
  43. /// <summary>
  44. /// Returns true if the given entity is equipped to an inventory slot with the given inventory slot flags.
  45. /// </summary>
  46. public bool InSlotWithFlags(Entity<TransformComponent?, MetaDataComponent?> entity, SlotFlags flags)
  47. {
  48. return TryGetContainingSlot(entity, out var slot)
  49. && (slot.SlotFlags & flags) == flags;
  50. }
  51. public bool SpawnItemInSlot(EntityUid uid, string slot, string prototype, bool silent = false, bool force = false, InventoryComponent? inventory = null)
  52. {
  53. if (!Resolve(uid, ref inventory, false))
  54. return false;
  55. // Let's do nothing if the owner of the inventory has been deleted.
  56. if (Deleted(uid))
  57. return false;
  58. // If we don't have that slot or there's already an item there, we do nothing.
  59. if (!HasSlot(uid, slot) || TryGetSlotEntity(uid, slot, out _, inventory))
  60. return false;
  61. // If the prototype in question doesn't exist, we do nothing.
  62. if (!_prototypeManager.HasIndex<EntityPrototype>(prototype))
  63. return false;
  64. // Let's spawn this first...
  65. var item = EntityManager.SpawnEntity(prototype, Transform(uid).Coordinates);
  66. // Helper method that deletes the item and returns false.
  67. bool DeleteItem()
  68. {
  69. EntityManager.DeleteEntity(item);
  70. return false;
  71. }
  72. // We finally try to equip the item, otherwise we delete it.
  73. return TryEquip(uid, item, slot, silent, force) || DeleteItem();
  74. }
  75. /// <summary>
  76. /// Will attempt to spawn a list of items inside of an entities bag, pockets, hands or nearby
  77. /// </summary>
  78. /// <param name="entity">The entity that you want to spawn an item on</param>
  79. /// <param name="items">A list of prototype IDs that you want to spawn in the bag.</param>
  80. public void SpawnItemsOnEntity(EntityUid entity, List<string> items)
  81. {
  82. foreach (var item in items)
  83. {
  84. SpawnItemOnEntity(entity, item);
  85. }
  86. }
  87. /// <summary>
  88. /// Will attempt to spawn an item inside of an entities bag, pockets, hands or nearby
  89. /// </summary>
  90. /// <param name="entity">The entity that you want to spawn an item on</param>
  91. /// <param name="item">The prototype ID that you want to spawn in the bag.</param>
  92. public void SpawnItemOnEntity(EntityUid entity, EntProtoId item)
  93. {
  94. //Transform() throws error if TransformComponent doesnt exist
  95. if (!HasComp<TransformComponent>(entity))
  96. return;
  97. var xform = Transform(entity);
  98. var mapCoords = _transform.GetMapCoordinates(xform);
  99. var itemToSpawn = Spawn(item, mapCoords);
  100. //Try insert into the backpack
  101. if (TryGetSlotContainer(entity, "back", out var backSlot, out _)
  102. && backSlot.ContainedEntity.HasValue
  103. && _storageSystem.Insert(backSlot.ContainedEntity.Value, itemToSpawn, out _)
  104. )
  105. return;
  106. //Try insert into pockets
  107. if (TryGetSlotContainer(entity, "pocket1", out var pocket1, out _)
  108. && _containerSystem.Insert(itemToSpawn, pocket1)
  109. )
  110. return;
  111. if (TryGetSlotContainer(entity, "pocket2", out var pocket2, out _)
  112. && _containerSystem.Insert(itemToSpawn, pocket2)
  113. )
  114. return;
  115. //Try insert into hands, or drop on the floor
  116. _handsSystem.PickupOrDrop(entity, itemToSpawn, false);
  117. }
  118. }