diff --git a/src/main/scala/li/cil/oc/common/block/Assembler.scala b/src/main/scala/li/cil/oc/common/block/Assembler.scala index 2cf67b433..9ab930bc4 100644 --- a/src/main/scala/li/cil/oc/common/block/Assembler.scala +++ b/src/main/scala/li/cil/oc/common/block/Assembler.scala @@ -11,9 +11,13 @@ import net.minecraft.util.EnumFacing import net.minecraft.world.IBlockAccess import net.minecraft.world.World -class Assembler extends SimpleBlock with traits.SpecialBlock with traits.PowerAcceptor with traits.StateAware { +class Assembler extends SimpleBlock with traits.PowerAcceptor with traits.StateAware { setLightLevel(0.34f) + override def isOpaqueCube = false + + override def isVisuallyOpaque = super.isVisuallyOpaque + override def isBlockSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = side == EnumFacing.DOWN || side == EnumFacing.UP // ----------------------------------------------------------------------- // diff --git a/src/main/scala/li/cil/oc/common/block/Cable.scala b/src/main/scala/li/cil/oc/common/block/Cable.scala index 336fe07a4..a63508731 100644 --- a/src/main/scala/li/cil/oc/common/block/Cable.scala +++ b/src/main/scala/li/cil/oc/common/block/Cable.scala @@ -29,8 +29,8 @@ import net.minecraftforge.fml.relauncher.SideOnly import scala.collection.mutable.ArrayBuffer -class Cable extends SimpleBlock with traits.Extended with traits.SpecialBlock { - setLightOpacity(0) +class Cable extends SimpleBlock with traits.Extended { + setLightOpacity(2) // For Immibis Microblock support. val ImmibisMicroblocks_TransformableBlockMarker = null @@ -38,6 +38,8 @@ class Cable extends SimpleBlock with traits.Extended with traits.SpecialBlock { // For FMP part coloring. var colorMultiplierOverride: Option[Int] = None + // ----------------------------------------------------------------------- // + override protected def setDefaultExtendedState(state: IBlockState) = setDefaultState(state) override protected def addExtendedState(state: IBlockState, world: IBlockAccess, pos: BlockPos) = @@ -54,6 +56,10 @@ class Cable extends SimpleBlock with traits.Extended with traits.SpecialBlock { // ----------------------------------------------------------------------- // + override def isOpaqueCube = false + + override def isFullCube = false + @SideOnly(Side.CLIENT) override def colorMultiplier(world: IBlockAccess, pos: BlockPos, renderPass: Int) = colorMultiplierOverride.getOrElse(super.colorMultiplier(world, pos, renderPass)) @@ -72,7 +78,7 @@ class Cable extends SimpleBlock with traits.Extended with traits.SpecialBlock { super.onNeighborBlockChange(world, pos, state, neighborBlock) } - override protected def doSetBlockBoundsBasedOnState(world: IBlockAccess, pos: BlockPos): Unit = { + override def setBlockBoundsBasedOnState(world: IBlockAccess, pos: BlockPos): Unit = { setBlockBounds(Cable.bounds(world, pos)) } } diff --git a/src/main/scala/li/cil/oc/common/block/Hologram.scala b/src/main/scala/li/cil/oc/common/block/Hologram.scala index f6d9757e1..d1e71d7f2 100644 --- a/src/main/scala/li/cil/oc/common/block/Hologram.scala +++ b/src/main/scala/li/cil/oc/common/block/Hologram.scala @@ -15,12 +15,16 @@ import net.minecraft.world.World import net.minecraftforge.fml.relauncher.Side import net.minecraftforge.fml.relauncher.SideOnly -class Hologram(val tier: Int) extends SimpleBlock with traits.SpecialBlock { +class Hologram(val tier: Int) extends SimpleBlock { setLightLevel(1) setBlockBounds(0, 0, 0, 1, 0.5f, 1) // ----------------------------------------------------------------------- // + override def isOpaqueCube = false + + override def isFullCube = false + override def isBlockSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = side == EnumFacing.DOWN @SideOnly(Side.CLIENT) diff --git a/src/main/scala/li/cil/oc/common/block/Keyboard.scala b/src/main/scala/li/cil/oc/common/block/Keyboard.scala index 5808aaf31..72a91913f 100644 --- a/src/main/scala/li/cil/oc/common/block/Keyboard.scala +++ b/src/main/scala/li/cil/oc/common/block/Keyboard.scala @@ -7,18 +7,27 @@ import li.cil.oc.common.tileentity import net.minecraft.block.Block import net.minecraft.block.state.IBlockState import net.minecraft.entity.player.EntityPlayer +import net.minecraft.util.AxisAlignedBB import net.minecraft.util.BlockPos import net.minecraft.util.EnumFacing import net.minecraft.world.IBlockAccess import net.minecraft.world.World import org.lwjgl.opengl.GL11 -class Keyboard extends SimpleBlock with traits.SpecialBlock with traits.OmniRotatable { +class Keyboard extends SimpleBlock with traits.OmniRotatable { setLightOpacity(0) // For Immibis Microblock support. val ImmibisMicroblocks_TransformableBlockMarker = null + // ----------------------------------------------------------------------- // + + override def isOpaqueCube = false + + override def isFullCube = false + + // ----------------------------------------------------------------------- // + override protected def setDefaultExtendedState(state: IBlockState) = setDefaultState(state) override def shouldSideBeRendered(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = true @@ -52,7 +61,7 @@ class Keyboard extends SimpleBlock with traits.SpecialBlock with traits.OmniRota }) } - override protected def doSetBlockBoundsBasedOnState(world: IBlockAccess, pos: BlockPos) = + override def setBlockBoundsBasedOnState(world: IBlockAccess, pos: BlockPos) = world.getTileEntity(pos) match { case keyboard: tileentity.Keyboard => setBlockBounds(keyboard.pitch, keyboard.yaw) case _ => @@ -71,9 +80,7 @@ class Keyboard extends SimpleBlock with traits.SpecialBlock with traits.OmniRota val y1 = up.getFrontOffsetY * sizes(1) + side.getFrontOffsetY * sizes(2) - forward.getFrontOffsetY * 0.5f val z0 = -up.getFrontOffsetZ * sizes(1) - side.getFrontOffsetZ * sizes(2) - forward.getFrontOffsetZ * sizes(0) val z1 = up.getFrontOffsetZ * sizes(1) + side.getFrontOffsetZ * sizes(2) - forward.getFrontOffsetZ * 0.5f - setBlockBounds( - math.min(x0, x1) + 0.5f, math.min(y0, y1) + 0.5f, math.min(z0, z1) + 0.5f, - math.max(x0, x1) + 0.5f, math.max(y0, y1) + 0.5f, math.max(z0, z1) + 0.5f) + setBlockBounds(new AxisAlignedBB(x0, y0, z0, x1, y1, z1).offset(0.5, 0.5, 0.5)) } override def onNeighborBlockChange(world: World, pos: BlockPos, state: IBlockState, neighborBlock: Block) = diff --git a/src/main/scala/li/cil/oc/common/block/RobotAfterimage.scala b/src/main/scala/li/cil/oc/common/block/RobotAfterimage.scala index 2258dcc24..9055f23e0 100644 --- a/src/main/scala/li/cil/oc/common/block/RobotAfterimage.scala +++ b/src/main/scala/li/cil/oc/common/block/RobotAfterimage.scala @@ -11,18 +11,21 @@ import li.cil.oc.util.Rarity import net.minecraft.block.state.IBlockState 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.MovingObjectPosition -import net.minecraft.util.Vec3i +import net.minecraft.util._ import net.minecraft.world.IBlockAccess import net.minecraft.world.World -class RobotAfterimage extends SimpleBlock with traits.SpecialBlock { +class RobotAfterimage extends SimpleBlock { setLightOpacity(0) setCreativeTab(null) NEI.hide(this) + // ----------------------------------------------------------------------- // + + override def isOpaqueCube = false + + override def isFullCube = false + override def shouldSideBeRendered(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = false override def isBlockSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = false @@ -64,19 +67,16 @@ class RobotAfterimage extends SimpleBlock with traits.SpecialBlock { } } - override protected def doSetBlockBoundsBasedOnState(world: IBlockAccess, pos: BlockPos) { + override def setBlockBoundsBasedOnState(world: IBlockAccess, pos: BlockPos) { findMovingRobot(world, pos) match { case Some(robot) => val block = robot.getBlockType block.setBlockBoundsBasedOnState(world, robot.getPos) val delta = robot.moveFrom.fold(Vec3i.NULL_VECTOR)(robot.getPos.subtract(_)) - setBlockBounds( - block.getBlockBoundsMinX.toFloat + delta.getX, - block.getBlockBoundsMinY.toFloat + delta.getY, - block.getBlockBoundsMinZ.toFloat + delta.getZ, - block.getBlockBoundsMaxX.toFloat + delta.getX, - block.getBlockBoundsMaxY.toFloat + delta.getY, - block.getBlockBoundsMaxZ.toFloat + delta.getZ) + setBlockBounds(new AxisAlignedBB( + block.getBlockBoundsMinX, block.getBlockBoundsMinY, block.getBlockBoundsMinZ, + block.getBlockBoundsMaxX, block.getBlockBoundsMaxY, block.getBlockBoundsMaxZ). + offset(delta.getX, delta.getY, delta.getZ)) case _ => // throw new Exception("Robot afterimage without a robot found. This is a bug!") } } diff --git a/src/main/scala/li/cil/oc/common/block/RobotProxy.scala b/src/main/scala/li/cil/oc/common/block/RobotProxy.scala index a2564c3b1..8b61b5960 100644 --- a/src/main/scala/li/cil/oc/common/block/RobotProxy.scala +++ b/src/main/scala/li/cil/oc/common/block/RobotProxy.scala @@ -26,7 +26,7 @@ import net.minecraft.util._ import net.minecraft.world.IBlockAccess import net.minecraft.world.World -class RobotProxy extends RedstoneAware with traits.SpecialBlock with traits.StateAware { +class RobotProxy extends RedstoneAware with traits.StateAware { setLightOpacity(0) setCreativeTab(null) NEI.hide(this) @@ -39,6 +39,10 @@ class RobotProxy extends RedstoneAware with traits.SpecialBlock with traits.Stat // ----------------------------------------------------------------------- // + override def isOpaqueCube = false + + override def isFullCube = false + override def shouldSideBeRendered(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = false override def isBlockSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = false @@ -150,15 +154,15 @@ class RobotProxy extends RedstoneAware with traits.SpecialBlock with traits.Stat private def gettingDropsForActualDrop = new Exception().getStackTrace.exists(element => getDropForRealDropCallers.contains(element.getClassName + "." + element.getMethodName)) - protected override def intersect(world: World, pos: BlockPos, origin: Vec3, direction: Vec3) = { + override def collisionRayTrace(world: World, pos: BlockPos, origin: Vec3, direction: Vec3) = { val bounds = getCollisionBoundingBox(world, pos, world.getBlockState(pos)) world.getTileEntity(pos) match { case proxy: tileentity.RobotProxy if proxy.robot.animationTicksLeft <= 0 && bounds.isVecInside(origin) => null - case _ => super.intersect(world, pos, origin, direction) + case _ => super.collisionRayTrace(world, pos, origin, direction) } } - protected override def doSetBlockBoundsBasedOnState(world: IBlockAccess, pos: BlockPos) { + override def setBlockBoundsBasedOnState(world: IBlockAccess, pos: BlockPos) { world.getTileEntity(pos) match { case proxy: tileentity.RobotProxy => val robot = proxy.robot @@ -169,7 +173,7 @@ class RobotProxy extends RedstoneAware with traits.SpecialBlock with traits.Stat bounds.offset(delta.getX * remaining, delta.getY * remaining, delta.getZ * remaining) } setBlockBounds(bounds) - case _ => super.doSetBlockBoundsBasedOnState(world, pos) + case _ => super.setBlockBoundsBasedOnState(world, pos) } } diff --git a/src/main/scala/li/cil/oc/common/block/ServerRack.scala b/src/main/scala/li/cil/oc/common/block/ServerRack.scala index c91229cf5..92faf2fbf 100644 --- a/src/main/scala/li/cil/oc/common/block/ServerRack.scala +++ b/src/main/scala/li/cil/oc/common/block/ServerRack.scala @@ -13,7 +13,7 @@ import net.minecraft.world.World import net.minecraftforge.fml.relauncher.Side import net.minecraftforge.fml.relauncher.SideOnly -class ServerRack extends RedstoneAware with traits.SpecialBlock with traits.PowerAcceptor with traits.Rotatable with traits.StateAware { +class ServerRack extends RedstoneAware with traits.PowerAcceptor with traits.Rotatable with traits.StateAware { override protected def setDefaultExtendedState(state: IBlockState) = setDefaultState(state) @SideOnly(Side.CLIENT) diff --git a/src/main/scala/li/cil/oc/common/block/SimpleBlock.scala b/src/main/scala/li/cil/oc/common/block/SimpleBlock.scala index 036d94c72..d67aa71a2 100644 --- a/src/main/scala/li/cil/oc/common/block/SimpleBlock.scala +++ b/src/main/scala/li/cil/oc/common/block/SimpleBlock.scala @@ -30,8 +30,57 @@ abstract class SimpleBlock(material: Material = Material.iron) extends BlockCont protected val validRotations_ = Array(EnumFacing.UP, EnumFacing.DOWN) + protected val bounds = new ThreadLocal[AxisAlignedBB]() { + override def initialValue() = new AxisAlignedBB(minX, minY, minZ, maxX, maxY, maxZ) + } + def createItemStack(amount: Int = 1) = new ItemStack(this, amount) + // ----------------------------------------------------------------------- // + // Synchronized block size, because threading... + // + // These functions can mess things up badly in single player if not + // synchronized because the bounds fields are in an instance stored in the + // static block list... which is used by both server and client thread. + // + // Also, final getBlockBoundsMin/MaxX/Y/Z(), really? + // ----------------------------------------------------------------------- // + + protected def setBlockBounds(bounds: AxisAlignedBB): Unit = { + this.bounds.set(bounds) + setBlockBounds( + bounds.minX.toFloat, + bounds.minY.toFloat, + bounds.minZ.toFloat, + bounds.maxX.toFloat, + bounds.maxY.toFloat, + bounds.maxZ.toFloat) + } + + override def getCollisionBoundingBox(world: World, pos: BlockPos, state: IBlockState) = { + setBlockBoundsBasedOnState(world, pos) + new AxisAlignedBB( + pos.getX + bounds.get.minX, pos.getY + bounds.get.minY, pos.getZ + bounds.get.minZ, + pos.getX + bounds.get.maxX, pos.getY + bounds.get.maxY, pos.getZ + bounds.get.maxZ) + } + + @SideOnly(Side.CLIENT) + override def getSelectedBoundingBox(world: World, pos: BlockPos): AxisAlignedBB = { + new AxisAlignedBB( + pos.getX + bounds.get.minX, pos.getY + bounds.get.minY, pos.getZ + bounds.get.minZ, + pos.getX + bounds.get.maxX, pos.getY + bounds.get.maxY, pos.getZ + bounds.get.maxZ) + } + + @SideOnly(Side.CLIENT) + override def shouldSideBeRendered(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = + (side == EnumFacing.DOWN && bounds.get.minY > 0) || + (side == EnumFacing.UP && bounds.get.maxY < 1) || + (side == EnumFacing.NORTH && bounds.get.minZ > 0) || + (side == EnumFacing.SOUTH && bounds.get.maxZ < 1) || + (side == EnumFacing.WEST && bounds.get.minX > 0) || + (side == EnumFacing.EAST && bounds.get.maxX < 1) || + !world.getBlockState(pos).getBlock.isOpaqueCube + // ----------------------------------------------------------------------- // // Rendering // ----------------------------------------------------------------------- // @@ -144,40 +193,6 @@ abstract class SimpleBlock(material: Material = Material.iron) extends BlockCont case _ => super.recolorBlock(world, pos, side, color) } - // This function can mess things up badly in single player if not - // synchronized because it sets fields in an instance stored in the - // static block list... which is used by both server and client thread. - // The other place where this is locked is in collisionRayTrace below, - // which seems to be the only built-in function that *logically* depends - // on the state bounds (rest is rendering which is unimportant). - final override def setBlockBoundsBasedOnState(world: IBlockAccess, pos: BlockPos) = - this.synchronized(doSetBlockBoundsBasedOnState(world, pos)) - - protected def doSetBlockBoundsBasedOnState(world: IBlockAccess, pos: BlockPos): Unit = - super.setBlockBoundsBasedOnState(world, pos) - - protected def setBlockBounds(bounds: AxisAlignedBB) { - setBlockBounds( - bounds.minX.toFloat, - bounds.minY.toFloat, - bounds.minZ.toFloat, - bounds.maxX.toFloat, - bounds.maxY.toFloat, - bounds.maxZ.toFloat) - } - - // NOTE: must not be final for immibis microblocks to work. - override def collisionRayTrace(world: World, pos: BlockPos, origin: Vec3, end: Vec3) = - this.synchronized(intersect(world, pos, origin, end)) - - override def getCollisionBoundingBox(world: World, pos: BlockPos, state: IBlockState) = this.synchronized { - doSetBlockBoundsBasedOnState(world, pos) - super.getCollisionBoundingBox(world, pos, state) - } - - protected def intersect(world: World, pos: BlockPos, origin: Vec3, end: Vec3) = - super.collisionRayTrace(world, pos, origin, end) - // ----------------------------------------------------------------------- // override def canConnectRedstone(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = false diff --git a/src/main/scala/li/cil/oc/common/block/traits/SpecialBlock.scala b/src/main/scala/li/cil/oc/common/block/traits/SpecialBlock.scala deleted file mode 100644 index cc49b9fc0..000000000 --- a/src/main/scala/li/cil/oc/common/block/traits/SpecialBlock.scala +++ /dev/null @@ -1,14 +0,0 @@ -package li.cil.oc.common.block.traits - -import li.cil.oc.common.block.SimpleBlock -import net.minecraft.util.BlockPos -import net.minecraft.world.IBlockAccess - -trait SpecialBlock extends SimpleBlock { - override def isNormalCube(world: IBlockAccess, pos: BlockPos) = false - - override def isOpaqueCube = false - - // TODO new equivalent? - // override def renderAsNormalBlock = false -} diff --git a/src/main/scala/li/cil/oc/common/entity/Drone.scala b/src/main/scala/li/cil/oc/common/entity/Drone.scala index 95df3e62a..5b803db74 100644 --- a/src/main/scala/li/cil/oc/common/entity/Drone.scala +++ b/src/main/scala/li/cil/oc/common/entity/Drone.scala @@ -228,24 +228,24 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern override def entityInit() { // Running or not. - dataWatcher.addObject(2, byte2Byte(0: Byte)) + dataWatcher.addObject(5, byte2Byte(0: Byte)) // Target position. - dataWatcher.addObject(3, float2Float(0f)) - dataWatcher.addObject(4, float2Float(0f)) - dataWatcher.addObject(5, float2Float(0f)) - // Max acceleration. dataWatcher.addObject(6, float2Float(0f)) + dataWatcher.addObject(7, float2Float(0f)) + dataWatcher.addObject(8, float2Float(0f)) + // Max acceleration. + dataWatcher.addObject(9, float2Float(0f)) // Selected inventory slot. - dataWatcher.addObject(7, byte2Byte(0: Byte)) + dataWatcher.addObject(10, byte2Byte(0: Byte)) // Current and maximum energy. - dataWatcher.addObject(8, int2Integer(0)) - dataWatcher.addObject(9, int2Integer(100)) + dataWatcher.addObject(11, int2Integer(0)) + dataWatcher.addObject(12, int2Integer(100)) // Status text. - dataWatcher.addObject(10, "") + dataWatcher.addObject(13, "") // Inventory size for client. - dataWatcher.addObject(11, byte2Byte(0: Byte)) + dataWatcher.addObject(14, byte2Byte(0: Byte)) // Light color. - dataWatcher.addObject(12, int2Integer(0x66DD55)) + dataWatcher.addObject(15, int2Integer(0x66DD55)) } def initializeAfterPlacement(stack: ItemStack, player: EntityPlayer, position: Vec3) { @@ -272,50 +272,50 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern components.connectComponents() } - def isRunning = dataWatcher.getWatchableObjectByte(2) != 0 + def isRunning = dataWatcher.getWatchableObjectByte(5) != 0 - def targetX = dataWatcher.getWatchableObjectFloat(3) + def targetX = dataWatcher.getWatchableObjectFloat(6) - def targetY = dataWatcher.getWatchableObjectFloat(4) + def targetY = dataWatcher.getWatchableObjectFloat(7) - def targetZ = dataWatcher.getWatchableObjectFloat(5) + def targetZ = dataWatcher.getWatchableObjectFloat(8) - def targetAcceleration = dataWatcher.getWatchableObjectFloat(6) + def targetAcceleration = dataWatcher.getWatchableObjectFloat(9) - def selectedSlot = dataWatcher.getWatchableObjectByte(7) & 0xFF + def selectedSlot = dataWatcher.getWatchableObjectByte(10) & 0xFF - def globalBuffer = dataWatcher.getWatchableObjectInt(8) + def globalBuffer = dataWatcher.getWatchableObjectInt(11) - def globalBufferSize = dataWatcher.getWatchableObjectInt(9) + def globalBufferSize = dataWatcher.getWatchableObjectInt(12) - def statusText = dataWatcher.getWatchableObjectString(10) + def statusText = dataWatcher.getWatchableObjectString(13) - def inventorySize = dataWatcher.getWatchableObjectByte(11) & 0xFF + def inventorySize = dataWatcher.getWatchableObjectByte(14) & 0xFF - def lightColor = dataWatcher.getWatchableObjectInt(12) + def lightColor = dataWatcher.getWatchableObjectInt(15) - def setRunning(value: Boolean) = dataWatcher.updateObject(2, byte2Byte(if (value) 1: Byte else 0: Byte)) + def setRunning(value: Boolean) = dataWatcher.updateObject(5, byte2Byte(if (value) 1: Byte else 0: Byte)) // Round target values to low accuracy to avoid floating point errors accumulating. - def targetX_=(value: Float): Unit = dataWatcher.updateObject(3, float2Float(math.round(value * 4) / 4f)) + def targetX_=(value: Float): Unit = dataWatcher.updateObject(6, float2Float(math.round(value * 4) / 4f)) - def targetY_=(value: Float): Unit = dataWatcher.updateObject(4, float2Float(math.round(value * 4) / 4f)) + def targetY_=(value: Float): Unit = dataWatcher.updateObject(7, float2Float(math.round(value * 4) / 4f)) - def targetZ_=(value: Float): Unit = dataWatcher.updateObject(5, float2Float(math.round(value * 4) / 4f)) + def targetZ_=(value: Float): Unit = dataWatcher.updateObject(8, float2Float(math.round(value * 4) / 4f)) - def targetAcceleration_=(value: Float): Unit = dataWatcher.updateObject(6, float2Float(math.max(0, math.min(maxAcceleration, value)))) + def targetAcceleration_=(value: Float): Unit = dataWatcher.updateObject(9, float2Float(math.max(0, math.min(maxAcceleration, value)))) - def selectedSlot_=(value: Int) = dataWatcher.updateObject(7, byte2Byte(value.toByte)) + def selectedSlot_=(value: Int) = dataWatcher.updateObject(10, byte2Byte(value.toByte)) - def globalBuffer_=(value: Int) = dataWatcher.updateObject(8, int2Integer(value)) + def globalBuffer_=(value: Int) = dataWatcher.updateObject(11, int2Integer(value)) - def globalBufferSize_=(value: Int) = dataWatcher.updateObject(9, int2Integer(value)) + def globalBufferSize_=(value: Int) = dataWatcher.updateObject(12, int2Integer(value)) - def statusText_=(value: String) = dataWatcher.updateObject(10, Option(value).map(_.lines.map(_.take(10)).take(2).mkString("\n")).getOrElse("")) + def statusText_=(value: String) = dataWatcher.updateObject(13, Option(value).map(_.lines.map(_.take(10)).take(2).mkString("\n")).getOrElse("")) - def inventorySize_=(value: Int) = dataWatcher.updateObject(11, byte2Byte(value.toByte)) + def inventorySize_=(value: Int) = dataWatcher.updateObject(14, byte2Byte(value.toByte)) - def lightColor_=(value: Int) = dataWatcher.updateObject(12, int2Integer(value)) + def lightColor_=(value: Int) = dataWatcher.updateObject(15, int2Integer(value)) @SideOnly(Side.CLIENT) override def func_180426_a(x: Double, y: Double, z: Double, yaw: Float, pitch: Float, data: Int, unused: Boolean) {