diff --git a/build.gradle b/build.gradle index 56cd0db6a..4a90d6036 100644 --- a/build.gradle +++ b/build.gradle @@ -195,6 +195,7 @@ dependencies { deobfCompile "mezz.jei:jei_1.10.2:${config.jei.version}" deobfCompile "net.darkhax.tesla:Tesla:${config.tesla.version}" deobfCompile "li.cil.tis3d:TIS-3D:${config.tis3d.version}" + /* deobfCompile "mcp.mobius.waila:Waila:${config.waila.version}"*/ //provided "codechicken:CodeChickenCore:${config.minecraft.version}-${config.ccc.version}:deobf" @@ -208,7 +209,11 @@ dependencies { provided "appeng:RotaryCraft:${config.rotc.version}:api" provided ("appeng:appliedenergistics2:${config.ae2.version}:dev") { exclude module: 'buildcraft' - } + }*/ + + provided files("libs/appliedenergistics2-rv4-alpha-11-api.jar") + +/* provided "codechicken:ForgeMultipart:${config.minecraft.version}-${config.fmp.version}:dev"*/ provided ("codechicken:WR-CBE:${config.minecraft.version}-${config.wrcbe.version}:universal") { exclude module: 'NotEnoughItems' @@ -282,7 +287,7 @@ sourceSets { main { scala { exclude 'li/cil/oc/integration/agricraft/**' - exclude 'li/cil/oc/integration/appeng/**' + //exclude 'li/cil/oc/integration/appeng/**' exclude 'li/cil/oc/integration/bloodmagic/**' exclude 'li/cil/oc/integration/bluepower/**' exclude 'li/cil/oc/integration/buildcraft/**' diff --git a/build.properties b/build.properties index 3d3de3422..64268d64f 100644 --- a/build.properties +++ b/build.properties @@ -5,7 +5,7 @@ forge.version=12.18.3.2221 oc.version=1.6.2 oc.subversion=dev -ae2.version=rv2-beta-26 +ae2.version=rv4-alpha-11 bc.version=7.0.9 bloodmagic.cf=2223/203 bloodmagic.version=1.3.0a-1 diff --git a/libs/appliedenergistics2-rv4-alpha-11-api.jar b/libs/appliedenergistics2-rv4-alpha-11-api.jar new file mode 100644 index 000000000..f51d29d44 Binary files /dev/null and b/libs/appliedenergistics2-rv4-alpha-11-api.jar differ diff --git a/src/main/scala/li/cil/oc/integration/Mods.scala b/src/main/scala/li/cil/oc/integration/Mods.scala index 6bec4d79b..9510bef0f 100644 --- a/src/main/scala/li/cil/oc/integration/Mods.scala +++ b/src/main/scala/li/cil/oc/integration/Mods.scala @@ -93,7 +93,7 @@ object Mods { val Proxies = Array( // integration.agricraft.ModAgriCraft, - // integration.appeng.ModAppEng, + integration.appeng.ModAppEng, // integration.betterrecords.ModBetterRecords, // integration.bloodmagic.ModBloodMagic, // integration.bluepower.ModBluePower, diff --git a/src/main/scala/li/cil/oc/integration/appeng/AEUtil.scala b/src/main/scala/li/cil/oc/integration/appeng/AEUtil.scala index eefcb9f59..678c1d89e 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/AEUtil.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/AEUtil.scala @@ -1,121 +1,72 @@ package li.cil.oc.integration.appeng +import javax.annotation.Nonnull + import appeng.api.AEApi -import cpw.mods.fml.common.Loader -import cpw.mods.fml.common.versioning.VersionRange +import appeng.api.networking.IGrid +import appeng.api.networking.crafting.ICraftingGrid +import appeng.api.networking.energy.IEnergyGrid +import appeng.api.networking.storage.IStorageGrid import li.cil.oc.integration.Mods import net.minecraft.item.ItemStack +import net.minecraftforge.fml.common.versioning.VersionRange +import net.minecraftforge.fml.common.Loader object AEUtil { - val versionsWithNewItemDefinitionAPI = VersionRange.createFromVersionSpec("[rv2-beta-20,)") + val versionsWithNewItemDefinitionAPI = VersionRange.createFromVersionSpec("[rv4-alpha-1,)") def useNewItemDefinitionAPI = versionsWithNewItemDefinitionAPI.containsVersion( Loader.instance.getIndexedModList.get(Mods.AppliedEnergistics2.id).getProcessedVersion) // ----------------------------------------------------------------------- // - def areChannelsEnabled: Boolean = AEApi.instance != null && { - if (useNewItemDefinitionAPI) areChannelsEnabledNew - else areChannelsEnabledOld - } - - private def areChannelsEnabledNew: Boolean = AEApi.instance.definitions.blocks.controller.maybeStack(1).isPresent - - private def areChannelsEnabledOld: Boolean = AEApi.instance.blocks != null && AEApi.instance.blocks.blockController != null && AEApi.instance.blocks.blockController.item != null + def areChannelsEnabled: Boolean = AEApi.instance != null && AEApi.instance.definitions.blocks.controller.maybeStack(1).isPresent // ----------------------------------------------------------------------- // def controllerClass: Class[_] = - if (AEApi.instance != null) { - if (AEUtil.useNewItemDefinitionAPI) controllerClassNew - else controllerClassOld - } + if (AEApi.instance != null) + if (areChannelsEnabled) AEApi.instance.definitions.blocks.controller.maybeEntity.get() + else null: Class[_] else null - private def controllerClassNew: Class[_] = - if (areChannelsEnabled) AEApi.instance.definitions.blocks.controller.maybeEntity.orNull - else null: Class[_] // ... why -.- + // ----------------------------------------------------------------------- // - private def controllerClassOld: Class[_] = { - // Not classOf[TileController] because that derps the compiler when it tries to resolve the class (says can't find API classes from RotaryCraft). - if (areChannelsEnabled) Class.forName("appeng.tile.networking.TileController") + def interfaceClass: Class[_] = + if (AEApi.instance != null) + if (areChannelsEnabled) AEApi.instance.definitions.blocks.iface.maybeEntity.get() + else null: Class[_] else null - } // ----------------------------------------------------------------------- // - def isController(stack: ItemStack): Boolean = stack != null && AEApi.instance != null && { - if (useNewItemDefinitionAPI) isControllerNew(stack) - else isControllerOld(stack) - } - - private def isControllerNew(stack: ItemStack): Boolean = - areChannelsEnabled && - AEApi.instance.definitions.blocks.controller.isSameAs(stack) - - private def isControllerOld(stack: ItemStack): Boolean = - areChannelsEnabled && - AEApi.instance.blocks != null && - AEApi.instance.blocks.blockController != null && - AEApi.instance.blocks.blockController.sameAsStack(stack) + def isController(stack: ItemStack): Boolean = stack != null && AEApi.instance != null && areChannelsEnabled && AEApi.instance.definitions.blocks.controller.isSameAs(stack) // ----------------------------------------------------------------------- // - def isExportBus(stack: ItemStack): Boolean = stack != null && AEApi.instance != null && { - if (useNewItemDefinitionAPI) isExportBusNew(stack) - else isExportBusOld(stack) - } - - private def isExportBusNew(stack: ItemStack): Boolean = - AEApi.instance.definitions.parts.exportBus.isSameAs(stack) - - private def isExportBusOld(stack: ItemStack): Boolean = - AEApi.instance.parts != null && - AEApi.instance.parts.partExportBus != null && - AEApi.instance.parts.partExportBus.sameAsStack(stack) + def isExportBus(stack: ItemStack): Boolean = stack != null && AEApi.instance != null && AEApi.instance.definitions.parts.exportBus.isSameAs(stack) // ----------------------------------------------------------------------- // - def isImportBus(stack: ItemStack): Boolean = stack != null && AEApi.instance != null && { - if (useNewItemDefinitionAPI) isImportBusNew(stack) - else isImportBusOld(stack) - } - - private def isImportBusNew(stack: ItemStack): Boolean = - AEApi.instance.definitions.parts.importBus.isSameAs(stack) - - private def isImportBusOld(stack: ItemStack): Boolean = - AEApi.instance.parts != null && - AEApi.instance.parts.partImportBus != null && - AEApi.instance.parts.partImportBus.sameAsStack(stack) + def isImportBus(stack: ItemStack): Boolean = stack != null && AEApi.instance != null && AEApi.instance.definitions.parts.importBus.isSameAs(stack) // ----------------------------------------------------------------------- // - def isBlockInterface(stack: ItemStack): Boolean = stack != null && AEApi.instance != null && { - if (useNewItemDefinitionAPI) isBlockInterfaceNew(stack) - else isBlockInterfaceOld(stack) - } - - private def isBlockInterfaceNew(stack: ItemStack): Boolean = - AEApi.instance.definitions.blocks.iface.isSameAs(stack) - - private def isBlockInterfaceOld(stack: ItemStack): Boolean = - AEApi.instance.blocks != null && - AEApi.instance.blocks.blockInterface != null && - AEApi.instance.blocks.blockInterface.sameAsStack(stack) + def isBlockInterface(stack: ItemStack): Boolean = stack != null && AEApi.instance != null && AEApi.instance.definitions.blocks.iface.isSameAs(stack) // ----------------------------------------------------------------------- // - def isPartInterface(stack: ItemStack): Boolean = stack != null && AEApi.instance != null && { - if (useNewItemDefinitionAPI) isPartInterfaceNew(stack) - else isPartInterfaceOld(stack) - } + def isPartInterface(stack: ItemStack): Boolean = stack != null && AEApi.instance != null && AEApi.instance.definitions.parts.iface.isSameAs(stack) - private def isPartInterfaceNew(stack: ItemStack): Boolean = - AEApi.instance.definitions.parts.iface.isSameAs(stack) + // ----------------------------------------------------------------------- // - private def isPartInterfaceOld(stack: ItemStack): Boolean = - AEApi.instance.parts != null && - AEApi.instance.parts.partInterface != null && - AEApi.instance.parts.partInterface.sameAsStack(stack) + def getGridStorage(@Nonnull grid: IGrid): IStorageGrid = grid.getCache( classOf[IStorageGrid] ) + + // ----------------------------------------------------------------------- // + + def getGridCrafting(@Nonnull grid: IGrid): ICraftingGrid = grid.getCache( classOf[ICraftingGrid] ) + + // ----------------------------------------------------------------------- // + + def getGridEnergy(@Nonnull grid: IGrid): IEnergyGrid = grid.getCache( classOf[IEnergyGrid] ) } diff --git a/src/main/scala/li/cil/oc/integration/appeng/DriverBlockInterface.scala b/src/main/scala/li/cil/oc/integration/appeng/DriverBlockInterface.scala index f41350014..174d0d1f4 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/DriverBlockInterface.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/DriverBlockInterface.scala @@ -1,6 +1,8 @@ package li.cil.oc.integration.appeng -import appeng.tile.misc.TileInterface +import appeng.api.implementations.tiles.ISegmentedInventory +import appeng.api.networking.security.IActionHost +import appeng.api.util.AEPartLocation import li.cil.oc.api.driver.EnvironmentProvider import li.cil.oc.api.driver.NamedBlock import li.cil.oc.api.internal.Database @@ -14,17 +16,20 @@ import li.cil.oc.integration.ManagedTileEntityEnvironment import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.ResultWrapper._ import net.minecraft.item.ItemStack +import net.minecraft.tileentity.TileEntity import net.minecraft.util.EnumFacing +import net.minecraft.util.math.BlockPos import net.minecraft.world.World object DriverBlockInterface extends DriverSidedTileEntity { - def getTileEntityClass: Class[_] = classOf[TileInterface] + def getTileEntityClass: Class[_] = AEUtil.interfaceClass - def createEnvironment(world: World, x: Int, y: Int, z: Int, side: EnumFacing): ManagedEnvironment = - new Environment(world.getTileEntity(x, y, z).asInstanceOf[TileInterface]) + def createEnvironment(world: World, pos: BlockPos, side: EnumFacing): ManagedEnvironment = + new Environment(world.getTileEntity(pos).asInstanceOf[TileEntity with ISegmentedInventory with IActionHost]) - final class Environment(val tile: TileInterface) extends ManagedTileEntityEnvironment[TileInterface](tile, "me_interface") with NamedBlock with NetworkControl[TileInterface] { + final class Environment(val tile: TileEntity with ISegmentedInventory with IActionHost) extends ManagedTileEntityEnvironment[TileEntity with ISegmentedInventory with IActionHost](tile, "me_interface") with NamedBlock with NetworkControl[TileEntity with ISegmentedInventory with IActionHost] { override def preferredName = "me_interface" + override def pos: AEPartLocation = AEPartLocation.INTERNAL override def priority = 5 diff --git a/src/main/scala/li/cil/oc/integration/appeng/DriverController.scala b/src/main/scala/li/cil/oc/integration/appeng/DriverController.scala index baf89de45..3f7b2e4ec 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/DriverController.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/DriverController.scala @@ -1,7 +1,8 @@ package li.cil.oc.integration.appeng +import appeng.api.networking.IGridHost import appeng.api.networking.security.IActionHost -import appeng.me.helpers.IGridProxyable +import appeng.api.util.AEPartLocation import li.cil.oc.api.driver.EnvironmentProvider import li.cil.oc.api.driver.NamedBlock import li.cil.oc.api.network.ManagedEnvironment @@ -10,21 +11,24 @@ import li.cil.oc.integration.ManagedTileEntityEnvironment import net.minecraft.item.ItemStack import net.minecraft.tileentity.TileEntity import net.minecraft.util.EnumFacing +import net.minecraft.util.math.BlockPos import net.minecraft.world.World import scala.language.existentials object DriverController extends DriverSidedTileEntity { - private type TileController = TileEntity with IGridProxyable with IActionHost + private type TileController = TileEntity with IActionHost def getTileEntityClass = AEUtil.controllerClass - def createEnvironment(world: World, x: Int, y: Int, z: Int, side: EnumFacing): ManagedEnvironment = - new Environment(world.getTileEntity(x, y, z).asInstanceOf[TileController]) + def createEnvironment(world: World, pos: BlockPos, side: EnumFacing): ManagedEnvironment = + new Environment(world.getTileEntity(pos).asInstanceOf[TileController]) final class Environment(val tile: TileController) extends ManagedTileEntityEnvironment[TileController](tile, "me_controller") with NamedBlock with NetworkControl[TileController] { override def preferredName = "me_controller" + override def pos: AEPartLocation = AEPartLocation.INTERNAL + override def priority = 5 } diff --git a/src/main/scala/li/cil/oc/integration/appeng/DriverExportBus.scala b/src/main/scala/li/cil/oc/integration/appeng/DriverExportBus.scala index 221ddad2f..6114cf5db 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/DriverExportBus.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/DriverExportBus.scala @@ -1,5 +1,14 @@ package li.cil.oc.integration.appeng +import appeng.api.AEApi +import appeng.api.config.{Actionable, FuzzyMode, Settings, Upgrades} +import appeng.api.implementations.IUpgradeableHost +import appeng.api.implementations.tiles.ISegmentedInventory +import appeng.api.networking.IGridHost +import appeng.api.networking.security.{IActionHost, MachineSource} +import appeng.api.parts.{IPartHost, PartItemStack} +import appeng.api.storage.data.IAEItemStack +import appeng.api.util.{AEPartLocation, IConfigurableObject} import li.cil.oc.api.driver import li.cil.oc.api.driver.EnvironmentProvider import li.cil.oc.api.driver.NamedBlock @@ -12,16 +21,18 @@ import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.InventoryUtils import li.cil.oc.util.ResultWrapper._ import net.minecraft.item.ItemStack +import net.minecraft.util.EnumFacing import net.minecraft.world.World +import net.minecraft.util.math.BlockPos object DriverExportBus extends driver.SidedBlock { - override def worksWith(world: World, x: Int, y: Int, z: Int, side: ForgeDirection) = - world.getTileEntity(x, y, z) match { - case container: IPartHost => ForgeDirection.VALID_DIRECTIONS.map(container.getPart).exists(_.isInstanceOf[PartExportBus]) + override def worksWith(world: World, pos: BlockPos, side: EnumFacing) = + world.getTileEntity(pos) match { + case container: IPartHost => EnumFacing.VALUES.map(container.getPart).map(_.getItemStack(PartItemStack.PICK)).exists(AEUtil.isExportBus) case _ => false } - override def createEnvironment(world: World, x: Int, y: Int, z: Int, side: ForgeDirection) = new Environment(world.getTileEntity(x, y, z).asInstanceOf[IPartHost]) + override def createEnvironment(world: World, pos: BlockPos, side: EnumFacing) = new Environment(world.getTileEntity(pos).asInstanceOf[IPartHost]) final class Environment(val host: IPartHost) extends ManagedTileEntityEnvironment[IPartHost](host, "me_exportbus") with NamedBlock with PartEnvironmentBase { override def preferredName = "me_exportbus" @@ -29,69 +40,67 @@ object DriverExportBus extends driver.SidedBlock { override def priority = 2 @Callback(doc = "function(side:number, [ slot:number]):boolean -- Get the configuration of the export bus pointing in the specified direction.") - def getExportConfiguration(context: Context, args: Arguments): Array[AnyRef] = getPartConfig[PartExportBus](context, args) + def getExportConfiguration(context: Context, args: Arguments): Array[AnyRef] = getPartConfig[ISegmentedInventory](context, args) @Callback(doc = "function(side:number[, slot:number][, database:address, entry:number):boolean -- Configure the export bus pointing in the specified direction to export item stacks matching the specified descriptor.") - def setExportConfiguration(context: Context, args: Arguments): Array[AnyRef] = setPartConfig[PartExportBus](context, args) + def setExportConfiguration(context: Context, args: Arguments): Array[AnyRef] = setPartConfig[ISegmentedInventory](context, args) @Callback(doc = "function(side:number, slot:number):boolean -- Make the export bus facing the specified direction perform a single export operation into the specified slot.") def exportIntoSlot(context: Context, args: Arguments): Array[AnyRef] = { val side = args.checkSideAny(0) - host.getPart(side) match { - case export: PartExportBus => - InventoryUtils.inventoryAt(BlockPosition(host.getLocation).offset(side)) match { - case Some(inventory) => - val targetSlot = args.checkSlot(inventory, 1) - val config = export.getInventoryByName("config") - val itemStorage = export.getProxy.getStorage.getItemInventory - var count = export.getInstalledUpgrades(Upgrades.SPEED) match { - case 1 => 8 - case 2 => 32 - case 3 => 64 - case 4 => 96 - case _ => 1 - } - // We need reflection here to avoid compiling against the return and - // argument type, which has changed in rv2-beta-20 or so. - val fuzzyMode = (try export.getConfigManager.getClass.getMethod("getSetting", classOf[Enum[_]]) catch { - case _: NoSuchMethodException => export.getConfigManager.getClass.getMethod("getSetting", classOf[Settings]) - }).invoke(export.getConfigManager, Settings.FUZZY_MODE).asInstanceOf[FuzzyMode] - val source = new MachineSource(export) - var didSomething = false - for (slot <- 0 until config.getSizeInventory if count > 0) { - val filter = AEApi.instance.storage.createItemStack(config.getStackInSlot(slot)) - val stacks = - if (export.getInstalledUpgrades(Upgrades.FUZZY) > 0) - itemStorage.getStorageList.findFuzzy(filter, fuzzyMode).toSeq - else - Seq(itemStorage.getStorageList.findPrecise(filter)) - for (ais <- stacks.filter(_ != null).map(_.copy()) if count > 0) { - val is = ais.getItemStack - is.stackSize = count - if (InventoryUtils.insertIntoInventorySlot(is, inventory, Option(side.getOpposite), targetSlot, count, simulate = true)) { - ais.setStackSize(count - is.stackSize) - val eais = AEApi.instance.storage.poweredExtraction(export.getProxy.getEnergy, itemStorage, ais, source) - if (eais != null) { - val eis = eais.getItemStack - count -= eis.stackSize - didSomething = true - InventoryUtils.insertIntoInventorySlot(eis, inventory, Option(side.getOpposite), targetSlot) - if (eis.stackSize > 0) { - eais.setStackSize(eis.stackSize) - itemStorage.injectItems(ais, Actionable.MODULATE, source) - } + val part = host.getPart(side) + + if(AEUtil.isExportBus(part.getItemStack(PartItemStack.PICK))) { + val export = part.asInstanceOf[ISegmentedInventory with IConfigurableObject with IUpgradeableHost with IActionHost] + InventoryUtils.inventoryAt(new BlockPosition(host.getLocation.x, host.getLocation.y, host.getLocation.z), side) match { + case Some(inventory) => + val targetSlot = args.checkSlot(inventory, 1) + val config = export.getInventoryByName("config") + val itemStorage = AEUtil.getGridStorage(export.getGridNode(AEPartLocation.fromFacing(side)).getGrid).getItemInventory + var count = export.getInstalledUpgrades(Upgrades.SPEED) match { + case 1 => 8 + case 2 => 32 + case 3 => 64 + case 4 => 96 + case _ => 1 + } + val fuzzyMode = export.getConfigManager.getSetting(Settings.FUZZY_MODE).asInstanceOf[FuzzyMode] + val source = new MachineSource(export) + var didSomething = false + for (slot <- 0 until config.getSizeInventory if count > 0) { + val filter = AEApi.instance.storage.createItemStack(config.getStackInSlot(slot)) + val stacks = + if (export.getInstalledUpgrades(Upgrades.FUZZY) > 0) + itemStorage.getStorageList.findFuzzy(filter, fuzzyMode).toArray.toSeq + else + Seq(itemStorage.getStorageList.findPrecise(filter)) + for (ais <- stacks.filter(_ != null).map(_.asInstanceOf[IAEItemStack].copy) if count > 0) { + val is = ais.getItemStack + is.stackSize = count + if (InventoryUtils.insertIntoInventorySlot(is, inventory, targetSlot, count, simulate = true)) { + ais.setStackSize(count - is.stackSize) + val eais = AEApi.instance.storage.poweredExtraction(AEUtil.getGridEnergy(export.getGridNode(AEPartLocation.fromFacing(side)).getGrid), itemStorage, ais, source) + if (eais != null) { + val eis = eais.getItemStack + count -= eis.stackSize + didSomething = true + InventoryUtils.insertIntoInventorySlot(eis, inventory, targetSlot) + if (eis.stackSize > 0) { + eais.setStackSize(eis.stackSize) + itemStorage.injectItems(ais, Actionable.MODULATE, source) } } } } - if (didSomething) { - context.pause(0.25) - } - result(didSomething) - case _ => result(Unit, "no inventory") - } - case _ => result(Unit, "no export bus") + } + if (didSomething) { + context.pause(0.25) + } + result(didSomething) + case _ => result(Unit, "no inventory") + } } + else result(Unit, "no export bus") } } diff --git a/src/main/scala/li/cil/oc/integration/appeng/DriverImportBus.scala b/src/main/scala/li/cil/oc/integration/appeng/DriverImportBus.scala index 1b55486dc..c8f38b270 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/DriverImportBus.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/DriverImportBus.scala @@ -1,7 +1,7 @@ package li.cil.oc.integration.appeng -import appeng.api.parts.IPartHost -import appeng.parts.automation.PartImportBus +import appeng.api.implementations.tiles.ISegmentedInventory +import appeng.api.parts.{IPartHost, PartItemStack} import li.cil.oc.api.driver import li.cil.oc.api.driver.EnvironmentProvider import li.cil.oc.api.driver.NamedBlock @@ -10,17 +10,18 @@ import li.cil.oc.api.machine.Callback import li.cil.oc.api.machine.Context import li.cil.oc.integration.ManagedTileEntityEnvironment import net.minecraft.item.ItemStack +import net.minecraft.util.EnumFacing +import net.minecraft.util.math.BlockPos import net.minecraft.world.World -import net.minecraftforge.common.util.ForgeDirection object DriverImportBus extends driver.SidedBlock { - override def worksWith(world: World, x: Int, y: Int, z: Int, side: ForgeDirection) = - world.getTileEntity(x, y, z) match { - case container: IPartHost => ForgeDirection.VALID_DIRECTIONS.map(container.getPart).exists(_.isInstanceOf[PartImportBus]) + override def worksWith(world: World, pos: BlockPos, side: EnumFacing) = + world.getTileEntity(pos) match { + case container: IPartHost => EnumFacing.VALUES.map(container.getPart).map(_.getItemStack(PartItemStack.PICK)).exists(AEUtil.isImportBus) case _ => false } - override def createEnvironment(world: World, x: Int, y: Int, z: Int, side: ForgeDirection) = new Environment(world.getTileEntity(x, y, z).asInstanceOf[IPartHost]) + override def createEnvironment(world: World, pos: BlockPos, side: EnumFacing) = new Environment(world.getTileEntity(pos).asInstanceOf[IPartHost]) final class Environment(val host: IPartHost) extends ManagedTileEntityEnvironment[IPartHost](host, "me_importbus") with NamedBlock with PartEnvironmentBase { override def preferredName = "me_importbus" @@ -28,10 +29,10 @@ object DriverImportBus extends driver.SidedBlock { override def priority = 1 @Callback(doc = "function(side:number[, slot:number]):boolean -- Get the configuration of the import bus pointing in the specified direction.") - def getImportConfiguration(context: Context, args: Arguments): Array[AnyRef] = getPartConfig[PartImportBus](context, args) + def getImportConfiguration(context: Context, args: Arguments): Array[AnyRef] = getPartConfig[ISegmentedInventory](context, args) @Callback(doc = "function(side:number[, slot:number][, database:address, entry:number]):boolean -- Configure the import bus pointing in the specified direction to import item stacks matching the specified descriptor.") - def setImportConfiguration(context: Context, args: Arguments): Array[AnyRef] = setPartConfig[PartImportBus](context, args) + def setImportConfiguration(context: Context, args: Arguments): Array[AnyRef] = setPartConfig[ISegmentedInventory](context, args) } object Provider extends EnvironmentProvider { diff --git a/src/main/scala/li/cil/oc/integration/appeng/DriverPartInterface.scala b/src/main/scala/li/cil/oc/integration/appeng/DriverPartInterface.scala index 52e519230..92423b404 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/DriverPartInterface.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/DriverPartInterface.scala @@ -1,26 +1,25 @@ package li.cil.oc.integration.appeng -import appeng.api.parts.IPartHost -import appeng.parts.misc.PartInterface +import appeng.api.implementations.tiles.ISegmentedInventory +import appeng.api.parts.{IPartHost, PartItemStack} import li.cil.oc.api.driver -import li.cil.oc.api.driver.EnvironmentProvider -import li.cil.oc.api.driver.NamedBlock -import li.cil.oc.api.machine.Arguments -import li.cil.oc.api.machine.Callback +import li.cil.oc.api.driver.{EnvironmentProvider, NamedBlock} +import li.cil.oc.api.machine.{Arguments, Callback} import li.cil.oc.api.machine.Context import li.cil.oc.integration.ManagedTileEntityEnvironment import net.minecraft.item.ItemStack +import net.minecraft.util.EnumFacing +import net.minecraft.util.math.BlockPos import net.minecraft.world.World -import net.minecraftforge.common.util.ForgeDirection object DriverPartInterface extends driver.SidedBlock { - override def worksWith(world: World, x: Int, y: Int, z: Int, side: ForgeDirection) = - world.getTileEntity(x, y, z) match { - case container: IPartHost => ForgeDirection.VALID_DIRECTIONS.map(container.getPart).exists(_.isInstanceOf[PartInterface]) + override def worksWith(world: World, pos: BlockPos, side: EnumFacing) = + world.getTileEntity(pos) match { + case container: IPartHost => EnumFacing.VALUES.map(container.getPart).map(_.getItemStack(PartItemStack.PICK)).exists(AEUtil.isPartInterface) case _ => false } - override def createEnvironment(world: World, x: Int, y: Int, z: Int, side: ForgeDirection) = new Environment(world.getTileEntity(x, y, z).asInstanceOf[IPartHost]) + override def createEnvironment(world: World, pos: BlockPos, side: EnumFacing) = new Environment(world.getTileEntity(pos).asInstanceOf[IPartHost]) final class Environment(val host: IPartHost) extends ManagedTileEntityEnvironment[IPartHost](host, "me_interface") with NamedBlock with PartEnvironmentBase { override def preferredName = "me_interface" @@ -28,10 +27,10 @@ object DriverPartInterface extends driver.SidedBlock { override def priority = 0 @Callback(doc = "function(side:number[, slot:number]):table -- Get the configuration of the interface pointing in the specified direction.") - def getInterfaceConfiguration(context: Context, args: Arguments): Array[AnyRef] = getPartConfig[PartInterface](context, args) + def getInterfaceConfiguration(context: Context, args: Arguments): Array[AnyRef] = getPartConfig[ISegmentedInventory](context, args) @Callback(doc = "function(side:number[, slot:number][, database:address, entry:number[, size:number]]):boolean -- Configure the interface pointing in the specified direction.") - def setInterfaceConfiguration(context: Context, args: Arguments): Array[AnyRef] = setPartConfig[PartInterface](context, args) + def setInterfaceConfiguration(context: Context, args: Arguments): Array[AnyRef] = setPartConfig[ISegmentedInventory](context, args) } object Provider extends EnvironmentProvider { diff --git a/src/main/scala/li/cil/oc/integration/appeng/EventHandlerAE2.scala b/src/main/scala/li/cil/oc/integration/appeng/EventHandlerAE2.scala index 5322092e7..893c8079d 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/EventHandlerAE2.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/EventHandlerAE2.scala @@ -3,11 +3,13 @@ package li.cil.oc.integration.appeng import appeng.api.implementations.items.IAEWrench import net.minecraft.entity.player.EntityPlayer import net.minecraft.item.ItemStack +import net.minecraft.util.EnumHand +import net.minecraft.util.math.BlockPos object EventHandlerAE2 { - def useWrench(player: EntityPlayer, x: Int, y: Int, z: Int, changeDurability: Boolean): Boolean = { - player.getHeldItem.getItem match { - case wrench: IAEWrench => wrench.canWrench(player.getHeldItem, player, x, y, z) + def useWrench(player: EntityPlayer, pos: BlockPos, changeDurability: Boolean): Boolean = { + player.getHeldItem(EnumHand.MAIN_HAND).getItem match { + case wrench: IAEWrench => wrench.canWrench(player.getHeldItem(EnumHand.MAIN_HAND), player, pos) case _ => false } } diff --git a/src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala b/src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala index 86602a0a4..7e066fd38 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/NetworkControl.scala @@ -1,5 +1,12 @@ package li.cil.oc.integration.appeng +import appeng.api.AEApi +import appeng.api.config.Actionable +import appeng.api.networking.IGridHost +import appeng.api.networking.crafting.{ICraftingLink, ICraftingRequester} +import appeng.api.networking.security.{IActionHost, MachineSource} +import appeng.api.storage.data.IAEItemStack +import appeng.api.util.AEPartLocation import com.google.common.collect.ImmutableSet import li.cil.oc.OpenComputers import li.cil.oc.api.machine.Arguments @@ -8,34 +15,34 @@ import li.cil.oc.api.machine.Context import li.cil.oc.api.network.Node import li.cil.oc.api.prefab.AbstractValue import li.cil.oc.common.EventHandler -import li.cil.oc.integration.Mods -import li.cil.oc.integration.ec.ECUtil import li.cil.oc.util.DatabaseAccess import li.cil.oc.util.ExtendedArguments._ import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ResultWrapper._ -import net.minecraft.item.Item +import net.minecraft.item.{Item, ItemStack} import net.minecraft.nbt.NBTTagCompound import net.minecraft.tileentity.TileEntity +import net.minecraft.util.math.BlockPos import net.minecraftforge.common.DimensionManager import net.minecraftforge.common.util.Constants.NBT import scala.collection.convert.WrapAsJava._ import scala.collection.convert.WrapAsScala._ import scala.collection.mutable -import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Future +import scala.concurrent.ExecutionContext.Implicits.global import scala.language.existentials // Note to self: this class is used by ExtraCells (and potentially others), do not rename / drastically change it. -trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActionHost] { +trait NetworkControl[AETile >: Null <: TileEntity with IActionHost] { def tile: AETile + def pos: AEPartLocation def node: Node @Callback(doc = "function():table -- Get a list of tables representing the available CPUs in the network.") def getCpus(context: Context, args: Arguments): Array[AnyRef] = - result(tile.getProxy.getCrafting.getCpus.map(cpu => Map( + result(AEUtil.getGridCrafting(tile.getGridNode(pos).getGrid).getCpus.map(cpu => Map( "name" -> cpu.getName, "storage" -> cpu.getAvailableStorage, "coprocessors" -> cpu.getCoProcessors, @@ -46,14 +53,14 @@ trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActi val filter = args.optTable(0, Map.empty[AnyRef, AnyRef]).collect { case (key: String, value: AnyRef) => (key, value) } - result(tile.getProxy.getStorage.getItemInventory.getStorageList. + result(AEUtil.getGridStorage(tile.getGridNode(pos).getGrid).getItemInventory.getStorageList. filter(_.isCraftable).filter(stack => matches(stack, filter)).map(stack => { - val patterns = tile.getProxy.getCrafting.getCraftingFor(stack, null, 0, tile.getWorldObj) + val patterns = AEUtil.getGridCrafting(tile.getGridNode(pos).getGrid).getCraftingFor(stack, null, 0, tile.getWorld) val result = patterns.find(pattern => pattern.getOutputs.exists(_.isSameType(stack))) match { case Some(pattern) => pattern.getOutputs.find(_.isSameType(stack)).get case _ => stack.copy.setStackSize(0) // Should not be possible, but hey... } - new NetworkControl.Craftable(tile, result) + new NetworkControl.Craftable(tile, pos, result) }).toArray) } @@ -62,7 +69,7 @@ trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActi val filter = args.optTable(0, Map.empty[AnyRef, AnyRef]).collect { case (key: String, value: AnyRef) => (key, value) } - result(tile.getProxy.getStorage.getItemInventory.getStorageList.filter(stack => matches(stack, filter)).map(_.getItemStack).toArray) + result(AEUtil.getGridStorage(tile.getGridNode(pos).getGrid).getItemInventory.getStorageList.filter(stack => matches(stack, filter)).map(_.getItemStack).toArray) } @Callback(doc = "function(filter:table, dbAddress:string[, startSlot:number[, count:number]]): Boolean -- Store items in the network matching the specified filter in the database with the specified address.") @@ -71,7 +78,7 @@ trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActi case (key: String, value: AnyRef) => (key, value) } DatabaseAccess.withDatabase(node, args.checkString(1), database => { - val stacks = tile.getProxy.getStorage.getItemInventory.getStorageList.filter(stack => matches(stack, filter)).map(_.getItemStack).filter(_ != null).toArray + val stacks = AEUtil.getGridStorage(tile.getGridNode(pos).getGrid).getItemInventory.getStorageList.filter(stack => matches(stack, filter)).map(_.getItemStack).filter(_ != null).toArray val offset = args.optSlot(database.data, 2, 0) val count = args.optInteger(3, Int.MaxValue) min (database.size - offset) min stacks.length var slot = offset @@ -88,29 +95,29 @@ trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActi @Callback(doc = "function():table -- Get a list of the stored fluids in the network.") def getFluidsInNetwork(context: Context, args: Arguments): Array[AnyRef] = - result(tile.getProxy.getStorage.getFluidInventory.getStorageList.filter(stack => - !Mods.ExtraCells.isAvailable || ECUtil.canSeeFluidInNetwork(stack)). - map(_.getFluidStack).toArray) + result(AEUtil.getGridStorage(tile.getGridNode(pos).getGrid).getFluidInventory.getStorageList.filter(stack => + stack != null). + map(_.getFluidStack).toArray) @Callback(doc = "function():number -- Get the average power injection into the network.") def getAvgPowerInjection(context: Context, args: Arguments): Array[AnyRef] = - result(tile.getProxy.getEnergy.getAvgPowerInjection) + result(AEUtil.getGridEnergy(tile.getGridNode(pos).getGrid).getAvgPowerInjection) @Callback(doc = "function():number -- Get the average power usage of the network.") def getAvgPowerUsage(context: Context, args: Arguments): Array[AnyRef] = - result(tile.getProxy.getEnergy.getAvgPowerUsage) + result(AEUtil.getGridEnergy(tile.getGridNode(pos).getGrid).getAvgPowerUsage) @Callback(doc = "function():number -- Get the idle power usage of the network.") def getIdlePowerUsage(context: Context, args: Arguments): Array[AnyRef] = - result(tile.getProxy.getEnergy.getIdlePowerUsage) + result(AEUtil.getGridEnergy(tile.getGridNode(pos).getGrid).getIdlePowerUsage) @Callback(doc = "function():number -- Get the maximum stored power in the network.") def getMaxStoredPower(context: Context, args: Arguments): Array[AnyRef] = - result(tile.getProxy.getEnergy.getMaxStoredPower) + result(AEUtil.getGridEnergy(tile.getGridNode(pos).getGrid).getMaxStoredPower) @Callback(doc = "function():number -- Get the stored power in the network. ") def getStoredPower(context: Context, args: Arguments): Array[AnyRef] = - result(tile.getProxy.getEnergy.getStoredPower) + result(AEUtil.getGridEnergy(tile.getGridNode(pos).getGrid).getStoredPower) private def matches(stack: IAEItemStack, filter: scala.collection.mutable.Map[String, AnyRef]) = { stack != null && @@ -119,15 +126,15 @@ trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActi filter.get("size").collect { case size: Number => size.intValue == stack.getStackSize || size.intValue == 0 }.getOrElse(true) && filter.get("maxSize").forall(_.equals(stack.getItemStack.getMaxStackSize.toDouble)) && filter.get("hasTag").forall(_.equals(stack.hasTagCompound)) && - filter.get("name").forall(_.equals(Item.itemRegistry.getNameForObject(stack.getItem))) && + filter.get("name").forall(_.equals(Item.REGISTRY.getNameForObject(stack.getItem))) && filter.get("label").forall(_.equals(stack.getItemStack.getDisplayName)) } } object NetworkControl { - class Craftable(var controller: TileEntity with IGridProxyable with IActionHost, var stack: IAEItemStack) extends AbstractValue with ICraftingRequester { - def this() = this(null, null) + class Craftable(var controller: TileEntity with IActionHost, var pos: AEPartLocation, var stack: IAEItemStack) extends AbstractValue with ICraftingRequester { + def this() = this(null, null, null) private val links = mutable.Set.empty[ICraftingLink] @@ -147,11 +154,11 @@ object NetworkControl { override def getActionableNode = controller.getActionableNode - override def getCableConnectionType(side: ForgeDirection) = controller.getCableConnectionType(side) + override def getCableConnectionType(side: AEPartLocation) = controller.getCableConnectionType(side) override def securityBreak() = controller.securityBreak() - override def getGridNode(side: ForgeDirection) = controller.getGridNode(side) + override def getGridNode(side: AEPartLocation) = controller.getGridNode(side) // ----------------------------------------------------------------------- // @@ -168,13 +175,13 @@ object NetworkControl { val request = stack.copy request.setStackSize(count) - val craftingGrid = controller.getProxy.getCrafting + val craftingGrid = AEUtil.getGridCrafting(controller.getGridNode(pos).getGrid) val source = new MachineSource(controller) - val future = craftingGrid.beginCraftingJob(controller.getWorldObj, controller.getProxy.getGrid, source, request, null) + val future = craftingGrid.beginCraftingJob(controller.getWorld, controller.getGridNode(pos).getGrid, source, request, null) val prioritizePower = args.optBoolean(1, true) val cpuName = args.optString(2, "") val cpu = if (!cpuName.isEmpty()) { - controller.getProxy.getCrafting.getCpus.collectFirst({ + craftingGrid.getCpus.collectFirst({ case c if cpuName.equals(c.getName()) => c }).orNull } else null @@ -208,7 +215,7 @@ object NetworkControl { override def load(nbt: NBTTagCompound) { super.load(nbt) - stack = AEItemStack.loadItemStackFromNBT(nbt) + stack = AEApi.instance().storage().createItemStack(ItemStack.loadItemStackFromNBT(nbt)) if (nbt.hasKey("dimension")) { val dimension = nbt.getInteger("dimension") val x = nbt.getInteger("x") @@ -216,9 +223,9 @@ object NetworkControl { val z = nbt.getInteger("z") EventHandler.scheduleServer(() => { val world = DimensionManager.getWorld(dimension) - val tileEntity = world.getTileEntity(x, y, z) - if (tileEntity != null && tileEntity.isInstanceOf[TileEntity with IGridProxyable with IActionHost]) { - controller = tileEntity.asInstanceOf[TileEntity with IGridProxyable with IActionHost] + val tileEntity = world.getTileEntity(new BlockPos(x, y, z)) + if (tileEntity != null && tileEntity.isInstanceOf[TileEntity with IActionHost]) { + controller = tileEntity.asInstanceOf[TileEntity with IActionHost] } }) } @@ -228,14 +235,18 @@ object NetworkControl { override def save(nbt: NBTTagCompound) { super.save(nbt) - stack.writeToNBT(nbt) + stack.getItemStack.writeToNBT(nbt) if (controller != null && !controller.isInvalid) { - nbt.setInteger("dimension", controller.getWorldObj.provider.dimensionId) - nbt.setInteger("x", controller.xCoord) - nbt.setInteger("y", controller.yCoord) - nbt.setInteger("z", controller.zCoord) + nbt.setInteger("dimension", controller.getWorld.provider.getDimension) + nbt.setInteger("x", controller.getPos.getX) + nbt.setInteger("y", controller.getPos.getY) + nbt.setInteger("z", controller.getPos.getZ) } - nbt.setNewTagList("links", links.map(_.writeToNBT _)) + nbt.setNewTagList("links", links.map((link) => { + val comp = new NBTTagCompound() + link.writeToNBT(comp) + comp + })) } } diff --git a/src/main/scala/li/cil/oc/integration/appeng/PartEnvironmentBase.scala b/src/main/scala/li/cil/oc/integration/appeng/PartEnvironmentBase.scala index 15c1334e7..24fdb1403 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/PartEnvironmentBase.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/PartEnvironmentBase.scala @@ -1,5 +1,7 @@ package li.cil.oc.integration.appeng +import appeng.api.implementations.tiles.ISegmentedInventory +import appeng.api.parts.IPartHost import li.cil.oc.api.internal.Database import li.cil.oc.api.machine.Arguments import li.cil.oc.api.machine.Context