Skip to content
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
22 changes: 4 additions & 18 deletions src/main/scala/li/cil/oc/integration/appeng/AEUtil.scala
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
package li.cil.oc.integration.appeng

import appeng.api.AEApi
import appeng.api.storage.IMEMonitor
import appeng.api.storage.data.IAEStack
import appeng.me.GridAccessException
import appeng.me.helpers.IGridProxyable
import appeng.parts.p2p.PartP2PItems
import cpw.mods.fml.common.Loader
import cpw.mods.fml.common.versioning.VersionRange
import li.cil.oc.api
import li.cil.oc.common.item.Delegator
import li.cil.oc.common.item.data.{DroneData, RobotData}
import li.cil.oc.integration.Mods
import net.minecraft.inventory.IInventory
import net.minecraft.item.ItemStack

import scala.reflect.ClassTag

object AEUtil {
val versionsWithNewItemDefinitionAPI = VersionRange.createFromVersionSpec("[rv2-beta-20,)")

Expand Down Expand Up @@ -140,6 +136,8 @@ object AEUtil {
AEApi.instance.definitions.parts.storageBus.isSameAs(stack)
}

def isPartP2PItems(inventory: IInventory): Boolean = inventory.isInstanceOf[PartP2PItems]

def isRobot(stack: ItemStack): Boolean =
api.Items.get(stack) == api.Items.get("robot")

Expand All @@ -165,16 +163,4 @@ object AEUtil {
}
null
}

def getMonitor[T <: IAEStack[T] : ClassTag](controller: IGridProxyable): Option[IMEMonitor[T]] = {
for {
c <- Option(controller)
entry <- AEStackFactory.getEntry[T]()
inv <- try {
Option(c.getProxy.getStorage.getMEMonitor(entry.stackType).asInstanceOf[IMEMonitor[T]])
} catch {
case _: GridAccessException => None
}
} yield inv
}
}
16 changes: 14 additions & 2 deletions src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import appeng.api.networking.crafting.{CraftingItemList, ICraftingLink, ICraftin
import appeng.api.networking.security.{BaseActionSource, IActionHost, MachineSource}
import appeng.api.networking.storage.IBaseMonitor
import appeng.api.storage.data.{IAEFluidStack, IAEItemStack, IAEStack, IItemList}
import appeng.api.storage.{IMEInventory, IMEMonitor, IMEMonitorHandlerReceiver}
import appeng.api.storage.{IMEMonitor, IMEMonitorHandlerReceiver}
import appeng.api.util.AECableType
import appeng.me.GridAccessException
import appeng.me.cluster.implementations.CraftingCPUCluster
import appeng.me.helpers.IGridProxyable
import appeng.tile.crafting.TileCraftingMonitorTile
Expand Down Expand Up @@ -334,6 +335,17 @@ trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActi
}

