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")
compileOnly("com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-310-GTNH:dev") {
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
}
compile("com.github.GTNewHorizons:ForestryMC:4.8.2:dev") {
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: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
}
compileOnly("com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-310-GTNH:dev") {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 }
compile("com.github.GTNewHorizons:ForestryMC:4.8.2:dev") {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: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: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") {
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 }
compile("curse.maven:cofh-core-69162:2388751")
compileOnly("curse.maven:agricraft-225635:2284133") {
transitive = false
}
compileOnly("curse.maven:stargatetech-2-226769:2230351") {
transitive = false
}
compileOnly("curse.maven:agricraft-225635:2284133") {transitive = false }
compileOnly("curse.maven:stargatetech-2-226769:2230351") {transitive = false }
compileOnlyApi("com.github.GTNewHorizons:Angelica:1.0.0-alpha31:api") { transitive = false }
compileOnly(deobf("https://immibis.com/mcmoddl/files/redlogic-59.1.13.jar"))
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"))

View File

@ -33,7 +33,7 @@ channel = stable
mappingsVersion = 12
# 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
# `./gradlew runClient --username=AnotherPlayer`, or configuring this command in your IDE.
@ -61,6 +61,9 @@ gradleTokenModId =
# [DEPRECATED] Mod name replacement token.
gradleTokenModName =
# [DEPRECATED] Mod Group replacement token.
gradleTokenGroupName =
# [DEPRECATED]
# 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";
@ -123,7 +126,7 @@ includeWellKnownRepositories = true
usesMavenPublishing = true
# 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.
#
@ -188,5 +191,4 @@ disableSpotless = true
# ideaCheckSpotlessOnBuild = true
# Non-GTNH properties
gradleTokenGroupName =
org.gradle.jvmargs = -Xmx2048m

View File

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

View File

@ -1,9 +1,6 @@
package li.cil.oc.client.renderer.block
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.util.ExtendedAABB._
import net.minecraft.block.Block
@ -14,15 +11,14 @@ import net.minecraft.util.IIcon
import net.minecraftforge.common.util.ForgeDirection
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 = {
val printBlock = block.asInstanceOf[li.cil.oc.common.block.Print].getPrintBlock
val shapes = if (state) data.stateOn else data.stateOff
printBlock.isSingleShape = shapes.size == 1
if (shapes.isEmpty) {
printBlock.textureOverride = Option(resolveTexture("missingno"))
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)) {
val bounds = shape.bounds.rotateTowards(facing)
@ -31,7 +27,7 @@ object Print {
renderer.setRenderBounds(
bounds.minX, bounds.minY, bounds.minZ,
bounds.maxX, bounds.maxY, bounds.maxZ)
renderer.renderStandardBlock(block, x, y, z)
renderer.renderStandardBlock(printBlock, x, y, z)
}
printBlock.colorMultiplierOverride = None
printBlock.textureOverride = None

View File

@ -6,6 +6,9 @@ import java.util.Random
import com.google.common.base.Strings
import cpw.mods.fml.relauncher.Side
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.Settings
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.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)
setHardness(1)
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.
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)
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))

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