Merge branch 'master-MC1.10' of https://github.com/28Smiles/OpenComputers into 28Smiles-master-MC1.10

This commit is contained in:
Florian Nücke 2017-09-09 20:10:03 +02:00
commit 4f939ac99f
13 changed files with 202 additions and 213 deletions

View File

@ -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/**'

View File

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

Binary file not shown.

View File

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

View File

@ -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] )
}

View File

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

View File

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

View File

@ -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")
}
}

View File

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

View File

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

View File

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

View File

@ -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
}))
}
}

View File

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