From 89eeae875bb28f3f4c8f4afc16e55d7194cf3f28 Mon Sep 17 00:00:00 2001 From: payonel Date: Sat, 22 Sep 2018 21:11:07 -0700 Subject: [PATCH] make weak ItemStack comparison for trading Mimicking vanilla minecraft, we now only compare Item types in recipe inputs for making a trade with villagers. This commit also adds a parameter to our inv utils for extracting ItemStacks, whether to make a strict and exact comparison (as it was always doing before, and is still the default) or to make a weak check only (which only verifies the Item types are the same) closes #2788 --- src/main/scala/li/cil/oc/server/component/Trade.scala | 6 +++--- src/main/scala/li/cil/oc/util/InventoryUtils.scala | 11 ++++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/scala/li/cil/oc/server/component/Trade.scala b/src/main/scala/li/cil/oc/server/component/Trade.scala index 8dfc38876..2e373143f 100644 --- a/src/main/scala/li/cil/oc/server/component/Trade.scala +++ b/src/main/scala/li/cil/oc/server/component/Trade.scala @@ -75,7 +75,7 @@ class Trade(val info: TradeInfo) extends AbstractValue { val secondInputStack = if (recipe.hasSecondItemToBuy) Option(recipe.getSecondItemToBuy) else None def containsAccumulativeItemStack(stack: ItemStack) = - InventoryUtils.extractFromInventory(stack, inventory, ForgeDirection.UNKNOWN, simulate = true).stackSize == 0 + InventoryUtils.extractFromInventory(stack, inventory, ForgeDirection.UNKNOWN, simulate = true, exact = false).stackSize == 0 def hasRoomForItemStack(stack: ItemStack) = { val remainder = stack.copy() InventoryUtils.insertIntoInventory(remainder, inventory, None, remainder.stackSize, simulate = true) @@ -88,8 +88,8 @@ class Trade(val info: TradeInfo) extends AbstractValue { val outputStack = recipe.getItemToSell.copy() if (hasRoomForItemStack(outputStack)) { // We established that out inventory allows to perform the trade, now actually do the trade. - InventoryUtils.extractFromInventory(firstInputStack, inventory, ForgeDirection.UNKNOWN) - secondInputStack.map(InventoryUtils.extractFromInventory(_, inventory, ForgeDirection.UNKNOWN)) + InventoryUtils.extractFromInventory(firstInputStack, inventory, ForgeDirection.UNKNOWN, exact = false) + secondInputStack.map(InventoryUtils.extractFromInventory(_, inventory, ForgeDirection.UNKNOWN, exact = false)) InventoryUtils.insertIntoInventory(outputStack, inventory, None, outputStack.stackSize) // Tell the merchant we used the recipe, so MC can disable it and/or enable more recipes. diff --git a/src/main/scala/li/cil/oc/util/InventoryUtils.scala b/src/main/scala/li/cil/oc/util/InventoryUtils.scala index 731926027..2eeb0ee47 100644 --- a/src/main/scala/li/cil/oc/util/InventoryUtils.scala +++ b/src/main/scala/li/cil/oc/util/InventoryUtils.scala @@ -231,23 +231,24 @@ object InventoryUtils { *

* This will try to remove items of the same type as the specified item stack * up to the number of the stack's size for all slots in the specified inventory. + * If exact is true, the items colated will also match meta data *

* This uses the extractFromInventorySlot method, and therefore * handles special cases such as sided inventories and stack size limits. */ - def extractFromInventory(stack: ItemStack, inventory: IInventory, side: ForgeDirection, simulate: Boolean = false) = { + def extractFromInventory(stack: ItemStack, inventory: IInventory, side: ForgeDirection, simulate: Boolean = false, exact: Boolean = true) : ItemStack = { val range = inventory match { case sided: ISidedInventory => sided.getAccessibleSlotsFromSide(side.ordinal).toIterable case _ => 0 until inventory.getSizeInventory } val remaining = stack.copy() for (slot <- range if remaining.stackSize > 0) { - extractFromInventorySlot(stack => { - if (haveSameItemType(remaining, stack, checkNBT = true)) { - val transferred = stack.stackSize min remaining.stackSize + extractFromInventorySlot(stackInInv => { + if (stackInInv != null && remaining.getItem == stackInInv.getItem && (!exact || haveSameItemType(remaining, stackInInv, checkNBT = true))) { + val transferred = stackInInv.stackSize min remaining.stackSize remaining.stackSize -= transferred if (!simulate) { - stack.stackSize -= transferred + stackInInv.stackSize -= transferred } } }, inventory, side, slot, remaining.stackSize)