/// <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); }
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); }