From e90c9ade09115e54b08c46da9f397b622c186969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sun, 27 Mar 2016 18:18:36 +0200 Subject: [PATCH] Basic MCMP integration for cables. --- build.gradle | 7 +- build.properties | 1 + .../oc/client/renderer/block/CableModel.scala | 6 +- .../scala/li/cil/oc/integration/Mods.scala | 3 + .../cil/oc/integration/mcmp/MCMultiPart.scala | 71 +++++++ .../oc/integration/mcmp/ModMCMultiPart.scala | 12 ++ .../cil/oc/integration/mcmp/PartCable.scala | 180 ++++++++++++++++++ .../oc/integration/mcmp/PartCableModel.scala | 31 +++ .../mcmp/PartCapabilityColored.scala | 32 ++++ .../mcmp/PartCapabilityEnvironment.scala | 36 ++++ .../mcmp/PartCapabilitySidedComponent.scala | 32 ++++ .../mcmp/PartCapabilitySidedEnvironment.scala | 30 +++ .../oc/integration/mcmp/PartConverter.scala | 55 ++++++ .../oc/integration/mcmp/PartProvider.scala | 31 +++ .../oc/integration/mcmp/WrapperColored.scala | 14 ++ .../integration/mcmp/WrapperEnvironment.scala | 14 ++ .../mcmp/WrapperSidedEnvironment.scala | 14 ++ 17 files changed, 567 insertions(+), 2 deletions(-) create mode 100644 src/main/scala/li/cil/oc/integration/mcmp/MCMultiPart.scala create mode 100644 src/main/scala/li/cil/oc/integration/mcmp/ModMCMultiPart.scala create mode 100644 src/main/scala/li/cil/oc/integration/mcmp/PartCable.scala create mode 100644 src/main/scala/li/cil/oc/integration/mcmp/PartCableModel.scala create mode 100644 src/main/scala/li/cil/oc/integration/mcmp/PartCapabilityColored.scala create mode 100644 src/main/scala/li/cil/oc/integration/mcmp/PartCapabilityEnvironment.scala create mode 100644 src/main/scala/li/cil/oc/integration/mcmp/PartCapabilitySidedComponent.scala create mode 100644 src/main/scala/li/cil/oc/integration/mcmp/PartCapabilitySidedEnvironment.scala create mode 100644 src/main/scala/li/cil/oc/integration/mcmp/PartConverter.scala create mode 100644 src/main/scala/li/cil/oc/integration/mcmp/PartProvider.scala create mode 100644 src/main/scala/li/cil/oc/integration/mcmp/WrapperColored.scala create mode 100644 src/main/scala/li/cil/oc/integration/mcmp/WrapperEnvironment.scala create mode 100644 src/main/scala/li/cil/oc/integration/mcmp/WrapperSidedEnvironment.scala diff --git a/build.gradle b/build.gradle index f90b0f080..9f078d374 100644 --- a/build.gradle +++ b/build.gradle @@ -80,9 +80,13 @@ repositories { url = "http://mobiusstrip.eu/maven" } ivy { - name 'ComputerCraft' + name = "ComputerCraft" artifactPattern "http://addons-origin.cursecdn.com/files/${config.cc.cf}/[module][revision].[ext]" } + maven { + name = "MCMP" + url "http://maven.amadornes.com/" + } /* maven { name = "BluePower" @@ -181,6 +185,7 @@ dependencies { deobfCompile "mezz.jei:jei_1.8.9:${config.jei.version}" deobfCompile "li.cil.tis3d:TIS-3D:${config.tis3d.version}" deobfCompile "mcp.mobius.waila:Waila:${config.waila.version}" + deobfCompile "MCMultiPart:MCMultiPart:${config.mcmp.version}:universal" /* provided "codechicken:CodeChickenCore:${config.minecraft.version}-${config.ccc.version}:dev" provided "codechicken:CodeChickenLib:${config.minecraft.version}-${config.ccl.version}:dev" diff --git a/build.properties b/build.properties index 44767380d..7effd29dc 100644 --- a/build.properties +++ b/build.properties @@ -30,6 +30,7 @@ gt.version=5.04.06 ic2.version=2.2.654-experimental igwmod.version=1.1.3-18 jei.version=2.28.7.174 +mcmp.version=1.0.8 mekanism.build=5 mekanism.version=7.1.2 mfr.cf=2229/626 diff --git a/src/main/scala/li/cil/oc/client/renderer/block/CableModel.scala b/src/main/scala/li/cil/oc/client/renderer/block/CableModel.scala index 21aa6d66f..84ce18e59 100644 --- a/src/main/scala/li/cil/oc/client/renderer/block/CableModel.scala +++ b/src/main/scala/li/cil/oc/client/renderer/block/CableModel.scala @@ -4,6 +4,8 @@ import li.cil.oc.client.Textures import li.cil.oc.common.block import li.cil.oc.common.block.Cable import li.cil.oc.common.tileentity +import li.cil.oc.integration.Mods +import li.cil.oc.integration.mcmp.PartCableModel import li.cil.oc.util.BlockPosition import li.cil.oc.util.Color import li.cil.oc.util.ExtendedWorld._ @@ -35,7 +37,9 @@ object CableModel extends SmartBlockModelBase with ISmartItemModel { } override def handleBlockState(state: IBlockState) = state match { - case extended: IExtendedBlockState => new BlockModel(extended) + case extended: IExtendedBlockState => + if (Mods.MCMultiPart.isAvailable) new PartCableModel.BlockModel(extended) + else new BlockModel(extended) case _ => missingModel } diff --git a/src/main/scala/li/cil/oc/integration/Mods.scala b/src/main/scala/li/cil/oc/integration/Mods.scala index cc73c6619..19232d4c6 100644 --- a/src/main/scala/li/cil/oc/integration/Mods.scala +++ b/src/main/scala/li/cil/oc/integration/Mods.scala @@ -52,6 +52,7 @@ object Mods { val IndustrialCraft2Classic = new SimpleMod(IDs.IndustrialCraft2Classic, providesPower = true) val IngameWiki = new SimpleMod(IDs.IngameWiki, version = "@[1.1.3,)") val JustEnoughItems = new SimpleMod(IDs.JustEnoughItems) + val MCMultiPart = new SimpleMod(IDs.MCMultiPart) val Mekanism = new SimpleMod(IDs.Mekanism, providesPower = true) val MekanismGas = new SimpleMod(IDs.MekanismGas) val Minecraft = new SimpleMod(IDs.Minecraft) @@ -114,6 +115,7 @@ object Mods { // integration.gc.ModGalacticraft, // integration.gregtech.ModGregtech, // integration.ic2.ModIndustrialCraft2, + integration.mcmp.ModMCMultiPart, // integration.mekanism.ModMekanism, // integration.mekanism.gas.ModMekanismGas, // integration.mfr.ModMineFactoryReloaded, @@ -204,6 +206,7 @@ object Mods { final val IndustrialCraft2Classic = "IC2-Classic" final val IngameWiki = "IGWMod" final val JustEnoughItems = "JEI" + final val MCMultiPart = "mcmultipart" final val Mekanism = "Mekanism" final val MekanismGas = "MekanismAPI|gas" final val Minecraft = "Minecraft" diff --git a/src/main/scala/li/cil/oc/integration/mcmp/MCMultiPart.scala b/src/main/scala/li/cil/oc/integration/mcmp/MCMultiPart.scala new file mode 100644 index 000000000..41c514baf --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/mcmp/MCMultiPart.scala @@ -0,0 +1,71 @@ +package li.cil.oc.integration.mcmp + +import li.cil.oc.Constants +import li.cil.oc.Settings +import li.cil.oc.api +import li.cil.oc.api.internal.Colored +import li.cil.oc.api.network.Environment +import li.cil.oc.api.network.SidedComponent +import li.cil.oc.api.network.SidedEnvironment +import mcmultipart.capabilities.CapabilityWrapperRegistry +import mcmultipart.capabilities.PartAttachCapabilitiesEvent +import mcmultipart.item.PartPlacementWrapper +import mcmultipart.multipart.IMultipart +import mcmultipart.multipart.MultipartRegistry +import net.minecraft.client.resources.model.IBakedModel +import net.minecraft.client.resources.model.ModelResourceLocation +import net.minecraft.util.RegistrySimple +import net.minecraftforge.client.event.ModelBakeEvent +import net.minecraftforge.common.MinecraftForge +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +object MCMultiPart { + final val CableMultipartLocation = Settings.resourceDomain + ":" + "multipart_" + Constants.BlockName.Cable + final val CableMultipartVariantLocation = new ModelResourceLocation(CableMultipartLocation, "multipart") + + def init(): Unit = { + MultipartRegistry.registerPart(classOf[PartCable], PartProvider.PartTypeCable) + MultipartRegistry.registerPartFactory(PartProvider, PartProvider.PartTypeCable) + MultipartRegistry.registerPartConverter(PartConverter) + MultipartRegistry.registerReversePartConverter(PartConverter) + + CapabilityWrapperRegistry.registerCapabilityWrapper(WrapperColored) + CapabilityWrapperRegistry.registerCapabilityWrapper(WrapperEnvironment) + CapabilityWrapperRegistry.registerCapabilityWrapper(WrapperSidedEnvironment) + + val placementWrapper = new PartPlacementWrapper(api.Items.get(Constants.BlockName.Cable).createItemStack(1), PartProvider) + placementWrapper.register(PartProvider.PartTypeCable) + + MinecraftForge.EVENT_BUS.register(this) + } + + @SubscribeEvent + def onModelBake(e: ModelBakeEvent): Unit = { + val registry = e.modelRegistry.asInstanceOf[RegistrySimple[ModelResourceLocation, IBakedModel]] + + registry.putObject(CableMultipartVariantLocation, PartCableModel) + } + + @SubscribeEvent + def onAttachPartCapabilities(event: PartAttachCapabilitiesEvent): Unit = { + event.getPart match { + case part: IMultipart with Environment => + event.addCapability(PartCapabilityEnvironment.PartProviderEnvironment, new PartCapabilityEnvironment.Provider(part)) + case _ => + } + + event.getPart match { + case part: IMultipart with Environment with SidedComponent => + event.addCapability(PartCapabilitySidedComponent.PartSidedComponent, new PartCapabilitySidedComponent.Provider(part)) + case part: IMultipart with SidedEnvironment => + event.addCapability(PartCapabilitySidedEnvironment.PartProviderSidedEnvironment, new PartCapabilitySidedEnvironment.Provider(part)) + case _ => + } + + event.getPart match { + case part: IMultipart with Colored => + event.addCapability(PartCapabilityColored.PartProviderColored, new PartCapabilityColored.Provider(part)) + case _ => + } + } +} diff --git a/src/main/scala/li/cil/oc/integration/mcmp/ModMCMultiPart.scala b/src/main/scala/li/cil/oc/integration/mcmp/ModMCMultiPart.scala new file mode 100644 index 000000000..5d2aa6a16 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/mcmp/ModMCMultiPart.scala @@ -0,0 +1,12 @@ +package li.cil.oc.integration.mcmp + +import li.cil.oc.integration.ModProxy +import li.cil.oc.integration.Mods + +object ModMCMultiPart extends ModProxy { + override def getMod = Mods.MCMultiPart + + override def initialize(): Unit = { + MCMultiPart.init() + } +} diff --git a/src/main/scala/li/cil/oc/integration/mcmp/PartCable.scala b/src/main/scala/li/cil/oc/integration/mcmp/PartCable.scala new file mode 100644 index 000000000..50ecc9142 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/mcmp/PartCable.scala @@ -0,0 +1,180 @@ +package li.cil.oc.integration.mcmp + +import java.util + +import li.cil.oc.Constants +import li.cil.oc.api +import li.cil.oc.api.internal.Colored +import li.cil.oc.api.network.Environment +import li.cil.oc.api.network.Message +import li.cil.oc.api.network.Node +import li.cil.oc.common.block.Cable +import li.cil.oc.common.block.property +import li.cil.oc.common.tileentity +import li.cil.oc.util.Color +import mcmultipart.multipart.ISlottedPart +import mcmultipart.multipart.Multipart +import mcmultipart.multipart.PartSlot +import mcmultipart.raytrace.PartMOP +import net.minecraft.block.material.Material +import net.minecraft.block.state.BlockState +import net.minecraft.block.state.IBlockState +import net.minecraft.entity.Entity +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.item.ItemStack +import net.minecraft.nbt.NBTTagCompound +import net.minecraft.network.PacketBuffer +import net.minecraft.tileentity.TileEntity +import net.minecraft.util.AxisAlignedBB +import net.minecraftforge.common.property.IExtendedBlockState +import net.minecraftforge.common.property.ExtendedBlockState + +class PartCable extends Multipart with ISlottedPart with Environment with Colored { + final val CableDefinition = api.Items.get(Constants.BlockName.Cable) + final val CableBlock = CableDefinition.block() + + val wrapped = new tileentity.Cable() + + // ----------------------------------------------------------------------- // + // Environment + + override def node(): Node = wrapped.node + + override def onMessage(message: Message): Unit = wrapped.onMessage(message) + + override def onConnect(node: Node): Unit = wrapped.onConnect(node) + + override def onDisconnect(node: Node): Unit = wrapped.onDisconnect(node) + + // ----------------------------------------------------------------------- // + // Colored + + override def getColor = wrapped.getColor + + override def setColor(value: Int): Unit = { + if (value != getColor) { + wrapped.setColor(value) + if (getWorld != null && !getWorld.isRemote) { + sendUpdatePacket(true) + } + } + } + + override def controlsConnectivity = wrapped.controlsConnectivity + + // ----------------------------------------------------------------------- // + // ISlottedPart + + override def getSlotMask: util.EnumSet[PartSlot] = util.EnumSet.of(PartSlot.CENTER) + + // ----------------------------------------------------------------------- // + // IMultipart + + override def addSelectionBoxes(list: util.List[AxisAlignedBB]): Unit = { + if (getWorld != null) { + list.add(Cable.bounds(getWorld, getPos)) + } + } + + override def addCollisionBoxes(mask: AxisAlignedBB, list: util.List[AxisAlignedBB], collidingEntity: Entity): Unit = { + if (getWorld != null) { + list.add(Cable.bounds(getWorld, getPos)) //.offset(getPos.getX, getPos.getY, getPos.getZ)) + } + } + + override def getPickBlock(player: EntityPlayer, hit: PartMOP): ItemStack = wrapped.createItemStack() + + override def getDrops: util.List[ItemStack] = util.Arrays.asList(wrapped.createItemStack()) + + override def getHardness(hit: PartMOP): Float = CableBlock.getBlockHardness(getWorld, getPos) + + override def getMaterial: Material = CableBlock.getMaterial + + override def isToolEffective(toolType: String, level: Int): Boolean = CableBlock.isToolEffective(toolType, getWorld.getBlockState(getPos)) + + // ----------------------------------------------------------------------- // + + override def getModelPath = MCMultiPart.CableMultipartLocation + + override def createBlockState(): BlockState = new ExtendedBlockState(CableBlock, Array.empty, Array(property.PropertyTile.Tile)) + + override def getExtendedState(state: IBlockState): IBlockState = + state match { + case extendedState: IExtendedBlockState => + wrapped.setWorldObj(getWorld) + wrapped.setPos(getPos) + extendedState.withProperty(property.PropertyTile.Tile, wrapped) + case _ => state + } + + override def onAdded(): Unit = { + super.onAdded() + wrapped.validate() + wrapped.setWorldObj(getWorld) + wrapped.setPos(getPos) + } + + override def onRemoved(): Unit = { + super.onRemoved() + wrapped.invalidate() + wrapped.setWorldObj(null) + wrapped.setPos(null) + } + + override def onLoaded(): Unit = { + super.onLoaded() + wrapped.validate() + wrapped.setWorldObj(getWorld) + wrapped.setPos(getPos) + } + + override def onUnloaded(): Unit = { + super.onUnloaded() + wrapped.invalidate() + wrapped.setWorldObj(null) + wrapped.setPos(null) + } + + override def onConverted(tile: TileEntity): Unit = { + super.onConverted(tile) + val nbt = new NBTTagCompound() + tile.writeToNBT(nbt) + wrapped.readFromNBT(nbt) + } + + // ----------------------------------------------------------------------- // + + override def onActivated(player: EntityPlayer, heldItem: ItemStack, hit: PartMOP): Boolean = { + if (Color.isDye(heldItem)) { + setColor(Color.rgbValues(Color.dyeColor(player.getHeldItem))) + markDirty() + if (!player.capabilities.isCreativeMode && wrapped.consumesDye) { + player.getHeldItem.splitStack(1) + } + true + } + else super.onActivated(player, heldItem, hit) + } + + // ----------------------------------------------------------------------- // + + override def writeToNBT(tag: NBTTagCompound): Unit = { + super.writeToNBT(tag) + wrapped.writeToNBT(tag) + } + + override def readFromNBT(tag: NBTTagCompound): Unit = { + super.readFromNBT(tag) + wrapped.readFromNBT(tag) + } + + override def writeUpdatePacket(buf: PacketBuffer): Unit = { + super.writeUpdatePacket(buf) + buf.writeInt(getColor) + } + + override def readUpdatePacket(buf: PacketBuffer): Unit = { + super.readUpdatePacket(buf) + setColor(buf.readInt()) + } +} diff --git a/src/main/scala/li/cil/oc/integration/mcmp/PartCableModel.scala b/src/main/scala/li/cil/oc/integration/mcmp/PartCableModel.scala new file mode 100644 index 000000000..576927fc1 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/mcmp/PartCableModel.scala @@ -0,0 +1,31 @@ +package li.cil.oc.integration.mcmp + +import li.cil.oc.client.renderer.block.CableModel +import li.cil.oc.client.renderer.block.SmartBlockModelBase +import li.cil.oc.util.BlockPosition +import mcmultipart.client.multipart.ISmartMultipartModel +import mcmultipart.multipart.MultipartHelper +import mcmultipart.multipart.PartSlot +import net.minecraft.block.state.IBlockState +import net.minecraft.client.resources.model.IBakedModel +import net.minecraftforge.common.property.IExtendedBlockState + +object PartCableModel extends SmartBlockModelBase with ISmartMultipartModel { + override def handlePartState(state: IBlockState): IBakedModel = state match { + case extended: IExtendedBlockState => new BlockModel(extended) + case _ => missingModel + } + + class BlockModel(state: IExtendedBlockState) extends CableModel.BlockModel(state) { + override protected def isCable(pos: BlockPosition): Boolean = super.isCable(pos) || (pos.world match { + case Some(world) => + val container = MultipartHelper.getPartContainer(world, pos.toBlockPos) + (container != null) && (container.getPartInSlot(PartSlot.CENTER) match { + case cable: PartCable => true + case _ => false + }) + case _ => false + }) + } + +} diff --git a/src/main/scala/li/cil/oc/integration/mcmp/PartCapabilityColored.scala b/src/main/scala/li/cil/oc/integration/mcmp/PartCapabilityColored.scala new file mode 100644 index 000000000..19639de40 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/mcmp/PartCapabilityColored.scala @@ -0,0 +1,32 @@ +package li.cil.oc.integration.mcmp + +import li.cil.oc.api.internal.Colored +import li.cil.oc.common.capabilities.Capabilities +import li.cil.oc.integration.Mods +import mcmultipart.multipart.IMultipart +import net.minecraft.util.EnumFacing +import net.minecraft.util.ResourceLocation +import net.minecraftforge.common.capabilities.Capability +import net.minecraftforge.common.capabilities.ICapabilityProvider + +object PartCapabilityColored { + final val PartProviderColored = new ResourceLocation(Mods.IDs.OpenComputers, "part_colored") + + class Provider(val part: IMultipart with Colored) extends ICapabilityProvider with Colored { + override def hasCapability(capability: Capability[_], facing: EnumFacing): Boolean = { + capability == Capabilities.ColoredCapability + } + + override def getCapability[T](capability: Capability[T], facing: EnumFacing): T = { + if (hasCapability(capability, facing)) this.asInstanceOf[T] + else null.asInstanceOf[T] + } + + override def getColor = part.getColor + + override def setColor(value: Int) = part.setColor(value) + + override def controlsConnectivity = part.controlsConnectivity + } + +} diff --git a/src/main/scala/li/cil/oc/integration/mcmp/PartCapabilityEnvironment.scala b/src/main/scala/li/cil/oc/integration/mcmp/PartCapabilityEnvironment.scala new file mode 100644 index 000000000..51f4f686e --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/mcmp/PartCapabilityEnvironment.scala @@ -0,0 +1,36 @@ +package li.cil.oc.integration.mcmp + +import li.cil.oc.api.network.Environment +import li.cil.oc.api.network.Message +import li.cil.oc.api.network.Node +import li.cil.oc.common.capabilities.Capabilities +import li.cil.oc.integration.Mods +import mcmultipart.multipart.IMultipart +import net.minecraft.util.EnumFacing +import net.minecraft.util.ResourceLocation +import net.minecraftforge.common.capabilities.Capability +import net.minecraftforge.common.capabilities.ICapabilityProvider + +object PartCapabilityEnvironment { + final val PartProviderEnvironment = new ResourceLocation(Mods.IDs.OpenComputers, "part_environment") + + class Provider(val part: IMultipart with Environment) extends ICapabilityProvider with Environment { + override def hasCapability(capability: Capability[_], facing: EnumFacing): Boolean = { + capability == Capabilities.EnvironmentCapability + } + + override def getCapability[T](capability: Capability[T], facing: EnumFacing): T = { + if (hasCapability(capability, facing)) this.asInstanceOf[T] + else null.asInstanceOf[T] + } + + override def node = part.node + + override def onMessage(message: Message) = part.onMessage(message) + + override def onConnect(node: Node) = part.onConnect(node) + + override def onDisconnect(node: Node) = part.onDisconnect(node) + } + +} diff --git a/src/main/scala/li/cil/oc/integration/mcmp/PartCapabilitySidedComponent.scala b/src/main/scala/li/cil/oc/integration/mcmp/PartCapabilitySidedComponent.scala new file mode 100644 index 000000000..55d2d92e8 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/mcmp/PartCapabilitySidedComponent.scala @@ -0,0 +1,32 @@ +package li.cil.oc.integration.mcmp + +import li.cil.oc.api.network.Environment +import li.cil.oc.api.network.SidedComponent +import li.cil.oc.api.network.SidedEnvironment +import li.cil.oc.common.capabilities.Capabilities +import li.cil.oc.integration.Mods +import mcmultipart.multipart.IMultipart +import net.minecraft.util.EnumFacing +import net.minecraft.util.ResourceLocation +import net.minecraftforge.common.capabilities.Capability +import net.minecraftforge.common.capabilities.ICapabilityProvider + +object PartCapabilitySidedComponent { + final val PartSidedComponent = new ResourceLocation(Mods.IDs.OpenComputers, "part_sided_component") + + class Provider(val part: IMultipart with Environment with SidedComponent) extends ICapabilityProvider with SidedEnvironment { + override def hasCapability(capability: Capability[_], facing: EnumFacing): Boolean = { + capability == Capabilities.SidedEnvironmentCapability + } + + override def getCapability[T](capability: Capability[T], facing: EnumFacing): T = { + if (hasCapability(capability, facing)) this.asInstanceOf[T] + else null.asInstanceOf[T] + } + + override def sidedNode(side: EnumFacing) = if (part.canConnectNode(side)) part.node else null + + override def canConnect(side: EnumFacing) = part.canConnectNode(side) + } + +} diff --git a/src/main/scala/li/cil/oc/integration/mcmp/PartCapabilitySidedEnvironment.scala b/src/main/scala/li/cil/oc/integration/mcmp/PartCapabilitySidedEnvironment.scala new file mode 100644 index 000000000..26fe80a77 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/mcmp/PartCapabilitySidedEnvironment.scala @@ -0,0 +1,30 @@ +package li.cil.oc.integration.mcmp + +import li.cil.oc.api.network.SidedEnvironment +import li.cil.oc.common.capabilities.Capabilities +import li.cil.oc.integration.Mods +import mcmultipart.multipart.IMultipart +import net.minecraft.util.EnumFacing +import net.minecraft.util.ResourceLocation +import net.minecraftforge.common.capabilities.Capability +import net.minecraftforge.common.capabilities.ICapabilityProvider + +object PartCapabilitySidedEnvironment { + final val PartProviderSidedEnvironment = new ResourceLocation(Mods.IDs.OpenComputers, "sided_environment") + + class Provider(val part: IMultipart with SidedEnvironment) extends ICapabilityProvider with SidedEnvironment { + override def hasCapability(capability: Capability[_], facing: EnumFacing): Boolean = { + capability == Capabilities.SidedEnvironmentCapability + } + + override def getCapability[T](capability: Capability[T], facing: EnumFacing): T = { + if (hasCapability(capability, facing)) this.asInstanceOf[T] + else null.asInstanceOf[T] + } + + override def sidedNode(side: EnumFacing) = part.sidedNode(side) + + override def canConnect(side: EnumFacing) = part.canConnect(side) + } + +} diff --git a/src/main/scala/li/cil/oc/integration/mcmp/PartConverter.scala b/src/main/scala/li/cil/oc/integration/mcmp/PartConverter.scala new file mode 100644 index 000000000..27d9ef8cf --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/mcmp/PartConverter.scala @@ -0,0 +1,55 @@ +package li.cil.oc.integration.mcmp + +import java.util +import java.util.Collections + +import li.cil.oc.Constants +import li.cil.oc.api +import li.cil.oc.common.EventHandler +import li.cil.oc.common.tileentity.Cable +import li.cil.oc.server.PacketSender +import mcmultipart.multipart.IMultipart +import mcmultipart.multipart.IMultipartContainer +import mcmultipart.multipart.IPartConverter.IPartConverter2 +import mcmultipart.multipart.IPartConverter.IReversePartConverter +import net.minecraft.block.Block +import net.minecraft.util.BlockPos +import net.minecraft.world.IBlockAccess + +object PartConverter extends IPartConverter2 with IReversePartConverter { + final lazy val CableBlock = api.Items.get(Constants.BlockName.Cable).block() + + override def getConvertableBlocks: util.Collection[Block] = Collections.singletonList(CableBlock) + + override def convertBlock(world: IBlockAccess, pos: BlockPos, simulated: Boolean): util.Collection[_ <: IMultipart] = { + world.getTileEntity(pos) match { + case tileEntity: Cable => + val part = new PartCable() + part.setColor(tileEntity.getColor) + Collections.singletonList(part) + case _ => Collections.emptyList() + } + } + + override def convertToBlock(container: IMultipartContainer): Boolean = { + val parts = container.getParts + (parts.size() == 1) && (parts.iterator().next() match { + case part: PartCable => + // TODO Create temporary node bridging hole left by removing multipart, remove after tile entity creation? + val color = part.getColor + val world = container.getWorldIn + val pos = container.getPosIn + world.setBlockToAir(pos) + world.setBlockState(pos, CableBlock.getDefaultState) + world.getTileEntity(pos) match { + case tileEntity: Cable => + tileEntity.setColor(color) + EventHandler.scheduleServer(() => PacketSender.sendColorChange(tileEntity)) // HACKS! + case _ => + } + true + case _ => + false + }) + } +} diff --git a/src/main/scala/li/cil/oc/integration/mcmp/PartProvider.scala b/src/main/scala/li/cil/oc/integration/mcmp/PartProvider.scala new file mode 100644 index 000000000..eac749026 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/mcmp/PartProvider.scala @@ -0,0 +1,31 @@ +package li.cil.oc.integration.mcmp + +import li.cil.oc.Constants +import li.cil.oc.api +import li.cil.oc.integration.Mods +import mcmultipart.item.IItemMultipartFactory +import mcmultipart.multipart.IMultipart +import mcmultipart.multipart.IPartFactory +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.item.ItemStack +import net.minecraft.util.BlockPos +import net.minecraft.util.EnumFacing +import net.minecraft.util.Vec3 +import net.minecraft.world.World + +object PartProvider extends IPartFactory with IItemMultipartFactory { + final val PartTypeCable = Mods.IDs.OpenComputers + ":cable" + + final lazy val CableDescriptor = api.Items.get(Constants.BlockName.Cable) + + override def createPart(partType: String, client: Boolean): IMultipart = { + if (partType == PartTypeCable) new PartCable() + else null + } + + override def createPart(world: World, pos: BlockPos, side: EnumFacing, hit: Vec3, stack: ItemStack, player: EntityPlayer): IMultipart = { + val descriptor = api.Items.get(stack) + if (descriptor == CableDescriptor) new PartCable() + else null + } +} diff --git a/src/main/scala/li/cil/oc/integration/mcmp/WrapperColored.scala b/src/main/scala/li/cil/oc/integration/mcmp/WrapperColored.scala new file mode 100644 index 000000000..8728d451b --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/mcmp/WrapperColored.scala @@ -0,0 +1,14 @@ +package li.cil.oc.integration.mcmp + +import java.util + +import li.cil.oc.api.internal.Colored +import li.cil.oc.common.capabilities.Capabilities +import mcmultipart.capabilities.ICapabilityWrapper +import net.minecraftforge.common.capabilities.Capability + +object WrapperColored extends ICapabilityWrapper[Colored] { + override def getCapability: Capability[Colored] = Capabilities.ColoredCapability + + override def wrapImplementations(implementations: util.Collection[Colored]): Colored = implementations.iterator().next() +} diff --git a/src/main/scala/li/cil/oc/integration/mcmp/WrapperEnvironment.scala b/src/main/scala/li/cil/oc/integration/mcmp/WrapperEnvironment.scala new file mode 100644 index 000000000..f08a2f3c8 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/mcmp/WrapperEnvironment.scala @@ -0,0 +1,14 @@ +package li.cil.oc.integration.mcmp + +import java.util + +import li.cil.oc.api.network.Environment +import li.cil.oc.common.capabilities.Capabilities +import mcmultipart.capabilities.ICapabilityWrapper +import net.minecraftforge.common.capabilities.Capability + +object WrapperEnvironment extends ICapabilityWrapper[Environment] { + override def getCapability: Capability[Environment] = Capabilities.EnvironmentCapability + + override def wrapImplementations(implementations: util.Collection[Environment]): Environment = implementations.iterator().next() +} diff --git a/src/main/scala/li/cil/oc/integration/mcmp/WrapperSidedEnvironment.scala b/src/main/scala/li/cil/oc/integration/mcmp/WrapperSidedEnvironment.scala new file mode 100644 index 000000000..2fb3d7835 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/mcmp/WrapperSidedEnvironment.scala @@ -0,0 +1,14 @@ +package li.cil.oc.integration.mcmp + +import java.util + +import li.cil.oc.api.network.SidedEnvironment +import li.cil.oc.common.capabilities.Capabilities +import mcmultipart.capabilities.ICapabilityWrapper +import net.minecraftforge.common.capabilities.Capability + +object WrapperSidedEnvironment extends ICapabilityWrapper[SidedEnvironment] { + override def getCapability: Capability[SidedEnvironment] = Capabilities.SidedEnvironmentCapability + + override def wrapImplementations(implementations: util.Collection[SidedEnvironment]): SidedEnvironment = implementations.iterator().next() +}