keyboard rendering in inventory now respects block bounds, making it look a little nicer; reworked keyboard texture to use same color theme as other blocks; fixed keyboard pop-off logic

This commit is contained in:
Florian Nücke 2013-11-24 18:29:50 +01:00
parent b203059ffa
commit eb2778d7aa
6 changed files with 118 additions and 91 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 B

After

Width:  |  Height:  |  Size: 374 B

View File

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

View File

@ -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) = {}
// ----------------------------------------------------------------------- //

View File

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

View File

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

View File

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