electrodynamics/src/main/scala/edx/quantum/laser/focus/ItemFocusingMatrix.scala
2015-01-27 16:15:44 +08:00

139 lines
4.2 KiB
Scala

package edx.quantum.laser.focus
import cpw.mods.fml.relauncher.{Side, SideOnly}
import edx.core.{EDXCreativeTab, Reference}
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.{Item, ItemStack}
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.{ChatComponentText, EnumChatFormatting}
import net.minecraft.world.World
import resonantengine.lib.transform.rotation.Quaternion
import resonantengine.lib.transform.vector.Vector3
import scala.collection.convert.wrapAsScala._
import scala.util.Random
/**
* @author Calclavia
*/
class ItemFocusingMatrix extends Item
{
setUnlocalizedName(Reference.prefix + "focusingMatrix")
setTextureName(Reference.prefix + "focusingMatrix")
setCreativeTab(EDXCreativeTab)
/**
* allows items to add custom lines of information to the mouseover description
*/
@SideOnly(Side.CLIENT)
override def addInformation(itemStack: ItemStack, player: EntityPlayer, list: java.util.List[_], par4: Boolean)
{
def add[T](list: java.util.List[T], value: Any) = list.add(value.asInstanceOf[T])
add(list, EnumChatFormatting.BLUE + "Right click to select device.")
add(list, EnumChatFormatting.BLUE + "Shift right click to focus device.")
add(list, "Focusing:")
val vec: Vector3 = getControlCoordinate(itemStack)
if (vec != null)
add(list, "[" + vec.xi + ", " + vec.yi + ", " + vec.z.toInt + "]")
else
add(list, "None")
}
def getControlCoordinate(stack: ItemStack): Vector3 =
{
val nbt = stack.getTagCompound
if (nbt != null)
{
return new Vector3(nbt)
}
return null
}
override def onItemUse(itemStack: ItemStack, player: EntityPlayer, world: World, x: Int, y: Int, z: Int, par7: Int, par8: Float, par9: Float, par10: Float): Boolean =
{
val tile = world.getTileEntity(x, y, z)
if (tile.isInstanceOf[IFocus] && !player.isSneaking)
{
if (!world.isRemote)
{
setControlCoordinate(itemStack, new Vector3(tile))
player.addChatMessage(new ChatComponentText("Focusing matrix control block set."))
}
return true
}
else
{
if (!world.isRemote)
{
val controlVec = getControlCoordinate(itemStack)
if (controlVec != null)
{
val controlTile = world.getTileEntity(controlVec.x.toInt, controlVec.y.toInt, controlVec.z.toInt)
if (controlTile.isInstanceOf[IFocus])
{
val focusDevice = controlTile.asInstanceOf[IFocus]
val clickPos = new Vector3(x, y, z) + 0.5
if ((focusDevice.getFocus - ((clickPos - controlVec) - 0.5).normalize).magnitude < 0.1)
{
val cachedHits = focusDevice.getCacheDirections
if (cachedHits != null && cachedHits.size > 0)
{
/**
Pick random cached laser hit and allow it to focus on a block
*/
val rand = new Random(System.currentTimeMillis())
val random_index = rand.nextInt(cachedHits.size)
val incident = cachedHits(random_index).normalize
val targetDirection: Vector3 = (new Vector3(x, y, z) - controlVec).normalize
if (targetDirection.magnitude > 0)
{
val angle = Math.acos(incident $ targetDirection)
val axis: Vector3 = incident.cross(targetDirection)
var focusDirection = incident.clone.transform(new Quaternion(-90 - Math.toDegrees(angle / 2), axis)).normalize
if (focusDirection.magnitude == 0 || focusDirection.magnitude.equals(Double.NaN))
{
focusDirection = targetDirection
}
controlTile.asInstanceOf[IFocus].focus(controlVec + 0.5 + focusDirection)
}
}
}
else
{
if (clickPos != (controlVec + 0.5))
controlTile.asInstanceOf[IFocus].focus(clickPos)
}
}
}
}
return true
}
return false
}
def setControlCoordinate(stack: ItemStack, vec: Vector3)
{
val nbt = if (stack.getTagCompound != null) stack.getTagCompound else new NBTTagCompound()
vec.writeNBT(nbt)
stack.setTagCompound(nbt)
}
}