If we say it's thread safe, that makes it true -- right? right? (#117)

* If we say it's thread safe, that makes it true -- right?  right?

* Threadsafe PatchedRenderBlocks

* Make 3d printed blocks threadsafe
This commit is contained in:
Jason Mitchell 2024-03-01 12:57:45 -08:00 committed by GitHub
parent 9299673622
commit a8c255a10d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 108 additions and 181 deletions

View File

@ -7,113 +7,48 @@ dependencies {
compile("com.google.code.findbugs:jsr305:3.0.2") compile("com.google.code.findbugs:jsr305:3.0.2")
compileOnly("com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-310-GTNH:dev") { compileOnly("com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-310-GTNH:dev") {transitive = false }
transitive = false compileOnly("com.github.GTNewHorizons:EnderStorage:1.5.0:dev") {transitive = false }
} compileOnly("com.github.GTNewHorizons:GT5-Unofficial:5.09.45.25:dev") {transitive = false }
compileOnly("com.github.GTNewHorizons:EnderStorage:1.5.0:dev") { compile("com.github.GTNewHorizons:ForestryMC:4.8.2:dev") {transitive = false }
transitive = false compileOnly("com.github.GTNewHorizons:Railcraft:9.15.3:dev") {transitive = false }
} compile("com.github.GTNewHorizons:NotEnoughItems:2.5.3-GTNH:dev") {transitive = false }
compileOnly("com.github.GTNewHorizons:GT5-Unofficial:5.09.45.25:dev") { compileOnly("com.github.GTNewHorizons:ForgeMultipart:1.4.6:dev") {transitive = false }
transitive = false compile("com.github.GTNewHorizons:CodeChickenLib:1.2.0:dev") {transitive = false }
} compile("com.github.GTNewHorizons:CodeChickenCore:1.2.0:dev") {transitive = false }
compile("com.github.GTNewHorizons:ForestryMC:4.8.2:dev") { compileOnly("com.github.GTNewHorizons:waila:1.6.5:dev") {transitive = false }
transitive = false compileOnly("com.github.GTNewHorizons:Galacticraft:3.1.1-GTNH:dev") {transitive = false }
} compileOnly("com.github.GTNewHorizons:TinkersMechworks:0.3.0:dev") {transitive = false }
compileOnly("com.github.GTNewHorizons:Railcraft:9.15.3:dev") { compileOnly("com.github.GTNewHorizons:ProjectRed:4.9.0-GTNH:dev") {transitive = false }
transitive = false compileOnly("com.github.GTNewHorizons:BloodMagic:1.4.3:dev") {transitive = false }
} compileOnly("com.github.GTNewHorizons:ThaumicEnergistics:1.6.1-GTNH:dev") {transitive = false }
compile("com.github.GTNewHorizons:NotEnoughItems:2.5.3-GTNH:dev") { compileOnly("com.github.GTNewHorizons:ExtraCells2:2.5.34:dev") {transitive = false }
transitive = false compileOnly('com.github.GTNewHorizons:AE2FluidCraft-Rework:1.2.8-gtnh:dev') {transitive = false }
}
compileOnly("com.github.GTNewHorizons:ForgeMultipart:1.4.6:dev") {
transitive = false
}
compile("com.github.GTNewHorizons:CodeChickenLib:1.2.0:dev") {
transitive = false
}
compile("com.github.GTNewHorizons:CodeChickenCore:1.2.0:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:waila:1.6.5:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:Galacticraft:3.1.1-GTNH:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:TinkersMechworks:0.3.0:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:ProjectRed:4.9.0-GTNH:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:BloodMagic:1.4.3:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:ThaumicEnergistics:1.6.1-GTNH:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:ExtraCells2:2.5.34:dev") {
transitive = false
}
compileOnly('com.github.GTNewHorizons:AE2FluidCraft-Rework:1.2.8-gtnh:dev') {
transitive = false
}
compile("com.github.GTNewHorizons:EnderIO:2.6.1:dev") { compile("com.github.GTNewHorizons:EnderIO:2.6.1:dev") {
compile("com.github.GTNewHorizons:EnderCore:0.3.0:dev") compile("com.github.GTNewHorizons:EnderCore:0.3.0:dev")
transitive = false
}
compileOnly("com.github.GTNewHorizons:Avaritiaddons:1.6.0-GTNH:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:gendustry:1.7.0-GTNH:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:WirelessRedstone-CBE:1.5.0:dev") {
transitive = false
}
compileOnly("com.github.GTNewHorizons:BuildCraft:7.1.38:dev") {
transitive = false
}
compileOnly("appeng:RotaryCraft:V5c:api") {
transitive = false
}
compileOnly("com.bluepowermod:BluePower:0.2.928:deobf") {
transitive = false
}
compileOnly("igwmod:IGW-Mod-1.7.10:1.1.3-18:userdev") {
transitive = false
}
compileOnly("li.cil.tis3d:TIS-3D:MC1.7.10-1.2.4.70:dev") {
transitive = false
}
compileOnly("dev.modwarriors.notenoughkeys:NotEnoughKeys:1.7.10-2.0.0b4:deobf-dev") {
transitive = false
}
compileOnly("qmunity:QmunityLib:0.1.105:deobf") {
transitive = false
}
compileOnly("thaumcraft:Thaumcraft:1.7.10-4.2.3.5:dev") {
transitive = false
}
compileOnly("curse.maven:mekanism-268560:2475797") {
transitive = false
}
compileOnly("net.industrial-craft:industrialcraft-2:2.2.828-experimental:dev") {
transitive = false
}
compileOnly("curse.maven:minefactory-reloaded-66672:2366150") {
transitive = false
}
compileOnly("curse.maven:computercraft-67504:2269339") {
transitive = false transitive = false
} }
compileOnly("com.github.GTNewHorizons:Avaritiaddons:1.6.0-GTNH:dev") {transitive = false }
compileOnly("com.github.GTNewHorizons:gendustry:1.7.0-GTNH:dev") {transitive = false }
compileOnly("com.github.GTNewHorizons:WirelessRedstone-CBE:1.5.0:dev") {transitive = false }
compileOnly("com.github.GTNewHorizons:BuildCraft:7.1.38:dev") {transitive = false }
compileOnly("appeng:RotaryCraft:V5c:api") {transitive = false }
compileOnly("com.bluepowermod:BluePower:0.2.928:deobf") {transitive = false }
compileOnly("igwmod:IGW-Mod-1.7.10:1.1.3-18:userdev") {transitive = false }
compileOnly("li.cil.tis3d:TIS-3D:MC1.7.10-1.2.4.70:dev") {transitive = false }
compileOnly("dev.modwarriors.notenoughkeys:NotEnoughKeys:1.7.10-2.0.0b4:deobf-dev") {transitive = false }
compileOnly("qmunity:QmunityLib:0.1.105:deobf") {transitive = false }
compileOnly("thaumcraft:Thaumcraft:1.7.10-4.2.3.5:dev") {transitive = false }
compileOnly("curse.maven:mekanism-268560:2475797") {transitive = false }
compileOnly("net.industrial-craft:industrialcraft-2:2.2.828-experimental:dev") {transitive = false }
compileOnly("curse.maven:minefactory-reloaded-66672:2366150") {transitive = false }
compileOnly("curse.maven:computercraft-67504:2269339") {transitive = false }
compile("curse.maven:cofh-core-69162:2388751") compile("curse.maven:cofh-core-69162:2388751")
compileOnly("curse.maven:agricraft-225635:2284133") { compileOnly("curse.maven:agricraft-225635:2284133") {transitive = false }
transitive = false compileOnly("curse.maven:stargatetech-2-226769:2230351") {transitive = false }
}
compileOnly("curse.maven:stargatetech-2-226769:2230351") { compileOnlyApi("com.github.GTNewHorizons:Angelica:1.0.0-alpha31:api") { transitive = false }
transitive = false
}
compileOnly(deobf("https://immibis.com/mcmoddl/files/redlogic-59.1.13.jar")) compileOnly(deobf("https://immibis.com/mcmoddl/files/redlogic-59.1.13.jar"))
compileOnly files("dependencies/ic2classic-api.zip") //curseforge one does NOT work ... compileOnly files("dependencies/ic2classic-api.zip") //curseforge one does NOT work ...
compileOnly(deobf("https://github.com/purpleposeidon/fz_archive/raw/master/old/Factorization-1.7.10-0.8.108.jar")) compileOnly(deobf("https://github.com/purpleposeidon/fz_archive/raw/master/old/Factorization-1.7.10-0.8.108.jar"))

View File

@ -33,7 +33,7 @@ channel = stable
mappingsVersion = 12 mappingsVersion = 12
# Defines other MCP mappings for dependency deobfuscation. # Defines other MCP mappings for dependency deobfuscation.
remoteMappings = https://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/ remoteMappings = https\://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/
# Select a default username for testing your mod. You can always override this per-run by running # Select a default username for testing your mod. You can always override this per-run by running
# `./gradlew runClient --username=AnotherPlayer`, or configuring this command in your IDE. # `./gradlew runClient --username=AnotherPlayer`, or configuring this command in your IDE.
@ -61,6 +61,9 @@ gradleTokenModId =
# [DEPRECATED] Mod name replacement token. # [DEPRECATED] Mod name replacement token.
gradleTokenModName = gradleTokenModName =
# [DEPRECATED] Mod Group replacement token.
gradleTokenGroupName =
# [DEPRECATED] # [DEPRECATED]
# Multiple source files can be defined here by providing a comma-separated list: Class1.java,Class2.java,Class3.java # Multiple source files can be defined here by providing a comma-separated list: Class1.java,Class2.java,Class3.java
# public static final String VERSION = "GRADLETOKEN_VERSION"; # public static final String VERSION = "GRADLETOKEN_VERSION";
@ -123,7 +126,7 @@ includeWellKnownRepositories = true
usesMavenPublishing = true usesMavenPublishing = true
# Maven repository to publish the mod to. # Maven repository to publish the mod to.
# mavenPublishUrl = https://nexus.gtnewhorizons.com/repository/releases/ # mavenPublishUrl = https\://nexus.gtnewhorizons.com/repository/releases/
# Publishing to Modrinth requires you to set the MODRINTH_TOKEN environment variable to your current Modrinth API token. # Publishing to Modrinth requires you to set the MODRINTH_TOKEN environment variable to your current Modrinth API token.
# #
@ -188,5 +191,4 @@ disableSpotless = true
# ideaCheckSpotlessOnBuild = true # ideaCheckSpotlessOnBuild = true
# Non-GTNH properties # Non-GTNH properties
gradleTokenGroupName =
org.gradle.jvmargs = -Xmx2048m org.gradle.jvmargs = -Xmx2048m

View File

@ -17,7 +17,7 @@ pluginManagement {
} }
plugins { plugins {
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.8' id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.14'
} }

