/// <summary>
        /// Gets the best sorted slot for the given item.
        /// </summary>
        /// <param name="sourceSlot">The source item slot.</param>
        /// <param name="skipSlots">The slots to skip.</param>
        /// <returns>A weighted slot set.</returns>
        public virtual WeightedSlot GetBestSuitedSlot(ItemSlot sourceSlot, List <ItemSlot> skipSlots = null)
        {
            WeightedSlot bestWSlot = new WeightedSlot();

            // Useless to put the item into the same inventory
            if (PutLocked || sourceSlot.Inventory == this)
            {
                return(bestWSlot);
            }

            // 1. Prefer already filled slots
            foreach (var slot in this)
            {
                if (skipSlots != null && skipSlots.Contains(slot))
                {
                    continue;
                }

                if (slot.Itemstack != null && slot.CanTakeFrom(sourceSlot))
                {
                    float curWeight = GetSuitability(sourceSlot, slot, true);

                    if (bestWSlot.slot == null || bestWSlot.weight < curWeight)
                    {
                        bestWSlot.slot   = slot;
                        bestWSlot.weight = curWeight;
                    }
                }
            }

            // 2. Otherwise use empty slots
            foreach (var slot in this)
            {
                if (skipSlots != null && skipSlots.Contains(slot))
                {
                    continue;
                }

                if (slot.Itemstack == null && slot.CanTakeFrom(sourceSlot))
                {
                    float curWeight = GetSuitability(sourceSlot, slot, false);

                    if (bestWSlot.slot == null || bestWSlot.weight < curWeight)
                    {
                        bestWSlot.slot   = slot;
                        bestWSlot.weight = curWeight;
                    }
                }
            }

            return(bestWSlot);
        }
Exemple #2
0
        public override bool TryGiveItemStack(ItemStack itemstack)
        {
            if (itemstack == null || itemstack.StackSize == 0)
            {
                return(false);
            }

            ItemSlot dummySlot = new DummySlot(null);

            dummySlot.Itemstack = itemstack.Clone();

            ItemStackMoveOperation op = new ItemStackMoveOperation(World, EnumMouseButton.Left, 0, EnumMergePriority.AutoMerge, itemstack.StackSize);

            if (GearInventory != null)
            {
                WeightedSlot wslot = GearInventory.GetBestSuitedSlot(dummySlot, new List <ItemSlot>());
                if (wslot.weight > 0)
                {
                    dummySlot.TryPutInto(wslot.slot, ref op);
                    itemstack.StackSize -= op.MovedQuantity;
                    WatchedAttributes.MarkAllDirty();
                    return(op.MovedQuantity > 0);
                }
            }

            if (LeftHandItemSlot?.Inventory != null)
            {
                WeightedSlot wslot = LeftHandItemSlot.Inventory.GetBestSuitedSlot(dummySlot, new List <ItemSlot>());
                if (wslot.weight > 0)
                {
                    dummySlot.TryPutInto(wslot.slot, ref op);
                    itemstack.StackSize -= op.MovedQuantity;
                    WatchedAttributes.MarkAllDirty();
                    return(op.MovedQuantity > 0);
                }
            }

            return(false);
        }
        /// <summary>
        /// Return the slot where a chute may push items into. Return null if it shouldn't move items into this inventory.
        /// </summary>
        /// <param name="atBlockFace"></param>
        /// <param name="fromSlot"></param>
        /// <returns></returns>
        public virtual ItemSlot GetAutoPushIntoSlot(BlockFacing atBlockFace, ItemSlot fromSlot)
        {
            WeightedSlot wslot = GetBestSuitedSlot(fromSlot);

            return(wslot.slot);
        }