From a6da00f4a9a732bb36f0f9dc5fa4f7f11cd7d7ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Fri, 10 Oct 2014 14:37:32 +0200 Subject: [PATCH] Added some block conversion logic. It's not perfect (item blocks have to be in a player's inventory to get converted), but good enough to justify 1.4 again. --- build.properties | 2 +- .../oc/common/block/DelegatorConverter.scala | 115 ++++++++++++++++++ .../scala/li/cil/oc/common/init/Blocks.scala | 7 ++ .../common/tileentity/traits/TileEntity.scala | 12 +- 4 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 src/main/scala/li/cil/oc/common/block/DelegatorConverter.scala diff --git a/build.properties b/build.properties index 87ced5586..087e35842 100644 --- a/build.properties +++ b/build.properties @@ -1,7 +1,7 @@ minecraft.version=1.7.10 forge.version=10.13.1.1217 -oc.version=2.0.0 +oc.version=1.4.0 oc.subversion=dev ae2.version=rv1+ diff --git a/src/main/scala/li/cil/oc/common/block/DelegatorConverter.scala b/src/main/scala/li/cil/oc/common/block/DelegatorConverter.scala new file mode 100644 index 000000000..45b2e141c --- /dev/null +++ b/src/main/scala/li/cil/oc/common/block/DelegatorConverter.scala @@ -0,0 +1,115 @@ +package li.cil.oc.common.block + +import li.cil.oc.api +import li.cil.oc.common.tileentity +import net.minecraft.block.Block +import net.minecraft.block.material.Material +import net.minecraft.entity.Entity +import net.minecraft.entity.player.EntityPlayer +import net.minecraft.item.ItemBlock +import net.minecraft.item.ItemStack +import net.minecraft.nbt.NBTTagCompound +import net.minecraft.tileentity.TileEntity +import net.minecraft.world.World + +class DelegatorConverter extends Block(Material.rock) { + override def hasTileEntity(metadata: Int) = true + + // We don't have to register this tile entity because it'll vanish immediately anyway, so + // it'll not be saved, therefore not be loaded, therefor no need for the mapping. + override def createTileEntity(world: World, metadata: Int) = new tileentity.traits.TileEntity() {} +} + +object DelegatorConverter { + + class Item(block: Block) extends ItemBlock(block) { + override def onUpdate(stack: ItemStack, world: World, entity: Entity, slot: Int, selected: Boolean) { + entity match { + case player: EntityPlayer => DelegatorConverter.convert(stack, this) match { + case Some(replacement) => player.inventory.setInventorySlotContents(slot, replacement) + case _ => // Nothing to convert. + } + case _ => // Can't convert. + } + } + } + + def convert(world: World, x: Int, y: Int, z: Int, data: Option[NBTTagCompound]) { + val block = world.getBlock(x, y, z) + val meta = world.getBlockMetadata(x, y, z) + getDescriptor(block, meta) match { + case Some(descriptor) => + world.setBlock(x, y, z, descriptor.block()) + data.foreach(nbt => world.getTileEntity(x, y, z) match { + case t: TileEntity => t.readFromNBT(nbt) + case _ => // Failed. + }) + case _ => // Nothing to convert. + } + } + + def convert(stack: ItemStack, item: ItemBlock) = { + val block = item.field_150939_a + val meta = stack.getItemDamage + getDescriptor(block, meta) match { + case Some(descriptor) => Option(descriptor.createItemStack(stack.stackSize)) + case _ => None + } + } + + def getDescriptor(block: Block, meta: Int) = { + val oldName = Block.blockRegistry.getNameForObject(block) + val newName = if (oldName == "OpenComputers:simple") convertSimple(meta) + else if (oldName == "OpenComputers:simple_redstone") convertSimpleRedstone(meta) + else if (oldName == "OpenComputers:special") convertSpecial(meta) + else if (oldName == "OpenComputers:special_redstone") convertSpecialRedstone(meta) + else None + newName.map(api.Items.get) + } + + private def convertSimple(id: Int): Option[String] = id match { + case 0 => Option("adapter") + case 1 => Option("capacitor") + case 2 => Option("diskDrive") + case 3 => Option("powerDistributor") + case 4 => Option("powerConverter") + case 5 => Option("switch") + case 6 => Option("screen1") + case 7 => Option("screen2") + case 8 => Option("screen3") + case 9 => Option("accessPoint") + case 10 => Option("geolyzer") + case 11 => Option("disassembler") + case 12 => Option("motionSensor") + case _ => None + } + + private def convertSimpleRedstone(id: Int): Option[String] = id match { + case 0 => Option("case1") + case 1 => Option("case2") + case 2 => Option("case3") + case 3 => Option("charger") + case 4 => Option("redstone") + case 5 => Option("screen1") + case 6 => Option("screen2") + case 7 => Option("screen3") + case 8 => Option("caseCreative") + case _ => None + } + + private def convertSpecial(id: Int): Option[String] = id match { + case 0 => Option("cable") + case 1 => Option("keyboard") + case 2 => Option("robotAfterimage") + case 3 => Option("hologram1") + case 4 => Option("hologram2") + case 5 => Option("assembler") + case _ => None + } + + private def convertSpecialRedstone(id: Int): Option[String] = id match { + case 0 => Option("robot") + case 1 => Option("serverRack") + case _ => None + } +} \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/common/init/Blocks.scala b/src/main/scala/li/cil/oc/common/init/Blocks.scala index 558965786..802b43f55 100644 --- a/src/main/scala/li/cil/oc/common/init/Blocks.scala +++ b/src/main/scala/li/cil/oc/common/init/Blocks.scala @@ -30,6 +30,13 @@ object Blocks { GameRegistry.registerTileEntity(classOf[tileentity.ServerRack], Settings.namespace + "serverRack") GameRegistry.registerTileEntity(classOf[tileentity.AccessPoint], Settings.namespace + "access_point") + // These are purely for converting existing blocks in delegator format to the new, + // one block type per block format. + GameRegistry.registerBlock(new DelegatorConverter(), classOf[DelegatorConverter.Item], "simple") + GameRegistry.registerBlock(new DelegatorConverter(), classOf[DelegatorConverter.Item], "simple_redstone") + GameRegistry.registerBlock(new DelegatorConverter(), classOf[DelegatorConverter.Item], "special") + GameRegistry.registerBlock(new DelegatorConverter(), classOf[DelegatorConverter.Item], "special_redstone") + // IMPORTANT: the multi block must come first, since the sub blocks will // try to register with it. Also, the order the sub blocks are created in // must not be changed since that order determines their actual IDs. diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/TileEntity.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/TileEntity.scala index 1a6bf8487..23d9a1189 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/TileEntity.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/TileEntity.scala @@ -2,10 +2,12 @@ package li.cil.oc.common.tileentity.traits import cpw.mods.fml.relauncher.Side import cpw.mods.fml.relauncher.SideOnly -import li.cil.oc.client.Sound -import li.cil.oc.util.SideTracker import li.cil.oc.OpenComputers import li.cil.oc.Settings +import li.cil.oc.client.Sound +import li.cil.oc.common.EventHandler +import li.cil.oc.common.block.DelegatorConverter +import li.cil.oc.util.SideTracker import net.minecraft.nbt.NBTTagCompound import net.minecraft.network.NetworkManager import net.minecraft.network.play.server.S35PacketUpdateTileEntity @@ -37,6 +39,7 @@ trait TileEntity extends net.minecraft.tileentity.TileEntity { override def validate() { super.validate() initialize() + EventHandler.schedule(() => DelegatorConverter.convert(world, x, y, z, None)) } override def invalidate() { @@ -60,6 +63,11 @@ trait TileEntity extends net.minecraft.tileentity.TileEntity { // ----------------------------------------------------------------------- // + override def readFromNBT(nbt: NBTTagCompound) { + super.readFromNBT(nbt) + EventHandler.schedule(() => DelegatorConverter.convert(world, x, y, z, Option(nbt))) + } + @SideOnly(Side.CLIENT) def readFromNBTForClient(nbt: NBTTagCompound) {}