diff --git a/src/main/resources/assets/opencomputers/lang/en_US.lang b/src/main/resources/assets/opencomputers/lang/en_US.lang index 5241900ea..de7da1a09 100644 --- a/src/main/resources/assets/opencomputers/lang/en_US.lang +++ b/src/main/resources/assets/opencomputers/lang/en_US.lang @@ -37,6 +37,7 @@ item.oc.AbstractBusCard.name=Abstract Bus Card item.oc.Acid.name=Grog item.oc.ALU.name=Arithmetic Logic Unit (ALU) item.oc.Analyzer.name=Analyzer +item.oc.AppengTunnel.name=P2P Tunnel - OpenComputers item.oc.ArrowKeys.name=Arrow Keys item.oc.ButtonGroup.name=Button Group item.oc.CardBase.name=Card Base diff --git a/src/main/resources/assets/opencomputers/recipes/default.recipes b/src/main/resources/assets/opencomputers/recipes/default.recipes index 79a01554c..388cd2a96 100644 --- a/src/main/resources/assets/opencomputers/recipes/default.recipes +++ b/src/main/resources/assets/opencomputers/recipes/default.recipes @@ -496,3 +496,8 @@ screen3 { [yellowDust, "oc:circuitChip3", glass] [obsidian, yellowDust, obsidian]] } + +appengTunnel { + type: shapeless + input: [{item="appliedenergistics2:item.ItemMultiPart", subID=460}, "oc:adapter"] +} diff --git a/src/main/scala/li/cil/oc/client/Proxy.scala b/src/main/scala/li/cil/oc/client/Proxy.scala index 354184880..fbd63e85a 100644 --- a/src/main/scala/li/cil/oc/client/Proxy.scala +++ b/src/main/scala/li/cil/oc/client/Proxy.scala @@ -1,5 +1,6 @@ package li.cil.oc.client +import appeng.client.render.BusRenderer import cpw.mods.fml.client.registry.ClientRegistry import cpw.mods.fml.client.registry.RenderingRegistry import cpw.mods.fml.common.FMLCommonHandler @@ -9,6 +10,7 @@ import cpw.mods.fml.common.event.FMLPreInitializationEvent import cpw.mods.fml.common.network.NetworkRegistry import li.cil.oc.OpenComputers import li.cil.oc.Settings +import li.cil.oc.api import li.cil.oc.client import li.cil.oc.client.renderer.PetRenderer import li.cil.oc.client.renderer.TextBufferRenderCache @@ -21,6 +23,7 @@ import li.cil.oc.common.init.Items import li.cil.oc.common.tileentity import li.cil.oc.common.tileentity.ServerRack import li.cil.oc.common.{Proxy => CommonProxy} +import li.cil.oc.integration.Mods import li.cil.oc.util.Audio import net.minecraftforge.client.MinecraftForgeClient import net.minecraftforge.common.MinecraftForge @@ -61,6 +64,9 @@ private[oc] class Proxy extends CommonProxy { ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Screen], ScreenRenderer) MinecraftForgeClient.registerItemRenderer(Items.multi, ItemRenderer) + if (Mods.AppliedEnergistics2.isAvailable) { + MinecraftForgeClient.registerItemRenderer(api.Items.get("appengTunnel").item(), BusRenderer.instance) + } ClientRegistry.registerKeyBinding(KeyBindings.extendedTooltip) ClientRegistry.registerKeyBinding(KeyBindings.materialCosts) @@ -78,4 +84,4 @@ private[oc] class Proxy extends CommonProxy { FMLCommonHandler.instance.bus.register(PetRenderer) FMLCommonHandler.instance.bus.register(TextBufferRenderCache) } -} \ No newline at end of file +} diff --git a/src/main/scala/li/cil/oc/common/block/Item.scala b/src/main/scala/li/cil/oc/common/block/Item.scala index c8a7cc6e5..c5e1a481e 100644 --- a/src/main/scala/li/cil/oc/common/block/Item.scala +++ b/src/main/scala/li/cil/oc/common/block/Item.scala @@ -2,12 +2,12 @@ package li.cil.oc.common.block import java.util +import li.cil.oc.Settings +import li.cil.oc.api import li.cil.oc.client.KeyBindings import li.cil.oc.common.tileentity import li.cil.oc.util.ItemCosts import li.cil.oc.util.ItemUtils -import li.cil.oc.Settings -import li.cil.oc.api import net.minecraft.block.Block import net.minecraft.entity.player.EntityPlayer import net.minecraft.item.EnumRarity diff --git a/src/main/scala/li/cil/oc/common/init/Items.scala b/src/main/scala/li/cil/oc/common/init/Items.scala index 5b64a1def..80e1da5c4 100644 --- a/src/main/scala/li/cil/oc/common/init/Items.scala +++ b/src/main/scala/li/cil/oc/common/init/Items.scala @@ -35,8 +35,10 @@ object Items extends ItemAPI { } def registerBlock[T <: Block](instance: T, id: String) = { - instance.setBlockName("oc." + id) - GameRegistry.registerBlock(instance, classOf[common.block.Item], id) + if (instance.getClass.getName.startsWith("li.cil.oc.")) { + instance.setBlockName("oc." + id) + GameRegistry.registerBlock(instance, classOf[common.block.Item], id) + } descriptors += id -> new ItemInfo { override def name = id @@ -65,6 +67,10 @@ object Items extends ItemAPI { } def registerItem(instance: Item, id: String) = { + if (instance.getClass.getName.startsWith("li.cil.oc.")) { + instance.setUnlocalizedName("oc." + id.capitalize) + GameRegistry.registerItem(instance, id) + } descriptors += id -> new ItemInfo { override def name = id @@ -256,5 +262,10 @@ object Items extends ItemAPI { Recipes.addItem(new item.UpgradeDatabase(multi, Tier.Two), "databaseUpgrade2", "oc:databaseUpgrade2") Recipes.addItem(new item.UpgradeDatabase(multi, Tier.Three), "databaseUpgrade3", "oc:databaseUpgrade3") registerItem(new item.Debugger(multi), "debugger") + + // 1.4.2 + if (Mods.AppliedEnergistics2.isAvailable) { + Recipes.addItem(new item.AppliedEnergisticsP2PTunnel(), "appengTunnel") + } } -} \ No newline at end of file +} diff --git a/src/main/scala/li/cil/oc/common/item/AppliedEnergisticsP2PTunnel.scala b/src/main/scala/li/cil/oc/common/item/AppliedEnergisticsP2PTunnel.scala new file mode 100644 index 000000000..b7cfb3704 --- /dev/null +++ b/src/main/scala/li/cil/oc/common/item/AppliedEnergisticsP2PTunnel.scala @@ -0,0 +1,30 @@ +package li.cil.oc.common.item + +import appeng.api.AEApi +import appeng.api.parts.IPartItem +import appeng.core.CreativeTab +import cpw.mods.fml.relauncher.Side +import cpw.mods.fml.relauncher.SideOnly +import li.cil.oc.api +import li.cil.oc.integration.appeng.PartP2POCNode +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.item.Item +import net.minecraft.item.ItemStack +import net.minecraft.world.World + +class AppliedEnergisticsP2PTunnel extends Item with IPartItem { + override def createPartFromItemStack(stack: ItemStack) = new PartP2POCNode(stack) + + override def onItemUse(stack: ItemStack, player: EntityPlayer, world: World, x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float) = + AEApi.instance().partHelper().placeBus(stack, x, y, z, side, player, world) || super.onItemUse(stack, player, world, x, y, z, side, hitX, hitY, hitZ) + + @SideOnly(Side.CLIENT) + override def getSpriteNumber = 0 + + @SideOnly(Side.CLIENT) + override def getIconFromDamage(damage: Int) = api.Items.get("adapter").block().getIcon(2, 0) + + // Override instead of setting manually to be independent of load order. + @SideOnly(Side.CLIENT) + override def getCreativeTab = CreativeTab.instance +} diff --git a/src/main/scala/li/cil/oc/integration/Mods.scala b/src/main/scala/li/cil/oc/integration/Mods.scala index c3707b455..5e05501b6 100644 --- a/src/main/scala/li/cil/oc/integration/Mods.scala +++ b/src/main/scala/li/cil/oc/integration/Mods.scala @@ -19,7 +19,7 @@ object Mods { def All = knownMods.clone() - val AppliedEnergistics2 = new SimpleMod(IDs.AppliedEnergistics2, version = "@[rv1,)") + val AppliedEnergistics2 = new SimpleMod(IDs.AppliedEnergistics2, version = "@[rv1,)", providesPower = true) val BattleGear2 = new SimpleMod(IDs.BattleGear2) val BuildCraft = new SimpleMod(IDs.BuildCraft) val BuildCraftTiles = new SimpleMod(IDs.BuildCraftTiles) diff --git a/src/main/scala/li/cil/oc/integration/appeng/LayerSidedEnvironment.scala b/src/main/scala/li/cil/oc/integration/appeng/LayerSidedEnvironment.scala new file mode 100644 index 000000000..dfb4ac581 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/appeng/LayerSidedEnvironment.scala @@ -0,0 +1,17 @@ +package li.cil.oc.integration.appeng + +import appeng.api.parts.LayerBase +import li.cil.oc.api.network._ +import net.minecraftforge.common.util.ForgeDirection + +class LayerSidedEnvironment extends LayerBase with SidedEnvironment { + override def sidedNode(side: ForgeDirection) = getPart(side) match { + case env: SidedEnvironment => env.sidedNode(side) + case _ => null + } + + override def canConnect(side: ForgeDirection) = getPart(side) match { + case env: SidedEnvironment => env.canConnect(side) + case _ => false + } +} diff --git a/src/main/scala/li/cil/oc/integration/appeng/ModAppEng.scala b/src/main/scala/li/cil/oc/integration/appeng/ModAppEng.scala index de20fd1b3..5b63c1673 100644 --- a/src/main/scala/li/cil/oc/integration/appeng/ModAppEng.scala +++ b/src/main/scala/li/cil/oc/integration/appeng/ModAppEng.scala @@ -1,5 +1,6 @@ package li.cil.oc.integration.appeng +import appeng.api.AEApi import li.cil.oc.api.Driver import li.cil.oc.integration.ModProxy import li.cil.oc.integration.Mods @@ -8,9 +9,11 @@ object ModAppEng extends ModProxy { override def getMod = Mods.AppliedEnergistics2 override def initialize() { + AEApi.instance().partHelper().registerNewLayer("li.cil.oc.integration.appeng.LayerSidedEnvironment", "li.cil.oc.api.network.SidedEnvironment") + Driver.add(DriverController) Driver.add(DriverExportBus) Driver.add(new ConverterCellInventory) } -} \ No newline at end of file +} diff --git a/src/main/scala/li/cil/oc/integration/appeng/PartP2POCNode.scala b/src/main/scala/li/cil/oc/integration/appeng/PartP2POCNode.scala new file mode 100644 index 000000000..65bdaf47e --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/appeng/PartP2POCNode.scala @@ -0,0 +1,80 @@ +package li.cil.oc.integration.appeng + +import appeng.api.config.TunnelType +import appeng.parts.p2p.PartP2PTunnel +import cpw.mods.fml.relauncher.Side +import cpw.mods.fml.relauncher.SideOnly +import li.cil.oc.api +import li.cil.oc.api.network._ +import li.cil.oc.common.EventHandler +import net.minecraft.item.ItemStack +import net.minecraft.nbt.NBTTagCompound +import net.minecraftforge.common.util.ForgeDirection + +class PartP2POCNode(stack: ItemStack) extends PartP2PTunnel[PartP2POCNode](stack) with Environment with SidedEnvironment { + val node = api.Network.newNode(this, Visibility.None).create() + api.Network.joinNewNetwork(node) + + var input: Option[Node] = None + + // ----------------------------------------------------------------------- // + + override def onConnect(node: Node) {} + + override def onMessage(message: Message) {} + + override def onDisconnect(node: Node) {} + + override def sidedNode(side: ForgeDirection) = if (proxy.isActive) node else null + + @SideOnly(Side.CLIENT) + override def canConnect(side: ForgeDirection) = true + + // ----------------------------------------------------------------------- // + + // TODO Never called, might as well return null. May have to, if enum gets removed. + override def getTunnelType = TunnelType.COMPUTER_MESSAGE + + @SideOnly(Side.CLIENT) + override def getTypeTexture = api.Items.get("adapter").block().getIcon(2, 0) + + // ----------------------------------------------------------------------- // + + override def onTunnelNetworkChange() { + super.onTunnelNetworkChange() + if (node != null) { + input.foreach(in => if (in != node) node.disconnect(in)) + input = None + if (output) { + Option(getInput) match { + case Some(part) => + input = Option(part.node) + input.foreach(node.connect) + case _ => + } + } + } + } + + override def addToWorld() { + super.addToWorld() + EventHandler.schedule(() => api.Network.joinOrCreateNetwork(getHost.getTile)) + } + + override def removeFromWorld() { + super.removeFromWorld() + if (node != null) node.remove() + } + + // ----------------------------------------------------------------------- // + + override def readFromNBT(data: NBTTagCompound) { + super.readFromNBT(data) + node.load(data) + } + + override def writeToNBT(data: NBTTagCompound) { + super.writeToNBT(data) + node.save(data) + } +} diff --git a/src/main/scala/li/cil/oc/server/network/Component.scala b/src/main/scala/li/cil/oc/server/network/Component.scala index 60615bb98..5625134d7 100644 --- a/src/main/scala/li/cil/oc/server/network/Component.scala +++ b/src/main/scala/li/cil/oc/server/network/Component.scala @@ -129,4 +129,6 @@ trait Component extends network.Component with Node { super.save(nbt) nbt.setInteger("visibility", _visibility.ordinal()) } + + override def toString = super.toString + s"@$name" } \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/server/network/Network.scala b/src/main/scala/li/cil/oc/server/network/Network.scala index 02a112d15..506ec5476 100644 --- a/src/main/scala/li/cil/oc/server/network/Network.scala +++ b/src/main/scala/li/cil/oc/server/network/Network.scala @@ -10,10 +10,10 @@ import li.cil.oc.Settings import li.cil.oc.api import li.cil.oc.api.network import li.cil.oc.api.network.Environment +import li.cil.oc.api.network.SidedEnvironment import li.cil.oc.api.network.Visibility import li.cil.oc.api.network.WirelessEndpoint import li.cil.oc.api.network.{Node => ImmutableNode} -import li.cil.oc.api.network.SidedEnvironment import li.cil.oc.api.network.{Node => ImmutableNode} import li.cil.oc.common.block.Cable import li.cil.oc.common.tileentity @@ -600,6 +600,8 @@ object Network extends api.detail.NetworkAPI { edges.foreach(edge => edge.other(this).edges -= edge) searchGraphs(edges.map(_.other(this))) } + + override def toString = s"$data [${edges.length}]" } private case class Edge(left: Vertex, right: Vertex) { diff --git a/src/main/scala/li/cil/oc/server/network/Node.scala b/src/main/scala/li/cil/oc/server/network/Node.scala index 12da4f88f..8f3ac128f 100644 --- a/src/main/scala/li/cil/oc/server/network/Node.scala +++ b/src/main/scala/li/cil/oc/server/network/Node.scala @@ -80,6 +80,8 @@ trait Node extends ImmutableNode { nbt.setString("address", address) } } + + override def toString = s"Node($address, $host)" } // We have to mixin the vararg methods individually in the actual