mirror of
https://github.com/GTNewHorizons/ForgeMultipart.git
synced 2026-11-13 17:04:25 +00:00
251 lines
9.6 KiB
Scala
251 lines
9.6 KiB
Scala
package codechicken.microblock
|
|
|
|
import net.minecraft.entity.player.EntityPlayer
|
|
import net.minecraft.util.MovingObjectPosition
|
|
import codechicken.multipart.TFacePart
|
|
import codechicken.lib.vec.{Translation, Cuboid6, Rotation, Vector3}
|
|
import codechicken.multipart.TNormalOcclusion
|
|
import codechicken.microblock.MicroMaterialRegistry.IMicroMaterial
|
|
import net.minecraft.client.renderer.RenderBlocks
|
|
import codechicken.lib.render.{BlockRenderer, RenderUtils, CCRenderState}
|
|
import scala.collection.JavaConversions._
|
|
import Rotation._
|
|
import Vector3._
|
|
import codechicken.lib.raytracer.IndexedCuboid6
|
|
import org.lwjgl.opengl.GL11
|
|
import codechicken.lib.render.uv.IconTransformation
|
|
import codechicken.lib.lighting.LightMatrix
|
|
|
|
object HollowPlacement extends PlacementProperties
|
|
{
|
|
|
|
object HollowPlacementGrid extends FaceEdgeGrid(3 / 8D)
|
|
|
|
def microClass = HollowMicroClass
|
|
|
|
def placementGrid = HollowPlacementGrid
|
|
|
|
def opposite(slot: Int, side: Int) = slot ^ 1
|
|
|
|
override def expand(slot: Int, side: Int) = sneakOpposite(slot, side)
|
|
|
|
override def sneakOpposite(slot: Int, side: Int) = slot == (side ^ 1)
|
|
}
|
|
|
|
object HollowMicroClass extends MicroblockClass
|
|
{
|
|
var pBoxes: Array[Seq[Cuboid6]] = new Array(256)
|
|
var occBounds: Array[Cuboid6] = new Array(256)
|
|
for (s <- 0 until 6) {
|
|
val transform = sideRotations(s).at(center)
|
|
for (t <- 1 until 8) {
|
|
val d = t / 8D
|
|
val w1 = 1 / 8D
|
|
val w2 = 3 / 16D
|
|
pBoxes(t << 4 | s) = Seq(
|
|
new Cuboid6(0, 0, 0, w1, d, 1),
|
|
new Cuboid6(1 - w1, 0, 0, 1, d, 1),
|
|
new Cuboid6(w1, 0, 0, 1 - w1, d, w1),
|
|
new Cuboid6(w1, 0, 1 - w1, 1 - w1, d, 1))
|
|
.map(_.apply(transform))
|
|
occBounds(t << 4 | s) = new Cuboid6(1 / 8D, 0, 1 / 8D, 7 / 8D, d, 7 / 8D).apply(transform)
|
|
}
|
|
}
|
|
|
|
def getName = "mcr_hllw"
|
|
|
|
def create(client: Boolean) =
|
|
if (client)
|
|
new HollowMicroblock with HollowMicroblockClient
|
|
else
|
|
new HollowMicroblock
|
|
|
|
def create(size: Int, slot: Int, material: Int, client: Boolean) =
|
|
if (client)
|
|
new HollowMicroblock(size, slot, material) with HollowMicroblockClient
|
|
else
|
|
new HollowMicroblock(size, slot, material)
|
|
|
|
def placementProperties = HollowPlacement
|
|
|
|
def getResistanceFactor = 1
|
|
}
|
|
|
|
trait HollowMicroblockClient extends HollowMicroblock with CommonMicroblockClient
|
|
{
|
|
renderMask |= 8 << 8
|
|
|
|
override def recalcBounds() {
|
|
super.recalcBounds()
|
|
renderMask = renderMask & 0xFF | getHollowSize << 8
|
|
}
|
|
|
|
override def drawBreaking(renderBlocks: RenderBlocks) {
|
|
CCRenderState.reset()
|
|
CCRenderState.setPipeline(new Translation(x, y, z), new IconTransformation(renderBlocks.overrideBlockTexture))
|
|
renderHollow(null, 0, getBounds, 0, false,
|
|
(pos: Vector3, mat: IMicroMaterial, pass: Int, c: Cuboid6, sideMask: Int) =>
|
|
BlockRenderer.renderCuboid(c, sideMask))
|
|
}
|
|
|
|
override def render(pos: Vector3, pass: Int) {
|
|
if (pass == -1)
|
|
renderHollow(pos, pass, getBounds, 0, false, MicroblockRender.renderCuboid)
|
|
else if (isTransparent)
|
|
renderHollow(pos, pass, renderBounds, renderMask, false, MicroblockRender.renderCuboid)
|
|
else {
|
|
renderHollow(pos, pass, renderBounds, renderMask | 1 << getSlot, false, MicroblockRender.renderCuboid)
|
|
renderHollow(pos, pass, Cuboid6.full, ~(1 << getSlot), true, MicroblockRender.renderCuboid)
|
|
}
|
|
}
|
|
|
|
def renderHollow(pos: Vector3, pass: Int, c: Cuboid6, sideMask: Int, face: Boolean,
|
|
f: (Vector3, IMicroMaterial, Int, Cuboid6, Int) => Unit) {
|
|
val mat = getIMaterial
|
|
val size = renderMask >> 8
|
|
val d1 = 0.5 - size / 32D
|
|
val d2 = 0.5 + size / 32D
|
|
val x1 = c.min.x
|
|
val x2 = c.max.x
|
|
val y1 = c.min.y
|
|
val y2 = c.max.y
|
|
val z1 = c.min.z
|
|
val z2 = c.max.z
|
|
|
|
var iMask = 0
|
|
getSlot match {
|
|
case 0 | 1 =>
|
|
if (face)
|
|
iMask = 0x3C
|
|
f(pos, mat, pass, new Cuboid6(d1, y1, d2, d2, y2, z2), 0x3B | iMask) //-z internal
|
|
f(pos, mat, pass, new Cuboid6(d1, y1, z1, d2, y2, d1), 0x37 | iMask) //+z internal
|
|
|
|
f(pos, mat, pass, new Cuboid6(d2, y1, d1, x2, y2, d2), sideMask & 0x23 | 0xC | iMask) //-x internal -y+y+x external
|
|
f(pos, mat, pass, new Cuboid6(x1, y1, d1, d1, y2, d2), sideMask & 0x13 | 0xC | iMask) //+x internal -y+y-x external
|
|
|
|
f(pos, mat, pass, new Cuboid6(x1, y1, d2, x2, y2, z2), sideMask & 0x3B | 4 | iMask) //-y+y+z-x+x external
|
|
f(pos, mat, pass, new Cuboid6(x1, y1, z1, x2, y2, d1), sideMask & 0x37 | 8 | iMask) //-y+y-z-x+x external
|
|
case 2 | 3 =>
|
|
if (face)
|
|
iMask = 0x33
|
|
f(pos, mat, pass, new Cuboid6(d2, d1, z1, x2, d2, z2), 0x2F | iMask) //-x internal
|
|
f(pos, mat, pass, new Cuboid6(x1, d1, z1, d1, d2, z2), 0x1F | iMask) //+x internal
|
|
|
|
f(pos, mat, pass, new Cuboid6(d1, d2, z1, d2, y2, z2), sideMask & 0xE | 0x30 | iMask) //-y internal -z+z+y external
|
|
f(pos, mat, pass, new Cuboid6(d1, y1, z1, d2, d1, z2), sideMask & 0xD | 0x30 | iMask) //+y internal -z+z-y external
|
|
|
|
f(pos, mat, pass, new Cuboid6(d2, y1, z1, x2, y2, z2), sideMask & 0x2F | 0x10 | iMask) //-z+z+x-y+y external
|
|
f(pos, mat, pass, new Cuboid6(x1, y1, z1, d1, y2, z2), sideMask & 0x1F | 0x20 | iMask) //-z+z-x-y+y external
|
|
case 4 | 5 =>
|
|
if (face)
|
|
iMask = 0xF
|
|
f(pos, mat, pass, new Cuboid6(x1, d2, d1, x2, y2, d2), 0x3E | iMask) //-y internal
|
|
f(pos, mat, pass, new Cuboid6(x1, y1, d1, x2, d1, d2), 0x3D | iMask) //+y internal
|
|
|
|
f(pos, mat, pass, new Cuboid6(x1, d1, d2, x2, d2, z2), sideMask & 0x38 | 3 | iMask) //-z internal -x+x+z external
|
|
f(pos, mat, pass, new Cuboid6(x1, d1, z1, x2, d2, d1), sideMask & 0x34 | 3 | iMask) //+z internal -x+x-z external
|
|
|
|
f(pos, mat, pass, new Cuboid6(x1, d2, z1, x2, y2, z2), sideMask & 0x3E | 1 | iMask) //-x+x+y-z+z external
|
|
f(pos, mat, pass, new Cuboid6(x1, y1, z1, x2, d1, z2), sideMask & 0x3D | 2 | iMask) //-x+x-y-z+z external
|
|
}
|
|
}
|
|
|
|
override def drawHighlight(hit: MovingObjectPosition, player: EntityPlayer, frame: Float): Boolean = {
|
|
val size = getHollowSize
|
|
val d1 = 0.5 - size / 32D
|
|
val d2 = 0.5 + size / 32D
|
|
val t = (shape >> 4) / 8D
|
|
|
|
import GL11._
|
|
glEnable(GL_BLEND)
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
|
glDisable(GL_TEXTURE_2D)
|
|
glColor4f(0, 0, 0, 0.4F)
|
|
glLineWidth(2)
|
|
glDepthMask(false)
|
|
glPushMatrix()
|
|
RenderUtils.translateToWorldCoords(player, frame)
|
|
glTranslated(x, y, z)
|
|
sideRotations(shape & 0xF).at(center).glApply()
|
|
|
|
RenderUtils.drawCuboidOutline(new Cuboid6(0, 0, 0, 1, t, 1).expand(0.001))
|
|
RenderUtils.drawCuboidOutline(new Cuboid6(d1, 0, d1, d2, t, d2).expand(-0.001))
|
|
glPopMatrix()
|
|
glDepthMask(true)
|
|
glEnable(GL_TEXTURE_2D)
|
|
glDisable(GL_BLEND)
|
|
return true
|
|
}
|
|
}
|
|
|
|
class HollowMicroblock(shape$: Byte = 0, material$: Int = 0) extends CommonMicroblock(shape$, material$) with TFacePart with TNormalOcclusion
|
|
{
|
|
def this(size: Int, shape: Int, material: Int) = this((size << 4 | shape).toByte, material)
|
|
|
|
def microClass = HollowMicroClass
|
|
|
|
def getBounds: Cuboid6 = FaceMicroClass.aBounds(shape)
|
|
|
|
override def getPartialOcclusionBoxes = HollowMicroClass.pBoxes(shape)
|
|
|
|
def getHollowSize = tile match {
|
|
case null => 8
|
|
case _ => tile.partMap(6) match {
|
|
case part: ISidedHollowConnect => part.getHollowSize(getSlot)
|
|
case _ => 8
|
|
}
|
|
}
|
|
|
|
def getOcclusionBoxes = {
|
|
val size = getHollowSize
|
|
val c = HollowMicroClass.occBounds(shape)
|
|
val d1 = 0.5 - size / 32D
|
|
val d2 = 0.5 + size / 32D
|
|
val x1 = c.min.x
|
|
val x2 = c.max.x
|
|
val y1 = c.min.y
|
|
val y2 = c.max.y
|
|
val z1 = c.min.z
|
|
val z2 = c.max.z
|
|
|
|
getSlot match {
|
|
case 0 | 1 =>
|
|
Seq(new Cuboid6(d2, y1, d1, x2, y2, d2),
|
|
new Cuboid6(x1, y1, d1, d1, y2, d2),
|
|
new Cuboid6(x1, y1, d2, x2, y2, z2),
|
|
new Cuboid6(x1, y1, z1, x2, y2, d1))
|
|
case 2 | 3 =>
|
|
Seq(new Cuboid6(d1, d2, z1, d2, y2, z2),
|
|
new Cuboid6(d1, y1, z1, d2, d1, z2),
|
|
new Cuboid6(d2, y1, z1, x2, y2, z2),
|
|
new Cuboid6(x1, y1, z1, d1, y2, z2))
|
|
case 4 | 5 =>
|
|
Seq(new Cuboid6(x1, d1, d2, x2, d2, z2),
|
|
new Cuboid6(x1, d1, z1, x2, d2, d1),
|
|
new Cuboid6(x1, d2, z1, x2, y2, z2),
|
|
new Cuboid6(x1, y1, z1, x2, d1, z2))
|
|
}
|
|
}
|
|
|
|
override def getCollisionBoxes = {
|
|
val size = getHollowSize
|
|
val d1 = 0.5 - size / 32D
|
|
val d2 = 0.5 + size / 32D
|
|
val t = (shape >> 4) / 8D
|
|
|
|
val tr = sideRotations(shape & 0xF).at(center)
|
|
Seq(new Cuboid6(0, 0, 0, 1, t, d1),
|
|
new Cuboid6(0, 0, d2, 1, t, 1),
|
|
new Cuboid6(0, 0, d1, d1, t, d2),
|
|
new Cuboid6(d2, 0, d1, 1, t, d2))
|
|
.map(c => c.apply(tr))
|
|
}
|
|
|
|
override def getSubParts = getCollisionBoxes.map(c => new IndexedCuboid6(0, c))
|
|
|
|
override def allowCompleteOcclusion = true
|
|
|
|
override def solid(side: Int) = false
|
|
|
|
override def redstoneConductionMap = 0x10
|
|
} |