View File

@ -1,10 +1,10 @@
package li.cil.oc.client.renderer.block package li.cil.oc.client.renderer.block
import com.gtnewhorizons.angelica.api.ThreadSafeISBRH
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler
import li.cil.oc.Settings import li.cil.oc.Settings
import li.cil.oc.client.renderer.tileentity.RobotRenderer import li.cil.oc.client.renderer.tileentity.RobotRenderer
import li.cil.oc.common import li.cil.oc.common
import li.cil.oc.util.RenderState
import net.minecraft.block.Block import net.minecraft.block.Block
import net.minecraft.client.renderer.RenderBlocks import net.minecraft.client.renderer.RenderBlocks
import net.minecraft.client.renderer.Tessellator import net.minecraft.client.renderer.Tessellator
@ -13,58 +13,53 @@ import net.minecraft.world.IBlockAccess
import net.minecraftforge.common.util.ForgeDirection import net.minecraftforge.common.util.ForgeDirection
import org.lwjgl.opengl.GL11 import org.lwjgl.opengl.GL11
@ThreadSafeISBRH(perThread = false)
object BlockRenderer extends ISimpleBlockRenderingHandler { object BlockRenderer extends ISimpleBlockRenderingHandler {
def getRenderId = Settings.blockRenderId def getRenderId = Settings.blockRenderId
override def shouldRender3DInInventory(modelID: Int) = true override def shouldRender3DInInventory(modelID: Int) = true
override def renderInventoryBlock(block: Block, metadata: Int, modelID: Int, realRenderer: RenderBlocks) { override def renderInventoryBlock(block: Block, metadata: Int, modelID: Int, realRenderer: RenderBlocks) {
RenderState.checkError(getClass.getName + ".renderInventoryBlock: entering (aka: wasntme)")
val renderer = patchedRenderer(realRenderer, block) val renderer = patchedRenderer(realRenderer, block)
val tessellator = Tessellator.instance
GL11.glPushMatrix() GL11.glPushMatrix()
block match { block match {
case _: common.block.Assembler => case _: common.block.Assembler =>
GL11.glTranslatef(-0.5f, -0.5f, -0.5f) GL11.glTranslatef(-0.5f, -0.5f, -0.5f)
Tessellator.instance.startDrawingQuads() tessellator.startDrawingQuads()
Assembler.render(block, metadata, renderer) Assembler.render(block, metadata, renderer)
Tessellator.instance.draw() tessellator.draw()
RenderState.checkError(getClass.getName + ".renderInventoryBlock: assembler")
case _: common.block.Hologram => case _: common.block.Hologram =>
GL11.glTranslatef(-0.5f, -0.5f, -0.5f) GL11.glTranslatef(-0.5f, -0.5f, -0.5f)
Tessellator.instance.startDrawingQuads() tessellator.startDrawingQuads()
Hologram.render(block, metadata, renderer) Hologram.render(block, metadata, renderer)
Tessellator.instance.draw() tessellator.draw()
RenderState.checkError(getClass.getName + ".renderInventoryBlock: hologram")
case _: common.block.Printer => case _: common.block.Printer =>
GL11.glTranslatef(-0.5f, -0.5f, -0.5f) GL11.glTranslatef(-0.5f, -0.5f, -0.5f)
Tessellator.instance.startDrawingQuads() tessellator.startDrawingQuads()
Printer.render(block, metadata, renderer) Printer.render(block, metadata, renderer)
Tessellator.instance.draw() tessellator.draw()
RenderState.checkError(getClass.getName + ".renderInventoryBlock: printer")
case _@(_: common.block.RobotProxy | _: common.block.RobotAfterimage) => case _@(_: common.block.RobotProxy | _: common.block.RobotAfterimage) =>
GL11.glScalef(1.5f, 1.5f, 1.5f) GL11.glScalef(1.5f, 1.5f, 1.5f)
GL11.glTranslatef(-0.5f, -0.4f, -0.5f) GL11.glTranslatef(-0.5f, -0.4f, -0.5f)
RobotRenderer.renderChassis() RobotRenderer.renderChassis()
RenderState.checkError(getClass.getName + ".renderInventoryBlock: robot")
case _: common.block.NetSplitter => case _: common.block.NetSplitter =>
GL11.glTranslatef(-0.5f, -0.5f, -0.5f) GL11.glTranslatef(-0.5f, -0.5f, -0.5f)
Tessellator.instance.startDrawingQuads() tessellator.startDrawingQuads()
NetSplitter.render(block, metadata, renderer) NetSplitter.render(block, metadata, renderer)
Tessellator.instance.draw() tessellator.draw()
RenderState.checkError(getClass.getName + ".renderInventoryBlock: splitter")
case _: common.block.Transposer => case _: common.block.Transposer =>
GL11.glTranslatef(-0.5f, -0.5f, -0.5f) GL11.glTranslatef(-0.5f, -0.5f, -0.5f)
Tessellator.instance.startDrawingQuads() tessellator.startDrawingQuads()
Transposer.render(block, metadata, renderer) Transposer.render(block, metadata, renderer)
Tessellator.instance.draw() tessellator.draw()
RenderState.checkError(getClass.getName + ".renderInventoryBlock: transposer")
case _ => case _ =>
block match { block match {
case simple: common.block.SimpleBlock => case simple: common.block.SimpleBlock =>
@ -74,86 +69,63 @@ object BlockRenderer extends ISimpleBlockRenderingHandler {
} }
renderer.setRenderBoundsFromBlock(block) renderer.setRenderBoundsFromBlock(block)
GL11.glTranslatef(-0.5f, -0.5f, -0.5f) GL11.glTranslatef(-0.5f, -0.5f, -0.5f)
Tessellator.instance.startDrawingQuads() tessellator.startDrawingQuads()
renderFaceYNeg(block, metadata, renderer) renderFaceYNeg(block, metadata, renderer)
renderFaceYPos(block, metadata, renderer) renderFaceYPos(block, metadata, renderer)
renderFaceZNeg(block, metadata, renderer) renderFaceZNeg(block, metadata, renderer)
renderFaceZPos(block, metadata, renderer) renderFaceZPos(block, metadata, renderer)
renderFaceXNeg(block, metadata, renderer) renderFaceXNeg(block, metadata, renderer)
renderFaceXPos(block, metadata, renderer) renderFaceXPos(block, metadata, renderer)
Tessellator.instance.draw() tessellator.draw()
RenderState.checkError(getClass.getName + ".renderInventoryBlock: standard block")
} }
GL11.glPopMatrix() GL11.glPopMatrix()
RenderState.checkError(getClass.getName + ".renderInventoryBlock: leaving")
} }
override def renderWorldBlock(world: IBlockAccess, x: Int, y: Int, z: Int, block: Block, modelId: Int, realRenderer: RenderBlocks) = { override def renderWorldBlock(world: IBlockAccess, x: Int, y: Int, z: Int, block: Block, modelId: Int, realRenderer: RenderBlocks) = {
RenderState.checkError(getClass.getName + ".renderWorldBlock: entering (aka: wasntme)")
val renderer = patchedRenderer(realRenderer, block) val renderer = patchedRenderer(realRenderer, block)
world.getTileEntity(x, y, z) match { world.getTileEntity(x, y, z) match {
case assembler: common.tileentity.Assembler => case assembler: common.tileentity.Assembler =>
Assembler.render(assembler.block, assembler.getBlockMetadata, x, y, z, renderer) Assembler.render(assembler.block, assembler.getBlockMetadata, x, y, z, renderer)
RenderState.checkError(getClass.getName + ".renderWorldBlock: assembler")
true true
case _: common.tileentity.Cable => case _: common.tileentity.Cable =>
Cable.render(world, x, y, z, block, renderer) Cable.render(world, x, y, z, block, renderer)
RenderState.checkError(getClass.getName + ".renderWorldBlock: cable")
true true
case hologram: common.tileentity.Hologram => case hologram: common.tileentity.Hologram =>
Hologram.render(hologram.block, hologram.getBlockMetadata, x, y, z, renderer) Hologram.render(hologram.block, hologram.getBlockMetadata, x, y, z, renderer)
RenderState.checkError(getClass.getName + ".renderWorldBlock: hologram")
true true
case keyboard: common.tileentity.Keyboard => case keyboard: common.tileentity.Keyboard =>
val result = Keyboard.render(keyboard, x, y, z, block, renderer) val result = Keyboard.render(keyboard, x, y, z, block, renderer)
RenderState.checkError(getClass.getName + ".renderWorldBlock: keyboard")
result result
case print: common.tileentity.Print => case print: common.tileentity.Print =>
Print.render(print.data, print.state, print.facing, x, y, z, block, renderer) Print.render(print.data, print.state, print.facing, x, y, z, block, renderer)
RenderState.checkError(getClass.getName + ".renderWorldBlock: print")
true true
case _: common.tileentity.Printer => case _: common.tileentity.Printer =>
Printer.render(block, x, y, z, renderer) Printer.render(block, x, y, z, renderer)
RenderState.checkError(getClass.getName + ".renderWorldBlock: printer")
true true
case rack: common.tileentity.Rack => case rack: common.tileentity.Rack =>
Rack.render(rack, x, y, z, block.asInstanceOf[common.block.Rack], renderer) Rack.render(rack, x, y, z, block.asInstanceOf[common.block.Rack], renderer)
RenderState.checkError(getClass.getName + ".renderWorldBlock: rack")
true true
case splitter: common.tileentity.NetSplitter => case splitter: common.tileentity.NetSplitter =>
NetSplitter.render(ForgeDirection.VALID_DIRECTIONS.map(splitter.isSideOpen), block, x, y, z, renderer) NetSplitter.render(ForgeDirection.VALID_DIRECTIONS.map(splitter.isSideOpen), block, x, y, z, renderer)
RenderState.checkError(getClass.getName + ".renderWorldBlock: splitter")
true true
case _: common.tileentity.Transposer => case _: common.tileentity.Transposer =>
Transposer.render(block, x, y, z, renderer) Transposer.render(block, x, y, z, renderer)
RenderState.checkError(getClass.getName + ".renderWorldBlock: transposer")
true true
case _ => case _ =>
val result = renderer.renderStandardBlock(block, x, y, z) val result = renderer.renderStandardBlock(block, x, y, z)
RenderState.checkError(getClass.getName + ".renderWorldBlock: standard block")
result result
} }
} }
@ -165,34 +137,38 @@ object BlockRenderer extends ISimpleBlockRenderingHandler {
block.isInstanceOf[common.block.NetSplitter] || block.isInstanceOf[common.block.NetSplitter] ||
block.isInstanceOf[common.block.Transposer] block.isInstanceOf[common.block.Transposer]
val patchedRenderBlocksThreadLocal = new ThreadLocal[PatchedRenderBlocks]() {
override def initialValue = new PatchedRenderBlocks()
}
// The texture flip this works around only seems to occur for blocks with custom block renderers? // The texture flip this works around only seems to occur for blocks with custom block renderers?
def patchedRenderer(renderer: RenderBlocks, block: Block) = def patchedRenderer(renderer: RenderBlocks, block: Block) =
if (needsFlipping(block)) { if (needsFlipping(block)) {
PatchedRenderBlocks.blockAccess = renderer.blockAccess val patchedRenderBlocks = patchedRenderBlocksThreadLocal.get()
PatchedRenderBlocks.overrideBlockTexture = renderer.overrideBlockTexture patchedRenderBlocks.blockAccess = renderer.blockAccess
PatchedRenderBlocks.flipTexture = renderer.flipTexture patchedRenderBlocks.overrideBlockTexture = renderer.overrideBlockTexture
PatchedRenderBlocks.renderAllFaces = renderer.renderAllFaces patchedRenderBlocks.flipTexture = renderer.flipTexture
PatchedRenderBlocks.useInventoryTint = renderer.useInventoryTint patchedRenderBlocks.renderAllFaces = renderer.renderAllFaces
PatchedRenderBlocks.renderFromInside = renderer.renderFromInside patchedRenderBlocks.useInventoryTint = renderer.useInventoryTint
PatchedRenderBlocks.renderMinX = renderer.renderMinX patchedRenderBlocks.renderFromInside = renderer.renderFromInside
PatchedRenderBlocks.renderMaxX = renderer.renderMaxX patchedRenderBlocks.renderMinX = renderer.renderMinX
PatchedRenderBlocks.renderMinY = renderer.renderMinY patchedRenderBlocks.renderMaxX = renderer.renderMaxX
PatchedRenderBlocks.renderMaxY = renderer.renderMaxY patchedRenderBlocks.renderMinY = renderer.renderMinY
PatchedRenderBlocks.renderMinZ = renderer.renderMinZ patchedRenderBlocks.renderMaxY = renderer.renderMaxY
PatchedRenderBlocks.renderMaxZ = renderer.renderMaxZ patchedRenderBlocks.renderMinZ = renderer.renderMinZ
PatchedRenderBlocks.lockBlockBounds = renderer.lockBlockBounds patchedRenderBlocks.renderMaxZ = renderer.renderMaxZ
PatchedRenderBlocks.partialRenderBounds = renderer.partialRenderBounds patchedRenderBlocks.lockBlockBounds = renderer.lockBlockBounds
PatchedRenderBlocks.uvRotateEast = renderer.uvRotateEast patchedRenderBlocks.partialRenderBounds = renderer.partialRenderBounds
PatchedRenderBlocks.uvRotateWest = renderer.uvRotateWest patchedRenderBlocks.uvRotateEast = renderer.uvRotateEast
PatchedRenderBlocks.uvRotateSouth = renderer.uvRotateSouth patchedRenderBlocks.uvRotateWest = renderer.uvRotateWest
PatchedRenderBlocks.uvRotateNorth = renderer.uvRotateNorth patchedRenderBlocks.uvRotateSouth = renderer.uvRotateSouth
PatchedRenderBlocks.uvRotateTop = renderer.uvRotateTop patchedRenderBlocks.uvRotateNorth = renderer.uvRotateNorth
PatchedRenderBlocks.uvRotateBottom = renderer.uvRotateBottom patchedRenderBlocks.uvRotateTop = renderer.uvRotateTop
PatchedRenderBlocks patchedRenderBlocks.uvRotateBottom = renderer.uvRotateBottom
patchedRenderBlocks
} }
else renderer else renderer
object PatchedRenderBlocks extends RenderBlocks { class PatchedRenderBlocks extends RenderBlocks {
override def renderFaceXPos(block: Block, x: Double, y: Double, z: Double, texture: IIcon) { override def renderFaceXPos(block: Block, x: Double, y: Double, z: Double, texture: IIcon) {
flipTexture = !flipTexture flipTexture = !flipTexture
super.renderFaceXPos(block, x, y, z, texture) super.renderFaceXPos(block, x, y, z, texture)

View File

@ -1,9 +1,6 @@
package li.cil.oc.client.renderer.block package li.cil.oc.client.renderer.block
import com.google.common.base.Strings import com.google.common.base.Strings
import li.cil.oc.Constants
import li.cil.oc.api.Items
import li.cil.oc.common.block
import li.cil.oc.common.item.data.PrintData import li.cil.oc.common.item.data.PrintData
import li.cil.oc.util.ExtendedAABB._ import li.cil.oc.util.ExtendedAABB._
import net.minecraft.block.Block import net.minecraft.block.Block
@ -14,15 +11,14 @@ import net.minecraft.util.IIcon
import net.minecraftforge.common.util.ForgeDirection import net.minecraftforge.common.util.ForgeDirection
object Print { object Print {
lazy val printBlock = Items.get(Constants.BlockName.Print).block().asInstanceOf[block.Print]
def render(data: PrintData, state: Boolean, facing: ForgeDirection, x: Int, y: Int, z: Int, block: Block, renderer: RenderBlocks): Unit = { def render(data: PrintData, state: Boolean, facing: ForgeDirection, x: Int, y: Int, z: Int, block: Block, renderer: RenderBlocks): Unit = {
val printBlock = block.asInstanceOf[li.cil.oc.common.block.Print].getPrintBlock
val shapes = if (state) data.stateOn else data.stateOff val shapes = if (state) data.stateOn else data.stateOff
printBlock.isSingleShape = shapes.size == 1 printBlock.isSingleShape = shapes.size == 1
if (shapes.isEmpty) { if (shapes.isEmpty) {
printBlock.textureOverride = Option(resolveTexture("missingno")) printBlock.textureOverride = Option(resolveTexture("missingno"))
renderer.setRenderBounds(0, 0, 0, 1, 1, 1) renderer.setRenderBounds(0, 0, 0, 1, 1, 1)
renderer.renderStandardBlock(block, x, y, z) renderer.renderStandardBlock(printBlock, x, y, z)
} }
else for (shape <- shapes if !Strings.isNullOrEmpty(shape.texture)) { else for (shape <- shapes if !Strings.isNullOrEmpty(shape.texture)) {
val bounds = shape.bounds.rotateTowards(facing) val bounds = shape.bounds.rotateTowards(facing)
@ -31,7 +27,7 @@ object Print {
renderer.setRenderBounds( renderer.setRenderBounds(
bounds.minX, bounds.minY, bounds.minZ, bounds.minX, bounds.minY, bounds.minZ,
bounds.maxX, bounds.maxY, bounds.maxZ) bounds.maxX, bounds.maxY, bounds.maxZ)
renderer.renderStandardBlock(block, x, y, z) renderer.renderStandardBlock(printBlock, x, y, z)
} }
printBlock.colorMultiplierOverride = None printBlock.colorMultiplierOverride = None
printBlock.textureOverride = None printBlock.textureOverride = None

View File

@ -6,6 +6,9 @@ import java.util.Random
import com.google.common.base.Strings import com.google.common.base.Strings
import cpw.mods.fml.relauncher.Side import cpw.mods.fml.relauncher.Side
import cpw.mods.fml.relauncher.SideOnly import cpw.mods.fml.relauncher.SideOnly
import li.cil.oc.api.Items
import li.cil.oc.Constants
import li.cil.oc.Localization import li.cil.oc.Localization
import li.cil.oc.Settings import li.cil.oc.Settings
import li.cil.oc.common.item.data.PrintData import li.cil.oc.common.item.data.PrintData
@ -30,7 +33,7 @@ import net.minecraftforge.common.util.ForgeDirection
import scala.collection.convert.WrapAsJava._ import scala.collection.convert.WrapAsJava._
import scala.reflect.ClassTag import scala.reflect.ClassTag
class Print(protected implicit val tileTag: ClassTag[tileentity.Print]) extends RedstoneAware with traits.SpecialBlock with traits.CustomDrops[tileentity.Print] { class Print(protected implicit val tileTag: ClassTag[tileentity.Print]) extends RedstoneAware with traits.SpecialBlock with traits.CustomDrops[tileentity.Print] with scala.Cloneable {
setLightOpacity(0) setLightOpacity(0)
setHardness(1) setHardness(1)
setCreativeTab(null) setCreativeTab(null)
@ -44,6 +47,21 @@ class Print(protected implicit val tileTag: ClassTag[tileentity.Print]) extends
// Again, used in model rendering, used to know whether we can potentially skip rendering sides. // Again, used in model rendering, used to know whether we can potentially skip rendering sides.
var isSingleShape = false var isSingleShape = false
override def clone(): Print = {
val clone = super.clone().asInstanceOf[Print]
clone.colorMultiplierOverride = colorMultiplierOverride
clone.textureOverride = textureOverride
clone.isSingleShape = isSingleShape
clone
}
lazy val printBlockThreadLocal = new ThreadLocal[Print]() {
override def initialValue: Print = Items.get(Constants.BlockName.Print).block().asInstanceOf[Print].clone()
}
def getPrintBlock: Print = printBlockThreadLocal.get()
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
override def getIcon(world: IBlockAccess, x: Int, y: Int, z: Int, globalSide: ForgeDirection, localSide: ForgeDirection): IIcon = override def getIcon(world: IBlockAccess, x: Int, y: Int, z: Int, globalSide: ForgeDirection, localSide: ForgeDirection): IIcon =
textureOverride.getOrElse(super.getIcon(world, x, y, z, globalSide, localSide)) textureOverride.getOrElse(super.getIcon(world, x, y, z, globalSide, localSide))

View File

@ -102,7 +102,7 @@ class PrintPart(val original: Option[tileentity.Print] = None) extends SimpleBlo
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def simpleBlock = Items.get(Constants.BlockName.Print).block().asInstanceOf[Print] override def simpleBlock = Items.get(Constants.BlockName.Print).block().asInstanceOf[Print].getPrintBlock
def getType = Settings.namespace + Constants.BlockName.Print def getType = Settings.namespace + Constants.BlockName.Print