]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Prioritize empty item slots when inserting (#28203)
authorDrSmugleaf <10968691+DrSmugleaf@users.noreply.github.com>
Thu, 23 May 2024 04:16:14 +0000 (21:16 -0700)
committerGitHub <noreply@github.com>
Thu, 23 May 2024 04:16:14 +0000 (14:16 +1000)
* Prioritize empty item slots when inserting

* Revert "Prioritize empty item slots when inserting"

This reverts commit 4272a65cba5fc18df801812b0af20123aec08409.

* Prioritize empty item slots when inserting

* Try drop

* Check for any can insert before dropping

Content.Shared/Containers/ItemSlot/ItemSlotsSystem.cs

index 914b34d3c125ee7d073106c3c5c982e53b823185..2e3f9ed461a33b0f7157174a8ee6b8f453753eaf 100644 (file)
@@ -197,6 +197,7 @@ namespace Content.Shared.Containers.ItemSlots
             if (!EntityManager.TryGetComponent(args.User, out HandsComponent? hands))
                 return;
 
+            var slots = new List<ItemSlot>();
             foreach (var slot in itemSlots.Slots.Values)
             {
                 if (!slot.InsertOnInteract)
@@ -205,10 +206,20 @@ namespace Content.Shared.Containers.ItemSlots
                 if (!CanInsert(uid, args.Used, args.User, slot, swap: slot.Swap, popup: args.User))
                     continue;
 
-                // Drop the held item onto the floor. Return if the user cannot drop.
-                if (!_handsSystem.TryDrop(args.User, args.Used, handsComp: hands))
-                    return;
+                slots.Add(slot);
+            }
 
+            if (slots.Count == 0)
+                return;
+
+            // Drop the held item onto the floor. Return if the user cannot drop.
+            if (!_handsSystem.TryDrop(args.User, args.Used, handsComp: hands))
+                return;
+
+            slots.Sort(SortEmpty);
+
+            foreach (var slot in slots)
+            {
                 if (slot.Item != null)
                     _handsSystem.TryPickupAnyHand(args.User, slot.Item.Value, handsComp: hands);
 
@@ -333,6 +344,65 @@ namespace Content.Shared.Containers.ItemSlots
             Insert(uid, slot, held, user, excludeUserAudio: excludeUserAudio);
             return true;
         }
+
+        /// <summary>
+        ///     Tries to insert an item into any empty slot.
+        /// </summary>
+        /// <param name="ent">The entity that has the item slots.</param>
+        /// <param name="item">The item to be inserted.</param>
+        /// <param name="user">The entity performing the interaction.</param>
+        /// <param name="excludeUserAudio">
+        ///     If true, will exclude the user when playing sound. Does nothing client-side.
+        ///     Useful for predicted interactions
+        /// </param>
+        /// <returns>False if failed to insert item</returns>
+        public bool TryInsertEmpty(Entity<ItemSlotsComponent?> ent, EntityUid item, EntityUid? user, bool excludeUserAudio = false)
+        {
+            if (!Resolve(ent, ref ent.Comp, false))
+                return false;
+
+            var slots = new List<ItemSlot>();
+            foreach (var slot in ent.Comp.Slots.Values)
+            {
+                if (slot.ContainerSlot?.ContainedEntity != null)
+                    continue;
+
+                if (CanInsert(ent, item, user, slot))
+                    slots.Add(slot);
+            }
+
+            if (slots.Count == 0)
+                return false;
+
+            if (user != null && _handsSystem.IsHolding(user.Value, item))
+            {
+                if (!_handsSystem.TryDrop(user.Value, item))
+                    return false;
+            }
+
+            slots.Sort(SortEmpty);
+
+            foreach (var slot in slots)
+            {
+                if (TryInsert(ent, slot, item, user, excludeUserAudio: excludeUserAudio))
+                    return true;
+            }
+
+            return false;
+        }
+
+        private static int SortEmpty(ItemSlot a, ItemSlot b)
+        {
+            var aEnt = a.ContainerSlot?.ContainedEntity;
+            var bEnt = b.ContainerSlot?.ContainedEntity;
+            if (aEnt == null && bEnt == null)
+                return a.Priority.CompareTo(b.Priority);
+
+            if (aEnt == null)
+                return -1;
+
+            return 1;
+        }
         #endregion
 
         #region Eject