Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add checkDamage Boolean for li.cil.oc.util.InventoryUtils#haveSameItemType #3706

Open
wants to merge 3 commits into
base: master-MC1.7.10
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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))
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
})
Expand All @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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))
})
}

Expand All @@ -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))
})
})
}
Expand Down Expand Up @@ -83,25 +83,27 @@ 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)
case _ => None
}
case _ => None
}

withInventorySource(facing, {
case BlockInventorySource(position, _) => blockAt(position) match {
case Some(block) => result(block.getUnlocalizedName)
Expand All @@ -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))))
}

Expand Down
28 changes: 15 additions & 13 deletions src/main/scala/li/cil/oc/util/InventoryUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ object InventoryUtils {
* <br>
* 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))

/**
Expand Down Expand Up @@ -247,24 +247,24 @@ object InventoryUtils {
}

/**
* Extracts an item stack from an inventory.
* <br>
* 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
* <br>
* 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, exact: Boolean = true) : ItemStack = {
* Extracts an item stack from an inventory.
* <br>
* 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
* <br>
* 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, 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(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) {
Expand Down Expand Up @@ -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