diff --git a/assets/opencomputers/textures/blocks/keyboard.png b/assets/opencomputers/textures/blocks/keyboard.png index 3a8b7efd2..b5d233c59 100644 Binary files a/assets/opencomputers/textures/blocks/keyboard.png and b/assets/opencomputers/textures/blocks/keyboard.png differ diff --git a/li/cil/oc/client/renderer/block/BlockRenderer.scala b/li/cil/oc/client/renderer/block/BlockRenderer.scala index 3ad17faa1..ef63d6206 100644 --- a/li/cil/oc/client/renderer/block/BlockRenderer.scala +++ b/li/cil/oc/client/renderer/block/BlockRenderer.scala @@ -2,7 +2,7 @@ package li.cil.oc.client.renderer.block import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler import li.cil.oc.client.renderer.tileentity.{CableRenderer, RobotRenderer} -import li.cil.oc.common.block.{RobotProxy, Keyboard, Cable, Delegator} +import li.cil.oc.common.block.{RobotProxy, Cable, Delegator} import li.cil.oc.common.tileentity import net.minecraft.block.Block import net.minecraft.client.renderer.{Tessellator, RenderBlocks} @@ -17,14 +17,13 @@ object BlockRenderer extends ISimpleBlockRenderingHandler { def shouldRender3DInInventory() = true def renderInventoryBlock(block: Block, metadata: Int, modelID: Int, renderer: RenderBlocks) { + GL11.glPushMatrix() Delegator.subBlock(block, metadata) match { case Some(cable: Cable) => GL11.glTranslatef(0, 0.3f, 0) GL11.glScalef(1.6f, 1.6f, 1.6f) GL11.glTranslatef(-0.5f, -0.5f, -0.5f) CableRenderer.renderCable(ForgeDirection.DOWN.flag) - GL11.glTranslatef(0.5f, 0.5f, 0.5f) - case Some(proxy: RobotProxy) => GL11.glTranslatef(0, -0.1f, 0) GL11.glScalef(1.5f, 1.5f, 1.5f) @@ -38,7 +37,12 @@ object BlockRenderer extends ISimpleBlockRenderingHandler { (icon: Icon) => renderer.renderFaceXNeg(block, 0, 0, 0, icon), (icon: Icon) => renderer.renderFaceXPos(block, 0, 0, 0, icon) ) - block.setBlockBoundsForItemRender() + block match { + case delegator: Delegator[_] => + delegator.setBlockBoundsForItemRender(metadata) + delegator.preItemRender(metadata) + case _ => block.setBlockBoundsForItemRender() + } renderer.setRenderBoundsFromBlock(block) GL11.glTranslatef(-0.5f, -0.5f, -0.5f) val t = Tessellator.instance @@ -48,46 +52,38 @@ object BlockRenderer extends ISimpleBlockRenderingHandler { renderFace(side.ordinal)(renderer.getBlockIconFromSideAndMetadata(block, side.ordinal, metadata)) t.draw() } - GL11.glTranslatef(0.5f, 0.5f, 0.5f) } + GL11.glPopMatrix() } - def renderWorldBlock(world: IBlockAccess, x: Int, y: Int, z: Int, block: Block, modelId: Int, renderer: RenderBlocks) = { - Delegator.subBlock(block, world.getBlockMetadata(x, y, z)) match { - case Some(keyboard: Keyboard) => - world.getBlockTileEntity(x, y, z) match { - case teK: tileentity.Keyboard => - if (teK.facing == ForgeDirection.UP || teK.facing == ForgeDirection.DOWN) { - teK.yaw match { - case ForgeDirection.NORTH => - renderer.uvRotateTop = 0 - renderer.uvRotateBottom = 0 - case ForgeDirection.EAST => - renderer.uvRotateTop = 1 - renderer.uvRotateBottom = 2 - - case ForgeDirection.SOUTH => - renderer.uvRotateTop = 3 - renderer.uvRotateBottom = 3 - case ForgeDirection.WEST => - renderer.uvRotateTop = 2 - renderer.uvRotateBottom = 1 - case _ => - - } - if (teK.facing == ForgeDirection.DOWN) { - renderer.flipTexture = true - } - } - val ret = renderer.renderStandardBlock(block, x, y, z) - renderer.uvRotateTop = 0 - renderer.uvRotateBottom = 0 - renderer.flipTexture = false - ret - case _ => - true + def renderWorldBlock(world: IBlockAccess, x: Int, y: Int, z: Int, block: Block, modelId: Int, renderer: RenderBlocks) = + world.getBlockTileEntity(x, y, z) match { + case keyboard: tileentity.Keyboard => + if (keyboard.facing == ForgeDirection.UP || keyboard.facing == ForgeDirection.DOWN) { + keyboard.yaw match { + case ForgeDirection.NORTH => + renderer.uvRotateTop = 0 + renderer.uvRotateBottom = 0 + case ForgeDirection.SOUTH => + renderer.uvRotateTop = 3 + renderer.uvRotateBottom = 3 + case ForgeDirection.WEST => + renderer.uvRotateTop = 2 + renderer.uvRotateBottom = 1 + case ForgeDirection.EAST => + renderer.uvRotateTop = 1 + renderer.uvRotateBottom = 2 + case _ => throw new AssertionError("Impossible yaw value on keyboard.") + } + if (keyboard.facing == ForgeDirection.DOWN) { + renderer.flipTexture = true + } } + val result = renderer.renderStandardBlock(block, x, y, z) + renderer.uvRotateTop = 0 + renderer.uvRotateBottom = 0 + renderer.flipTexture = false + result case _ => renderer.renderStandardBlock(block, x, y, z) } - } } diff --git a/li/cil/oc/common/block/Delegate.scala b/li/cil/oc/common/block/Delegate.scala index 77c99149c..e0191ac3a 100644 --- a/li/cil/oc/common/block/Delegate.scala +++ b/li/cil/oc/common/block/Delegate.scala @@ -35,7 +35,7 @@ trait Delegate { def canConnectRedstone(world: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection) = false - def canPlaceBlockOnSide(world: World, x: Int, y: Int, z: Int, side: Int) = true + def canPlaceBlockOnSide(world: World, x: Int, y: Int, z: Int, side: ForgeDirection) = true def colorMultiplier(world: IBlockAccess, x: Int, y: Int, z: Int) = getRenderColor @@ -91,6 +91,12 @@ trait Delegate { def setBlockBoundsBasedOnState(world: IBlockAccess, x: Int, y: Int, z: Int) = parent.setBlockBounds(0, 0, 0, 1, 1, 1) + def setBlockBoundsForItemRender(): Unit = parent.setBlockBoundsForItemRender() + + def preItemRender() {} + + def postItemRender() {} + def update(world: World, x: Int, y: Int, z: Int) = {} // ----------------------------------------------------------------------- // diff --git a/li/cil/oc/common/block/Delegator.scala b/li/cil/oc/common/block/Delegator.scala index e18837191..14fbcca57 100644 --- a/li/cil/oc/common/block/Delegator.scala +++ b/li/cil/oc/common/block/Delegator.scala @@ -112,7 +112,7 @@ class Delegator[Child <: Delegate](id: Int) extends Block(id, Material.iron) { override def canPlaceBlockOnSide(world: World, x: Int, y: Int, z: Int, side: Int, stack: ItemStack) = subBlock(stack) match { - case Some(subBlock) => subBlock.canPlaceBlockOnSide(world, x, y, z, side) + case Some(subBlock) => subBlock.canPlaceBlockOnSide(world, x, y, z, ForgeDirection.getOrientation(side).getOpposite) case _ => super.canPlaceBlockOnSide(world, x, y, z, side, stack) } @@ -174,10 +174,6 @@ class Delegator[Child <: Delegate](id: Int) extends Block(id, Material.iron) { super.getCollisionBoundingBoxFromPool(world, x, y, z) } - override def setBlockBoundsForItemRender() { - setBlockBounds(0, 0, 0, 1, 1, 1) - } - override def getBlockTexture(world: IBlockAccess, x: Int, y: Int, z: Int, side: Int) = subBlock(world, x, y, z) match { case Some(subBlock) => @@ -317,6 +313,22 @@ class Delegator[Child <: Delegate](id: Int) extends Block(id, Material.iron) { case _ => } + override def setBlockBoundsForItemRender() { + setBlockBounds(0, 0, 0, 1, 1, 1) + } + + def setBlockBoundsForItemRender(metadata: Int): Unit = + subBlock(metadata) match { + case Some(subBlock) => subBlock.setBlockBoundsForItemRender() + case _ => setBlockBoundsForItemRender() + } + + def preItemRender(metadata: Int) = + subBlock(metadata) match { + case Some(subBlock) => subBlock.preItemRender() + case _ => + } + override def updateTick(world: World, x: Int, y: Int, z: Int, rng: Random) = subBlock(world, x, y, z) match { case Some(subBlock) => subBlock.update(world, x, y, z) diff --git a/li/cil/oc/common/block/Keyboard.scala b/li/cil/oc/common/block/Keyboard.scala index c266eeb6b..bd8250971 100644 --- a/li/cil/oc/common/block/Keyboard.scala +++ b/li/cil/oc/common/block/Keyboard.scala @@ -7,9 +7,10 @@ import net.minecraft.client.renderer.texture.IconRegister import net.minecraft.entity.EntityLivingBase import net.minecraft.entity.player.EntityPlayer import net.minecraft.item.ItemStack -import net.minecraft.util.Icon +import net.minecraft.util.{AxisAlignedBB, Icon} import net.minecraft.world.{IBlockAccess, World} import net.minecraftforge.common.ForgeDirection +import org.lwjgl.opengl.GL11 class Keyboard(val parent: SpecialDelegator) extends SpecialDelegate { val unlocalizedName = "Keyboard" @@ -33,12 +34,11 @@ class Keyboard(val parent: SpecialDelegator) extends SpecialDelegate { case _ => } - override def canPlaceBlockOnSide(world: World, x: Int, y: Int, z: Int, side: Int) = - ForgeDirection.VALID_DIRECTIONS. - map(side => world.getBlockTileEntity(x + side.offsetX, y + side.offsetY, z + side.offsetZ)). - collect { - case screen: tileentity.Screen => screen - }.exists(_.facing.ordinal() != side) + override def canPlaceBlockOnSide(world: World, x: Int, y: Int, z: Int, side: ForgeDirection) = + world.getBlockTileEntity(x + side.offsetX, y + side.offsetY, z + side.offsetZ) match { + case screen: tileentity.Screen => screen.facing != side.getOpposite + case _ => false + } override def isBlockNormalCube(world: World, x: Int, y: Int, z: Int) = false @@ -46,31 +46,44 @@ class Keyboard(val parent: SpecialDelegator) extends SpecialDelegate { override def setBlockBoundsBasedOnState(world: IBlockAccess, x: Int, y: Int, z: Int) = world.getBlockTileEntity(x, y, z) match { - case keyboard: tileentity.Keyboard => - val (forward, up) = keyboard.pitch match { - case side@(ForgeDirection.DOWN | ForgeDirection.UP) => (side, keyboard.yaw) - case _ => (keyboard.yaw, ForgeDirection.UP) - } - val side = forward.getRotation(up) - val x0 = -forward.offsetX * 0.4f - up.offsetX * 0.2f - side.offsetX * 0.4f - val x1 = -forward.offsetX * 0.5f + up.offsetX * 0.2f + side.offsetX * 0.4f - val y0 = -forward.offsetY * 0.4f - up.offsetY * 0.2f - side.offsetY * 0.4f - val y1 = -forward.offsetY * 0.5f + up.offsetY * 0.2f + side.offsetY * 0.4f - val z0 = -forward.offsetZ * 0.4f - up.offsetZ * 0.2f - side.offsetZ * 0.4f - val z1 = -forward.offsetZ * 0.5f + up.offsetZ * 0.2f + side.offsetZ * 0.4f - parent.setBlockBounds( - (x0 min x1) + 0.5f, (y0 min y1) + 0.5f, (z0 min z1) + 0.5f, - (x0 max x1) + 0.5f, (y0 max y1) + 0.5f, (z0 max z1) + 0.5f) + case keyboard: tileentity.Keyboard => parent.setBlockBounds(computeBounds(keyboard.pitch, keyboard.yaw)) case _ => super.setBlockBoundsBasedOnState(world, x, y, z) } + override def setBlockBoundsForItemRender() { + parent.setBlockBounds(computeBounds(ForgeDirection.NORTH, ForgeDirection.WEST)) + } + + override def preItemRender() { + GL11.glTranslatef(-0.75f, 0, 0) + GL11.glScalef(1.5f, 1.5f, 1.5f) + } + + private def computeBounds(pitch: ForgeDirection, yaw: ForgeDirection) = { + val (forward, up) = pitch match { + case side@(ForgeDirection.DOWN | ForgeDirection.UP) => (side, yaw) + case _ => (yaw, ForgeDirection.UP) + } + val side = forward.getRotation(up) + val sizes = Array(7f / 16f, 4f / 16f, 7f / 16f) + val x0 = -up.offsetX * sizes(1) - side.offsetX * sizes(2) - forward.offsetX * sizes(0) + val x1 = up.offsetX * sizes(1) + side.offsetX * sizes(2) - forward.offsetX * 0.5f + val y0 = -up.offsetY * sizes(1) - side.offsetY * sizes(2) - forward.offsetY * sizes(0) + val y1 = up.offsetY * sizes(1) + side.offsetY * sizes(2) - forward.offsetY * 0.5f + val z0 = -up.offsetZ * sizes(1) - side.offsetZ * sizes(2) - forward.offsetZ * sizes(0) + val z1 = up.offsetZ * sizes(1) + side.offsetZ * sizes(2) - forward.offsetZ * 0.5f + AxisAlignedBB.getBoundingBox( + (x0 min x1) + 0.5f, (y0 min y1) + 0.5f, (z0 min z1) + 0.5f, + (x0 max x1) + 0.5f, (y0 max y1) + 0.5f, (z0 max z1) + 0.5f) + } + override def onBlockPlacedBy(world: World, x: Int, y: Int, z: Int, player: EntityLivingBase, item: ItemStack) { super.onBlockPlacedBy(world, x, y, z, player, item) } override def onNeighborBlockChange(world: World, x: Int, y: Int, z: Int, blockId: Int) = world.getBlockTileEntity(x, y, z) match { - case keyboard: tileentity.Keyboard if canPlaceBlockOnSide(world, x, y, z, keyboard.facing.ordinal()) => // Can stay. + case keyboard: tileentity.Keyboard if canPlaceBlockOnSide(world, x, y, z, keyboard.facing.getOpposite) => // Can stay. case _ => parent.dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0) world.setBlockToAir(x, y, z) diff --git a/li/cil/oc/util/Tooltip.scala b/li/cil/oc/util/Tooltip.scala index ed5c52130..8c7e41345 100644 --- a/li/cil/oc/util/Tooltip.scala +++ b/li/cil/oc/util/Tooltip.scala @@ -4,33 +4,33 @@ import net.minecraft.util.EnumChatFormatting object Tooltip { - val Reset = "\u00A7" + EnumChatFormatting.RESET.func_96298_a + val Reset = "\u00A7" + EnumChatFormatting.RESET.func_96298_a // 'r' object Color { - val Aqua = "\u00A7" + EnumChatFormatting.AQUA.func_96298_a - val Black = "\u00A7" + EnumChatFormatting.BLACK.func_96298_a - val Blue = "\u00A7" + EnumChatFormatting.BLUE.func_96298_a - val DarkAqua = "\u00A7" + EnumChatFormatting.DARK_AQUA.func_96298_a - val DarkBlue = "\u00A7" + EnumChatFormatting.DARK_BLUE.func_96298_a - val DarkGray = "\u00A7" + EnumChatFormatting.DARK_GRAY.func_96298_a - val DarkGreen = "\u00A7" + EnumChatFormatting.DARK_GREEN.func_96298_a - val DarkPurple = "\u00A7" + EnumChatFormatting.DARK_PURPLE.func_96298_a - val DarkRed = "\u00A7" + EnumChatFormatting.DARK_RED.func_96298_a - val Gold = "\u00A7" + EnumChatFormatting.GOLD.func_96298_a - val Gray = "\u00A7" + EnumChatFormatting.GRAY.func_96298_a - val Green = "\u00A7" + EnumChatFormatting.GREEN.func_96298_a - val LightPurple = "\u00A7" + EnumChatFormatting.LIGHT_PURPLE.func_96298_a - val Red = "\u00A7" + EnumChatFormatting.RED.func_96298_a - val White = "\u00A7" + EnumChatFormatting.WHITE.func_96298_a - val Yellow = "\u00A7" + EnumChatFormatting.YELLOW.func_96298_a + val Aqua = "\u00A7" + EnumChatFormatting.AQUA.func_96298_a // 'b' + val Black = "\u00A7" + EnumChatFormatting.BLACK.func_96298_a // '0' + val Blue = "\u00A7" + EnumChatFormatting.BLUE.func_96298_a // '9' + val DarkAqua = "\u00A7" + EnumChatFormatting.DARK_AQUA.func_96298_a // '3' + val DarkBlue = "\u00A7" + EnumChatFormatting.DARK_BLUE.func_96298_a // '1' + val DarkGray = "\u00A7" + EnumChatFormatting.DARK_GRAY.func_96298_a // '8' + val DarkGreen = "\u00A7" + EnumChatFormatting.DARK_GREEN.func_96298_a // '2' + val DarkPurple = "\u00A7" + EnumChatFormatting.DARK_PURPLE.func_96298_a // '5' + val DarkRed = "\u00A7" + EnumChatFormatting.DARK_RED.func_96298_a // '4' + val Gold = "\u00A7" + EnumChatFormatting.GOLD.func_96298_a // '6' + val Gray = "\u00A7" + EnumChatFormatting.GRAY.func_96298_a // '7' + val Green = "\u00A7" + EnumChatFormatting.GREEN.func_96298_a // 'a' + val LightPurple = "\u00A7" + EnumChatFormatting.LIGHT_PURPLE.func_96298_a // 'd' + val Red = "\u00A7" + EnumChatFormatting.RED.func_96298_a // 'c' + val White = "\u00A7" + EnumChatFormatting.WHITE.func_96298_a // 'f' + val Yellow = "\u00A7" + EnumChatFormatting.YELLOW.func_96298_a // 'e' } object Format { - val Obfuscated = "\u00A7" + EnumChatFormatting.OBFUSCATED.func_96298_a - val Bold = "\u00A7" + EnumChatFormatting.BOLD.func_96298_a - val StrikeThrough = "\u00A7" + EnumChatFormatting.STRIKETHROUGH.func_96298_a - val Underline = "\u00A7" + EnumChatFormatting.UNDERLINE.func_96298_a - val Italic = "\u00A7" + EnumChatFormatting.ITALIC.func_96298_a + val Obfuscated = "\u00A7" + EnumChatFormatting.OBFUSCATED.func_96298_a // 'k' + val Bold = "\u00A7" + EnumChatFormatting.BOLD.func_96298_a // 'l' + val StrikeThrough = "\u00A7" + EnumChatFormatting.STRIKETHROUGH.func_96298_a // 'm' + val Underline = "\u00A7" + EnumChatFormatting.UNDERLINE.func_96298_a // 'n' + val Italic = "\u00A7" + EnumChatFormatting.ITALIC.func_96298_a // 'o' } def format(value: String, format: String) = format + value + Reset + Color.Gray