package edx.electrical.circuit.component.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) } }