object NetworkControl extends AETypes {
def getMonitor[T <: IAEStack[T] : ClassTag](controller: IGridProxyable): Option[IMEMonitor[T]] = {
for {
c <- Option(controller)
entry <- AEStackFactory.getEntry[T]()
inv <- try {
Option(c.getProxy.getStorage.getMEMonitor(entry.stackType).asInstanceOf[IMEMonitor[T]])
} catch {
case _: GridAccessException => None
}
} yield inv
}

//noinspection ScalaUnusedSymbol
private class Craftable(var controller: TileEntity with IGridProxyable with IActionHost, var stack: AEStack) extends AbstractValue with ICraftingRequester {
Expand Down Expand Up @@ -592,7 +604,7 @@ object NetworkControl extends AETypes {
private abstract class NetworkContents[T <: IAEStack[T] : ClassTag](var controller: TileEntity with IGridProxyable with IActionHost) extends AbstractValue with IMEMonitorHandlerReceiver[T] {
def this() = this(null)

private def getMonitor: Option[IMEMonitor[T]] = AEUtil.getMonitor[T](controller)
private def getMonitor: Option[IMEMonitor[T]] = NetworkControl.getMonitor[T](controller)

private var items: IItemList[T] = null
private var itemIterator: java.util.Iterator[T] = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import appeng.me.helpers.IGridProxyable
import li.cil.oc.api.Persistable
import li.cil.oc.api.network.Node
import li.cil.oc.common.EventHandler
import li.cil.oc.integration.appeng.AEUtil
import li.cil.oc.integration.appeng.NetworkControl.convert
import li.cil.oc.integration.appeng.NetworkControl.{convert, getMonitor}
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.tileentity.TileEntity

Expand All @@ -36,7 +35,7 @@ trait SubscriptionBase[T <: IAEStack[T]] extends IMEMonitorHandlerReceiver[T] wi

private def updateSubscribe(): Unit = {
if (tile.isInvalid) return
AEUtil.getMonitor[T](tile) match {
getMonitor[T](tile) match {
case Some(inv) =>
if (subscribe)
inv.addListener(this, null)
Expand Down Expand Up @@ -71,4 +70,4 @@ trait SubscriptionBase[T <: IAEStack[T]] extends IMEMonitorHandlerReceiver[T] wi
override def save(nbt: NBTTagCompound): Unit = {
nbt.setBoolean(event_name, subscribe)
}
}
}
33 changes: 21 additions & 12 deletions src/main/scala/li/cil/oc/util/InventoryUtils.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package li.cil.oc.util

import li.cil.oc.integration.Mods
import li.cil.oc.integration.appeng.AEUtil
import li.cil.oc.util.ExtendedWorld._
import net.minecraft.block.BlockChest
import net.minecraft.entity.Entity
Expand Down Expand Up @@ -55,6 +57,11 @@ object InventoryUtils {
def inventoryAt(position: BlockPosition): Option[IInventory] = inventorySourceAt(position).
map(a => a.inventory)

def shouldSkipStackSizeCheck(inventory: IInventory): Boolean = {
(inventory.getClass.toString == "class wanion.avaritiaddons.block.chest.infinity.TileEntityInfinityChest") ||
(Mods.AppliedEnergistics2.isModAvailable && AEUtil.isPartP2PItems(inventory) && inventory.getInventoryStackLimit == Int.MaxValue)
}

/**
* Inserts a stack into an inventory.
* <br>
Expand All @@ -76,14 +83,15 @@ object InventoryUtils {
* The number of items inserted can be limited, to avoid unnecessary
* changes to the inventory the stack may come from, for example.
*/
def insertIntoInventorySlot(stack: ItemStack, inventory: IInventory, side: Option[ForgeDirection], slot: Int, limit: Int = 64, simulate: Boolean = false) =
def insertIntoInventorySlot(stack: ItemStack, inventory: IInventory, side: Option[ForgeDirection], slot: Int, limit: Int = Int.MaxValue, simulate: Boolean = false) =
(stack != null && limit > 0) && {
val isSideValidForSlot = (inventory, side) match {
case (inventory: ISidedInventory, Some(s)) => inventory.canInsertItem(slot, stack, s.ordinal)
case _ => true
}
(stack.stackSize > 0 && inventory.isItemValidForSlot(slot, stack) && isSideValidForSlot) && {
val maxStackSize = math.min(inventory.getInventoryStackLimit, stack.getMaxStackSize)
val invLimit = inventory.getInventoryStackLimit
val maxStackSize = if (shouldSkipStackSizeCheck(inventory)) invLimit else math.min(invLimit, stack.getMaxStackSize)
val existing = inventory.getStackInSlot(slot)
val shouldMerge = existing != null && existing.stackSize < maxStackSize &&
existing.isItemEqual(stack) && ItemStack.areItemStackTagsEqual(existing, stack)
Expand Down Expand Up @@ -134,7 +142,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: IInventory, side: ForgeDirection, slot: Int, limit: Int = 64): Int = {
def extractFromInventorySlot(consumer: ItemStack => Unit, inventory: IInventory, side: ForgeDirection, slot: Int, limit: Int = Int.MaxValue): Int = {
val stack = inventory.getStackInSlot(slot)

if (stack == null || limit <= 0)
Expand All @@ -147,7 +155,8 @@ object InventoryUtils {
case _ =>
}

val maxStackSize = math.min(inventory.getInventoryStackLimit, stack.getMaxStackSize)
val invLimit = inventory.getInventoryStackLimit
val maxStackSize = if (shouldSkipStackSizeCheck(inventory)) invLimit else math.min(invLimit, stack.getMaxStackSize)
val amount = stack.stackSize min limit min maxStackSize
val extracted = stack.splitStack(amount)
consumer(extracted)
Expand Down Expand Up @@ -177,7 +186,7 @@ object InventoryUtils {
* item stack will be adjusted to reflect the number items inserted, by
* having its size decremented accordingly.
*/
def insertIntoInventory(stack: ItemStack, inventory: IInventory, side: Option[ForgeDirection] = None, limit: Int = 64, simulate: Boolean = false, slots: Option[Iterable[Int]] = None) =
def insertIntoInventory(stack: ItemStack, inventory: IInventory, side: Option[ForgeDirection] = None, limit: Int = Int.MaxValue, simulate: Boolean = false, slots: Option[Iterable[Int]] = None) =
(stack != null && limit > 0) && {
var success = false
var remaining = limit
Expand Down Expand Up @@ -233,7 +242,7 @@ object InventoryUtils {
* <br>
* This returns <tt>true</tt> if at least one item was extracted.
*/
def extractAnyFromInventory(consumer: ItemStack => Unit, inventory: IInventory, side: ForgeDirection, limit: Int = 64): Int = {
def extractAnyFromInventory(consumer: ItemStack => Unit, inventory: IInventory, side: ForgeDirection, limit: Int = Int.MaxValue): Int = {
val range = inventory match {
case sided: ISidedInventory => sided.getAccessibleSlotsFromSide(side.ordinal).toIterable
case _ => 0 until inventory.getSizeInventory
Expand Down Expand Up @@ -280,7 +289,7 @@ object InventoryUtils {
* Utility method for calling <tt>insertIntoInventory</tt> on an inventory
* in the world.
*/
def insertIntoInventoryAt(stack: ItemStack, position: BlockPosition, side: Option[ForgeDirection] = None, limit: Int = 64, simulate: Boolean = false): Boolean =
def insertIntoInventoryAt(stack: ItemStack, position: BlockPosition, side: Option[ForgeDirection] = None, limit: Int = Int.MaxValue, simulate: Boolean = false): Boolean =
inventoryAt(position).exists(insertIntoInventory(stack, _, side, limit, simulate))

type Extractor = () => Int
Expand All @@ -289,7 +298,7 @@ object InventoryUtils {
* Utility method for calling <tt>extractFromInventory</tt> on an inventory
* in the world.
*/
def getExtractorFromInventoryAt(consumer: ItemStack => Unit, position: BlockPosition, side: ForgeDirection, limit: Int = 64): Extractor =
def getExtractorFromInventoryAt(consumer: ItemStack => Unit, position: BlockPosition, side: ForgeDirection, limit: Int = Int.MaxValue): Extractor =
inventoryAt(position) match {
case Some(inventory) => () => extractAnyFromInventory(consumer, inventory, side, limit)
case _ => null
Expand All @@ -309,14 +318,14 @@ object InventoryUtils {
* <br>
* This returns <tt>true</tt> if at least one item was transferred.
*/
def transferBetweenInventories(source: IInventory, sourceSide: ForgeDirection, sink: IInventory, sinkSide: Option[ForgeDirection], limit: Int = 64) =
def transferBetweenInventories(source: IInventory, sourceSide: ForgeDirection, sink: IInventory, sinkSide: Option[ForgeDirection], limit: Int = Int.MaxValue) =
extractAnyFromInventory(
insertIntoInventory(_, sink, sinkSide, limit), source, sourceSide, limit)

/**
* Like <tt>transferBetweenInventories</tt> but moving between specific slots.
*/
def transferBetweenInventoriesSlots(source: IInventory, sourceSide: ForgeDirection, sourceSlot: Int, sink: IInventory, sinkSide: Option[ForgeDirection], sinkSlot: Option[Int], limit: Int = 64) =
def transferBetweenInventoriesSlots(source: IInventory, sourceSide: ForgeDirection, sourceSlot: Int, sink: IInventory, sinkSide: Option[ForgeDirection], sinkSlot: Option[Int], limit: Int = Int.MaxValue) =
sinkSlot match {
case Some(explicitSinkSlot) =>
extractFromInventorySlot(
Expand All @@ -330,7 +339,7 @@ object InventoryUtils {
* Utility method for calling <tt>transferBetweenInventories</tt> on inventories
* in the world.
*/
def getTransferBetweenInventoriesAt(source: BlockPosition, sourceSide: ForgeDirection, sink: BlockPosition, sinkSide: Option[ForgeDirection], limit: Int = 64): Extractor =
def getTransferBetweenInventoriesAt(source: BlockPosition, sourceSide: ForgeDirection, sink: BlockPosition, sinkSide: Option[ForgeDirection], limit: Int = Int.MaxValue): Extractor =
inventoryAt(source) match {
case Some(sourceInventory) =>
inventoryAt(sink) match {
Expand All @@ -344,7 +353,7 @@ object InventoryUtils {
* Utility method for calling <tt>transferBetweenInventoriesSlots</tt> on inventories
* in the world.
*/
def getTransferBetweenInventoriesSlotsAt(sourcePos: BlockPosition, sourceSide: ForgeDirection, sourceSlot: Int, sinkPos: BlockPosition, sinkSide: Option[ForgeDirection], sinkSlot: Option[Int], limit: Int = 64): Extractor =
def getTransferBetweenInventoriesSlotsAt(sourcePos: BlockPosition, sourceSide: ForgeDirection, sourceSlot: Int, sinkPos: BlockPosition, sinkSide: Option[ForgeDirection], sinkSlot: Option[Int], limit: Int = Int.MaxValue): Extractor =
inventoryAt(sourcePos) match {
case Some(sourceInventory) =>
inventoryAt(sinkPos) match {
Expand Down