diff --git a/src/main/scala/li/cil/oc/server/component/traits/InventoryAnalytics.scala b/src/main/scala/li/cil/oc/server/component/traits/InventoryAnalytics.scala index bc8696af44..0c202c3c34 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/InventoryAnalytics.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/InventoryAnalytics.scala @@ -49,7 +49,7 @@ trait InventoryAnalytics extends InventoryAware with NetworkAware { DatabaseAccess.withDatabase(node, dbAddress, database => { val dbSlot = args.checkSlot(database.data, 2) val dbStack = database.getStackInSlot(dbSlot) - result(InventoryUtils.haveSameItemType(localStack, dbStack, args.optBoolean(3, false))) + result(InventoryUtils.haveSameItemType(localStack, dbStack, args.optBoolean(3, false), checkDamage = true)) }) } } diff --git a/src/main/scala/li/cil/oc/server/component/traits/InventoryControl.scala b/src/main/scala/li/cil/oc/server/component/traits/InventoryControl.scala index 25591dcb21..4b9d2d2b1b 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/InventoryControl.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/InventoryControl.scala @@ -42,7 +42,7 @@ trait InventoryControl extends InventoryAware { def compareTo(context: Context, args: Arguments): Array[AnyRef] = { val slot = args.checkSlot(inventory, 0) result((stackInSlot(selectedSlot), stackInSlot(slot)) match { - case (Some(stackA), Some(stackB)) => InventoryUtils.haveSameItemType(stackA, stackB, args.optBoolean(1, false)) + case (Some(stackA), Some(stackB)) => InventoryUtils.haveSameItemType(stackA, stackB, args.optBoolean(1, false), checkDamage = true) case (None, None) => true case _ => false }) @@ -57,7 +57,7 @@ trait InventoryControl extends InventoryAware { } else result((stackInSlot(selectedSlot), stackInSlot(slot)) match { case (Some(from), Some(to)) => - if (InventoryUtils.haveSameItemType(from, to, checkNBT = true)) { + if (InventoryUtils.haveSameItemType(from, to, checkNBT = true, checkDamage = true)) { val space = math.min(inventory.getInventoryStackLimit, to.getMaxStackSize) - to.stackSize val amount = math.min(count, math.min(space, from.stackSize)) if (amount > 0) { diff --git a/src/main/scala/li/cil/oc/server/component/traits/WorldInventoryAnalytics.scala b/src/main/scala/li/cil/oc/server/component/traits/WorldInventoryAnalytics.scala index 94c67f9782..ce010e0412 100644 --- a/src/main/scala/li/cil/oc/server/component/traits/WorldInventoryAnalytics.scala +++ b/src/main/scala/li/cil/oc/server/component/traits/WorldInventoryAnalytics.scala @@ -41,7 +41,7 @@ trait WorldInventoryAnalytics extends WorldAware with SideRestricted with Networ withInventory(facing, inventory => { val stackA = inventory.getStackInSlot(args.checkSlot(inventory, 1)) val stackB = inventory.getStackInSlot(args.checkSlot(inventory, 2)) - result(stackA == stackB || InventoryUtils.haveSameItemType(stackA, stackB, args.optBoolean(3, false))) + result(stackA == stackB || InventoryUtils.haveSameItemType(stackA, stackB, args.optBoolean(3, false), checkDamage = true)) }) } @@ -55,7 +55,7 @@ trait WorldInventoryAnalytics extends WorldAware with SideRestricted with Networ DatabaseAccess.withDatabase(node, dbAddress, database => { val dbSlot = args.checkSlot(database.data, 3) val dbStack = database.getStackInSlot(dbSlot) - result(InventoryUtils.haveSameItemType(stack, dbStack, args.optBoolean(4, false))) + result(InventoryUtils.haveSameItemType(stack, dbStack, args.optBoolean(4, false), checkDamage = true)) }) }) } @@ -83,18 +83,19 @@ trait WorldInventoryAnalytics extends WorldAware with SideRestricted with Networ def getAllStacks(context: Context, args: Arguments): Array[AnyRef] = if (Settings.get.allowItemStackInspection) { val facing = checkSideForAction(args, 0) withInventory(facing, inventory => { - val stacks = new Array[ItemStack](inventory.getSizeInventory) - for(i <- 0 until inventory.getSizeInventory){ - stacks(i) = inventory.getStackInSlot(i) - } - result(new ItemStackArrayValue(stacks)) - }) + val stacks = new Array[ItemStack](inventory.getSizeInventory) + for (i <- 0 until inventory.getSizeInventory) { + stacks(i) = inventory.getStackInSlot(i) + } + result(new ItemStackArrayValue(stacks)) + }) } else result(Unit, "not enabled in config") @Callback(doc = """function(side:number):string -- Get the the name of the inventory on the specified side of the device.""") def getInventoryName(context: Context, args: Arguments): Array[AnyRef] = if (Settings.get.allowItemStackInspection) { val facing = checkSideForAction(args, 0) + def blockAt(position: BlockPosition): Option[Block] = position.world match { case Some(world) if world.blockExists(position) => world.getBlock(position) match { case block: Block => Some(block) @@ -102,6 +103,7 @@ trait WorldInventoryAnalytics extends WorldAware with SideRestricted with Networ } case _ => None } + withInventorySource(facing, { case BlockInventorySource(position, _) => blockAt(position) match { case Some(block) => result(block.getUnlocalizedName) @@ -117,12 +119,14 @@ trait WorldInventoryAnalytics extends WorldAware with SideRestricted with Networ def store(context: Context, args: Arguments): Array[AnyRef] = { val facing = checkSideForAction(args, 0) val dbAddress = args.checkString(2) + def store(stack: ItemStack) = DatabaseAccess.withDatabase(node, dbAddress, database => { val dbSlot = args.checkSlot(database.data, 3) val nonEmpty = database.getStackInSlot(dbSlot) != null database.setStackInSlot(dbSlot, stack.copy()) result(nonEmpty) }) + withInventory(facing, inventory => store(inventory.getStackInSlot(args.checkSlot(inventory, 1)))) } diff --git a/src/main/scala/li/cil/oc/util/InventoryUtils.scala b/src/main/scala/li/cil/oc/util/InventoryUtils.scala index e540302645..af41d4e210 100644 --- a/src/main/scala/li/cil/oc/util/InventoryUtils.scala +++ b/src/main/scala/li/cil/oc/util/InventoryUtils.scala @@ -20,10 +20,10 @@ object InventoryUtils { *
* Optionally check for equality in NBT data. */ - def haveSameItemType(stackA: ItemStack, stackB: ItemStack, checkNBT: Boolean = false) = + def haveSameItemType(stackA: ItemStack, stackB: ItemStack, checkNBT: Boolean = false, checkDamage: Boolean = false) = stackA != null && stackB != null && stackA.getItem == stackB.getItem && - (!stackA.getHasSubtypes || stackA.getItemDamage == stackB.getItemDamage) && + (!checkDamage || stackA.getItemDamage == stackB.getItemDamage) && (!checkNBT || ItemStack.areItemStackTagsEqual(stackA, stackB)) /** @@ -247,16 +247,16 @@ object InventoryUtils { } /** - * Extracts an item stack from an inventory. - *
- * 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, exact: Boolean = true) : ItemStack = { + * Extracts an item stack from an inventory. + *
+ * 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, exact: Boolean = true): ItemStack = { val range = inventory match { case sided: ISidedInventory => sided.getAccessibleSlotsFromSide(side.ordinal).toIterable case _ => 0 until inventory.getSizeInventory @@ -264,7 +264,7 @@ object InventoryUtils { val remaining = stack.copy() for (slot <- range if remaining.stackSize > 0) { extractFromInventorySlot(stackInInv => { - if (stackInInv != null && remaining.getItem == stackInInv.getItem && (!exact || haveSameItemType(remaining, stackInInv, checkNBT = true))) { + if (stackInInv != null && remaining.getItem == stackInInv.getItem && (!exact || haveSameItemType(remaining, stackInInv, checkNBT = true, checkDamage = true))) { val transferred = stackInInv.stackSize min remaining.stackSize remaining.stackSize -= transferred if (!simulate) { @@ -425,5 +425,7 @@ object InventoryUtils { sealed trait InventorySource { def inventory: IInventory } + final case class BlockInventorySource(position: BlockPosition, inventory: IInventory) extends InventorySource + final case class EntityInventorySource(entity: Entity, inventory: IInventory) extends InventorySource