166 lines
4.7 KiB
Scala
166 lines
4.7 KiB
Scala
package edx.electrical.circuit.component.laser.focus
|
|
|
|
import cpw.mods.fml.client.FMLClientHandler
|
|
import cpw.mods.fml.relauncher.{Side, SideOnly}
|
|
import edx.core.{Electrodynamics, Reference}
|
|
import edx.electrical.circuit.component.laser.{ILaserHandler, Laser}
|
|
import net.minecraft.block.material.Material
|
|
import net.minecraft.item.ItemStack
|
|
import net.minecraft.nbt.NBTTagCompound
|
|
import net.minecraft.network.play.server.S35PacketUpdateTileEntity
|
|
import net.minecraft.network.{NetworkManager, Packet}
|
|
import net.minecraft.util.{MovingObjectPosition, ResourceLocation}
|
|
import net.minecraftforge.client.model.AdvancedModelLoader
|
|
import net.minecraftforge.common.util.ForgeDirection
|
|
import org.lwjgl.opengl.GL11._
|
|
import resonantengine.lib.transform.rotation.Quaternion
|
|
import resonantengine.lib.transform.vector.Vector3
|
|
|
|
import scala.collection.convert.wrapAsJava._
|
|
|
|
object TileMirror
|
|
{
|
|
@SideOnly(Side.CLIENT) val model = AdvancedModelLoader.loadModel(new ResourceLocation(Reference.domain, Reference.modelPath + "mirror.tcn"))
|
|
@SideOnly(Side.CLIENT) val texture = new ResourceLocation(Reference.domain, Reference.modelPath + "mirror.png")
|
|
}
|
|
|
|
/**
|
|
* A mirror reflects lasers.
|
|
*
|
|
* TODO: Make it actually reflect light (render reflection)
|
|
*
|
|
* @author Calclavia
|
|
*/
|
|
class TileMirror extends TileFocus(Material.glass) with ILaserHandler with IFocus
|
|
{
|
|
private var normal = new Vector3(0, 1, 0)
|
|
private var cachedHits = List[Vector3]()
|
|
|
|
domain = ""
|
|
textureName = "stone"
|
|
normalRender = false
|
|
isOpaqueCube = false
|
|
|
|
override def update()
|
|
{
|
|
if (isPowered)
|
|
{
|
|
for (a <- 0 to 5)
|
|
{
|
|
val dir = ForgeDirection.getOrientation(a)
|
|
val axis = new Vector3(dir)
|
|
val rotateAngle = world.getIndirectPowerLevelTo((x.toInt + axis.x).toInt, (y + axis.y).toInt, (z + axis.z).toInt, a) * 15
|
|
|
|
if (rotateAngle > 0)
|
|
{
|
|
normal = normal.transform(new Quaternion(Math.toRadians(rotateAngle), axis)).normalize
|
|
}
|
|
}
|
|
|
|
world.markBlockForUpdate(x.toInt, y.toInt, z.toInt)
|
|
}
|
|
|
|
if (world.getTotalWorldTime % 20 == 0)
|
|
cachedHits = List()
|
|
}
|
|
|
|
override def focus(newPosition: Vector3)
|
|
{
|
|
normal = ((newPosition - toVectorWorld) - 0.5).normalize
|
|
world.markBlockForUpdate(x.toInt, y.toInt, z.toInt)
|
|
}
|
|
|
|
override def getFocus: Vector3 = normal
|
|
|
|
def setFocus(focus: Vector3)
|
|
{
|
|
normal = focus
|
|
}
|
|
|
|
override def getCacheDirections: java.util.List[Vector3] = cachedHits.toList
|
|
|
|
override def onLaserHit(renderStart: Vector3, incidentDirection: Vector3, hit: MovingObjectPosition, color: Vector3, energy: Double): Boolean =
|
|
{
|
|
/**
|
|
* Cache hits
|
|
*/
|
|
cachedHits = incidentDirection :: cachedHits
|
|
|
|
/**
|
|
* Render incoming laser
|
|
*/
|
|
Electrodynamics.proxy.renderLaser(worldObj, renderStart, toVectorWorld + 0.5, color, energy)
|
|
|
|
/**
|
|
* Calculate Reflection
|
|
*/
|
|
val angle = Math.acos(incidentDirection $ normal)
|
|
|
|
val axisOfReflection = incidentDirection.cross(normal)
|
|
val rotateAngle = 2 * angle - Math.PI
|
|
|
|
if (rotateAngle < Math.PI)
|
|
{
|
|
val newDirection = (incidentDirection.clone.transform(new Quaternion(rotateAngle, axisOfReflection))).normalize
|
|
Laser.spawn(worldObj, toVectorWorld+ 0.5 + newDirection * 0.9, toVectorWorld + 0.5, newDirection, color, energy / 1.2)
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
override def getDescriptionPacket: Packet =
|
|
{
|
|
val nbt = new NBTTagCompound()
|
|
writeToNBT(nbt)
|
|
return new S35PacketUpdateTileEntity(x.toInt, y.toInt, z.toInt, 0, nbt)
|
|
}
|
|
|
|
override def writeToNBT(nbt: NBTTagCompound)
|
|
{
|
|
super.writeToNBT(nbt)
|
|
val normalNBT = new NBTTagCompound()
|
|
normal.writeNBT(normalNBT)
|
|
nbt.setTag("normal", normalNBT)
|
|
}
|
|
|
|
override def onDataPacket(net: NetworkManager, pkt: S35PacketUpdateTileEntity)
|
|
{
|
|
val receive = pkt.func_148857_g
|
|
readFromNBT(receive)
|
|
}
|
|
|
|
override def readFromNBT(nbt: NBTTagCompound)
|
|
{
|
|
super.readFromNBT(nbt)
|
|
normal = new Vector3(nbt.getCompoundTag("normal"))
|
|
}
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
override def renderDynamic(pos: Vector3, frame: Float, pass: Int)
|
|
{
|
|
glPushMatrix()
|
|
glTranslated(pos.x + 0.5, pos.y + 0.5, pos.z + 0.5)
|
|
|
|
FMLClientHandler.instance.getClient.renderEngine.bindTexture(TileMirror.texture)
|
|
|
|
val angle = normal.toEulerAngle
|
|
glRotated(angle.yaw, 0, 1, 0)
|
|
glRotated(angle.pitch, 1, 0, 0)
|
|
glRotated(90, 1, 0, 0)
|
|
TileMirror.model.renderOnly("mirror", "mirrorBacking", "standConnector")
|
|
|
|
glPopMatrix()
|
|
}
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
override def renderInventory(itemStack: ItemStack)
|
|
{
|
|
glPushMatrix()
|
|
|
|
FMLClientHandler.instance.getClient.renderEngine.bindTexture(TileMirror.texture)
|
|
TileMirror.model.renderAll()
|
|
|
|
glPopMatrix()
|
|
}
|
|
}
|