From 8c6af2f8d5080cb8a1de2963545ac3d835b9e4e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Thu, 22 May 2014 17:45:53 +0200 Subject: [PATCH 1/2] Corrected a trait name in class transformer (yay refactoring). Keyboards behave the same visually as logically. Leads to ugly cable rendering nearby (connecting to thin air) but avoids movement glitches. Closes #264. --- .../cil/oc/common/asm/ClassTransformer.scala | 24 ++++++++++--------- .../cil/oc/common/tileentity/Keyboard.scala | 5 ++-- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/main/scala/li/cil/oc/common/asm/ClassTransformer.scala b/src/main/scala/li/cil/oc/common/asm/ClassTransformer.scala index 9df3efe81..9c2e28489 100644 --- a/src/main/scala/li/cil/oc/common/asm/ClassTransformer.scala +++ b/src/main/scala/li/cil/oc/common/asm/ClassTransformer.scala @@ -20,7 +20,7 @@ class ClassTransformer extends IClassTransformer { override def transform(name: String, transformedName: String, basicClass: Array[Byte]): Array[Byte] = { var transformedClass = basicClass try { - if (name == "li.cil.oc.common.tileentity.Computer" || name == "li.cil.oc.common.tileentity.Rack") { + if (name == "li.cil.oc.common.tileentity.traits.Computer" || name == "li.cil.oc.common.tileentity.Rack") { transformedClass = ensureStargateTechCompatibility(transformedClass) } if (transformedClass != null @@ -52,15 +52,17 @@ class ClassTransformer extends IClassTransformer { classNode.methods.removeAll(incompleteMethods) transformedClass = writeClass(classNode) } - val classNode = newClassNode(transformedClass) - if (classNode.interfaces.contains("li/cil/oc/api/network/SimpleComponent")) { - try { - transformedClass = injectEnvironmentImplementation(classNode, transformedClass) - log.info(s"Successfully injected component logic into class $name.") - } - catch { - case e: Throwable => - log.log(Level.WARNING, s"Failed injecting component logic into class $name.", e) + { + val classNode = newClassNode(transformedClass) + if (classNode.interfaces.contains("li/cil/oc/api/network/SimpleComponent")) { + try { + transformedClass = injectEnvironmentImplementation(classNode) + log.info(s"Successfully injected component logic into class $name.") + } + catch { + case e: Throwable => + log.log(Level.WARNING, s"Failed injecting component logic into class $name.", e) + } } } } @@ -95,7 +97,7 @@ class ClassTransformer extends IClassTransformer { else basicClass } - def injectEnvironmentImplementation(classNode: ClassNode, basicClass: Array[Byte]): Array[Byte] = { + def injectEnvironmentImplementation(classNode: ClassNode): Array[Byte] = { log.fine(s"Injecting methods from Environment interface into ${classNode.name}.") if (!isTileEntity(classNode)) { throw new InjectionFailedException("Found SimpleComponent on something that isn't a tile entity, ignoring.") diff --git a/src/main/scala/li/cil/oc/common/tileentity/Keyboard.scala b/src/main/scala/li/cil/oc/common/tileentity/Keyboard.scala index e57f071a2..1d7c73277 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Keyboard.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Keyboard.scala @@ -31,10 +31,9 @@ class Keyboard(isRemote: Boolean) extends traits.Environment with traits.Rotatab // ----------------------------------------------------------------------- // @SideOnly(Side.CLIENT) - override def canConnect(side: ForgeDirection) = side == facing.getOpposite + override def canConnect(side: ForgeDirection) = hasNodeOnSide(side) - override def sidedNode(side: ForgeDirection) = - if (hasNodeOnSide(side)) node else null + override def sidedNode(side: ForgeDirection) = if (hasNodeOnSide(side)) node else null // Override automatic analyzer implementation for sided environments. override def onAnalyze(player: EntityPlayer, side: Int, hitX: Float, hitY: Float, hitZ: Float) = Array(node) From 31ed1efb310ddfb79afb3a75db74684a9a8e3195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Thu, 22 May 2014 18:33:28 +0200 Subject: [PATCH 2/2] Checking for actual contents when computing screen fill rate and using it to determine whether to even try to render the screen contents or not. --- .../renderer/tileentity/ScreenRenderer.scala | 2 +- .../li/cil/oc/common/tileentity/Screen.scala | 27 ++++++++++++------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/main/scala/li/cil/oc/client/renderer/tileentity/ScreenRenderer.scala b/src/main/scala/li/cil/oc/client/renderer/tileentity/ScreenRenderer.scala index c8901e178..948efc05b 100644 --- a/src/main/scala/li/cil/oc/client/renderer/tileentity/ScreenRenderer.scala +++ b/src/main/scala/li/cil/oc/client/renderer/tileentity/ScreenRenderer.scala @@ -72,7 +72,7 @@ object ScreenRenderer extends TileEntitySpecialRenderer with Callable[Int] with RenderState.setBlendAlpha(math.max(0, 1 - ((distance - fadeDistanceSq) * fadeRatio).toFloat)) } - if (screen.hasPower) { + if (screen.hasPower && screen.relativeLitArea != 0) { MonospaceFontRenderer.init(tileEntityRenderer.renderEngine) compileOrDraw(cache.get(screen, this)) } diff --git a/src/main/scala/li/cil/oc/common/tileentity/Screen.scala b/src/main/scala/li/cil/oc/common/tileentity/Screen.scala index 6af29ded3..4618e04dc 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Screen.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Screen.scala @@ -7,7 +7,7 @@ import li.cil.oc.client.{PacketSender => ClientPacketSender} import li.cil.oc.common.component import li.cil.oc.server.{PacketSender => ServerPacketSender} import li.cil.oc.Settings -import li.cil.oc.util.Color +import li.cil.oc.util.{PackedColor, Color} import net.minecraft.client.Minecraft import net.minecraft.entity.Entity import net.minecraft.entity.player.EntityPlayer @@ -206,22 +206,31 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with override def updateEntity() { super.updateEntity() - if (isServer && isOn && isOrigin && world.getWorldTime % Settings.get.tickFrequency == 0) { + if (isOn && isOrigin && world.getWorldTime % Settings.get.tickFrequency == 0) { if (relativeLitArea < 0) { // The relative lit area is the number of pixels that are not blank // versus the number of pixels in the *current* resolution. This is // scaled to multi-block screens, since we only compute this for the // origin. val (w, h) = buffer.resolution - relativeLitArea = width * height * buffer.lines.foldLeft(0) { - (acc, line) => acc + line.count(' ' !=) + relativeLitArea = width * height * (buffer.lines, buffer.color).zipped.foldLeft(0) { + case (acc, (line, colors)) => acc + (line, colors).zipped.foldLeft(0) { + case (acc2, (char, color)) => + val bg = PackedColor.unpackBackground(color, buffer.depth) + val fg = PackedColor.unpackForeground(color, buffer.depth) + acc2 + (if (char == ' ') if (bg == 0) 0 else 1 + else if (char == 0x2588) if (fg == 0) 0 else 1 + else if (fg == 0 && bg == 0) 0 else 1) + } } / (w * h).toDouble } - val hadPower = hasPower - val neededPower = relativeLitArea * fullyLitCost * Settings.get.tickFrequency - hasPower = buffer.node.tryChangeBuffer(-neededPower) - if (hasPower != hadPower) { - ServerPacketSender.sendScreenPowerChange(this, isOn && hasPower) + if (isServer) { + val hadPower = hasPower + val neededPower = relativeLitArea * fullyLitCost * Settings.get.tickFrequency + hasPower = buffer.node.tryChangeBuffer(-neededPower) + if (hasPower != hadPower) { + ServerPacketSender.sendScreenPowerChange(this, isOn && hasPower) + } } } if (shouldCheckForMultiBlock) {