mirror of
https://github.com/GTNewHorizons/ForgeMultipart.git
synced 2026-11-12 16:37:38 +00:00
270 lines
8.3 KiB
Scala
270 lines
8.3 KiB
Scala
package codechicken.microblock
|
|
|
|
import codechicken.core.vec.Cuboid6
|
|
import codechicken.core.vec.Scale
|
|
import codechicken.core.vec.Vector3
|
|
import codechicken.core.raytracer.SelectionBox
|
|
import codechicken.core.vec.TransformationList
|
|
import codechicken.core.vec.AxisCycle
|
|
import codechicken.core.vec.Rotation
|
|
import codechicken.multipart.TMultiPart
|
|
import codechicken.multipart.TNormalOcclusion
|
|
import codechicken.multipart.JPartialOcclusion
|
|
import codechicken.multipart.NormalOcclusionTest
|
|
import codechicken.multipart.TileMultipart
|
|
import codechicken.multipart.MultiPartRegistry
|
|
import codechicken.core.lighting.LazyLightMatrix
|
|
import codechicken.microblock.MicroMaterialRegistry.IMicroMaterial
|
|
import cpw.mods.fml.relauncher.SideOnly
|
|
import cpw.mods.fml.relauncher.Side
|
|
import codechicken.scala.ScalaBridge._
|
|
import codechicken.core.raytracer.ExtendedMOP
|
|
|
|
object EdgePlacement extends PlacementProperties
|
|
{
|
|
import codechicken.multipart.PartMap._
|
|
|
|
def microClass = EdgeMicroClass
|
|
|
|
def placementGrid = EdgePlacementGrid
|
|
|
|
def opposite(slot:Int, side:Int):Int =
|
|
{
|
|
if(slot < 0)//custom placement
|
|
return slot
|
|
val e = slot-15
|
|
return 15+(packEdgeBits(e, unpackEdgeBits(e)^(1<<(side>>1))))
|
|
}
|
|
|
|
override def customPlacement(pmt:MicroblockPlacement):ExecutablePlacement =
|
|
{
|
|
if(pmt.size%2 == 1) return null
|
|
|
|
val part = PostMicroClass.create(pmt.size, pmt.hit.sideHit>>1, pmt.material, pmt.world.isRemote)
|
|
if(pmt.doExpand)
|
|
{
|
|
val hpart = pmt.htile.partList(ExtendedMOP.getData[(Int, _)](pmt.hit)._1)
|
|
if(hpart.getType == PostMicroClass.getName)
|
|
{
|
|
val mpart = hpart.asInstanceOf[Microblock]
|
|
if(mpart.material == pmt.material && mpart.getSize + pmt.size < 8)
|
|
{
|
|
part.shape = ((mpart.getSize+pmt.size)<<4|mpart.getShape).toByte
|
|
return pmt.expand(mpart, part)
|
|
}
|
|
}
|
|
}
|
|
|
|
if(pmt.slot >= 0)
|
|
return null
|
|
|
|
if(pmt.internal && !pmt.oppMod)
|
|
return pmt.internalPlacement(pmt.htile.asInstanceOf[TileMultipart], part)
|
|
|
|
return pmt.externalPlacement(part)
|
|
}
|
|
}
|
|
|
|
object EdgeMicroClass extends MicroblockClass
|
|
{
|
|
var aBounds:Array[Cuboid6] = new Array(256)
|
|
|
|
for(s <- 0 until 12)
|
|
{
|
|
val rx = if((s&2) != 0) -1 else 1
|
|
val rz = if((s&1) != 0) -1 else 1
|
|
val transform = new TransformationList(new Scale(new Vector3(rx, 1, rz)), AxisCycle.cycles(s>>2)).at(Vector3.center)
|
|
|
|
for(t <- 1 until 8)
|
|
{
|
|
val d = t/8D
|
|
aBounds(t<<4|s) = new SelectionBox(new Cuboid6(0, 0, 0, d, 1, d))
|
|
.transform(transform).bound
|
|
}
|
|
}
|
|
|
|
override def itemSlot = 15
|
|
|
|
def getName = "mcr_edge"
|
|
|
|
def create(client:Boolean) =
|
|
if(client)
|
|
new EdgeMicroblockClient
|
|
else
|
|
new EdgeMicroblock
|
|
|
|
def create(size:Int, slot:Int, material:Int, client:Boolean) =
|
|
if(client)
|
|
new EdgeMicroblockClient(size, slot, material)
|
|
else
|
|
new EdgeMicroblock(size, slot, material)
|
|
|
|
def placementProperties = EdgePlacement
|
|
|
|
override def sizeToVolume(size:Int) = size*size
|
|
|
|
def getDisplayName(size:Int):String = size match
|
|
{
|
|
case 1 => "Strip"
|
|
case 2 => "Post"
|
|
case 4 => "Pillar"
|
|
}
|
|
}
|
|
|
|
class EdgeMicroblockClient(shape$:Byte = 0, material$:Int = 0) extends EdgeMicroblock(shape$, material$) with CommonMicroblockClient
|
|
{
|
|
def this(size:Int, slot:Int, material:Int) = this((size<<4|(slot-15)).toByte, material)
|
|
}
|
|
|
|
class EdgeMicroblock(shape$:Byte = 0, material$:Int = 0) extends CommonMicroblock(shape$, material$)
|
|
{
|
|
def this(size:Int, slot:Int, material:Int) = this((size<<4|(slot-15)).toByte, material)
|
|
|
|
def microClass = EdgeMicroClass
|
|
|
|
def getBounds = EdgeMicroClass.aBounds(shape)
|
|
|
|
override def getSlot = getShape+15
|
|
}
|
|
|
|
object PostMicroClass
|
|
{
|
|
var aBounds:Array[Cuboid6] = new Array(256)
|
|
|
|
for(s <- 0 until 3)
|
|
{
|
|
val transform = Rotation.sideRotations(s<<1).at(Vector3.center)
|
|
for(t <- 2 until 8 by 2)
|
|
{
|
|
val d1 = 0.5-t/16D
|
|
val d2 = 0.5+t/16D
|
|
aBounds(t<<4|s) = new SelectionBox(new Cuboid6(d1, 0, d1, d2, 1, d2))
|
|
.transform(transform).bound
|
|
}
|
|
}
|
|
|
|
def getName = "mcr_post"
|
|
|
|
def create(client:Boolean) =
|
|
if(client)
|
|
new PostMicroblockClient
|
|
else
|
|
new PostMicroblock
|
|
|
|
def create(size:Int, slot:Int, material:Int, client:Boolean) =
|
|
if(client)
|
|
new PostMicroblockClient(size, slot, material)
|
|
else
|
|
new PostMicroblock(size, slot, material)
|
|
|
|
def register() = MultiPartRegistry.registerParts((_, c:Boolean) => create(c), getName)
|
|
}
|
|
|
|
class PostMicroblockClient(shape$:Byte = 0, material$:Int = 0) extends PostMicroblock(shape$, material$) with MicroblockClient
|
|
{
|
|
var renderBounds1:Cuboid6 = _
|
|
var renderBounds2:Cuboid6 = _
|
|
|
|
def this(size:Int, orient:Int, material:Int) = this((size<<4|orient).toByte, material)
|
|
|
|
override def renderStatic(pos:Vector3, olm:LazyLightMatrix, pass:Int)
|
|
{
|
|
val mat = MicroMaterialRegistry.getMaterial(material)
|
|
if(mat != null && pass == mat.getRenderPass)
|
|
render(pos, olm, mat)
|
|
}
|
|
|
|
def render(pos:Vector3, olm:LazyLightMatrix, mat:IMicroMaterial)
|
|
{
|
|
renderCuboid(pos, olm, mat, renderBounds1, 0)
|
|
if(renderBounds2 != null)
|
|
renderCuboid(pos, olm, mat, renderBounds2, 0)
|
|
}
|
|
|
|
override def onPartChanged()
|
|
{
|
|
if(tile.worldObj.isRemote)
|
|
recalcBounds()
|
|
}
|
|
|
|
def recalcBounds()
|
|
{
|
|
renderBounds1 = getBounds.copy
|
|
renderBounds2 = null
|
|
|
|
shrinkFace(getShape<<1)
|
|
shrinkFace(getShape<<1|1)
|
|
|
|
tile.partList.foreach(p =>
|
|
if(p.isInstanceOf[PostMicroblock] && p != this)
|
|
shrinkPost(p.asInstanceOf[PostMicroblock])
|
|
)
|
|
}
|
|
|
|
def shrinkFace(fside:Int)
|
|
{
|
|
val part = tile.partMap(fside)
|
|
if(part != null && part.getType.equals("mcr_face"))
|
|
MicroOcclusion.shrink(renderBounds1, part.asInstanceOf[CommonMicroblock].getBounds, fside)
|
|
}
|
|
|
|
def shrinkPost(post:PostMicroblock)
|
|
{
|
|
if(post == this)
|
|
return
|
|
|
|
if(thisShrinks(post))
|
|
{
|
|
if(renderBounds2 == null)
|
|
{
|
|
renderBounds2 = renderBounds1.copy
|
|
getShape match
|
|
{
|
|
case 0 => renderBounds2.min.y = 0.5; renderBounds1.max.y = 0.5
|
|
case 1 => renderBounds2.min.z = 0.5; renderBounds1.max.z = 0.5
|
|
case 2 => renderBounds2.min.x = 0.5; renderBounds1.max.x = 0.5
|
|
}
|
|
}
|
|
MicroOcclusion.shrink(renderBounds1, post.getBounds, getShape<<1|1)
|
|
MicroOcclusion.shrink(renderBounds2, post.getBounds, getShape<<1)
|
|
}
|
|
}
|
|
|
|
def thisShrinks(other:PostMicroblock):Boolean =
|
|
{
|
|
if(getSize != other.getSize) return getSize < other.getSize
|
|
if(isTransparent != other.isTransparent) return isTransparent
|
|
return getShape > other.getShape
|
|
}
|
|
}
|
|
|
|
class PostMicroblock(shape$:Byte = 0, material$:Int = 0) extends Microblock(shape$, material$) with JPartialOcclusion with TNormalOcclusion
|
|
{
|
|
def this(size:Int, orient:Int, material:Int) = this((size<<4|orient).toByte, material)
|
|
|
|
override def getType = PostMicroClass.getName
|
|
|
|
def getBounds = PostMicroClass.aBounds(shape)
|
|
|
|
def getOcclusionBoxes = Seq(getBounds)
|
|
|
|
def getPartialOcclusionBoxes = getOcclusionBoxes
|
|
|
|
override def itemSizes = EdgeMicroClass.itemSizes
|
|
|
|
override def itemClassID = EdgeMicroClass.classID
|
|
|
|
override def sizeToVolume(size:Int) = EdgeMicroClass.sizeToVolume(size)
|
|
|
|
override def occlusionTest(npart:TMultiPart): Boolean =
|
|
{
|
|
if(npart.isInstanceOf[PostMicroblock])
|
|
return npart.asInstanceOf[PostMicroblock].getShape != getShape
|
|
|
|
if(npart.getType.equals("mcr_face"))
|
|
if(npart.asInstanceOf[CommonMicroblock].getSlot>>1 == getShape)
|
|
return true
|
|
|
|
return super.occlusionTest(npart)
|
|
}
|
|
} |