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
This commit is contained in:
payonel 2018-09-22 21:11:07 -07:00
parent e5ccda83f0
commit 89eeae875b
2 changed files with 9 additions and 8 deletions

View File

@ -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.

View File

@ -231,23 +231,24 @@ object InventoryUtils {
* <p/>
* 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
* <p/>
* This uses the <tt>extractFromInventorySlot</tt> 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)