diff --git a/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControl.scala b/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControl.scala
index 28efa6716..c1c7f8efd 100644
--- a/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControl.scala
+++ b/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControl.scala
@@ -105,7 +105,7 @@ trait InventoryWorldControl extends InventoryAware with WorldAware with SideRest
val blockPos = position.offset(facing)
var extracted: Int = InventoryUtils.inventoryAt(blockPos, facing.getOpposite) match {
case Some(inventory) => mayInteract(blockPos, facing.getOpposite)
- InventoryUtils.extractAnyFromInventory(InventoryUtils.insertIntoInventory(_, InventoryUtils.asItemHandler(this.inventory), slots = Option(insertionSlots)), inventory, count)
+ InventoryUtils.extractAnyFromInventory((is, sim) => InventoryUtils.insertIntoInventory(is, InventoryUtils.asItemHandler(this.inventory), slots = Option(insertionSlots), simulate = sim), inventory, count)
case _ => 0
}
if (extracted <= 0) {
diff --git a/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControlMk2.scala b/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControlMk2.scala
index 60914b32f..5df2854a9 100644
--- a/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControlMk2.scala
+++ b/src/main/scala/li/cil/oc/server/component/traits/InventoryWorldControlMk2.scala
@@ -50,7 +50,7 @@ trait InventoryWorldControlMk2 extends InventoryAware with WorldAware with SideR
val fromSide = args.optSideAny(3, facing.getOpposite)
withInventory(position.offset(facing), fromSide, inventory => {
val slot = args.checkSlot(inventory, 1)
- val extracted = InventoryUtils.extractFromInventorySlot(InventoryUtils.insertIntoInventory(_, InventoryUtils.asItemHandler(this.inventory), slots = Option(insertionSlots)), inventory, slot, count)
+ val extracted = InventoryUtils.extractFromInventorySlot((is, sim) => InventoryUtils.insertIntoInventory(is, InventoryUtils.asItemHandler(this.inventory), slots = Option(insertionSlots), simulate = sim), inventory, slot, count)
if (extracted > 0) {
context.pause(Settings.get.suckDelay)
result(extracted)
diff --git a/src/main/scala/li/cil/oc/server/component/traits/ItemInventoryControl.scala b/src/main/scala/li/cil/oc/server/component/traits/ItemInventoryControl.scala
index 42026cd36..61f078575 100644
--- a/src/main/scala/li/cil/oc/server/component/traits/ItemInventoryControl.scala
+++ b/src/main/scala/li/cil/oc/server/component/traits/ItemInventoryControl.scala
@@ -21,7 +21,7 @@ trait ItemInventoryControl extends InventoryAware {
withItemInventory(args.checkSlot(inventory, 0), itemInventory => {
val slot = args.checkSlot(itemInventory, 1)
val count = args.optItemCount(2)
- result(InventoryUtils.extractFromInventorySlot(InventoryUtils.insertIntoInventorySlot(_, itemInventory, slot), inventory, null, selectedSlot, count))
+ result(InventoryUtils.extractFromInventorySlot((is, sim) => InventoryUtils.insertIntoInventorySlot(is, itemInventory, slot, simulate = sim), inventory, null, selectedSlot, count))
})
}
@@ -30,7 +30,7 @@ trait ItemInventoryControl extends InventoryAware {
withItemInventory(args.checkSlot(inventory, 0), itemInventory => {
val slot = args.checkSlot(itemInventory, 1)
val count = args.optItemCount(2)
- result(InventoryUtils.extractFromInventorySlot(InventoryUtils.insertIntoInventory(_, InventoryUtils.asItemHandler(inventory), slots = Option(insertionSlots)), itemInventory, slot, count))
+ result(InventoryUtils.extractFromInventorySlot((is, sim) => InventoryUtils.insertIntoInventory(is, InventoryUtils.asItemHandler(inventory), slots = Option(insertionSlots), simulate = sim), itemInventory, slot, count))
})
}
diff --git a/src/main/scala/li/cil/oc/util/InventoryUtils.scala b/src/main/scala/li/cil/oc/util/InventoryUtils.scala
index 6cab2e54e..8fc41876f 100644
--- a/src/main/scala/li/cil/oc/util/InventoryUtils.scala
+++ b/src/main/scala/li/cil/oc/util/InventoryUtils.scala
@@ -110,9 +110,9 @@ object InventoryUtils {
*
* Only tries to extract from the specified slot. This can be used
* to empty a slot. It will extract items using the specified consumer method
- * which is called with the extracted stack before the stack in the inventory
- * that we extract from is cleared from. This allows placing back excess
- * items with as few inventory updates as possible.
+ * which is called with the extracted stack and a simulation flag before the
+ * stack in the inventory that we extract from is cleared from. This allows
+ * placing back excess items with as few inventory updates as possible.
*
* The consumer is the only way to retrieve the actually extracted stack. It
* is called with a separate stack instance, so it does not have to be copied
@@ -129,7 +129,7 @@ object InventoryUtils {
* also be achieved by a check in the consumer, but it saves some unnecessary
* code repetition this way.
*/
- def extractFromInventorySlot(consumer: ItemStack => Unit, inventory: IItemHandler, slot: Int, limit: Int = 64): Int = {
+ def extractFromInventorySlot(consumer: (ItemStack, Boolean) => Unit, inventory: IItemHandler, slot: Int, limit: Int = 64): Int = {
val stack = inventory.getStackInSlot(slot)
if (stack.isEmpty || limit <= 0 || stack.getCount <= 0)
return 0
@@ -138,19 +138,19 @@ object InventoryUtils {
case simExtracted: ItemStack =>
val extracted = simExtracted.copy
amount = extracted.getCount
- consumer(extracted)
+ consumer(extracted, true)
val count = (amount - extracted.getCount) max 0
if (count > 0) inventory.extractItem(slot, count, false) match {
- case realExtracted: ItemStack if realExtracted.getCount == count =>
+ case realExtracted: ItemStack if realExtracted.getCount == count => consumer(realExtracted, false)
case _ =>
- OpenComputers.log.warn("Items may have been duplicated during inventory extraction. This means an IItemHandler instance acted differently between simulated and non-simulated extraction. Offender: " + inventory)
+ OpenComputers.log.warn("An IItemHandler instance acted differently between simulated and non-simulated extraction. Offender: " + inventory)
}
count
case _ => 0
}
}
- def extractFromInventorySlot(consumer: (ItemStack) => Unit, inventory: IInventory, side: EnumFacing, slot: Int, limit: Int): Int =
+ def extractFromInventorySlot(consumer: (ItemStack, Boolean) => Unit, inventory: IInventory, side: EnumFacing, slot: Int, limit: Int): Int =
extractFromInventorySlot(consumer, asItemHandler(inventory, side), slot, limit)
/**
@@ -200,7 +200,7 @@ object InventoryUtils {
*
* This returns true if at least one item was extracted.
*/
- def extractAnyFromInventory(consumer: ItemStack => Unit, inventory: IItemHandler, limit: Int = 64): Int = {
+ def extractAnyFromInventory(consumer: (ItemStack, Boolean) => Unit, inventory: IItemHandler, limit: Int = 64): Int = {
for (slot <- 0 until inventory.getSlots) {
val extracted = extractFromInventorySlot(consumer, inventory, slot, limit)
if (extracted > 0)
@@ -209,7 +209,7 @@ object InventoryUtils {
0
}
- def extractAnyFromInventory(consumer: ItemStack => Unit, inventory: IInventory, side: EnumFacing, limit: Int): Int =
+ def extractAnyFromInventory(consumer: (ItemStack, Boolean) => Unit, inventory: IInventory, side: EnumFacing, limit: Int): Int =
extractAnyFromInventory(consumer, asItemHandler(inventory, side), limit)
/**
@@ -225,11 +225,13 @@ object InventoryUtils {
def extractFromInventory(stack: ItemStack, inventory: IItemHandler, simulate: Boolean = false, exact: Boolean = true): ItemStack = {
val remaining = stack.copy()
for (slot <- 0 until inventory.getSlots if remaining.getCount > 0) {
- extractFromInventorySlot(stackInInv => {
+ extractFromInventorySlot((stackInInv, simulateInsert) => {
if (stackInInv != null && remaining.getItem == stackInInv.getItem && (!exact || haveSameItemType(remaining, stackInInv, checkNBT = true))) {
val transferred = stackInInv.getCount min remaining.getCount
- remaining.shrink(transferred)
- if (!simulate) {
+ if(!simulateInsert) {
+ remaining.shrink(transferred)
+ }
+ if (simulateInsert || !simulate) {
stackInInv.shrink(transferred)
}
}
@@ -254,7 +256,7 @@ object InventoryUtils {
* Utility method for calling extractFromInventory on an inventory
* in the world.
*/
- def getExtractorFromInventoryAt(consumer: (ItemStack) => Unit, position: BlockPosition, side: EnumFacing, limit: Int = 64): Extractor =
+ def getExtractorFromInventoryAt(consumer: (ItemStack, Boolean) => Unit, position: BlockPosition, side: EnumFacing, limit: Int = 64): Extractor =
inventoryAt(position, side) match {
case Some(inventory) => () => extractAnyFromInventory(consumer, inventory, limit)
case _ => null
@@ -275,7 +277,7 @@ object InventoryUtils {
*/
def transferBetweenInventories(source: IItemHandler, sink: IItemHandler, limit: Int = 64): Int =
extractAnyFromInventory(
- insertIntoInventory(_, sink, limit), source, limit = limit)
+ insertIntoInventory(_, sink, limit, _), source, limit = limit)
def transferBetweenInventories(source: IInventory, sourceSide: EnumFacing, sink: IInventory, sinkSide: Option[EnumFacing], limit: Int): Int =
transferBetweenInventories(asItemHandler(source, sourceSide), asItemHandler(sink, sinkSide.orNull), limit)
@@ -287,10 +289,10 @@ object InventoryUtils {
sinkSlot match {
case Some(explicitSinkSlot) =>
extractFromInventorySlot(
- insertIntoInventorySlot(_, sink, explicitSinkSlot, limit), source, sourceSlot, limit = limit)
+ insertIntoInventorySlot(_, sink, explicitSinkSlot, limit, _), source, sourceSlot, limit = limit)
case _ =>
extractFromInventorySlot(
- insertIntoInventory(_, sink, limit), source, sourceSlot, limit = limit)
+ insertIntoInventory(_, sink, limit, _), source, sourceSlot, limit = limit)
}
def transferBetweenInventoriesSlots(source: IInventory, sourceSide: EnumFacing, sourceSlot: Int, sink: IInventory, sinkSide: Option[EnumFacing], sinkSlot: Option[Int], limit: Int): Int =